2017-02-16 49 views
0

我有一個項目使用我自己的代碼和需要編譯的外部代碼。我的文件樹如下。CMake:將子目錄中的靜態庫鏈接到另一個子目錄中的可執行文件

PROJECT_ROOT 
|--CMakeLists.txt 
|--src 
    |--CMakeLists.txt 
    |--B1.cpp 
    |--B1.h 
    |--B2.cpp 
    |--B2.h 
    | 
    |--ext 
    | |--CMakeLists.txt 
    | |--outside_module 
    | | |--CMakeLists.txt 
    | | |--A1.h 
    | | |--A1.cpp 
    | 
    |--exe 
     |--CMakeLists.txt 
     |--runnerA.cpp 
     |--runnerB.cpp 

我粘貼了下面我的CMakeList.txt文件的結構。我遇到的問題是我的runnerA可執行文件給了我一大堆未定義的參考錯誤給A1.h和A1.cpp中定義的符號。然而,出於某種原因,當CMake嘗試鏈接到可執行文件runnerA時,無法找到我的庫A

我包括了其餘的代碼,因爲它編譯得很好。我能夠構建可執行文件runnerB,沒有任何問題。我推斷runnerB的工作原理是源文件位於我的src文件夾中,該文件夾是我的exe文件夾的父文件夾,因此B庫範圍包括exe

我怎樣才能讓CMake的知道在哪裏找到我的A庫,以便它可以在它連接src/exerunnerA時找到了嗎?


PROJECT_ROOT

cmake_minimum_required(VERSION 2.8) 
project(MyProject) 

add_subdirectory(src) 

PROJECT_ROOT/SRC

find_package(Module REQUIRED) 

# CREATE LIBRARIES 
add_library(
    B 
    B1.cpp B1.h 
    B2.cpp B2.h 
) 

# GROUP LIBRARIES TOGETHER 
set(
    B_LIBS 
    B 
    ${Module_LIBS} 
) 


# INCLUDE DIRECTORIES 
set(
    B_INCLUDES 
    . 
    ${Module_INCLUDE_DIRS} 
) 

# ASSIGN INCLUDES TO LIBRARY 
target_include_directories(
    B PUBLIC 
    ${B_INCLUDES} 
) 


add_subdirectory(ext) 
add_subdirectory(exe) 

PROJECT_ROOT/SRC/EXT

add_subdirectory(outside_module) 

PROJECT_ROOT/src目錄/ EXT/outside_module

find_package(Boost COMPONENTS 
    filesystem 
    system 
    log 
    thread 
    REQUIRED) 

# ADD DEFINITIONS 
add_definitions(-DBOOST_LOG_DYN_LINK) # Necessary to compile A with log shared libraries (instead of static) 

# DEFINE LIBRARY 
add_library(
    A 
    A1.cpp A2.h 
) 

# LINK LIBRARIES 
set(
    A_LIBS 
    A 
    ${Boost_FILESYSTEM_LIBRARY} 
    ${Boost_LOG_LIBRARY} 
    ${Boost_SYSTEM_LIBRARY} 
    ${Boost_THREAD_LIBRARY} 
) 

# INCLUDE DIRECTORIES 
set(
    A_INCLUDES 
    ${Boost_INCLUDE_DIRS} 
) 

PROJECT_ROOT/src目錄/ EXE

# DEFINE EXECUTABLES 
add_executable(runnerB runnerB.cpp) 
add_executable(runnerA runnerA.cpp) 


################## 
# LINK LIBRARIES 
################## 
target_link_libraries(
    runnerB 
    ${B_LIBS} 
) 

target_link_libraries(
    runnerA 
    ${A_LIBS} 
) 

target_include_directories(
    runnerA PUBLIC 
    ${A_INCLUDES} 
) 

# INSTALLATION 
install(TARGETS runnerB DESTINATION bin/) 
install(TARGETS runnerA DESTINATION bin/) 
+0

您需要將您的可執行文件鏈接到A:'target_link_libraries(runnerA A)'。 – arrowd

+0

@arrowd:我做到了。在我的代碼中輸入「PROJECT_ROOT/src/exe」部分。現在已經修復了 – marcman

+0

@arrowd:另外,這就是說,我真的認爲這是一個範圍問題。由於我的CMake命令適用於跑步者B – marcman

回答

0

權,你在嵌套的CMakeLists.txt設置${A_LIBS}變量。解決方法是使用set() commandPARENT_SCOPECACHE關鍵字。

+0

在我的情況下,當我需要「祖父母」範圍時會發生什麼? – marcman

+0

使用'CACHE',這會在'CMakeCache.txt'中創建一個條目,因此您的變量將是全局的。 – arrowd

+0

在這種情況下也不要忘記'FORCE'! – arrowd

相關問題