2012-11-01 79 views
1

我是CMake的新手,我試圖讓我的項目編譯。該項目創建了一些靜態庫和一些可執行文件。CMake創建可執行文件時未定義的參考

下面是我有的文件結構的例子。

項目

  • SRC

    1. subProject_1
      的.cpp(所有源文件)和1的CMakeLists.txt這個文件夾(創建靜態庫)
    2. subproject_2
      。 cpp(所有源文件)和CMakeLists.txt 2用於此文件夾(創建靜態庫)
    3. subproject_3
      的.cpp(所有源文件)和3的CMakeLists.txt此文件夾(創建可執行文件)
  • 包括

    1. subProject_1
      .H(所有頭文件)
    2. subProject_2
      .H(所有頭文件)
    3. subProject_3
      .H(所有頭文件)
  • 構建/ Linux的

    1. 的CMakeLists.txt(主CMakelist文件)

主要的CMakeLists.txt

cmake_minimum_required(VERSION 2.6) 
SET(CMAKE_CXX_COMPILER "g++") 
Project(ort) 
SET (CMAKE_CXX_FLAGS " -g -Wall -pThread") 

#set the source and header directories location 
set(ORT_HEADER_DIRECTORY "../../include") #include folder structure explained above 
set(ORT_SOURCE_DIRECTORY "../../src") 
set(ORT_BINARY_DIRECTORY "../../lib") # lib folder to contain all the libraries 

set (CMAKE_CURRENT_BINARY_DIR ".") 

#Include the library packages 
include_directories("/usr/include/wx-2.8") 
include_directories("/usr/local/cuda/include") and so on 


#set the names of all the projects (for creating the libraries) 
SET(PROJECT_NAMES "log" "data" "cc") 

foreach(PROJECT_NAME ${PROJECT_NAMES}) 
    # Create the cmake related files in the out folder so that the libraries can be 
    # copied to the lib folder 
    add_subdirectory("{ORT_SOURCE_DIRECTORY}/${PROJECT_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/out/${PROJECT_NAME}" 

endforeach(PROJECT_NAME ${PROJECT_NAMES}) 

#set the names of all the projects (for creating the libraries) 
SET(EXECUATALE_PROJECTS "metadata") 

foreach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS}) 
    # Create the cmake related files in the out folder so that the libraries can be 
    # copied to the lib folder 
    add_subdirectory("{ORT_SOURCE_DIRECTORY}/${EXECUATALE_PROJECT}" "${CMAKE_CURRENT_BINARY_DIR}/out/${EXECUATALE_PROJECT}" 

endforeach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS}) 

日誌目錄的CMakeLists.txt文件(同樣的邏輯我已經使用了CC和數據項目)

include_directories(${ORT_HEADER_DIRECTORY}) 
SET(LOG_SOURCE a.cpp b.cpp c.cpp) 
ADD_LIBRARY(log_d ${LOG_SOURCE}) 
target_link)libraries(log_d cc_d data_d) 

元數據的CMakeLists.txt文件(創建可執行項目)

FIND_PACKAGE(wxWidgets) 
IF(wxWidgets_FOUND) 
     INCLUDE(${wxWidgets_USE_FILE}) 
ENDIF(wxWidgets_FOUND) 

Include_Directories(${wxWidgets_INCLUDE_DIRS}) 
include_directories(${ORT_HEADER_DIRECTORY}) 
include_directories("/usr/ort/lib/unixODBC/include") 

SET(META_SOURCE meta.cpp data.cpp) 

ADD_EXECUTABLE(meta_d ${META_SOURCE }) 
TARGET_LINK_LIBRARIES(meta_d log_d data_d) 

當我剛做項目,而不產生的可執行文件,正在生成靜態文件。但是,當我完成整個項目時(即包含subProject_3目錄),我得到了未定義的參考a::String這是a.cpp中的函數。

注意:所有3個項目都相互依賴。例如,在a.cpp中,我有#include "b.h",而在b.cpp中我有#include "a2.h"

所以,我有幾個問題:

一)如何解決未定義參考問題?一旦我爲項目1和2生成了庫,我如何將這些庫鏈接到可執行文件?

b)當我創建靜態庫時,我應該提供還是添加任何依賴項?這是創建靜態庫的正確方式(因爲項目是相互依賴的)? 即target_link_libraries(project1 project2 ...)項目1和target_link_libraries(project2 project1 ...)在項目2中。您能否告訴我如何爲每個單獨的項目指定相同的項目?

錯誤詳細信息:

喜愛程度CXX可執行metadata_d ../log/liblog_d.a:文件無法識別:文件截斷 collect2:LD返回1退出狀態

我也得到了未定義的引用錯誤 /home...../metadata/data.cpp 172:未定義的引用xmlSerahNs 等等。 collect2:ld返回1退出狀態

感謝您的幫助。

回答

6

How do I resolve the undefined reference issue ? Since, I have generating the libraries for project 1 and 2, how do I link these to the executable.

就再次使用target_link_libraries,這次在subProject3的的CMakeLists.txt:

target_link_libraries(subProject3 subProject2 subProject1) 

Is this the right way of creating the static libraries (as the projects are inter dependent)

是。從文檔爲target_link_libraries

The library dependency graph is normally acyclic (a DAG), but in the case of mutually-dependent STATIC libraries CMake allows the graph to contain cycles (strongly connected components). When another target links to one of the libraries CMake repeats the entire connected component. For example, the code

add_library(A STATIC a.c) 
add_library(B STATIC b.c) 
target_link_libraries(A B) 
target_link_libraries(B A) 
add_executable(main main.c) 
target_link_libraries(main A) 

links 'main' to 'A B A B'. (While one repetition is usually sufficient, pathological object file and symbol arrangements can require more. One may handle such cases by manually repeating the component in the last target_link_libraries call. However, if two archives are really so interdependent they should probably be combined into a single archive.)


Every project needs to be compiled with there own compilation setting. Can you please let me know how can I specify the same for every individual project?

在頂層的CMakeLists.txt,加入子目錄之前,你可以設置你需要有所有的標誌。 (例如,參見add_definitionsProperties on Targets)它們將被所有子項目採納,除非專門針對子項目進行了更改。

+0

嗨弗雷澤。感謝您的答覆。 W.r.t target_link_libraries我做了這樣的事情: target_link_libraries(subProject3 subProject1 subProject2) 但是,我仍然得到一個錯誤 libsubProject1.a:文件無法識別:文件截斷。 – Pintu

+0

另外,當我剛剛嘗試過使用target_link_libraries(subProject3 subProject_1 subProject_2)時,我收到以下錯誤: /usr/bin/ld:找不到-lsubProject_1 – Pintu

+0

@Pintu您確定始終使用正確的名稱嗎?您的示例代碼不能與您正在運行的內容完全相同,因爲其中存在一些錯誤。即使你上面的評論表明命名不一致。看起來您的文件夾可能被稱爲subProject_1(帶下劃線)和可能在'subProject1'裏面定義的目標(不帶下劃線)。如果是這種情況,您需要在'target_link_libraries'命令中指定'subProject1 subProject2',而不是'subProject_1 subProject_2'。 – Fraser