我正在开发一个由3个服务器可执行文件和一个共享代码库组成的项目。我希望它是跨平台的,所以我正在使用CMake(因为Xcode很痛苦)来处理构建过程。我在设置CMakeLists时遇到问题,以便在构建可执行文件时可以从同一级别的目录中包含库。
这是目录结构(和CMake文件):
tethealla2.0/
CMakeLists.txt
libtethealla/
CMakeLists.txt
encryption/
utils/
patch_server/
CMakeLists.txt
login_server/
CMakeLists.txt
ship_server/
CMakeLists.txt
我的顶级CMake(tethealla2.0 / CMakeLists.txt,仅包含应编译的子项目):
project(tethealla CXX)
cmake_minimum_required(VERSION 2.6)
add_subdirectory(libtethealla)
add_subdirectory(patch_server)
tethealla2.0 / libtethealla / CMakeLists.txt,它生成一个静态库:
project(Libtethealla C)
cmake_minimum_required(VERSION 2.6)
include_directories(encryption)
set(ENC_DR encryption/)
set(ENCRYPTION_SOURCES
${ENC_DR}/psobb-crypt.c
${ENC_DR}/psogc-crypt.c
${ENC_DR}/psobb-crypt.c
${ENC_DR}/encryption.c
)
add_library(tethealla STATIC ${ENCRYPTION_SOURCES})
到目前为止tethealla2.0 / patch_server / CMakeLists.txt:
project(patch_server CXX)
cmake_minimum_required(VERSION 2.6)
add_executable(server main.cc)
target_link_libraries(server tethealla)
因此,如果我从顶层构建它更有意义,因为tethealla2.0 / CMakeLists.txt将从每个子目录继承目标,而patch_server中的目标将可以访问tethealla库。但是我想要的是能够从这些子目录中构建生成Xcode项目,以便我可以单独处理/重新编译它们。为此,我需要能够访问libtethealla / build目录(CMake输出)以从patch_server访问libtethealla.a库。这可能吗?
另外请注意,即使在顶级目录的构建中,我在patch_server中的源也不能包含“encryption.h”,即加密库中的头文件。这看起来很好。对此的任何想法也非常感谢!
答案 0 :(得分:15)
我的解决方案是使用add_subdirectory和shared_lib目录的相对补丁。我不认为这是一个完美的解决方案,它有其警告:
我们假设目录结构如下所示:
root/
CMakeLists.txt
shared_lib/
CMakeLists.txt
inc/
foo.h
src/
foo.c
exec1/
CMakeLists.txt
main.c
exec2/
CMakeLists.txt
main.c
根/ CMakeList.txt
cmake_minimum_required(VERSION 2.6)
add_subdirectory(shared_lib)
add_subdirectory(exec1)
add_subdirectory(exec2)
我已经确定shared_lib / CMakeLists.txt将导出名为SHARED_DIR_INCLUDE_DIR
的变量。这种方法有助于解决一些问题。
根/ exec1 /的CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
add_subdirectory(./../shared_lib shared_lib)
include_directories(${SHARED_LIB_INCLUDE_DIR})
set(SRCS main.c)
add_executable(exec1 ${SRCS})
target_link_libraries(exec1 shared_lib)
第四行中的 if()
解决了目标多重定义的问题,以防多次添加CMakeLists文件。第二行和第三行导出SHARED_LIB_INCLUDE_DIR
根/ shared_lib /的CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
set(SHARED_LIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)
set(SHARED_LIB_INCLUDE_DIR ${SHARED_LIB_INCLUDE_DIR} PARENT_SCOPE)
if(TARGET shared_lib)
message("shared_lib is already defined")
else()
include_directories(${SHARED_LIB_INCLUDE_DIR})
set(LIB_SRCS ./src/foo.c)
add_library(shared_lib STATIC ${LIB_SRCS})
endif()