2016-02-01 85 views
4

未定義參考我有folllowing目錄結構:與使用cmake自己的庫

-project 

    -helper 
    -build 
    -include 
     -h_a.h 
     -h_b.h 
    -src 
     -h_a 
     -h_a.cpp 
     -CMakeLists.txt 
     -h_b 
     -h_b.cpp 
     -CMakeLists.txt 
     -CMakeLists.txt 

    -proj_c 
    -build 
    -src 
     -main.cpp 
     -CMakeLists.txt 

helper項目生成兩個庫:libh_a.alibh_b.alibh_a.a用於構建libh_b.a。這些文件如下:

helper/src/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6) 

project(helper) 

set(CMAKE_CXX_FLAGS "-Wall -g -std=c++11") 

add_subdirectory(h_a) 
add_subdirectory(h_b) 

helper/src/h_a/CMakeLists.txt:

project(h_a) 

add_library(h_a h_a.cpp) 

helper/src/h_a/h_a.cpp

void func_a(){} 

helper/src/h_b/CMakeLists.txt:

project(h_b) 

add_library(h_b h_b.cpp) 

target_link_libraries(
    h_b STATIC 
    h_a 
) 

helper/src/h_b/h_b.cpp:

#include "../../include/h_a.h" 

void func_b(){ 
    func_a(); 
} 

proj_c/src/CMakeLists.txt:

cmake_minimum_required(VERSION 3.2) 

project(proj_c) 

find_library(h_a PATHS ../../helper/build/h_a) 
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_a) 

find_library(h_b PATHS ../../helper/build/h_b) 
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_b) 

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/") 

add_executable(proj_c main.cpp) 

target_link_libraries(
    proj_c 
    h_a 
    h_b 
) 

proj_c/src/main.cpp:

#include "../../helper/include/h_b.h" 

int main(){ 
    func_b(); 
} 

首先,我跑cmake ../srchelper/build(無誤差形式交往),比cmake ../srcproj_c/build和我

proj_c/src/../../helper/build/h_b/libh_b.a(h_b.cpp.o): In function `func_b()': 
helper/src/h_b/h_b.cpp:4: undefined reference to `func_a()' 

看來這個問題是h_b.cpp,但libh_b.a已沒有錯誤之前建成。

+0

相依通用CMake的建議:'設置(CMAKE_CXX_STANDARD 11)'設置C++ 11平臺獨立。將'CMAKE_BUILD_TYPE'設置爲'Debug'(而不是將'-g'添加到'CMAKE_CXX_FLAGS')來獲取平臺獨立編譯的調試信息。設置'-Wall'之前檢查'CMAKE_COMPILER_IS_GNUCC'。 – DevSolar

回答

5

第一個問題是您的庫沒有找到。在proj_c/build/CMakeCache.txt

//Path to a library. 
h_a:FILEPATH=h_a-NOTFOUND 

//Path to a library. 
h_b:FILEPATH=h_b-NOTFOUND 

(使用DOC選項find_library()得到通用的「路徑一庫」的東西更有助於更換。)

這種「無聲的失敗」可以通過添加克服find_library()後檢查:

if (NOT h_a) 
    message(FATAL_ERROR "Library h_a not found in ${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_a") 
endif() 

(對於較大的項目,你將有一個FindXyz.cmake模塊設置了查找依賴關係,您可以通過find_package(Xyz REQUIRED)來電避免沉默失敗。但是,這個助手提供給您的功能寫這樣一個模塊時,是受自身所有的)

失敗本身是由於一個問題,您使用的find_library

find_library(h_a PATHS ../../helper/build/h_a) 

你告訴CMake在哪裏看,以及在哪個變量中存儲結果,但不看

用途:

find_library(h_a NAMES h_a PATHS ../../helper/build/h_a) 

這將解決-NOTFOUND。 (申請h_b爲好。)

你仍然會得到鏈接錯誤,雖然,因爲......

target_link_libraries(
    proj_c 
    h_a 
    h_b 
) 

...鏈接順序。 proj_c尋找func_b(),不h_a找到它,確實發現它在h_b,這又需要func_a()未發現因爲鏈接正在上只有庫列表中的一個通行證。

這是在命令行上specifyling -lh_a -lh_b相同。

根據依賴關係鏈切換庫周圍(proj_c取決於h_b取決於h_a):

target_link_libraries(
    proj_c 
    h_b 
    h_a 
) 

,將工作。