我正在做一个cmake项目,该项目需要在本地安装另一个库"foo"(即通过在其源目录中运行make ; sudo make install
)。
在这种情况下,"foo"恰好是另一个 cmake 项目,它将自身作为标头和 .a 库文件安装到${CMAKE_INSTALL_INCLUDEDIR}/foo/foo.h
和${CMAKE_INSTALL_LIBDIR}/foo/foo.a
中。不幸的是,foo.h
包括自己的bar.h
作为#include "bar.h"
,而不是#include "foo/bar.h"
。因此,任何使用 foo 库的项目都需要将foo
子目录添加到其搜索路径中。
在我的机器上,我可以通过以下CMakeLists.txt构建我的可执行文件:
find_library(FOO_LIBRARIES NAMES foo PATH /usr/local/lib/foo)
add_executable(my_exe main.cc)
target_link_libraries(my_exe ${FOO_LIBRARIES})
target_include_directories(my_exe /usr/local/include/foo)
然而,这种方法需要硬编码/usr/local/lib
和/usr/local/include
,这似乎很脆弱和错误。有什么更好的方法呢?
命令find_library有一个特殊的参数PATH_SUFFIXES
,它表示要附加到搜索路径的后缀:
find_library(FOO_LIBRARIES NAMES foo PATH_SUFFIXES "foo")
命令 find_path 也存在类似的参数,用于查找包含目录。
# Usual include directory, which contains 'foo/foo.h'
find_path(FOO_INCLUDE_DIR "foo/foo.h")
# Specific include directory, which contains (directly) 'bar.h'
# This specific directory is usually suffixed with 'foo/'.
find_path(BAR_INCLUDE_DIR "bar.h" PATH_SUFFIXES "foo")
target_include_directories(my_exe ${FOO_INCLUDE_DIR} ${BAR_INCLUDE_DIR} )
使用find_library
和find_path
对于可能使用本地安装的库很有用。 例如,如果foo
库将使用自定义安装前缀/home/me/foo-install
安装,那么将该前缀添加到变量CMAKE_PREFIX_PATH就足够了。
使用 CMake 机制导出/导入目标。
简而言之,您的foo
项目应该生成 CMake 导出的目标(以及相应的配置)。因此,您的项目仅使用find_package(foo...)
来导入它。正确配置了foo
的构建要求后,在您的项目中,您将只使用target_link_libraries()
而忘记路径和其他编译器/预处理器/链接器选项可能需要链接 w/foo
。