CMake - 带有示例子目录 运行 的库作为单独的项目
CMake - Library with example subdirectory running as separate project
编辑 2 - 已修复!
问题已通过正确使用 绝对路径 而不是相对路径,并将 add_subdirectory
添加到 example/CMakelists.txt
.
来解决
我已经更新了提供的代码(并将离开存储库以防有人想将其用作起点。
编辑:
- 调整
CMakelists.txt
文件以仅使用绝对路径(根据 @Tsyvarev 的建议
- 添加了准确的编译错误消息
原文post:
我正在尝试编写一个库,其中包含示例项目,并且可以作为 Git 子模块添加。所需的结构是这样的:
- source
- MyLib
lib.cpp
- CMakelists.txt
- include
- MyLib
lib.h
- example
main.cpp
CMakelists.txt
CMakelists.txt (main CMake for library)
我要达到什么目的:
- 结构可能或多或少应该保留,所以只需添加一个 gitmodule 就可以安装库
example
项目应该能够通过加载目录中的 CMakelists.txt
自行 运行,并且应该能够使用库
我的问题是什么:
我最大的问题是将示例链接到同级文件夹中的库,并确保它可以编译。我设法以我的 IDE 正确理解 #include
语句的方式编写了 CMakelists.txt,但在编译期间找不到函数定义。
请问谁能指点一下吗?
准确的编译错误信息:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lMY_LIB
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\MY_LIB_EXAMPLE.dir\build.make:95: MY_LIB_EXAMPLE.exe] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:82: CMakeFiles/MY_LIB_EXAMPLE.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:89: CMakeFiles/MY_LIB_EXAMPLE.dir/rule] Error 2
mingw32-make: *** [Makefile:123: MY_LIB_EXAMPLE] Error 2
CMakelists.txt 个文件
CMakelists.txt:
cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 20)
project(MY_LIB)
add_subdirectory(source)
source/CMakelists.txt
add_library(MY_LIB MyLib/library.cpp ../include/MyLib/library.h)
target_include_directories(MY_LIB PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/MyLib)
target_include_directories(MY_LIB PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source/MyLib)
example/CMakelists.txt
cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 20)
#--------------------------------------------------------------------
# Get solution root
#--------------------------------------------------------------------
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR PARENT_PATH LIB_PATH)
cmake_path(SET LIB_INCLUDE_PATH "${LIB_PATH}/include")
message(${LIB_PATH})
message(${LIB_INCLUDE_PATH})
#--------------------------------------------------------------------
# Set project name
#--------------------------------------------------------------------
project(MY_LIB_EXAMPLE)
#--------------------------------------------------------------------
# Add source
#--------------------------------------------------------------------
add_executable(MY_LIB_EXAMPLE main.cpp)
add_subdirectory(${LIB_PATH} library-build)
#--------------------------------------------------------------------
# Link libraries
#--------------------------------------------------------------------
target_link_libraries(MY_LIB_EXAMPLE MY_LIB)
#--------------------------------------------------------------------
# Link include directories
#--------------------------------------------------------------------
target_include_directories(MY_LIB_EXAMPLE PUBLIC ${LIB_INCLUDE_PATH})
我用我的设置创建了一个示例存储库:https://github.com/jiriKralovec/cmake-library
he example project should be capable of running on its own by loading the CMakelists.txt in the directory, and should be able to use the library
只需添加:
add_subdirectory(./../ some_unique_name_here)
我想我会删除 source/CMakelists.txt
并将其全部写入根目录 CMakelists.txt
。使用 ../
来引用包含目录很奇怪。
我建议做选项 and/or 单元测试:
root CMakeLists.txt:
include(CTest)
add_library(MY_LIB ....)
# one design
if (BUILD_TESTING)
add_subdirectory(example)
endif()
# another design
add_subdirectory(utilities)
example/CMakeLists.txt:
# if it is something simple, add unit test:
add_executable(MY_LIB_EXAMPLE1 <maybe EXCLUDE_FROM_ALL?> ...)
add_test(NAME MY_LIB_EXAMPLE1 COMMAND MY_LIB_EXAMPLE1)
utilities/CMakeLists.txt:
# if it is a utility, optionally build it
add_executable(MY_LIB_UTILITY_TO_DO_SMTH ...)
option(... BUILD_MY_LIB_UTILITY_TO_DO_SMTH OFF)
if(NOT BUILD_MY_LIB_UTILITY_TO_DO_SMTH)
set_target_properties(
MY_LIB_UTILITY_TO_DO_SMTH
PROPERTIES EXCLUDE_FROM_ALL ON
)
endif()
不管怎样,做一个 CMake 构建。然后,如果用户想要构建该实用程序,他将执行 cmake --build <builddir> --target MY_LIB_UTILITY_TO_DO_SMTH
(或 make MY_LIB_UTILITY_TO_DO_SMTH
)。如果你想要构建单元测试,你会做cmake ... -D BUILD_TESTING=1
。
有些人将所有单元测试可执行文件添加为 EXCLUDE_FROM_ALL 并制作特殊 add_custom_target(build_tests) add_target_dependencies(build_tests MY_LIB_EXAMPLE1 etc. etc.)
并在测试前构建该自定义目标。
编辑 2 - 已修复!
问题已通过正确使用 绝对路径 而不是相对路径,并将 add_subdirectory
添加到 example/CMakelists.txt
.
我已经更新了提供的代码(并将离开存储库以防有人想将其用作起点。
编辑:
- 调整
CMakelists.txt
文件以仅使用绝对路径(根据 @Tsyvarev 的建议
- 添加了准确的编译错误消息
原文post:
我正在尝试编写一个库,其中包含示例项目,并且可以作为 Git 子模块添加。所需的结构是这样的:
- source
- MyLib
lib.cpp
- CMakelists.txt
- include
- MyLib
lib.h
- example
main.cpp
CMakelists.txt
CMakelists.txt (main CMake for library)
我要达到什么目的:
- 结构可能或多或少应该保留,所以只需添加一个 gitmodule 就可以安装库
example
项目应该能够通过加载目录中的CMakelists.txt
自行 运行,并且应该能够使用库
我的问题是什么:
我最大的问题是将示例链接到同级文件夹中的库,并确保它可以编译。我设法以我的 IDE 正确理解 #include
语句的方式编写了 CMakelists.txt,但在编译期间找不到函数定义。
请问谁能指点一下吗?
准确的编译错误信息:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lMY_LIB
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\MY_LIB_EXAMPLE.dir\build.make:95: MY_LIB_EXAMPLE.exe] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:82: CMakeFiles/MY_LIB_EXAMPLE.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:89: CMakeFiles/MY_LIB_EXAMPLE.dir/rule] Error 2
mingw32-make: *** [Makefile:123: MY_LIB_EXAMPLE] Error 2
CMakelists.txt 个文件 CMakelists.txt:
cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 20)
project(MY_LIB)
add_subdirectory(source)
source/CMakelists.txt
add_library(MY_LIB MyLib/library.cpp ../include/MyLib/library.h)
target_include_directories(MY_LIB PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/MyLib)
target_include_directories(MY_LIB PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source/MyLib)
example/CMakelists.txt
cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 20)
#--------------------------------------------------------------------
# Get solution root
#--------------------------------------------------------------------
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR PARENT_PATH LIB_PATH)
cmake_path(SET LIB_INCLUDE_PATH "${LIB_PATH}/include")
message(${LIB_PATH})
message(${LIB_INCLUDE_PATH})
#--------------------------------------------------------------------
# Set project name
#--------------------------------------------------------------------
project(MY_LIB_EXAMPLE)
#--------------------------------------------------------------------
# Add source
#--------------------------------------------------------------------
add_executable(MY_LIB_EXAMPLE main.cpp)
add_subdirectory(${LIB_PATH} library-build)
#--------------------------------------------------------------------
# Link libraries
#--------------------------------------------------------------------
target_link_libraries(MY_LIB_EXAMPLE MY_LIB)
#--------------------------------------------------------------------
# Link include directories
#--------------------------------------------------------------------
target_include_directories(MY_LIB_EXAMPLE PUBLIC ${LIB_INCLUDE_PATH})
我用我的设置创建了一个示例存储库:https://github.com/jiriKralovec/cmake-library
he example project should be capable of running on its own by loading the CMakelists.txt in the directory, and should be able to use the library
只需添加:
add_subdirectory(./../ some_unique_name_here)
我想我会删除 source/CMakelists.txt
并将其全部写入根目录 CMakelists.txt
。使用 ../
来引用包含目录很奇怪。
我建议做选项 and/or 单元测试:
root CMakeLists.txt:
include(CTest)
add_library(MY_LIB ....)
# one design
if (BUILD_TESTING)
add_subdirectory(example)
endif()
# another design
add_subdirectory(utilities)
example/CMakeLists.txt:
# if it is something simple, add unit test:
add_executable(MY_LIB_EXAMPLE1 <maybe EXCLUDE_FROM_ALL?> ...)
add_test(NAME MY_LIB_EXAMPLE1 COMMAND MY_LIB_EXAMPLE1)
utilities/CMakeLists.txt:
# if it is a utility, optionally build it
add_executable(MY_LIB_UTILITY_TO_DO_SMTH ...)
option(... BUILD_MY_LIB_UTILITY_TO_DO_SMTH OFF)
if(NOT BUILD_MY_LIB_UTILITY_TO_DO_SMTH)
set_target_properties(
MY_LIB_UTILITY_TO_DO_SMTH
PROPERTIES EXCLUDE_FROM_ALL ON
)
endif()
不管怎样,做一个 CMake 构建。然后,如果用户想要构建该实用程序,他将执行 cmake --build <builddir> --target MY_LIB_UTILITY_TO_DO_SMTH
(或 make MY_LIB_UTILITY_TO_DO_SMTH
)。如果你想要构建单元测试,你会做cmake ... -D BUILD_TESTING=1
。
有些人将所有单元测试可执行文件添加为 EXCLUDE_FROM_ALL 并制作特殊 add_custom_target(build_tests) add_target_dependencies(build_tests MY_LIB_EXAMPLE1 etc. etc.)
并在测试前构建该自定义目标。