Clang, Microsoft linker and standard library - c

I have successfully built Clang with Microsoft C++ and I'm trying to get it to compile a hello world test case; it gets as far as generating an object file, linking with the standard library being the remaining stumbling block:
hello-202520.o : error LNK2019: unresolved external symbol _printf referenced in function _main
LINK : error LNK2001: unresolved external symbol _mainCRTStartup
There are comments from previous years saying Clang doesn't yet do Windows linking at all, but I get the impression those are outdated, and indeed it does now seem to be able to generate Windows format object files:
clang -c hello.c
ren hello.o hello.obj
link hello.obj
... doesn't barf, so the file format seems to be correct, but still gets the unresolved external symbol errors. Likely guess is the Microsoft compiler tags its output object files with an indication of the standard library they need to be linked with whereas Clang doesn't, and eyeballing a hex dump of the respective object files seems to confirm this and gives a hint of the linker command line to use:
link /defaultlib:libcmt /defaultlib:oldnames hello.obj
I had high hopes by this stage but alas it still gives the same unresolved external symbol errors.
What am I still missing?

Turns out Clang was by default generating 32-bit code but I was using 64-bit MSC, and the leading _ on C symbols has been dropped with the move to x64, so specifying -m64 on the clang command line did the job.

Related

Why is clang removing an underscore from a function declared as 'extern "C"'?

I'm watching a video in an attempt to better understand object files. The presenter uses the following as an example of a program that produces a very simple object file:
extern "C" void _start() {
asm("mov $60, %eax\n"
"mov $24567837, %edi\n"
"syscall\n");
}
The program is compiled via
clang++ -c step0.cpp -O1 -o step0.o
and linked via
ld -static step0.o -o step0
I get this error message when trying to link:
Undefined symbols for architecture x86_64:
"start", referenced from:
-u command line option
(maybe you meant: __start)
ld: symbol(s) not found for inferred architecture x86_64
I don't pass the -u command line option, so I'm not sure why I'm getting that error message.
clang isn't removing an underscore, it's adding an underscore. Your program is actually exporting a __start symbol, but ld expects you to have a start symbol for your entry point, i.e. ld runs with -u start by default for your architecture.
You could disable this check in ld with -U start (which suppresses the error from the start symbol being undefined) or via -undefined suppress (which suppresses all undefined symbol errors). However, you will end up with an executable that does not have an entry point for your architecture, so the program won't actually work.
Instead of suppressing the error, I suggest controlling the symbol that clang chooses directly. You can tell clang what symbol to generate by using a standalone asm declaration:
void _start() asm ("start");
Make sure this standalone declaration is separate from the function definition.
You can read more about controlling the symbols generated by gcc here: https://stackoverflow.com/a/1035937/12928775
Also, as was pointed out in a comment to a similar answer, you will most likely want to use __attribute__((naked)) on the function definition to prevent clang from generating a stack frame on entry. See: https://stackoverflow.com/a/60311490/12928775

Hidden symbol `__udivti3' in .../libgcc.a is referenced by DSO

I am trying to compile a simple executable using CMake and Clang on Ubuntu 18. Some code coming from a third party source and compiled as a shared library libtommath ends up calling the function __udivti3 after the compiler does some code optimisations.
At link time, I have an error coming from ld saying hidden symbol "__udivti3" in /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a(_udivdi3.o) is referenced by DSO
I did some research and thanks to this link this effectively means that __udivti3 is referenced by the shared library but It cannot be used from the libgcc.a as it is marked as hidden in this library.
My issue is whatever I try to fix it, the linkage always fails. I tried to link with libgcc_s which is located in the same directory but clang complains it cannot find it. On the other hand though, the compilation and linkage work perfectly on MacOS, with that problematic symbol still being present.

MATLAB Generated C Code Compilation Error

I have a MATLAB function that has signal processing and machine learning and I wanted to test it on another OS like linux. So I use codegen to generate C code for that function. When I come to run it (predictActivityFromSignalBuffer) on the command line, this is what I get:
MacBook-Pro-2:predictActivityFromSignalBuffer kareem$ gcc predictActivityFromSignalBuffer.c
Undefined symbols for architecture x86_64:
"_featuresFromBuffer", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
"_main", referenced from:
implicit entry/start for main executable
"_mynn", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
"_rtIsNaN", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What is this error telling me exactly? I have no idea how to debug this or where to start/look.
Did you really just call
$ gcc predictActivityFromSignalBuffer.c
without any other dependencies? Usually there come a lot of other files with a code generation that have to be linked.
I do not know what you have done to produce your .c file. I recommend to use the coder wizard by typing
coder
in the Matlab command window. This will guide you through the whole process of code generation and also offers a lot of support and testing possibilities. You can also choose to compile your functions to ready-to-use DLL libraries or executatables. Just have a look at it.

Undefined symbols for architecture x86_64 "_min"

I'm having a problem using min() and max() function in my C project. I've imported math.h, but when I compile the file I keep getting the following error (a similar error is displayed even using gcc instead of llvm):
Undefined symbols for architecture x86_64:
"_min", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I think the problem is that there isn't a 64 bit library of math.h... or the compiler can't find it. I'm using Mac OS X 10.7. How may I fix this problem?
Even though I can see "min" defined in libSystem.dylib, I don't think there's an exported header for that. And I can't figure out where "_min" is coming in from, in terms of the include files.
Normally "min" is referred to with a macro or with your own function. Check out this very related question somebody else asked a while back.
If you look in math.h, there are some "min" type functions in there but they are for floats and doubles. If you are just working with integers or custom types, roll your own function.

GetUserName under Win64

I am trying to compile a C program using the Intel icl compiler under MINGW/64. The program uses the following code:
#include <Userenv.h>
HANDLE process;
HANLDE token;
GetUserProfileDirectory(process, TOKEN_QUERY, &ptoken)
I am using the following compile command:
$ icl -g -DMINGW32 -DTESTMAIN user.c -o user -UserEnv.Lib
and I am linking against the UserEnv.Lib from the Microsoft SDK.
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version Microsoft (R) Incremental Linker Version 9.00.21022.08
-out:user.exe
user.obj
user.obj : error LNK2019: unresolved external symbol __imp_GetUserProfileDirectoryA referenced in function main
Any idea how to solve this problem?
SOLUTION:
The solution is to use
/link /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/UserEnv.Lib /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/A
I copied the file UserEnv.lib from the Microsoft SDK (x64, 6.0) into the current working directory and compiled the program with
$ icl test.c -DMINGW32 ./UserEnv.Lib
LNK2019: unresolved external symbol __imp_GetUserNameA referenced in function main test.obj : error LNK2019: unresolved external symbol __imp_OpenProcessToken referenced in function main test.obj : error LNK2019: unresolved external symbol –
and I am still getting the unresolved symbols.
Olaf
You need to add userenv.lib to your input libraries for the linker to see GetUserProfileDirectory().
EDIT: It's been a while since I've touched an Intel compiler, but IIRC you're supposed to use /link to introduce linker options:
$ icl test.c -DMINGW32 /link ./UserEnv.Lib

Resources