You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
libatomic.a dependency causes issues when building on Arch Linux #616
Nuitka (and probably other py-to-exe software) tries to use libatomic.a instead of libatomic.so, which crashes gcc or other compilers.
In Arch Linux, libatomic.a does not exist anymore.
replacing compiler flags from -l:libatomic.a to -latomic fixes the issue, the dynamic version of libatomic is always available.
Example error:
gcc -o /home/csd4ni3l/Documents/Python3/shatterstack/test.dist/test -s -z noexecstack -export-dynamic -Wl,-R,'$ORIGIN' -Wl,--disable-new-dtags @"./@link_input.txt" -L/home/csd4ni3l/.local/share/uv/python/cpython-3.11.11-linux-x86_64-gnu/lib -ldl -lm -lpython3.11 -ldl -lpthread -lutil -lrt -lm -l:libatomic.a -l:libatomic.a
/usr/bin/ld: cannot find -l:libatomic.a: No such file or directory
/usr/bin/ld: cannot find -l:libatomic.a: No such file or directory
collect2: error: ld returned 1 exit status
I think this is leaking out from our internal use of -l:libatomic.a (see cpython-unix/extension-modules.yml), the original purpose of which was to avoid needing libatomic on end user systems, but unfortunately the Python extension build process leaks flags from how Python itself was built, which is probably why you're getting that on your build command line.
We have since started also using libatomic.so on some platforms; see #410. It may be the case that we can actually assume there's a platform libatomic.so everywhere.
Alternatively, we should be able to stop leaking this command line flag.
I might be wrong, but I believe at this time Nuitka works with the Standalone Python Build, albeit in a non-optimal way. My exchange with UV developers has revealed that the static link libraries it contains are tied to the specific compiler that is however not shipped, while Nuitka expects to be able to use any clang or gcc with them. Hence --static-libpython=auto defaults to --static-libpython=no with that Python flavor. Using a managed Python, e.g. Debian/Ubuntu Pythons gives a better result, so does Anaconda, and probably a lot more. This is of course no issue on Windows, where static linking of Python is not possible.
/usr/bin/ld: cannot find -l:libatomic.a
/usr/bin/ld: cannot find -l:libatomic.a
collect2: error: ld returned 1 exit status
scons: *** [/home/munsys_william__bk/testing/build/main.dist/argus.bin] Error 1
FATAL: Failed unexpectedly in Scons C backend compilation.
Nuitka:WARNING: Complex topic! More information can be found at https://nuitka.net/info/scons-backend-failure.html
Nuitka-Reports: Compilation crash report written to file 'nuitka-crash-report.xml'.
after trying to pinpoint if the problem is nuitka or uv side and this thread Nuitka/Nuitka#3474 i went with trying it on vanila python. im copying the results here
can confirm that in my case (red hat 8.9) using uv python leads to the error /usr/bin/ld: cannot find -l:libatomic.a but if you install python normally (or in my case used the old install - python3.6) it works fine.
Self compiled Python of course can make the same mistakes as the standalone Python build there, and the solution would be the same. Build it correctly or use a supported Python. For Fedora Python I believe that static libpython also defaults to "no" because they don't know how to provide a usable libpython either. Debian and others can do it. Although for Ubuntu I recently needed to give up with Python 3.14, or so it seems. These things are typically very neglected. I might describe more publically how to achieve it, but I lack the time and am out of here for now.
The libatomic dependency is coming from OpenSSL. We could potentially change our OpenSSL build script to statically link libatomic. And then if libssl.a / libssl.so (or libcrypto) have the atomic symbols, we should be able to purge references to libatomic from CPython's build system, eliminating the possibility that sysconfig will leak implementation details.
Assuming CPython itself doesn't direct depend on the symbols in libatomic, removing all references to libatomic from sysconfig could also work.
Short and sweet: Honestly quick and easy fix in this scenario (should libatomic.a not be acceptable, but libatomic.so is), just switch to -l atomic and ensure preference in your container build still selects the libatomic.a, matching the same behaviour as the other link args?
Read on if that was not clear, I think I've covered everything relevant?
eliminating the possibility that sysconfig will leak implementation details.
I am perhaps lacking the expertise here, is the only concern the presence of -l:libatomic.a?
I assume other libs there are also statically linked, but by not enforcing static/dynamic linking any build environment that would care about these link args is free to prioritize static libs ahead of dynamic libs?
If static libs are not relevant in this sysconfig metadata, shouldn't they be filtered out? (including those that are not explicitly static but still linked in statically?)
I'm a tad confused to what exactly is leaked in this scenario (I understand the discussion is focused on -l:libatomic.a, but that aside the two parties involved it is unclear why this is considered a leak given how both have implemented this).
python-build-standalone has a workaround to prioritize static libs, but for some reason has chosen to have an explicit libatomic.a
Projects like Nuitka are reading the sysconfig MODLIBS and only filtering for the explicitly static linked libs. This seems questionable on their end, and they could just as easily fix it there too if that's the case.
"Leaked" flags concern
unfortunately the Python extension build process leaks flags from how Python itself was built, which is probably why you're getting that on your build command line.
I don't think it's necessarily reasonable for us to remove every flag we use.
The flags in sysconfig MODLIBS entry is only really relevant for linking a new .so of libpython (or to some degree creating a .a static lib), so I don't think there's any need to hide any of that through filtering/removal? 🤷♂️ (NOTE: I don't know much about the Python ecosystem, it would be good to clarify relevance 😅)
There is a bit of duplicates listed, so filtering that to unique items might be nice at least?:
NOTE: Some users at #275 are querying about the size of the library, either unaware of all the extra deps linked statically or stating the bundling is a bit more excessive and requesting a minimal version (Ubuntu packages a minimal Python variant for example).
Presently only reported as a problem for Nuitka?
The Nuitka maintainer @kayhayen is interested in a libpython.a instead of a libpython.so output.
The above indicates what deps were linked in, but is only explicit about a static link for libatomic, yet a good portion of those deps appear to be static linked into the library itself, so the build system either lacked dynamic lib copies, or the static libs were in a search path with higher precedence than the .so equivalents.
IIRC I saw in the python-build-standalone source there was some logic to remove the .so equivalents for most of those listed above from system lib paths, as a way to get the linker to favor the static libs, and justifying that as an acceptable workaround because it was a container build.
When in control of how the link args are invoked, you could enforce static lib selection via -Bstatic and switch back to dynamic libs with -Bdyamic.
Alternatively just add "-l:lib${LIB_NAME}.a" (easy enough transform to do), and you'll also prefer static lib selection if you prefer that over the -B flags. If taking the latter approach you can likewise specifically link libs dynamically by using .so instead of .a. Otherwise place your custom built static libs in a new search path and give that priority (preferred IMO).
Nuitka to my knowledge presently mistakenly reads this Python's build sysconfig MODLIBS to carry over any .a links it finds into link args for the output binary it produces (this is handled in Nuitka source via getModuleLinkerLibs(), see "Investigation" section of this comment for more info).
Seems unnecessary though? Nuitka seems to have done this because at the time they had come across a python-build-standalone supplied libpython.a (3.7) rather than a .so. Since creating a static lib would only bundle any built .o objects and defers linking, I'm not sure why only explicit static libs were of interest for Nuitka to capture? 🤷♂️
Drop the explicit static link?
I'm sure I'm missing something... otherwise if Nuitka is still carrying support around a libpython.a assumption, it could instead autodetect that easily enough for -lpython3.10 (ambiguous preference). In Nuitka's case, this is linking to the output binary, where libpython.so shouldn't need any of it's deps carried over AFAIK, it is only doing so for the libpython.a scenario? (where static libs like libatomic could technically be merged IIRC, but -l atomic should work just as well at Nuitka's side?)
Here's an example of preferring ambiguous link args when that makes sense (otherwise explicitly static/dynamic linking as demonstrated here):
$ docker run --rm -it fedora:42 bash
$ dnf install -yq gcc libatomic libatomic-static
$ mkdir /tmp/prefer-static
$ ln --symbolic "$(gcc -print-search-dirs | grep ^install: | cut -d'' -f2)libatomic.a" /tmp/prefer-static/libatomic.a
$ gcc -shared -nodefaultlibs -L /tmp/prefer-static/ -l atomic -o /tmp/example
# No dynamic link, `/tmp/prefer-static` only contained a `libatomic.a` and was found first:
$ ldd /tmp/example statically linked
@kayhayen since you're linking with Nuitka, you should have the choice here how Nuitka passes these link args to the compiler/linker. Normalize -l:lib<name>.a to -l <name> and problem solved? A user could still link libs statically if they wanted.
My exchange with UV developers has revealed that the static link libraries it contains are tied to the specific compiler that is however not shipped, while Nuitka expects to be able to use any clang or gcc with them.
libatomic is a system library. If you were to link dynamically, GCC provides libatomic.so which is just a linker script to the system versioned library (eg: /usr/lib64/libatomic.so.1.2.0) which has the common DT_SONAME entry of libatomic.so.1, which is the actual lib linked and queried for at runtime (the .so is purely a placeholder for dev convenience at build/link-time).
On Fedora Clang depends on GCC and implicitly includes the GCC search paths, so it will also find libatomic.so at link-time. Other compilers like Zig would need to be given the extra search dir via -L. Same scenario for libatomic.a (via libatomic-static package).
This shouldn't be any different to linking libgcc_s.so.1? (something Rust built software commonly links to, but is not present if compiling with Zig instead)
For Fedora Python I believe that static libpython also defaults to "no" because they don't know how to provide a usable libpython either.
A shared library is still usable, a static lib can be convenient/beneficial but is not always available in a build environment (if depending only on system packages to source that static lib).
Rust *-sys crates often offer support for static builds, but you can look at the issues open on a few of those to see the various headaches that users can run into from offering such, whereas a shared library is much more accessible for them to get a successful build.
I'm not familiar enough with building Python, but the following may be of interest to you:
So they probably do know how to provide what you'd like, but for whatever reason Fedora doesn't offer a python-static package or similar. Debian/Ubuntu might make you happy in this situation, but they're not without their own caveats in my experiences with using those distros 😓
Activity
csd4ni3l commentedon May 18, 2025
Nuitka issue: Nuitka/Nuitka#3474
geofft commentedon May 18, 2025
I think this is leaking out from our internal use of
-l:libatomic.a(see cpython-unix/extension-modules.yml), the original purpose of which was to avoid needing libatomic on end user systems, but unfortunately the Python extension build process leaks flags from how Python itself was built, which is probably why you're getting that on your build command line.We have since started also using libatomic.so on some platforms; see #410. It may be the case that we can actually assume there's a platform libatomic.so everywhere.
Alternatively, we should be able to stop leaking this command line flag.
csd4ni3l commentedon Jun 5, 2025
Any updates?
zanieb commentedon Jun 5, 2025
While we could add filtering for this to sysconfig, I don't think it's necessarily reasonable for us to remove every flag we use.
It seems like Nuitka should provide a way to filter what it pulls from sysconfig?
WilliamStam commentedon Sep 30, 2025
getting this on redhat as well.
is this a dependency for UV? (using nuitka 2.7.16). tried installing
sudo dnf install libatomicand running nuitka with the flagsenv LDFLAGS="-L/usr/lib/gcc/x86_64-redhat-linux/8/32/libatomic.a -latomic"
but no such luck. which project is actually responsible for it? anyone found a way past it?
kayhayen commentedon Sep 30, 2025
I might be wrong, but I believe at this time Nuitka works with the Standalone Python Build, albeit in a non-optimal way. My exchange with UV developers has revealed that the static link libraries it contains are tied to the specific compiler that is however not shipped, while Nuitka expects to be able to use any clang or gcc with them. Hence --static-libpython=auto defaults to --static-libpython=no with that Python flavor. Using a managed Python, e.g. Debian/Ubuntu Pythons gives a better result, so does Anaconda, and probably a lot more. This is of course no issue on Windows, where static linking of Python is not possible.
WilliamStam commentedon Oct 1, 2025
just fired up an ubuntu VM and tried in there. can confirm it works great after installing patchelf
after sudo apt install patchelf and voila..
steps:
install uv
curl -LsSf https://astral.sh/uv/install.sh | shget python
uv python installsetup venv
uv venvrun build.sh
worked perfectly (ubuntu server 24.04)
the same on red hat (8.9) tho fails with
WilliamStam commentedon Oct 1, 2025
after trying to pinpoint if the problem is nuitka or uv side and this thread Nuitka/Nuitka#3474 i went with trying it on vanila python. im copying the results here
can confirm that in my case (red hat 8.9) using uv python leads to the error
/usr/bin/ld: cannot find -l:libatomic.abut if you install python normally (or in my case used the old install - python3.6) it works fine.kayhayen commentedon Oct 2, 2025
Self compiled Python of course can make the same mistakes as the standalone Python build there, and the solution would be the same. Build it correctly or use a supported Python. For Fedora Python I believe that static libpython also defaults to "no" because they don't know how to provide a usable libpython either. Debian and others can do it. Although for Ubuntu I recently needed to give up with Python 3.14, or so it seems. These things are typically very neglected. I might describe more publically how to achieve it, but I lack the time and am out of here for now.
indygreg commentedon Oct 2, 2025
The libatomic dependency is coming from OpenSSL. We could potentially change our OpenSSL build script to statically link libatomic. And then if
libssl.a/libssl.so(orlibcrypto) have the atomic symbols, we should be able to purge references tolibatomicfrom CPython's build system, eliminating the possibility thatsysconfigwill leak implementation details.Assuming CPython itself doesn't direct depend on the symbols in
libatomic, removing all references tolibatomicfromsysconfigcould also work.polarathene commentedon Oct 11, 2025
Short and sweet: Honestly quick and easy fix in this scenario (should
libatomic.anot be acceptable, butlibatomic.sois), just switch to-l atomicand ensure preference in your container build still selects thelibatomic.a, matching the same behaviour as the other link args?Read on if that was not clear, I think I've covered everything relevant?
This comment follows after a similar one I posted at Nuitka on the topic: Nuitka/Nuitka#3331 (comment)
I am perhaps lacking the expertise here, is the only concern the presence of
-l:libatomic.a?I'm a tad confused to what exactly is leaked in this scenario (I understand the discussion is focused on
-l:libatomic.a, but that aside the two parties involved it is unclear why this is considered a leak given how both have implemented this).python-build-standalonehas a workaround to prioritize static libs, but for some reason has chosen to have an explicitlibatomic.a"Leaked" flags concern
The flags in sysconfig
MODLIBSentry is only really relevant for linking a new.sooflibpython(or to some degree creating a.astatic lib), so I don't think there's any need to hide any of that through filtering/removal? 🤷♂️ (NOTE: I don't know much about the Python ecosystem, it would be good to clarify relevance 😅)There is a bit of duplicates listed, so filtering that to unique items might be nice at least?:
Inspecting symbols in the lib sure enough confirms the libs being statically linked:
NOTE: Some users at #275 are querying about the size of the library, either unaware of all the extra deps linked statically or stating the bundling is a bit more excessive and requesting a minimal version (Ubuntu packages a minimal Python variant for example).
Presently only reported as a problem for Nuitka?
The Nuitka maintainer @kayhayen is interested in a
libpython.ainstead of alibpython.sooutput.The above indicates what deps were linked in, but is only explicit about a static link for
libatomic, yet a good portion of those deps appear to be static linked into the library itself, so the build system either lacked dynamic lib copies, or the static libs were in a search path with higher precedence than the.soequivalents.IIRC I saw in the
python-build-standalonesource there was some logic to remove the.soequivalents for most of those listed above from system lib paths, as a way to get the linker to favor the static libs, and justifying that as an acceptable workaround because it was a container build.When in control of how the link args are invoked, you could enforce static lib selection via
-Bstaticand switch back to dynamic libs with-Bdyamic.Alternatively just add
"-l:lib${LIB_NAME}.a"(easy enough transform to do), and you'll also prefer static lib selection if you prefer that over the-Bflags. If taking the latter approach you can likewise specifically link libs dynamically by using.soinstead of.a. Otherwise place your custom built static libs in a new search path and give that priority (preferred IMO).Nuitka to my knowledge presently mistakenly reads this Python's build sysconfig
MODLIBSto carry over any.alinks it finds into link args for the output binary it produces (this is handled in Nuitka source viagetModuleLinkerLibs(), see "Investigation" section of this comment for more info).Seems unnecessary though? Nuitka seems to have done this because at the time they had come across a
python-build-standalonesuppliedlibpython.a(3.7) rather than a.so. Since creating a static lib would only bundle any built.oobjects and defers linking, I'm not sure why only explicit static libs were of interest for Nuitka to capture? 🤷♂️Drop the explicit static link?
I'm sure I'm missing something... otherwise if Nuitka is still carrying support around a
libpython.aassumption, it could instead autodetect that easily enough for-lpython3.10(ambiguous preference). In Nuitka's case, this is linking to the output binary, wherelibpython.soshouldn't need any of it's deps carried over AFAIK, it is only doing so for thelibpython.ascenario? (where static libs likelibatomiccould technically be merged IIRC, but-l atomicshould work just as well at Nuitka's side?)Here's an example of preferring ambiguous link args when that makes sense (otherwise explicitly static/dynamic linking as demonstrated here):
Extra reference context (collapsed for brevity)
Static vs Dynamic choice
@kayhayen since you're linking with Nuitka, you should have the choice here how Nuitka passes these link args to the compiler/linker. Normalize
-l:lib<name>.ato-l <name>and problem solved? A user could still link libs statically if they wanted.libatomicis a system library. If you were to link dynamically, GCC provideslibatomic.sowhich is just a linker script to the system versioned library (eg:/usr/lib64/libatomic.so.1.2.0) which has the commonDT_SONAMEentry oflibatomic.so.1, which is the actual lib linked and queried for at runtime (the.sois purely a placeholder for dev convenience at build/link-time).On Fedora Clang depends on GCC and implicitly includes the GCC search paths, so it will also find
libatomic.soat link-time. Other compilers like Zig would need to be given the extra search dir via-L. Same scenario forlibatomic.a(vialibatomic-staticpackage).This shouldn't be any different to linking
libgcc_s.so.1? (something Rust built software commonly links to, but is not present if compiling with Zig instead)A shared library is still usable, a static lib can be convenient/beneficial but is not always available in a build environment (if depending only on system packages to source that static lib).
Rust
*-syscrates often offer support for static builds, but you can look at the issues open on a few of those to see the various headaches that users can run into from offering such, whereas a shared library is much more accessible for them to get a successful build.I'm not familiar enough with building Python, but the following may be of interest to you:
.specbuilds with--without-static-libpython).so)So they probably do know how to provide what you'd like, but for whatever reason Fedora doesn't offer a
python-staticpackage or similar. Debian/Ubuntu might make you happy in this situation, but they're not without their own caveats in my experiences with using those distros 😓