gpt4 book ai didi

c++ - 如何让cmake在子文件夹中找到共享库

转载 作者:太空狗 更新时间:2023-10-29 21:15:19 25 4
gpt4 key购买 nike

我正在尝试学习如何制作共享库。以下似乎有效(如果您对此方法有任何反馈,请发表评论,我基本上不知道我在做什么)。

在我的库项目中,我将头文件放入名为“include”的文件夹中,并将源文件放入“src”中。

我的图书馆的 CMakeLists.txt:

cmake_minimum_required(VERSION 2.4.0)

project(mycustomlib)

# Find source files
file(GLOB SOURCES src/*.cpp)

# Include header files
include_directories(include)

# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})

# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib)

# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include)

我的应用程序的 CMakeLists.txt:

cmake_minimum_required(VERSION 2.4.0)

project(myprogram)

# Find source files
file(GLOB SOURCES src/*.cpp)

# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})

# Find and link library
find_library(MYCUSTOMLIB mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})

有效。问题是我想将 header 和库都放入子文件夹中(具体来说:/usr/local/include/mycustomlib/ 用于 header ,/usr/local/lib/mycustomlib/ 用于库)。

所以这是我的尝试:

我的库的新 CMakeLists.txt:

cmake_minimum_required(VERSION 2.4.0)

project(mycustomlib)

# Find source files
file(GLOB SOURCES src/*.cpp)

# Include header files
include_directories(include)

# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})

# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})

# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})

我的应用程序的新 CMakeLists.txt:

cmake_minimum_required(VERSION 2.4.0)

project(myprogram)

# Find source files
file(GLOB SOURCES src/*.cpp)

# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})

# Find and link library
find_library(MYCUSTOMLIB mycustomlib/mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})

这是的。现在,我不得不像这样指定库的 .so 文件:

find_library(MYCUSTOMLIB mycustomlib/libmycustomlib.so)

怎么会?

最佳答案

我会先处理您的实际问题,然后再提供其他评论。从技术上讲,你要求 CMake 找到一个名为 mycustomlib/mycustomlib 的库,但你真正想说的是你想要找到 mycustomlib 并且它可以在子目录中找到名为 mycustomlib。调用 find_library() 来为您的第二种情况实现此目的的几种替代方法是:

find_library(MYCUSTOMLIB mycustomlib PATH_SUFFIXES mycustomlib)
find_library(MYCUSTOMLIB mycustomlib PATHS /usr/local/lib/mycustomlib)

后者对库的安装位置做了更多的假设,所以我倾向于第一个选项。第一个选项假设 CMake 已经在/usr/local/lib 中找到库,这似乎来自您的问题。您可以通过修改 CMAKE_PREFIX_PATH 来影响 CMake 查找库的位置。和 CMAKE_LIBRARY_PATH .我希望上述任一选项都能使您的第二个案例奏效。

现在进行其他观察。您在每个 CMakeLists.txt 文件的第一行中请求了一个非常旧的最低 CMake 版本。您可能至少要考虑将此版本设为 2.8(就个人而言,我建议更像是 3.2 或更高版本,但这取决于您的项目需要支持什么)。

您已使用文件通配来获取源和标题列表。这是不稳健的,通常应该避免(参见关于 here 的讨论)。为简单起见,您会看到大量使用此方法的示例代码,但不建议将其用于现实世界的项目(CMake 文档甚至是 says not to use it)。如果您想要健壮的构建,请单独明确列出您的源文件和头文件。

如果您乐于要求 CMake 2.8.11 或更高版本(这些天您应该是),而不是调用 include_directories() 让所有内容都选择您指定的标题搜索路径,您应该更愿意将搜索路径要求附加到需要它的目标。您使用 target_include_directories() 执行此操作.上面的代码等效于:

target_include_directories(${PROJECT_NAME} PUBLIC include)

随着项目规模和复杂性的增长,这可以更好地控制目标间的依赖关系。有关此主题的更深入讨论,请参阅 this article也许还有this one (披露:这两篇文章都是我写的)。

您的库和程序是完全独立的源代码存储库吗?它们可以构建在同一个项目中吗?您可以在一个 CMakeLists.txt 文件中构建多个目标。项目名称不必与任何目标的名称有任何关系(您经常看到 PROJECT_NAME 变量在简单示例中被重新用于目标名称,这很不幸,因为它表明两者之间的关系,但对于除简单项目之外的所有项目,情况并非如此)。如果它们在同一个存储库中,将它们构建在一起会更简单,因为您不必为可执行文件安装库来找到它并链接到它。

如果它们必须在单独的项目中构建,那么应用程序项目的类似以下内容应该可以让您关闭:

cmake_minimum_required(VERSION 2.8.11)
project(myprogram)

# List your program's sources here explicitly
add_executable(myprogram src/foo.cpp src/bar.cpp)

# Find and link library
find_library(MYCUSTOMLIB mycustomlib PATH_SUFFIXES mycustomlib)
target_link_libraries(myprogram PUBLIC ${MYCUSTOMLIB})

# Find library's headers and add it as a search path.
# Provide the name of one header file you know should
# be present in mycustomlib's include dir.
find_path(MCL_HEADER_PATH mycustomlib.h PATH_SUFFIXES mycustomlib)
target_include_directories(myprogram PUBLIC ${MCL_HEADER_PATH})

加分可以尝试通过检查公共(public)路径前缀来确认header路径和library在同一个区域,或者直接推导通过假定目录结构从 MYCUSTOMLIB 路径中获取 MCL_HEADER_PATH。两种方法都有优点和缺点。如果你想探索后者,get_filename_component()命令将是你的 friend 。

希望这能为您指明正确的方向。

关于c++ - 如何让cmake在子文件夹中找到共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38142999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com