c++ - 是否可以将具有外部依赖项的 C++ 项目/库配置为立即运行?

标签 c++ standards libraries external-dependencies

我是 C++ 的初学者,最近我正在研究下载外部库并将其链接到我正在处理的项目的过程。来自添加新的依赖项和安装必要的依赖项是一个命令的语言,似乎有几种方法可以下载和链接 C++ 中的库,所以我很难想象有经验的大型项目开发人员能够使他们的脚本和库可移植且易于设置。

举个例子,我最终在我的项目中使用的是一个 CMakeLists.txt 文件,其中包含我正在使用的库 libxml2 的硬编码路径,如下所示:

include_directories(/opt/homebrew/Cellar/libxml2/2.10.3_1/include);
link_directories(/opt/homebrew/Cellar/libxml2/2.10.3_1/lib);

但这需要将 libxml2 单独下载到克隆该项目的每台机器上,并且路径也会根据版本和环境而改变。所以我的具体问题是,打包具有外部依赖项的 C++ 项目的最佳实践是什么?

比如node.js有一个package.jsonnpm install,python有一个requirement.txtpip安装 -r requirements.txt。是否有 C++ 等效项?

如果这是一个愚蠢的问题,我很抱歉,但我真的很难找到正确的搜索词来找到正确的答案。提前致谢!

最佳答案

我个人只是使​​用带有依赖项的 git 模块作为我存储库的一部分,因此当有人 checkout 它时,他/她还可以拉取构建/链接所需依赖项所需的所有源代码。

幸运的是,许多流行的库本身都是使用 CMake 构建的,因此您无需做任何花哨的事情即可将它们添加到您的 CMake 项目中。模块还引用依赖库的特定提交,它有助于在贡献者之间保持一致的依赖版本。

例如这是我的一个项目中文件结构的样子(我去掉了一些与问题没有直接联系的细节):

|-- CMakeLists.txt
|-- CMakeSettings.json
|-- README.md
|-- assets
|   |-- assets-files
|-- lib
|   |-- CMakeLists.txt
|   |-- libTwo
|   |-- libThree
|   `-- libFour
`-- src
    |-- source-files

lib 中的每个子文件夹在我的存储库中都是一个单独的子模块。在根 CMakeLists.txt 中,我仅通过一行配置添加了这个文件夹和我的依赖项:

add_subdirectory(lib)

当 lib 文件夹中的 CMakeLists.txt 负责其余部分时:

add_compile_options(-w)
# Lib One
find_package(libOne REQUIRED)
list(APPEND LIB_TARGETS ${LIB_ONE_LIBRARIES})
list(APPEND LIB_INCLUDE_DIRS ${LIB_ONE_INCLUDE_DIRS})

# Lib Two
add_subdirectory(libTwo)
list(APPEND LIB_TARGETS libTwo)
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libTwo/include")

# Lib Three
add_subdirectory(libThree)
list(APPEND LIB_TARGETS libThreeProj)
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libThree/include")

# Lib Four
add_subdirectory(libFour)
list(APPEND LIB_TARGETS libFour)

if(LIB_INCLUDE_DIRS)
        list(REMOVE_DUPLICATES LIB_INCLUDE_DIRS)
        target_include_directories(${PROJ_NAME} PRIVATE ${LIB_INCLUDE_DIRS})
        if(MSVC)
                target_compile_options(${PROJ_NAME} PRIVATE
                        "$<$<CXX_COMPILER_ID:Clang>:SHELL:-Xclang -isystem$<JOIN:${LIB_INCLUDE_DIRS}, -Xclang -isystem>>"
                        "$<$<CXX_COMPILER_ID:MSVC>:SHELL:-experimental:external -external:W0 -external:anglebrackets -external:I$<JOIN:${LIB_INCLUDE_DIRS}, -external:I>>")
        else()
                target_compile_options(${PROJ_NAME} PRIVATE "SHELL:-isystem $<JOIN:${LIB_INCLUDE_DIRS}, -isystem>")
        endif()
endif()

target_link_libraries(${PROJ_NAME} PRIVATE ${LIB_TARGETS})

您可能会注意到,我还保留了其他依赖项(即本例中的 libOne),它们可以在同一位置使用 find_package 找到,并且它与所有我从远程仓库加载的依赖项。

当然,它并不总是无缝运行,并且在很大程度上取决于库作者如何分发他们的代码,但对我来说大部分时间都可以工作,即使它需要在配置中进行一些调整(例如 libFour 是仅包含 header 的库,根本不需要任何链接,而 libThree 的目标名称不一致 libThreeProj)

关于c++ - 是否可以将具有外部依赖项的 C++ 项目/库配置为立即运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74916407/

相关文章:

c++ - 使用STM32Cube IDE将代码从Arduino移植到stm32f100

html - 是否有提交空选择倍数的标准客户端行为?

javascript - 对象或数组的首选声明约定是什么 : const or let?

c++ - 在 Windows 中,如何拥有作为重定向管道的非阻塞标准输入?

c++ - 读取和解析文件,将解析后的字符串的每一段分配给它自己的变量

debugging - 标准调试方法

mysql - 在 cmakelist.txt 中添加和链接 mysql 库

c++ - POCO C++ SAX 解析器 : If the xml document encoding is ANSI then next statement is not reading and throwing encoding error exception

c++ - 使用 MSYS2 安装后如何运行 Glade 和 Devhelp

c++ - 虚幻引擎射击游戏示例中的 'class' 中的 'class DataType* Variable' 是什么