-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
Quite some time ago, I wanted to use the bundled conan version (the one made with PyInstaller) since I’m using scoop on Windows to install most of my software.
At that time, I had an issue with the missing tool conan.tools.scons. I didn’t report the bug back then, and as I was finally about to do it today, I realized it was fixed by PR #17809 as an answer to issue #17808.
Now, while I’m glad it’s finally fixed, there are a few concerns regarding that topic of bundling:
- the mentioned issue is not about
conan.tools.scons, but aboutconan.tools.sbom. That means the applied correction only luckily fixed a technical gap which existed for a while - by the past, other tools were also missing, like
conan.tools.scmas mentioned in issue [bug] Installer package is missing conan.tools.scm #11676 and fixed by PR add conan.tools.scm as hidden-import to pyinstaller #11677. This time, the PR added only that one, while some other tools were already missing - other issues like [bug] Windows installer package is missing python modules (pathlib) #10365 pointed out that
PyInstallerreally pulls by itself only the code which is statically imported, even for the Python standard library apparently, and that the preferred solution remains to install the Python package ofconan, not the bundled version
Still, since the bundled version exists and can be more practical for some, I guess a couple of improvements could be made.
I wonder if you could automatically add all tools, using the --collect-modules=conan.tools option, knowing that you already use that option for something else. I tried it and, at the time of writing, seemed to only bundle one more set of modules, all related to the conan.tools.cps tool, which is a good sign that it may be the right solution.
But if you want more fine grained control, since you are already using a Python script to invoke PyInstaller, you could maybe even loop over your existing conan/tools folder and add all the --hidden-import=conan.tools.xxx options.
First solution looks like this:
# Modules that can be imported in ConanFile conan.tools and errors
"--collect-submodules=conan.cli.commands "
"--hidden-import=conan.errors "
- "--hidden-import=conan.tools.android "
- "--hidden-import=conan.tools.apple "
- "--hidden-import=conan.tools.build "
- "--hidden-import=conan.tools.cmake "
- "--hidden-import=conan.tools.env "
- "--hidden-import=conan.tools.files "
- "--hidden-import=conan.tools.gnu "
- "--hidden-import=conan.tools.google "
- "--hidden-import=conan.tools.intel "
- "--hidden-import=conan.tools.layout "
- "--hidden-import=conan.tools.meson "
- "--hidden-import=conan.tools.microsoft "
- "--hidden-import=conan.tools.premake "
- "--hidden-import=conan.tools.qbs "
- "--hidden-import=conan.tools.ros "
- "--hidden-import=conan.tools.sbom "
- "--hidden-import=conan.tools.scm "
- "--hidden-import=conan.tools.scons "
- "--hidden-import=conan.tools.system "
- "--hidden-import=conan.tools.system.package_manager")
+ "--collect-submodules=conan.tools")and at the time being adds the following modules: conan.cps, conan.cps.cps, conan.tools.cps, conan.tools.cps.cps_deps.
Second solution would be:
+from pathlib import Path
+ tools = (
+ f'--hidden-import=conan.tools.{child.name}'
+ for child in Path(source_folder, 'conan', 'tools').iterdir()
+ if child.is_dir() and child.name != '__pycache__'
+ )
hidden = ("--hidden-import=glob " # core stdlib
"--hidden-import=pathlib "
# Modules that can be imported in ConanFile conan.tools and errors
"--collect-submodules=conan.cli.commands "
"--hidden-import=conan.errors "
- "--hidden-import=conan.tools.android "
- "--hidden-import=conan.tools.apple "
- "--hidden-import=conan.tools.build "
- "--hidden-import=conan.tools.cmake "
- "--hidden-import=conan.tools.env "
- "--hidden-import=conan.tools.files "
- "--hidden-import=conan.tools.gnu "
- "--hidden-import=conan.tools.google "
- "--hidden-import=conan.tools.intel "
- "--hidden-import=conan.tools.layout "
- "--hidden-import=conan.tools.meson "
- "--hidden-import=conan.tools.microsoft "
- "--hidden-import=conan.tools.premake "
- "--hidden-import=conan.tools.qbs "
- "--hidden-import=conan.tools.ros "
- "--hidden-import=conan.tools.sbom "
- "--hidden-import=conan.tools.scm "
- "--hidden-import=conan.tools.scons "
- "--hidden-import=conan.tools.system "
- "--hidden-import=conan.tools.system.package_manager")
+ + ' '.join(tools))and at the time being adds the same modules as solution 1, but as a difference removes module conan.tools.system.package_manager. Indeed, the manual looping over tools needs to handle nested tools if any (like that one) and is harder to maintain.
Btw, I know you have a comment about it in the code, but you are not tying to a specific PyInstaller version and therefore you are relying on the developer to install it, which could be problematic in some situations.
How to reproduce it
Well, there’s not really one scenario, it all depends on whether you want to use a given tool and if it has been bundled or not.
Here’s what I did though to check my changes:
- in the
conanrepository, run thepyinstaller.pyscript - after that, use
pyi-archive_viewer --list --recursive --brief $pathToTheConanBinand check in the output what tools/modules are being bundled or not
I did that multiple times with the 3 different versions (untouched, solution 1 and solution 2) and then output the list to different files that I could diff.