-
-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static linking of Python library for programs not supported #95
Comments
FWIW: I was able to get this solution to work, as I am a user of Environmentpyenv version: 1.2.6
Steps taken
ResultsAfter compiling an internal program, it succeeds and yields an acceptable executable. Hopefully the above information is a confirmation of your thoughts, @kayhayen. Perhaps someone can use this to submit a patch. :) |
Indeed, if somebody were to create a PR, that would be great. Using statically linked libpython would actually make for some nice optimization potential all by itself for link time optimization, which then will make a lot of sense. So there is some benefit to be had. |
On Windows this probably not ever going to work, but for Linux and friends it will be great. |
Checked with pyenv upstream, they are not interested in solving the The main problem will be finding out what library file |
I'm not sure if this really is the same situation, but pyinstaller allows to select a Maybe I found this issue: pyinstaller/pyinstaller#3363. To me it reads like a similar problem? Please excuse me if this is nonsense. I really don't know much about the internals of nuitka and pyinstaller. I just ran into similar looking problems with both tools and thought I should share this. :) |
@feluxe The problem isn't how to specify another The "trouble" is, we would assume a job Scons and the linker normally take care of, to locate this library. Nothing to really want to get into. |
I actually did implement the searching for But without LTO, this is probably not nearly as much fun. However, there are compilers installable in MiniConda, and using those, I expect it to work. So this might be approaching a solution. In general however, say I am still figuring out, how to install the static library into an AnaConda, MiniConda comes with it, but it may only be about finding the right package. |
So the LTO problem can likely be solved by using the Anaconda compiler that can be installed with some As for |
I just came across pyenv/pyenv#65 If you set
|
That should work better @feluxe or so I am thinking. With current code on factory or maybe develop already, static linking is currently automatic for AnaConda only. so the bad libpython is avoided. I have yet to make measurements, but as seen in #150 there are drawbacks to using "libpython.so" definitely, so for best performance this won't be advisable. |
Hmm, this is really unfortunate, IMHO. There is a large amount of people who have their Python dev-environments build around Do you know where |
I totally agree @feluxe which is why I went to the bug tracker some time ago, found a comment that suggesting to ask in the gitter chat before raising an issue, and so I did. Without success. |
This sort of works, but currently setting the CC of AnaConda is a tad bit too manual and needs documentation for Linux and MacOS to be usable generally. Removing factory tag as the code is now in develop and will be in next stable release. |
The quick solution of removing
Briefly looking through the 3.7 code, and the Python 3.8 code, it looks like a non-trivial task for Python 3.7 to create a new .o which includes parts of the original built main.o . However main.c has been split quite neatly in Python 3.8. Oddly they have still included the now tiny main.o into the .a - it now contains very little of use to anyone who is intending to build something which doesnt look and feel like the real CPython. Anyway, when compiling against Python 3.8.0 rc1, I get the following with gcc: [ 1223s] scons: building `cli.build/MetaPathBasedLoader.o' because it doesn't exist
[ 1223s] gcc -o cli.build/MetaPathBasedLoader.o -c -fvisibility=hidden -std=c11 -fwrapv -fpartial-inlining -fno-lto -ffile-prefix-map=cli.build/static_src=/usr/lib/python3.8/site-packages/nuitka/build/static_src -fno-var-tracking -O3 -pipe -D_NUITKA_STANDALONE -D_NUITKA_SYSFLAG_BYTES_WARNING=0 -D_NUITKA_SYSFLAG_NO_SITE=1 -D_NUITKA_SYSFLAG_VERBOSE=0 -D_NUITKA_SYSFLAG_UTF8=1 -D_NUITKA_SYSFLAG_OPTIMIZE=0 -D__NUITKA_NO_ASSERT__ -D_NUITKA_FROZEN=163 -D_NUITKA_MODULE_COUNT=1036 -D_NUITKA_EXE -I/usr/include/python3.8 -I/usr/PC -Icli.build -I/usr/lib/python3.8/site-packages/nuitka/build/include -I/usr/lib/python3.8/site-packages/nuitka/build/static_src cli.build/MetaPathBasedLoader.c
[ 1224s] cli.build/MetaPathBasedLoader.c: In function ‘callIntoShlibModule’:
[ 1224s] cli.build/MetaPathBasedLoader.c:430:50: error: dereferencing pointer to incomplete type ‘PyInterpreterState’ {aka ‘struct _is’}
[ 1224s] 430 | int dlopenflags = PyThreadState_GET()->interp->dlopenflags;
[ 1224s] | ^~
[ 1224s] scons: *** [cli.build/MetaPathBasedLoader.o] Error 1 From the relnotes it appears that I notice that Python 3.8 isnt setup in the test suite yet. Is anyone attempting it? Are there plans/motivation to support it soon, or is it an undesirable distraction at the moment? |
In Python 3.8, [ 2144s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(obmalloc.o): in function `new_arena':
[ 2144s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Objects/obmalloc.c:1232: undefined reference to `Py_IgnoreEnvironmentFlag'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(unicodeobject.o): in function `init_fs_encoding':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Objects/unicodeobject.c:15799: undefined reference to `_Py_DumpPathConfig'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pathconfig.o): in function `config_init_module_search_paths':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pathconfig.c:239: undefined reference to `_PyWideStringList_Clear'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pathconfig.c:258: undefined reference to `PyWideStringList_Append'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pathconfig.o): in function `pathconfig_global_read':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pathconfig.c:436: undefined reference to `_PyConfig_InitCompatConfig'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pathconfig.c:439: undefined reference to `PyConfig_Read'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pathconfig.c:447: undefined reference to `PyConfig_Clear'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `preconfig_get_global_vars':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:471: undefined reference to `Py_IsolatedFlag'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:472: undefined reference to `Py_IgnoreEnvironmentFlag'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:473: undefined reference to `Py_UTF8Mode'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `_PyPreConfig_Read':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:816: undefined reference to `Py_UTF8Mode'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `precmdline_parse_cmdline':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:208: undefined reference to `PyWideStringList_Append'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `_PyArgv_AsWstrList':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:98: undefined reference to `_PyWideStringList_Clear'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:104: undefined reference to `_PyWideStringList_Copy'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `_PyPreCmdline_Clear':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:117: undefined reference to `_PyWideStringList_Clear'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:118: undefined reference to `_PyWideStringList_Clear'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `preconfig_set_global_vars':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:497: undefined reference to `Py_IsolatedFlag'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:498: undefined reference to `Py_IgnoreEnvironmentFlag'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:502: undefined reference to `Py_UTF8Mode'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `_PyPreCmdline_SetConfig':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:165: undefined reference to `_PyWideStringList_Extend'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(preconfig.o): in function `_PyArgv_AsWstrList':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/preconfig.c:90: undefined reference to `_PyWideStringList_Clear'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `Py_InitializeEx':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:1069: undefined reference to `_PyConfig_InitCompatConfig'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pyinit_core':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:846: undefined reference to `_PyConfig_InitCompatConfig'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:848: undefined reference to `_PyConfig_Copy'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:853: undefined reference to `PyConfig_Read'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pyinit_config':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:668: undefined reference to `_PyConfig_Write'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pycore_init_runtime':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:492: undefined reference to `_PyConfig_Write'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pycore_create_interpreter':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:529: undefined reference to `_PyConfig_Copy'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pyinit_core':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:869: undefined reference to `PyConfig_Clear'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `init_sys_streams':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:1969: undefined reference to `_Py_ClearStandardStreamEncoding'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `new_interpreter':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:1441: undefined reference to `_PyConfig_Copy'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `pyinit_core_reconfigure':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:466: undefined reference to `_PyConfig_Write'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:468: undefined reference to `_PyConfig_Copy'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `_Py_ReconfigureMainInterpreter':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:882: undefined reference to `_PyWideStringList_AsList'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `init_sys_streams':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:1969: undefined reference to `_Py_ClearStandardStreamEncoding'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:1969: undefined reference to `_Py_ClearStandardStreamEncoding'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pylifecycle.o): in function `Py_FdIsInteractive':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pylifecycle.c:2354: undefined reference to `Py_InteractiveFlag'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pystate.o): in function `PyInterpreterState_New':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pystate.c:209: undefined reference to `PyConfig_InitPythonConfig'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(pystate.o): in function `_PyInterpreterState_Clear':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/pystate.c:269: undefined reference to `PyConfig_Clear'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `_PySys_ReadPreinitWarnOptions':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:2080: undefined reference to `PyWideStringList_Append'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `_PySys_ReadPreinitXOptions':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:2098: undefined reference to `PyWideStringList_Append'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `_PySys_InitMain':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:2881: undefined reference to `_PyWideStringList_AsList'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:2896: undefined reference to `_PyWideStringList_AsList'
[ 2145s] /usr/bin/ld: /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:2897: undefined reference to `_PyWideStringList_AsList'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `_PySys_ClearAuditHooks':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:271: undefined reference to `Py_VerboseFlag'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `sys_breakpointhook':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:419: undefined reference to `Py_IgnoreEnvironmentFlag'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(sysmodule.o): in function `PySys_SetArgv':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/./Python/sysmodule.c:3124: undefined reference to `Py_IsolatedFlag'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(fileutils.o): in function `encode_locale_ex':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/fileutils.c:743: undefined reference to `Py_UTF8Mode'
[ 2145s] /usr/bin/ld: /usr/lib/python3.8/config-3.8-i386-linux-gnu/libpython3.8.a(fileutils.o): in function `_Py_DecodeLocaleEx':
[ 2145s] /home/abuild/rpmbuild/BUILD/Python-3.8.0rc1/Python/fileutils.c:551: undefined reference to `Py_UTF8Mode' |
@jayvdb Regarding 3.8, I have followed the betas, and updated Nuitka as necessary, there were a couple of bugs filed against CPython as a result of that. I haven't looked at 3.8 for some time though. The first goal is usually to get it to work with 3.7 test suite in a compatible fashion and add low hanging fruits of new features. I had that for beta3 or beta4, I forget. I am hopeful that their assignment expressions will be easy for Nuitka, since it always did those as part of its re-formulations, but I havent't take the time yet to look at it. As stated in other channels, my family duties have made me fall back on Nuitka a lot recently, and that is probably only going to change this weekend. I have to make a plan how to prioritize things in catching up. Currently I have a lot of unread emails. But getting current 3.8 to work as before, doing the minor tweaks needed will be nice. From experience I know that once 3.8 is released, I will be hammered with questions about it. Last time I manged to be there at release day. Since it's only rc1 I might still get there in time, or at least not that late. It's always hard to tell how heavy features really hard to follow. Surely I will be posting this in a first "Nuitka this week" posting after a long time this weekend, or so I hope. :) |
@jayvdb for static linking: That unusable Going through DLL jump pads disables some optimization for unicode strings, making programs that use Anaconda has a Not sure how good static linking without LTO is, but I believe it might be equally well. It's sad this is so under-supported by upstream there. |
One day, maybe Nuitka should become a proper fork of CPython, it would make a bunch of things easier, although of course, out of the box usability will drop to zero in an instant. |
I was able to get linking working on a regular Python 3.7m build (not with --disabled-shared) by doctoring the .a ar x libpython3.7m.a main.o
strip --strip-symbol=Py_GetArgcArgv main.o
ar r libpython3.7m.a main.o The generated cli dist still included lots of .so, including libpython3.7m.so, presumably because they were referred to by my app, and the standalone app core dumped while loading the .so it found. Maybe the above doctoring will work for a simple app and the doctoring might be enough to the dockers at https://github.com/pypa/manylinux/ working for static linking of standalone (as opposed to module mode as discussed at #81). I'm now roughly following https://github.com/indygreg/python-build-standalone to build a more inclusive static Python. |
Sharing my experience: I didn't have to do any of the |
So static linking no longer fails. The solution is to make the colliding symbol weak. It is rarely needed anyway. |
I had an error for xxh project:
And this works for me now:
Thanks! |
This is now in the latest pre-release, and will soon be released. |
The release 0.6.8 was just made and contains the correction. |
In case anyone else finds themself here, I ran into this issue in Ubuntu + Python 3.9 (Anaconda) and alleviated the issue through installing
|
Yes, static linking was not supported at the time, but now is, and it warns about. I guess, it would be nice to have a PR for Anaconda that tells people to install just that to resolve it. |
thanks @kayhayen ! I will see if I can submit such a PR in the next few days. |
This hasn't worked so far.
Currently the issue seems to be that Py_GetArgcArgv collides with the symbols in a "libpythonXY.a" coming from "Modules/main.c".
Wo do not use that, and cannot use it. So the values would be wrong, while there are Python modules with semi wide usage, which rely on these functions to work correctly.
The idea therefore is that we can find a "libpython.a" that would be used, and turn it into a (cached) form with "main.o" removed from the archive.
What will be needed is to statically compile a CPython from source. Do not use --enable-shared doing that. Then examine the resulting "libpython.a" and try to remove "main.o" and see if linking to a program then works with Nuitka without any duplicate symbols errors.
The way caching is done can be seen in "makeWindowsMingGW64Lib" which gets an appdirs provided directory "nuitka_cache" from the outside. So it would only do that once then.
This should be a simple task. I invite others to try it for themselves and create a PR to include in Nuitka.
The text was updated successfully, but these errors were encountered: