conan-io / conan-center-index

Recipes for the ConanCenter repository
https://conan.io/center
MIT License
956 stars 1.75k forks source link

[question] How to build Qt with its dependencies as shared libraries #15403

Open scandyna opened 1 year ago

scandyna commented 1 year ago

What is your question?

As an example, I would like to build qt/5.15.6 with zlib:shared=True.

This is something that I have tried, and it failed on Windows (Linux build worked, probably because zlib is installed in the docker image). Example of a MinGW build:

moc C:\.conan\dd64af\1\qt5\qtbase\src\corelib\animation\qabstractanimation.h 
mingw32-make[4]: *** [Makefile.Release:10149: .moc/release/moc_qabstractanimation.cpp] Error -1073741515
mingw32-make[3]: *** [Makefile:45: release] Error 2

Note that Error -1073741515 means 0xFFFFFFFFC0000135: missing dll.

After investigating: moc (and also rcc) depends on zlib1.dll. Building with zlib:shared=False works.

The question: should something be changed in the recipes to be able to build Qt with its dependencies built as shared libraries ?

I have tried to update the qt/5.x.x recipe on my fork to use VirtualBuildEnv:

...
from conan.tools.env import VirtualBuildEnv
...
generators = "pkg_config", "VirtualBuildEnv"

(Here is the diff).

This does not solve the problem.

Should the zlib recipe also be updated to bring its shared libraries to the PATH ? As an example for Windows only:

def package_info(self):
  self.buildenv_info.prepend_path( "PATH", os.path.join(self.package_folder, "bin") )

If the above is true, should every dependency be updated ? Or is there another mechanism for that ?

Some discussions that seem to be similar:

Note: I only mention zlib here, but building other dependencies, like icu , as shared libraries is also expected.

SpaceIm commented 1 year ago

I don't know how qt5 recipe is written currently, if it has been migrated to conan v2 or not, but since moc is called after being built and it depends on zlib, this recipe should inject VirtualRunEnv into build scope in case of native build:

def generate(self):
    if not cross_building(self):
        VirtualRunEnv(self).generate(scope="build")