【问题标题】:CMake doesn't link C and C++ static libraries (undefined reference to function)CMake 不链接 C 和 C++ 静态库(未定义对函数的引用)
【发布时间】:2018-08-07 11:21:47
【问题描述】:

我试图重现最小的问题。当我在 Ubuntu 上运行 CMake+Make 时出现错误

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

即在 C++ 库中导入时,找不到 C 库中的导出函数。当我尝试使用g++ main.cpp funcc.c funccpp.cpp 手动编译时,它成功编译了最终程序。如何解决 CMake 问题?

作为参考,当我运行nm libfuncc_lib.a 时,我得到T FuncC 行(所以符号是外部的并在文本部分中定义),当我运行nm libfunccpp_lib.a 时,我得到U FuncC(所以符号是未定义的,应该链接从外面)。

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)

ma​​in.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");
}

【问题讨论】:

  • 尝试使用 'target_link_libraries(prog funccpp_lib funcc_lib)' 而不是 'target_link_libraries(prog funcc_lib funccpp_lib)' 因为您的 C++ 库依赖于 C 库。
  • 如果将库的顺序切换为target_link_libraries(prog funccpp_lib funcc_lib)会怎样?
  • 不确定 CMake 和“target_link_libraries”,但对于单通道 LD 链接器实现,它指示链接器在“funcc_lib”中搜索“funccpp_lib”的符号,反之亦然。

标签: c++ c cmake


【解决方案1】:

这里的问题是,链接器依赖于库的顺序。与

target_link_libraries(prog funcc_lib funccpp_lib)

它首先链接funcc_lib,然后链接funccpp_lib。但它永远不会回到funcc_lib。由于funccpp_lib 依赖于funcc_lib,因此您必须更改库的顺序:

target_link_libraries(prog funccpp_lib funcc_lib)

For additional information, see this discussion.

【讨论】:

  • 谢谢!问题已修复。但是,当有两个库 A 和 B,存在循环依赖时该怎么办 - A 需要 B 的一些函数,反之亦然?
  • @ArtyOneSoul 看看我提供的链接:只需多次列出库,即target_link_libraries(prog funccpp_lib funcc_lib funccpp_lib)
  • 更好的是,告诉 CMake funccpp_lib 依赖于 funcc_lib: target_link_libraries(funccpp_lib funcc_lib)。
【解决方案2】:

make cmake c link command as c++ commmand 即可解决问题

SET(CMAKE_C_LINK_EXECUTABLE ${CMAKE_CXX_LINK_EXECUTABLE})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多