CMake doesn't link C and C++ static libraries (undefined reference to function)

11,312

The problem here is, that the linker relies on the order of the libraries. With

target_link_libraries(prog funcc_lib funccpp_lib)

It first links funcc_lib and then funccpp_lib. But it never gets back to funcc_lib. Since funccpp_lib depends on funcc_lib, you have to change the order of the libraries:

target_link_libraries(prog funccpp_lib funcc_lib)

For additional information, see this discussion.

Share:
11,312

Related videos on Youtube

Arty
Author by

Arty

Updated on July 06, 2022

Comments

  • Arty
    Arty almost 2 years

    I tried to reproduce minimal problem. When I run CMake+Make on Ubuntu I get error

    funccpp.cpp:(.text+0x5): undefined reference to `FuncC'

    i.e. exported function in C library is not found when importing in C++ library. When I try to manually compile using g++ main.cpp funcc.c funccpp.cpp it successfully compiles final program. How to fix CMake issue?

    For reference, when I run nm libfuncc_lib.a I get line T FuncC (so symbol is external and defined in Text section), when I run nm libfunccpp_lib.a I get U FuncC (so symbol is Undefined and should be linked from outside).

    CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    project(Test C CXX)
    
    set (SRC_CPP funccpp.cpp)
    set (SRC_C funcc.c)
    set (SRC_MAIN main.cpp)
    
    add_library(funcc_lib STATIC ${SRC_C})
    add_library(funccpp_lib STATIC ${SRC_CPP})
    add_executable(prog ${SRC_MAIN})
    target_link_libraries(prog funcc_lib funccpp_lib)
    

    main.cpp

    #include "funccpp.h"
    
    int main() {
        FuncCPP();
        return 0;
    }
    

    funccpp.h

    #ifndef FUNCCPP_H
    #define FUNCCPP_H
    
    void FuncCPP();
    
    #endif
    

    funccpp.cpp

    #include "funcc.h"
    
    void FuncCPP() {
        FuncC();
    }
    

    funcc.h

    #ifndef FUNCC_H
    #define FUNCC_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void FuncC();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif // FUNCC_H
    

    funcc.c

    #include "funcc.h"
    #include <stdio.h>
    
    void FuncC() {
        printf("Hello, World!\n");
    }
    
    • Viktor Latypov
      Viktor Latypov over 5 years
      Try using 'target_link_libraries(prog funccpp_lib funcc_lib)' instead of 'target_link_libraries(prog funcc_lib funccpp_lib)' since your C++ lib depdends on C lib.
    • aschepler
      aschepler over 5 years
      What happens if you switch the order of libraries to target_link_libraries(prog funccpp_lib funcc_lib)?
    • Viktor Latypov
      Viktor Latypov over 5 years
      Not sure about CMake and 'target_link_libraries', but for single-pass LD linker implementation it instructs the linker to search symbols for 'funccpp_lib' in 'funcc_lib', not vice versa.