我正试图在跨平台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的更多信息可以在这里找到。