我是CMake的新手,我正在尝试编译我的项目。该项目创建了一些静态库和一些可执行文件。
以下是我拥有的文件结构示例。
PROJECT
SRC
包含
build / linux
主要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退出状态
感谢您的帮助。
答案 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_definitions
和Properties on Targets
)除非为子项目进行特别更改,否则所有子项目都将采用它们。