Command Line Tools Linker does not work for linking assembly and C code

On Ventura 13.5.2 (22G91), Macbook pro 13 2019 (Intel): The following combination of the C code and Assembly code fails to link conftest_c.c:

//conftest_c.c:
#ifdef __cplusplus
extern "C" {
#endif
void gsym_test_func(void);
#ifdef __cplusplus
}
#endif
int
main()
{
    gsym_test_func();
    return 0;
}

Obj compiled using the command clang -O3 -DNDEBUG -finline-functions -fno-strict-aliasing -mcx16 -I. conftest_c.c -c produces conftest_c.o That exposes the following symbols:


SYMBOL TABLE:
0000000000000000 g     F __TEXT,__text _main
0000000000000000         *UND* _gsym_test_func

Now we create assembly conftest.s that define _gsym_test_func:

.text
# _gsym_test_func
.globl _gsym_test_func
_gsym_test_func:
# _gsym_test_func

with the objdumb symbols:


SYMBOL TABLE:
0000000000000000 g     F __TEXT,__text _gsym_test_func

Trying to link the two object files into a binary using the following command

clang -O3 -DNDEBUG -v -finline-functions -fno-strict-aliasing -mcx16 conftest_c.o conftest.o -o conftest    -lz  

results in the following error:

Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: x86_64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
 "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch x86_64 -platform_version macos 13.0.0 14.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -O3 -o conftest -L/usr/local/lib conftest_c.o conftest.o -lz -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.osx.a
ld: Undefined symbols:
  _gsym_test_func, referenced from:
      _main in conftest_c.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I do not understand why the linker cannot find the symbol _gsym_test_func defined in conftest.o

Post not yet marked as solved Up vote post of abhinavsns Down vote post of abhinavsns
804 views

Replies

I’m not entirely sure why this is failing for you. I suspect it’s because your _gsym_test_func symbol has no implementation. Regardless, here’s something that works for me:

% cat test-asm.s 
.text

.globl _gsym_test_func

_gsym_test_func:
    ret
% cat test.c 
extern void gsym_test_func(void);

int main(int argc, char ** argv) {
    gsym_test_func();
    return 0;
}
% rm *.o                           
% clang -c test-asm.s -o test-asm.o
% clang test.c test-asm.o -o test  
% ./test 

This is using the Xcode 15.0 command-line tools on macOS 13.5.2 on Intel.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello! Thank you for the reply.

The conftest works on Command Line Tools 14.3. Maybe there are some linker changes that makes it fail? The primary reason is to do this is I am compiling OpenMPI and it performs this specific conftest to find a prefix for global symbols ( _ for macos) but it fails with Xcode 15.

Any suggestion would be appreciated.

Xcode 15, and its associated Command Line Tools package, includes a new linker implementation. See my response here. I recommend that you try using the Xcode 15 tools but with the flag to use the old linker implementation. That’ll tell you whether this is specific to the new linker.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks!

export LDFLAGS="-Wl,-weak_reference_mismatches,weak -Wl,-ld_classic"

makes it work.

Cool. But it’s important to understand why it’s not working before we remove the old linker implementation. Did you file a bug about this? If so, what was the bug number?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"