I'm trying to build Godot with SCons. Everything was working fine until I've used std::atomic
in my library my custom module uses (the library is working fine with a Qt application I've created to test it). Then this error happened:
[100%] Linking Program ==> bin/godot.x11.tools.64
/usr/bin/ld: /home/sms/Code/_BUILDS/build-PyWally-Desktop-Release/libPyWally.so: undefined reference to `__atomic_store_16'
/usr/bin/ld: /home/sms/Code/_BUILDS/build-PyWally-Desktop-Release/libPyWally.so: undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
scons: *** [bin/godot.x11.tools.64] Error 1
scons: building terminated because of errors.
I was googling around and found out about atomic/architecture problems, so I've added -march=native
, -mtune=native
and -latomic
because I have modern x64 PC/system and it shoudn't be an issue... so my SCsub looks like this (wallycontroller
being my custom module, and pywally
- my library):
Import('env')
sources = [
"wallycontroller.cpp",
"wallycontroller.cpp",
"register_types.cpp"
]
env.Append(CPPPATH=["/usr/include/python3.10"])
env.Append(LIBS=['python3.10'])
env.Append(CCFLAGS=['-march=native', '-mtune=native', '-latomic'])
env.Append(CPPPATH=["#bin/../../PyWallie"])
env.Append(LIBPATH=["#bin/../../../_BUILDS/build-PyWally-Desktop-Release"])
env.Append(LIBS=['PyWally'])
envw = env.Clone()
envw.Append(CCFLAGS=['-O2'])
if ARGUMENTS.get('wallycontroller_shared', 'no') == 'yes':
envw.Append(CCFLAGS=['-fPIC'])
envw['LIBS'] = []
envw.Append(LIBS=['python3.10'])
envw.Append(LIBS=['PyWally'])
shared_lib = envw.SharedLibrary(target='#bin/../../godot_modules/wallycontroller', source=sources)
shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
env.Append(LIBS=[shared_lib_shim])
env.Append(LIBPATH=['#bin'])
else:
envw.add_source_files(env.modules_sources, sources)
And these are my SCons arguments on build:
platform = "x11"
tools = "yes"
target = "debug"
bits = 64
custom_modules = "../godot_modules"
use_lto = "yes"
walliecontroller_shared = "yes"
udev = "no"
Any issue wasn't happening for this configuration until I've add std::atomic
but it's really convenient and I wouldn't want to remove it... any help will be appreciated.
To help you debug, try temporarily commenting out the setting of LINKCOMSTR
(should be in methods.py
) so that SCons can show you the whole link line - normally Godot tries to be "helpful" and emit shorter messages, but it doesn't help when you're getting something like a link failure. You'll probably notice that it's not linking with libatomic after all. In SCons, you actually need to add that library to LIBS
(without the -l
) to pass it to the linker.
A separate question is why it thinks it need it - I'm presuming the architecture you're building on has atomic support?
With optimization disabled, GCC often calls helper functions for atomic operations instead of inlining.
For x86-64, GCC7 and later always calls a helper function for 16-byte atomics, instead of inlining lock cmpxchg16b
. (And now so it can use movaps
on CPUs with AVX where that guarantees atomicity of 16-byte pure-load and pure-store.) So gcc -latomic
is always necessary when compiling for x86-64, if you use 16-byte atomic objects.