CMake 不会将 C 库链接到C++程序

CMake won't Link C library to C++ program

本文关键字:链接 C++ 程序 CMake      更新时间:2023-10-16

可能是我能想到的最短的工作示例:

CMakeLists.txt

project(myprogs)
cmake_minimum_required(VERSION 2.8)
add_executable(myprog2 main.c)
add_executable(myprog main.cpp)
add_library(mylib SHARED mylib.c)
target_link_libraries(myprog2 mylib)
target_link_libraries(myprog mylib)

main.c/main.cpp(内容相同):

#include "mylib.h"
int main(int argc, char** argv)
{
  doit();
}

mylib.h

#ifndef MYLIB_H
#define MYLIB_H
void doit(void);
#endif

mylib.c

#include "mylib.h"
#include <stdio.h>
void doit(void)
{
  printf("doit");
}

系统:

  • Ubunto 15.10
  • gcc 5.2.1/clang 3.6.2(两者都试过)
  • C拍摄3.2.2

当我执行make myprog时,myprog的链接阶段会抱怨存在对doit的未定义引用。但是,如果我使用make myprog2,则所有内容都会正确链接,并且程序会按预期运行。

我不明白为什么CMake在C++程序中没有正确地链接到mylib。从编译器获得详细的输出(我已经修剪了一些到系统库路径/对象文件的链接):

"/usr/bin/ld"-export dynamic--eh frame hdr-m elf_x86_64-dynamic链接器/lib64/ld-linux-x86-64.so.2-o myprog CMakeFiles/myprog.dir/main.cpp.olibmylib.so-rpath/home/andrew/code/misc/myprog/build-lsdc++-lm-lgcc_s-lcc_s-lcc

奇怪的是,它没有使用-lmylib来链接mylib。我得到了myprog2的类似输出。

我的问题是为什么会发生这种情况,更重要的是,我如何使myprog正确链接到mylib

您需要在c++中用extern "C"声明c函数。c++编译器更改函数名以允许函数重载,例如

int function(int value);

int function(char *value);

两者都可以用完全相同的名称在c++中定义,编译器将生成两个不同名称的函数,以便正确工作。

在c中,你不能这样做,函数名称也不需要修改。通过使用extern "C",可以防止编译器更改函数名,因此链接阶段将按预期工作

要修复它,请以这种方式启动main.cpp:

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