CMake的不能链接C库以C++程序
可能最短的工作的例子,我能想到的: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 myprog
,myprog
的链接阶段抱怨说,有一个未定义的参考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
?
你需要在C++中声明c函数extern "C"
。该c++编译器改变函数名,以允许函数重载,所以例如
int function(int value);
和
int function(char *value);
既可以c++完全相同的名称来定义,编译器将产生两个不同的功能用不同的名称来正确工作。
在c你不能这样做,并且函数名不需要修改。通过使用extern "C"
,可以防止编译器更改函数名称,因此链接阶段将按照您的预期工作。
为了解决这个问题,开始main.cpp中这样说:
extern "C" {
#include "mylib.h"
}
嗯...这是有道理的,但为什么我不用用'extern“C”'来包装系统C库(或者我应该是并且迄今为止一直很幸运?)例如,我搜索了GTK + 3.0头文件,并没有提及'extern“C”',而且我没有在我的C++代码中做这个包装。 – helloworld922
@ helloworld922 - 这是因为大多数包含文件已经包含像'#ifdef __cplusplus','extern“C”{'和'#endif'这样的行。 – alvits
你在C++代码中使用* GTK-3.0 *吗?或者它是* gtkmm-3.0 *? –
这不是CMake的有问题,而是链接。 CMake不会链接 – Clifford