Llvm-link: Linking globals named 'global': symbol multyply defined!

I’ve installed llvm-12 using apt install llvm-12 on my Ubuntu 20.04 x86_64. I want to compile all the *.c file to *.bc and using llvm-link-12 to consolidate to one .bc file. The first step is finished, but the error below occurs when doing the second step.

llvm-link-12 cgi.bc config.bc files.bc format.bc http.bc main.bc server.bc -o httpd.bc
error: Linking globals named ‘config’: symbol multiply defined!
make: *** [Makefile:14: httpd.bc] Error 1

To find the reason, I use llvm-nm-12 to check the config global value. It shows that the main.h define a global value named config, and other *.c all include main.h

cgi.c:#include “main.h”
config.c:#include “main.h”
files.c:#include “main.h”
format.c:#include “main.h”
http.c:#include “main.h”
main.c:#include “main.h”
server.c:#include “main.h”
win32.c:#include “main.h”

How could I solve this symbol name confict? In another post, it show a way to rename confilict symbols. But I think it doesn’t solve the root cause. Any help will be appreciated!

This is rather unrelated with with llvm-link but in general with linking modules. You can not define global symbol more than once (there might be some exeptions like weak etc.) so in general it is bad idea to define symbol in header file. In header file it is good to have just extern declaration of symbol which is defined in one od the .c file.
So in your case config.c should have definition ‘int config;’
And in ‘main.h’ declare just ‘extern int config;’

1 Like

It works when I define all global variables in ‘main.c’ and only declare using ‘extern’ keyword in ‘main.h’. The source code is from nullhttpd-0.5.0 (about in 2002), really old code. Thanks for your help!

It used to be the case that zero-initialised variables could be defined in headers because they ended up as common symbols, but GCC 10 and Clang 11 stopped supporting this (it can hide real bugs) by default; see the -f(no-)common flag.

1 Like