如何以跨平台的方式使用CMAKE包含库



我正试图在跨平台C++项目中使用assimp库。我将repo作为git子模块包括在内,因此,实际上,如果有人下载我的项目,他们也会下载ASSIMP项目。

在我完成assimp build/CMAKE指令并(在Linux上)键入make install之后,从那时起,我可以在我的项目中使用:

target_link_libraries(${PROJECT_NAME} assimp)

但是,Windows上没有make install

我能够在Linux上包含该库的唯一其他方法是(在我的CmakeLists.txt文件中)放入:

target_link_libraries(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/build/assimp/code/libassimp.so)

这不是跨平台的,因为它对.so文件的名称和位置进行了硬编码,该文件在Windows上不起作用。

如何公开库,以便在所有平台上执行类似target_link_libraries(${PROJECT_NAME} assimp)的操作?

我的目录树看起来像:

- src
- include
- assimp
- bin

其中include目录中的assimp目录是git子模块

我认为你的做法不对。您不需要在项目的单独步骤中构建assimp,也不需要make install使其可用。

Cmake中有许多处理第三方依赖关系的方法,因为您已经选择了对assimp存储库进行子模块化,所以我们将从那里开始。假设assimp位于存储库的根目录assimp/中,这将是一个包含它的基本项目:

cmake_minimum_required(VERSION 3.0)
project(Project myassimpproj)
# include your directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
# set any variables you might need to set for your app and assimp
set(BUILD_ASSIMP_TOOLS  ON)
set(ASSIMP_BUILD_STATIC_LIB ON)
# add assimp source dir as a subdirectory, effectively making 
# assimp's CMakeLists.txt part of your build
add_subdirectory(/path/to/assimp ${CMAKE_BINARY_DIR}/assimp)
add_executable(assimp_target main.cpp)
# be sure to link in assimp, use platform-agnostic syntax for the linker
target_link_libraries(assimp_target assimp)

使用生成器表达式语法可能有更好的表达方式,但我还没有查看assimp的CMakeLists.txt来了解它是否受支持(无论如何,这是一种更通用的方式)

并不是每个项目都使用Cmake,所以您可能无法仅使用add_subdirectory()。在这些情况下,您可以有效地"伪造"用户调用,以便在各自的平台上使用他们的构建命令来构建它们。execute_process()在配置时运行命令add_custom_command()add_custom_target()在构建时运行命令。然后你创建一个假目标来进行整合,并祈祷他们有一天会支持Cmake。

您也可以使用添加到Cmake的ExternalProject命令来创建一个自定义目标,以驱动外部项目的下载、更新/修补、配置、构建、安装和测试步骤,但请注意,此解决方案和下一个解决方案下载依赖项,而不是使用子模块的源代码。

最后,我更喜欢使用预构建的依赖项,减少构建时间,并且可以在项目之外对它们进行单独的单元测试。Conan是一个开源、去中心化和多平台的包管理器,对C++有很好的支持,如果使用得当,对Cmake几乎是透明的支持。在过去的一年里,它们变得非常稳定。关于如何使用柯南和Cmake的更多信息可以在这里找到。

最新更新