意外的未定义引用
我得到一个未定义的引用错误,不知道原因。
所以我有两个文件构成一个静态的lib:keyboard_input.c,keyboard_input.h
这是.h文件的内容:
#ifndef __MOD_KBINPUT__ #define __MOD_KBINPUT__ int kbInit(); int kbWait(); int kbTest(); #endif
并且CMakeLists.txt文件如下所示:
FILE( GLOB_RECURSE sources *.c ) INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader") ADD_LIBRARY(keyboardReader ${sources})
编译此lib会发出一些警告:
src/utils/kbreader/keyboard_input.c: In function 'kbInit': src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default] src/utils/kbreader/keyboard_input.c: In function 'kbWait': src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of 'fread' from incompatible pointer type [enabled by default] /usr/include/stdio.h:708:15: note: expected 'struct FILE * __restrict__' but argument is of type 'struct FILE *'
现在,对于我的主要可执行文件(main.cpp):
#include int main() { kbTest(); return 0; }
由以下CMakeLists.txt文件处理:
include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader") file( GLOB_RECURSE srcs *.cpp ) add_executable( PEM ${srcs} ) target_link_libraries(PEM keyboardReader)
最终得到错误:
CMakeFiles/PEM.dir/main.cpp.o: In function `main': main.cpp:(.text+0xb): undefined reference to `kbTest()' collect2: ld returned 1 exit status make[2]: *** [src/PEM/main2/PEM] Error 1 make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2
创建了libkeyboardReader.a,kbTest()函数除了以外什么都不做
{return 0; }
如果我在头文件中设置kbTest()的定义,它就可以工作。
但是当我输入时,有一些我无法得到的东西:make keyboardReader在这里是输出:
[ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.co [Warning explained above] Linking C static library ../../../lib/libKeyboardReader.a
有什么不对? note错误消息是否使我的lib省略了keyboard_input.c文件?
你正在混合C和C ++文件。 要做到这一点,你只需告诉C ++编译器它正在调用一个C函数,通过更改头文件,如下所示:
#ifndef MOD_KBINPUT #define MOD_KBINPUT /* note I also fixed the macro so you aren't using a system-reserved name */ #if __cplusplus /* this is the important part */ extern "C" { #endif int kbInit(); int kbWait(); int kbTest(); #if __cplusplus } #endif #endif
否则,C ++编译器会假定该函数将被赋予一个C ++内部名称(它编码签名中的所有类型信息,这是让链接器区分重载函数)然后链接器找不到它。