0

I thought I understood cmake pretty well until I came accross this problem that I just can't figure out. I've built a static library in C, and I'm trying to run a unit test on it in C++, but I can't seem to link to any of the static functions in that library and I can't figure out why. I've reproduced the problem in the skeleton project below:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.6) 
project(myproj) 

add_library(mylib STATIC mylib.c) 

find_package(Boost 1.64.0 COMPONENTS unit_test_framework) 

add_executable(mytestapp mytest.cpp) 
target_include_directories(mytestapp PRIVATE .) 
target_link_libraries(mytestapp mylib) 

enable_testing() 
add_test( mytest mytestapp)

mylib.c:

int add(int a, int b)
{
    return a + b;
}

mylib.h

int add(int a, int b);

mytest.cpp:

#define BOOST_TEST_MODULE mylib_test
#include <boost/test/included/unit_test.hpp>
#include "mylib.h"

BOOST_AUTO_TEST_CASE(mylib_test)
{
    BOOST_TEST( add(2,2) == 4);
}

Then my output is:

$ make
Scanning dependencies of target mylib
[ 25%] Building C object CMakeFiles/mylib.dir/mylib.c.o
[ 50%] Linking C static library libmylib.a
[ 50%] Built target mylib
Scanning dependencies of target mytestapp
[ 75%] Building CXX object CMakeFiles/mytestapp.dir/mytest.cpp.o
[100%] Linking CXX executable mytestapp
CMakeFiles/mytestapp.dir/mytest.cpp.o: In function `mylib_test::test_method()':
mytest.cpp:(.text+0x1e411): undefined reference to `add(int, int)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/mytestapp.dir/build.make:96: mytestapp] Error 1
make[1]: *** [CMakeFiles/Makefile2:105: CMakeFiles/mytestapp.dir/all] Error 2
make: *** [Makefile:95: all] Error 2

If I compile mylib in C++, then it links fine, but not in C. That's a problem for me because I have a huge library in C and I'm trying to use the boost_test_framework (in C++) to load this lib and test it.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Stewart
  • 4,356
  • 2
  • 27
  • 59
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – too honest for this site Jul 20 '17 at 17:17
  • Not a duplicate, the problem is cross-language. Works fine if I do everytrhing in C++. And why the downvote? – Stewart Jul 20 '17 at 17:18
  • Apparently is a duplicate. If you don't understand why and the answers, you should do some research. We are not a tutoring or debugging service. And that is not related to the languages C or C++, but linking. Don't spam tags. – too honest for this site Jul 20 '17 at 17:20
  • That's why I've broken it into a simple skeleton to explain the issue exactly. I understand linker errors in general, but I don't get why a C++ lib can't load C functions. I've built lots of projects with a mix of C and C++ obj and interfaces between DLLs are frequently in C anyways. – Stewart Jul 20 '17 at 17:22
  • Hmm, you might be correct. It is a C++ problem, but not a C problem. I'm pretty sure every C++ book explains how to use C headers. Also read the error message **carefully** and do some research. I cancel the CV, but as that is an obvious error, I'll leave it at the hints given. – too honest for this site Jul 20 '17 at 17:36

1 Answers1

1

Solution:

I needed to import the library with extern "C" like so:

#define BOOST_TEST_MODULE mylib_test
#include <boost/test/included/unit_test.hpp>

extern "C" {
  #include "mylib.h"
}

BOOST_AUTO_TEST_CASE(mylib_test)
{
    BOOST_TEST( add(2,2) == 4);
}
Stewart
  • 4,356
  • 2
  • 27
  • 59