创建可执行文件时CMake未定义的引用

时间:2012-11-01 17:53:16

标签: cmake

我是CMake的新手,我正在尝试编译我的项目。该项目创建了一些静态库和一些可执行文件。

以下是我拥有的文件结构示例。

PROJECT

  • SRC

    1. subProject_1
      .cpp(所有源文件)和CMakeLists.txt 1用于此文件夹(创建静态库)
    2. subproject_2
      此文件夹的.cpp(所有源文件)和CMakeLists.txt 2(创建静态库)
    3. subproject_3
      .cpp(所有源文件)和CMakeLists.txt 3用于此文件夹(创建可执行文件)
  • 包含

    1. subProject_1
      .h(所有头文件)
    2. subProject_2
      .h(所有头文件)
    3. subProject_3
      .h(所有头文件)
  • build / 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"

所以,我几乎没有问题:

a)如何解决未定义的引用问题?为项目1和项目2生成库后,如何将这些库链接到可执行文件?

b)在创建静态库时,我应该提供或添加任何依赖项吗?这是创建静态库的正确方法(因为项目是依赖于内部的)吗? 即项目1中的target_link_libraries(project1 project2 ...)和项目2中的target_link_libraries(project2 project1 ...)

c)每个项目都需要使用自己的编译设置进行编译。能告诉我如何为每个项目指定相同的内容?

错误细节:

喜欢CXX可执行元数据_d ../log/liblog_d.a:文件无法识别:文件被截断 collect2:ld返回1退出状态

我也得到了未定义的引用错误 /home...../metadata/data.cpp 172:对xmlSerahNs的未定义引用 等等。 collect2:ld返回1退出状态

感谢您的帮助。

1 个答案:

答案 0 :(得分:7)

  

如何解决未定义的引用问题?因为,我已经为项目1和2生成了库,我如何将它们链接到可执行文件。

再次使用target_link_libraries,这次是在subProject3的CMakeLists.txt中:

target_link_libraries(subProject3 subProject2 subProject1)

  

这是创建静态库的正确方法(因为项目是相互依赖的)

是。来自target_link_libraries的文档:

  

库依赖图通常是非循环的(DAG),但在   相互依赖的STATIC库的情况CMake允许图形   包含循环(强连接组件)。当另一个目标   链接到其中一个库CMake重复整个连接   零件。例如,代码

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)
     

将'main'链接到'A B A B'。 (虽然通常会重复一次   足够的,病理对象文件和符号安排可以   需要更多。人们可以通过手动重复来处理这种情况   最后一个target_link_libraries调用中的组件。但是,如果两个   档案真的如此相互依赖,它们应该结合起来   到一个档案馆。)


  

每个项目都需要使用自己的编译设置进行编译。能告诉我如何为每个项目指定相同的内容?

在顶级CMakeLists.txt中,在添加子目录之前,您可以设置所需的所有标志。 (例如,参见add_definitionsProperties on Targets)除非为子项目进行特别更改,否则所有子项目都将采用它们。