Open jgsogo opened 2 years ago
I personally not a fan of fragmentation, where you need to obtain sources from different places in order to get ports for different platforms.
ideally, all patches should go upstream. if it's impossible, I'd say we need to copy their patches. the reason is that we're already apply some patches, which are vital in many cases, but if you will try to use emscripten ports as is, you will lost them. include patches that fix cmake targets and so on. as a result, we may get a very different behavior for emscripten ports.
to my knowledge, most of libraries should port flawlessly. at least ones providing just algorithms. problematic libraries are mostly ones who use various system APIs (graphics, audio, etc).
So you are in this team, right? ▶️ apply patches from the port and build the Conan package as usual
I'm mostly there too, but I would like to find a way to keep those patches updated so people using the port and people using the Conan package can expect the same behavior.
Things are not so simple to patch and/or maintain when including different targets. e.g. the Nintendo Switch
devkitpro provides ports for some common game libraries. See https://github.com/devkitPro/pacman-packages/tree/master/switch
The patches for e.g. SDL2 are non-trivial and conflict with other platforms.
If we want to support this, then it should be possible to conditionally add patches. e.g. for sdl
conandata.yml
patches:
2.0.14:
all:
- patch_file: "patches/2.0.14-0001-fix-this.patch"
base_path: "source_subfolder"
- patch_file: "patches/2.0.14-0002-fix-that.patch"
base_path: "source_subfolder"
Emscripten:
- patch_file: "patches/Emscripten/2.0.14-0001-fix.patch"
base_path: "source_subfolder"
"Nintendo Switch":
- patch_file: "patches/Nintendo Switch/SDL2-2.0.14.patch"
base_path: "source_subfolder"
conanfile.py
def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, {}).get("all", []):
tools.patch(**patch)
for patch in self.conan_data.get("patches", {}).get(self.version, {}).get(str(self.settings.os), []):
tools.patch(**patch)
Looking at the Switch case, it will need special handling anyways in the recipe (=extra requirements + system libraries)
To keep this maintainable, I would add a requirement to include comments/commands on how to update the patches. For the sdl case, this could be:
wget "https://raw.githubusercontent.com/devkitPro/pacman-packages/master/switch/SDL2/SDL2-2.0.14.patch"
or add a helper script that will automatically fetch the newest patches:
update_patches.sh
#!/bin/sh
set -e
wget "https://raw.githubusercontent.com/devkitPro/pacman-packages/master/switch/SDL2/SDL2-2.0.14.patch" -O "patches/Nintendo Switch/SDL2-2.0.14.patch"
conan v2.0 will have helper function to automatically apply patches, so I don't know how that will work.
IMHO, it would also be very pretentious to try to centralize those patches in ConanCenter. We know that fragmentation is bad, but probably a single source of truth where everyone contributes is a dream (and unmaintainable in the long term).
I envision a workflow where the CI will retrieve the patches from those remotes (some script in this repo), put them in place and run the conan create
afterward. Those patches will be uploaded together with the recipe to the remote, so reproducibility is guaranteed, everyone consuming from ConanCenter remote will get them and will be able to build from sources.
No external dependencies, and the patches are maintained by someone else, centralized in a repo where people are dedicated to that effort.
create an empty target with just the corresponding link flag (how to identify the versions!!!)
using pre-built libraries from emsdk
is definitely not an option IMO
for instance, if you link with this pre-built boost:
this will be confusing and misleading, as well it may take a significant time to consumers to debug why options they have passed were silently ignored.
if we cannot afford centralizing patches in our repo, we may create alternative packages for Emscripten, like:
boost-emscripten/1.77.0
(this will require a condition in recipes)boost/1.77.0-emscipten
(this will allow an override)This alias feature request would also be useful to create aliases for different ports.
e.g. for sdl:
class SdlConan(ConanFile):
name = "sdl"
def set_alias(self):
if self.settings.os == "Emscripten":
self.alias = f"emscripten-sdl/{self.version}"
elif self.settings.os == "Nintendo Switch":
self.alias = f"nx-sdl/{self.version}"
else:
# move current sdl recipe to libsdl
self.alias = f"libsdl/{self.version}"
@madebr I think there is really no need in this case to have an alias. You can have regular requires self.requires(f"emscripten-sdl/{self.version}"
.
You mainly need aliases when you want to reference the same package, but a different version of that package.
I'm playing with emscripten these days and I'm not sure how to deal with some of the libraries that are also provided as ports https://github.com/emscripten-ports (probably it's also my poor experience using emscripten).
Currently emscripten 2.0.30 (https://github.com/conan-io/conan-center-index/pull/6163) provides the following ports:
Some of these libraries are already Conan packages and they work if cross-compiled to emscripten, so I'm not sure what is the advantage of using the ports over regular libraries (I haven't check the diff, so maybe without the ports some functions might break in runtime). Also, ports can be outdated, for example,
zlib
is still using1.2.8
.From the Conan perspective we could follow different paths:
if
in the recipe forself.settings.os=="Emscripten"
and create an empty target with just the corresponding link flag (how to identify the versions!!!). Maybe theif
can be conditioned to someuse_emscripten_port: [True, False]
option.