2015-12-22 79 views
4

可能最短的工作的例子,我能想到的:CMake的不能链接C库以C++程序

的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 /铛3.6.2 (两者都试过)
  • CMake的3.2.2

当我做了make myprogmyprog的链接阶段抱怨说,有一个未定义的参考doit。但是,如果我使用make myprog2,则所有链接均正确并且程序按预期运行。

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

“/ usr/bin/ld”-export-dynamic --eh-frame-hdr -m elf_x86_64 -dyna mic-linker /lib64/ld-linux-x86-64.so.2 -o myprog CMakeFiles/myprog.dir/main.cpp.o libmylib.so -rpath/home/andrew/code /其它/ MYPROG /编译-lstdC++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc

奇怪的是,它不使用-lmylib与MYLIB链接。我得到了类似的输出myprog2

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

+0

这不是CMake的有问题,而是链接。 CMake不会链接 – Clifford

回答

10

你需要在C++中声明函数extern "C"。该编译器改变函数名,以允许函数重载,所以例如

int function(int value); 

int function(char *value); 

既可以完全相同的名称来定义,编译器将产生两个不同的功能用不同的名称来正确工作。

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

为了解决这个问题,开始main.cpp中这样说:

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

嗯...这是有道理的,但为什么我不用用'extern“C”'来包装系统C库(或者我应该是并且迄今为止一直很幸运?)例如,我搜索了GTK + 3.0头文件,并没有提及'extern“C”',而且我没有在我的C++代码中做这个包装。 – helloworld922

+2

@ helloworld922 - 这是因为大多数包含文件已经包含像'#ifdef __cplusplus','extern“C”{'和'#endif'这样的行。 – alvits

+0

你在C++代码中使用* GTK-3.0 *吗?或者它是* gtkmm-3.0 *? –