The Problem
I was trying to work with a library the other day that I built from source, however, I could not get it to work with my local C project. I was getting undefined reference
errors when linking to the shared library.
/bin/ld: /tmp/ccHb7mJ8.o: in function `SDL_main':
main.c:(.text+0x3c): undefined reference to `SDL_EnterAppMainCallbacks'
/bin/ld: /tmp/ccHb7mJ8.o: in function `main':
main.c:(.text+0x6b): undefined reference to `SDL_RunApp'
/bin/ld: /tmp/ccHb7mJ8.o: in function `SDL_AppInit':
main.c:(.text+0xa7): undefined reference to `SDL_SetAppMetadata'
/bin/ld: main.c:(.text+0xb1): undefined reference to `SDL_Init'
/bin/ld: main.c:(.text+0xbd): undefined reference to `SDL_GetError'
/bin/ld: main.c:(.text+0xd4): undefined reference to `SDL_Log'
/bin/ld: main.c:(.text+0x107): undefined reference to `SDL_CreateWindowAndRenderer'
/bin/ld: main.c:(.text+0x113): undefined reference to `SDL_GetError'
/bin/ld: main.c:(.text+0x12a): undefined reference to `SDL_Log'
collect2: error: ld returned 1 exit status
make: *** [Makefile:7: all] Error 1
The Investigation
I recompiled the library several times trying different methods and nothing helped. After searching google for a couple of hours I came across a forum where someone was having a similar issue but they were using a 32bit version of their toolchain instead of a 64bit. I figured this wasn't the issue but I investigated anyways. Everything I checked showed it was 64bit, so I was back to square one. Though after thinking about toolchains I did think maybe I could try a different compiler.
The Solution?
I was using gcc
at the time so I switched to clang
and reran my Makefile.
To my surprise, everything worked! I was shocked.
It couldn't be that simple? Why has this never been a problem before?
Understanding the Solution
So I decided to create a control project to test this phenomenon. I setup a small add
shared library built with clang
and then tried to compile a driver program with gcc
.
lib.h
#pragma once
int add(int a, int b);
lib.c
#include "lib.h"
int add(int a, int b) {
return a + b;
}
main.c
#include "lib.h"
#include <stdio.h>
int main () {
printf("4+3=%d\n", add(4, 3));
return 0;
}
build_so.sh
clang -std=c11 -c -o lib.o lib.c
clang -shared -fPIC -o libm.so lib.o
build_main.sh
gcc -std=c11 -L. -l:libm.so main.c -o main
It failed, just like in my C project.
/bin/ld: /tmp/ccymm8ki.o: in function `main':
main.c:(.text+0x13): undefined reference to `add'
collect2: error: ld returned 1 exit status
Changing the build.sh
to use clang
obviously fixes the problem but I wanted to know if this problem happens the other way round, so I tried to switch the compiler positions, to see if it would fail the other way.
build_so.sh
gcc -std=c11 -c -o lib.o lib.c
gcc -shared -fPIC -o libm.so lib.o
build_main.sh
clang -std=c11 -L. -l:libm.so main.c -o main
This time and everything worked. So this might be why I had never encountered this before.
The Conclusion
clang
shared libraries have problems being used with gcc
for some reason, but gcc
shared libraries can be used with clang
no problem.
If there is a way around this problem, I would love to know!
I think in most cases you probably will use the same compiler for your projects but in my case where the project I was compiling from source decided to use clang
instead of gcc
to create this unique shared library problem I had not encountered before.
Top comments (0)