我是C / C ++开发的新手,并且正与CLion IDE中的CMakeLists.txt挣扎。
我无法创建可以包含在另一个程序中的库(静态或共享)。
我有这种结构:
src/
|
|---> utilities/
| |---> CMakeLists.txt
| |---> utilties.h
| |
| |---> file_utilities/
| | |---> file_utilities.h
| | |---> file_utilities.c
| ...
|
|---> my_app
|---> CMakeLists.txt
|---> main.c
我生成了一个libutilities.so和一个libutilities.a。在我的main.c文件中,如果我执行#include "../utilities/utilities.h"
或#include "../utilities/file_utilities/file_utilities.h"
,它就可以工作。
更糟糕的是,如果我使用另一个程序创建另一个项目并链接我的libutilities.so,则该链接似乎有效,但仍然不能包含我的标题。
我已经尝试了CMakeLists.txt中的许多配置和许多选项,但是直到现在为止,它从未起作用。
这是我用于库的CMakeLists.txt。我很确定问题出在此文件中。
cmake_minimum_required(VERSION 3.7)
project(utilities VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 11)
link_libraries(pthread)
link_libraries(ssl)
link_libraries(crypto)
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
file(GLOB_RECURSE SOURCES RELATIVES "*.c")
file(GLOB_RECURSE HEADERS RELATIVES "*.h")
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME} PROPERTIES
PUBLIC_HEADER "${HEADERS}"
ARCHIVE_OUTPUT_DIRECTORY "lib"
LIBRARY_OUTPUT_DIRECTORY "lib"
OUTPUT_NAME ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} PUBLIC .)
target_link_libraries(${PROJECT_NAME} ${CURL_LIBRARIES})
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
我想拥有一个更像#include <utilities/utilties.h>
的东西,因为它是一个图书馆。但是我无法使其正常工作。
在我提供的示例中,该库是一个简单的“ utils”库,但是我必须创建更多我必须交付的库,并将其集成到我的库之外的其他程序中。
答案 0 :(得分:0)
我强烈建议您阅读this article,其中创建了一个虚构的库目标,从项目结构到安装/导出。据我了解,作者的目标与您完全相同。刚开始时,这篇文章为我整理了很多东西。我还推荐其中列出的项目结构。
项目结构:
libjsonutils
├── CMakeLists.txt
├── include
│ └── jsonutils
│ └── json_utils.h
├── src
│ ├── file_utils.h
│ └── json_utils.cpp
└── test
├── CMakeLists.txt
└── src
└── test_main.cpp
具体来说,您将要看一下Targets and Properties,其中生成器表达式用于区分构建时和安装时的include目录:
target_include_directories(JSONUtils
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
稍后在This is how you do CMake中说明目标的安装过程和导出/导入。作者想要做的就是能够通过执行以下操作在其他cmake项目(例如,名为“ example”的目标)中使用该库:
find_package(JSONUtils 1.0 REQUIRED)
target_link_libraries(example JSONUtils::JSONUtils)
为了使此工作有效,您将需要安装和导出该库。作者鼓励这样做进行安装:
include(GNUInstallDirs)
install(TARGETS JSONUtils
EXPORT jsonutils-export
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
用于导出的
install(EXPORT jsonutils-targets
FILE
JSONUtilsTargets.cmake
NAMESPACE
JSONUtils::
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/JSONUtils
)
导出将在给定目标中放置一个名为findJsonUtils.cmake的文件。该文件将是您使用find_package机制在其他项目中导入库所需要的。
本文中的所有代码示例均摘自Pablo Arias的链接文章。
答案 1 :(得分:0)
您的CMakeLists.txt位于内部 utilities
中,尝试使用它。
src/utilities/CMakeLists.txt
:
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
)
对于应用程序,您应该具有以下内容:
src/my_app/CMakeLists.txt
:
target_link_libraries(${PROJECT_NAME} PRIVATE utilities)
,你应该简单
src/CMakeLists.txt
:
add_subdirectory(utilities)
add_subdirectory(my_app)