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

Pin*_*ntu 2 cmake

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

下面是我的文件结构示例.

项目

  • 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(所有头文件)
  • 建立/ 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})
Run Code Online (Sandbox Code Playgroud)

日志目录的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)
Run Code Online (Sandbox Code Playgroud)

元数据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)
Run Code Online (Sandbox Code Playgroud)

当我刚刚创建项目时,没有创建可执行文件,正在生成静态文件.但是,当我创建整个项目(即包含subProject_3目录)时,我得到一个未定义的引用,a::String它是a.cpp中的一个函数.

注意:所有3个项目都相互依赖.例如,在a.cpp中,我有#include "b.h"和b.cpp我有#include "a2.h".

所以,我几乎没有问题:

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

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

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

错误详情:

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

我也得到未定义的引用错误/home...../metadata/data.cpp 172:对xmlSerahNs的未定义引用,依此类推.collect2:ld返回1退出状态

谢谢您的帮助.

Fra*_*ser 7

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

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

target_link_libraries(subProject3 subProject2 subProject1)
Run Code Online (Sandbox Code Playgroud)

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

是.来自以下文档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)
Run Code Online (Sandbox Code Playgroud)

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


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

在顶级CMakeLists.txt中,在添加子目录之前,您可以设置所需的所有标志.(见add_definitionsProperties on Targets举例)他们将所有的子项目被采用,除非特别改变一个子项目.