2017-05-31 83 views
0

我建立使用CMake的C庫找到的符號。這裏是庫的CMakeLists文件:鏈接不能在圖書館

cmake_minimum_required(VERSION 3.7) 
project(sshserial) 

set(CMAKE_C_STANDARD 99) 

include_directories(BEFORE SYSTEM ${CMAKE_SOURCE_DIR}/common/include) 
link_directories(${CMAKE_SOURCE_DIR}/common/lib) 

set(SOURCE_FILES sshserial.c sshserial.h) 
add_library(sshserial ${SOURCE_FILES}) 

TARGET_LINK_LIBRARIES(sshserial libssh.a) 

我在C++程序中使用這個庫。下面是該程序的CMakeLists文件:

cmake_minimum_required(VERSION 3.7) 
project(sshtest) 

set(CMAKE_CXX_STANDARD 11) 

include_directories(BEFORE SYSTEM ${CMAKE_SOURCE_DIR}/common/include) 
link_directories(${CMAKE_SOURCE_DIR}/common/lib) 

set(SOURCE_FILES main.cpp) 
add_executable(sshtest ${SOURCE_FILES}) 

TARGET_LINK_LIBRARIES(sshtest libsshserial.a) 

我已將該庫複製到正確的文件夾中。當我在圖書館運行nm我得到這個:

$ nm libsshserial.a 

libsshserial.a(sshserial.c.o): 
       U ___error 
       U ___stack_chk_fail 
       U ___stack_chk_guard 
       U ___stderrp 
       U ___stdinp 
0000000000000330 T _create_session 
       U _exit 
       U _fgets 
       U _fprintf 
       U _free 
       U _getpass 
0000000000000490 T _read_from_session 
       U _ssh_channel_close 
       U _ssh_channel_free 
       U _ssh_channel_new 
       U _ssh_channel_open_session 
       U _ssh_channel_read 
       U _ssh_channel_request_exec 
       U _ssh_channel_send_eof 
       U _ssh_connect 
       U _ssh_disconnect 
       U _ssh_free 
       U _ssh_get_error 
       U _ssh_get_hexa 
       U _ssh_get_pubkey_hash 
       U _ssh_is_server_known 
       U _ssh_new 
       U _ssh_options_set 
       U _ssh_print_hexa 
       U _ssh_userauth_password 
       U _ssh_write_knownhost 
       U _strerror 
       U _strncasecmp 
0000000000000000 T _verify_knownhost 
       U _write 

當我嘗試建立的程序,我得到這個鏈接錯誤:

Undefined symbols for architecture x86_64: 
    "create_session()", referenced from: 
     _main in main.cpp.o 
    "read_from_session(ssh_session_struct*)", referenced from: 
     _main in main.cpp.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make[3]: *** [sshtest] Error 1 
make[2]: *** [CMakeFiles/sshtest.dir/all] Error 2 
make[1]: *** [CMakeFiles/sshtest.dir/rule] Error 2 
make: *** [sshtest] Error 2 

我已經困在這裏了一段時間,我我確定我錯過了一些微不足道的東西。我究竟做錯了什麼?

P.S.我在Mac上

$ uname -a 
Darwin XXXXXX 15.6.0 Darwin Kernel Version 15.6.0: Tue Apr 11 16:00:51 PDT 2017; root:xnu-3248.60.11.5.3~1/RELEASE_X86_64 x86_64 
+0

爲什麼不把測試項目a *子項目*(在子文件夾中)的圖書館項目?然後你可以做'TARGET_LINK_LIBRARIES(sshtest sshserial)',CMake設置makefile以自動鏈接庫。 –

+0

此外,當由C++編譯器編譯時,你會*在使用'extern「C」'聲明函數時使用'extern「C」'。 –

+0

@Someprogrammerdude:我現在可以嘗試,我會的。但後來我想在其他項目中使用C庫,所以它不是我想的永久解決方案。 – nakiya

回答

2

問題是C++使用name mangling。要禁止這種情況,您需要用extern "C"聲明C函數,但僅限於由C++編譯器編譯時。你可以編譯C.

當在聲明函數原型的頭文件與__cplusplus宏,這是編譯C++時定義的查詢,但在這,這樣做

#ifdef __cplusplus 
// Being compiled by a C++ compiler, inhibit name mangling 
extern "C" { 
#endif 

// All your function prototype declarations here 

#ifdef __cplusplus 
} // End of extern "C" 
#endif 
+0

正如我在文章上的評論指出,該庫以C,所以我不需要用'爲extern「C」來裝點導出符號' – nakiya

+3

@nakiya如果你想使用C++的功能,那麼您***需要它!故事結局!去嘗試一下。 –

+0

好的,我明白你的觀點。我會試試這個。 – nakiya