- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试学习如何制作共享库。以下似乎有效(如果您对此方法有任何反馈,请发表评论,我基本上不知道我在做什么)。
在我的库项目中,我将头文件放入名为“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/
我是一名优秀的程序员,十分优秀!