Cmake仅链接标头库(工作示例)我需要说明

发布于 2025-02-08 15:47:21 字数 2657 浏览 1 评论 0原文

我正在学习如何使用 external -project 仅下载header libaries并链接到我的可执行文件。

我的工作流程如下:

  1. 我使用EndenalProject下载标头库EIGEN:

cmake -dget_libs = on -dbuild_shared_libs = on -dbuild_my_projects = off -g -g “ Visual Studio 17 2022” -A X64 ..&& CMAKE-建造。 -Config版本

  1. 然后第二次运行相同的cmakelists,但是这次我禁用外部专用项目并编译链接特征的可执行文件:

cmake -dget_libs = off -dbuild_shared_libs = off -dbuild_my_projects = on -g“ Visual Studio 17 2022” -A x64 ..&& CMAKE-建造。 -Config版本

Question

为什么我需要使用这两个命令,因为在target_include_directories中命令i指定与Indunce Indulce_directories中相同的路径?

在下面的代码中,我需要两个命令include_directoriestarget_include_directories。 我认为仅使用target_include_directories,但是没有include_directories它将无法使用。

if (BUILD_MY_PROJECTS)
add_executable(my_exe main.cpp)


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable
endif ()

我的完整cmakelists.txt如下:

project(superbuild LANGUAGES CXX)
cmake_minimum_required(VERSION 3.19)

########################################################################
# EIGEN
########################################################################
SET(GET_LIBS "" CACHE STRING "Set option to download dependencies")
if (GET_LIBS)
  message(AUTHOR_WARNING ${GET_LIBS})
  ExternalProject_Add(eigen
    GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
    GIT_TAG 3.4.0
    CMAKE_ARGS
      -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
      -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/install/eigen #this does nothing...
    SOURCE_DIR   "${CMAKE_BINARY_DIR}/install/eigen" #install in my local build dir
    #SOURCE_DIR ${CMAKE_INSTALL_PREFIX}
    BUILD_COMMAND "" #do not build
    INSTALL_COMMAND "" #do not install
  )

endif ()


###############################################################################
#EXECUTABLES
###############################################################################
if (BUILD_MY_PROJECTS)
add_executable(my_exe main.cpp)


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable
endif ()

I am learning how to use ExternalProject to download header only libaries and link to my executable.

My workflow is following:

  1. I download header library Eigen using ExtenalProject:

cmake -DGET_LIBS=ON -DBUILD_SHARED_LIBS=ON -DBUILD_MY_PROJECTS=OFF -G
"Visual Studio 17 2022" -A x64 .. && cmake --build . --config Release

  1. Then I run the same CMakeLists a second time, but this time I disable ExternalProject and compile the executable that links the Eigen:

cmake -DGET_LIBS=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_MY_PROJECTS=ON
-G "Visual Studio 17 2022" -A x64 .. && cmake --build . --config Release

Question

Why I need to use both of these commands since in target_include_directories command I specify the same path as in include_directories?

In the code below I need two commands include_directories and target_include_directories.
I thought that it would be enough to use only target_include_directories, but without include_directories it wont work.

if (BUILD_MY_PROJECTS)
add_executable(my_exe main.cpp)


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable
endif ()

My full CMakeLists.txt is following:

project(superbuild LANGUAGES CXX)
cmake_minimum_required(VERSION 3.19)

########################################################################
# EIGEN
########################################################################
SET(GET_LIBS "" CACHE STRING "Set option to download dependencies")
if (GET_LIBS)
  message(AUTHOR_WARNING ${GET_LIBS})
  ExternalProject_Add(eigen
    GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
    GIT_TAG 3.4.0
    CMAKE_ARGS
      -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
      -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/install/eigen #this does nothing...
    SOURCE_DIR   "${CMAKE_BINARY_DIR}/install/eigen" #install in my local build dir
    #SOURCE_DIR ${CMAKE_INSTALL_PREFIX}
    BUILD_COMMAND "" #do not build
    INSTALL_COMMAND "" #do not install
  )

endif ()


###############################################################################
#EXECUTABLES
###############################################################################
if (BUILD_MY_PROJECTS)
add_executable(my_exe main.cpp)


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable
endif ()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独自←快乐 2025-02-15 15:47:21

tl; dr 切勿使用include_directories 。曾经。了解属性可见性如何在CMAKE中起作用。


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable

在您提供的代码中,include_directories隐含地设置include_directories在您的my_exe target上的属性。然后,第二行设置Interface_include_directories属性。

include_directories是构建目标时必须传递给编译器的包括目录的列表。 Interface_include_directories是一个包括目录的列表,当构建链接到此的目标时,必须将其传递给编译器。对于可执行文件而言,这并没有多大意义

,就是写:

target_include_directories(my_exe PRIVATE "${CMAKE_BINARY_DIR}/install/eigen/")

这​​只会填充include_directories而无需触摸接口_版本。如果您愿意,则可以编写public,而不是private接口。根据定义,public只是其他两个。


但这并不是一个很好的依赖性管理策略...挖掘项目的源肠道是无法扩展的。在不编辑构建文件的情况下,尝试不同版本的特征也很难。

我只会写:

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Eigen3 REQUIRED)

add_executable(my_exe main.cpp)
target_link_libraries(my_exe PRIVATE Eigen3::Eigen)

使用适当的软件包管理器,例如VCPKG或CONAN在系统上没有可用时处理eigen。

Tl;dr never use include_directories. Ever. Learn how property visibility works in CMake instead.


include_directories("${CMAKE_BINARY_DIR}/install/eigen/") #add directory of the header-only library without this the next line wort work
target_include_directories(my_exe INTERFACE "${CMAKE_BINARY_DIR}/install/eigen/")# link exe to exectable

In the code you supplied, include_directories is implicitly setting the INCLUDE_DIRECTORIES property on your my_exe target. Then the second line sets the INTERFACE_INCLUDE_DIRECTORIES property.

INCLUDE_DIRECTORIES is a list of include directories that must be passed to the compiler when building the target. INTERFACE_INCLUDE_DIRECTORIES is a list of include directories that must be passed to the compiler when building targets that link to this one. This doesn't make much sense for an executable

Slightly better would be to write:

target_include_directories(my_exe PRIVATE "${CMAKE_BINARY_DIR}/install/eigen/")

This will just populate INCLUDE_DIRECTORIES without touching the INTERFACE_ version. If you wanted both you could write PUBLIC instead of PRIVATE or INTERFACE. By definition, PUBLIC is just both of the others.


But this isn't a great dependency management strategy anyway... digging into the source tree guts of a project isn't scalable. It's also difficult to try different versions of Eigen without editing your build files.

I would just write:

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Eigen3 REQUIRED)

add_executable(my_exe main.cpp)
target_link_libraries(my_exe PRIVATE Eigen3::Eigen)

Use a proper package manager like vcpkg or Conan to handle downloading Eigen when it isn't available on the system.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文