I am trying to convert a Makefile project to a CMake project. The project has a file a.cxx that has an extern
function declaration:
extern int shared_int;
extern void say_hello(void);
int main(int argc, char ** argv)
{
say_hello();
return 0;
}
The definition to that function is in b.c:
#include <stdio.h>
int shared_int = 5;
void say_hello()
{
printf("Hello!\n");
}
and my CMakeLists.txt is as follows:
project(extern_example)
add_executable(extern_example a.cxx b.c)
If I change the printf
to be used in a.cc to print shared_int
, it works fine, but when I try to use say_hello
from a.cxx, I get
CMakeFiles/extern_example.dir/a.cxx.o: In function `main':
a.cxx:(.text+0x10): undefined reference to `say_hello()'
collect2: error: ld returned 1 exit status
CMakeFiles/extern_example.dir/build.make:120: recipe for target 'extern_example' failed
make[2]: *** [extern_example] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/extern_example.dir/all' failed
make[1]: *** [CMakeFiles/extern_example.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
The error makes it look like b.c is not being linked correctly in the executable, but then why would shared_int
be available?
I have tried to make this as general as possible, but the files in question are on BitBucket (Makefile and analyzer.c/h are of interest) and here is the file that I'm calling A.cxx. I have also trimmed off other includes and links in the compile commands, but I can post those if necessary.
The problem was with function definitions in a.cxx defined as
extern void f(void);
rather than
extern "C" void f(void);
or
extern "C" {
void f(void);
}
Without specifying the C-style extern
, the compiler mangles the function names, which are unable to be read by b.c.