如何设置带有子文件夹的 CMake 项目?
How do I set up a CMake project with subfolders?
我是 CMake 的新手,所以如果我的问题是菜鸟问题,我深表歉意。
我正在尝试用 C++ 建立一个项目,其目录结构类似于我在 Java(src 目录和构建目录)中编码时 Maven 将创建的目录结构:
root
├── build (where to build)
├── CMakeLists.txt (main one)
├── compile_commands.json -> ./build/compile_commands.json
├── doc
├── Doxyfile
└── src
├── CMakeLists.txt
├── common
│ └── Terminal.hpp
├── fsa
│ ├── CMakeLists.txt
│ ├── Machine.cpp
│ ├── Machine.hpp
│ └── MachineState.hpp
└── main.cpp
我不知道如何正确设置 CMake 以便识别、编译和 link 所有文件。特别是,我认为我应该使用(混合)add_subdirectory()
、add_executable()
、link_directories()
、target_link_libraries()
、add_library()
和 target_include_directories()
,但是我不确定我是怎么做到的。
我稍后提供我的 CMakeLists.txt
文件,但是当我配置和编译时,我得到:
/usr/bin/ld: fsa/libfsalib.a(Machine.cpp.o): in function `Machine::addState(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, bool)':
Machine.cpp:(.text+0xd1): undefined reference to `MachineState::MachineState(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/elr1.dir/build.make:98: src/elr1] Error 1
make[1]: *** [CMakeFiles/Makefile2:115: src/CMakeFiles/elr1.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
我做错了什么?
编辑: 原来这是我的一个非常愚蠢的错误,我忘了添加一个实现。但是,仍然存在一些问题:
- 如果这个 project/cmake 结构是最佳实践,你能告诉我吗?
- 我不知道应该在哪里使用
link_directories()
和 target_include_directories()
。
- 更一般地说,我怎样才能保持我的代码库整洁并编译我的项目?
提前致谢
我的命令是
to configure: "cmake -S /path_to_root_project -B /path_to_root_project/build -D CMAKE_EXPORT_COMPILE_COMMANDS=ON"
to compile: "cmake --build /path_to_root_project/build"
root_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
# set the project name
project(elr1 VERSION 0.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(src)
root_project/src/CMakeLists.txt:
add_subdirectory(fsa)
# add the executable
add_executable(elr1 main.cpp)
link_directories(fsa)
target_link_libraries(elr1 #target in which link
fsalib #library name
)
root_project/src/fsa/CMakeLists.txt:
add_library(fsalib #name
Machine.cpp #files
MachineState.hpp
)
target_include_directories(fsalib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
Can you please tip me if this project/cmake structure is best practice or not?
有 none 或无穷无尽的最佳实践,并且每天都有人发明新的最佳实践。特别是关于如何构建与 CMake 无关的项目。以您想要的方式构建它,然后您判断是最好的。你的结构看起来完全没问题。
看看无尽的google结果。 What's a good directory structure for larger C++ projects using Makefile? and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1204r0.html 项目。
至于CMake你可以看看终极版https://github.com/friendlyanon/cmake-init , https://github.com/cmake-lint/cmake-lint , https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1.
where i should use link_directories() and target_include_directories().
通常你应该更喜欢 target
东西,即 target_link_directories
而不是非目标。
使用 target_include_directories
将路径添加到 #include <thishere>
搜索路径。
使用target_link_directories
添加一个库路径到搜索路径target_link_libraries(... this_library_here)
。通常你想使用 add_library(... IMPORTED)
,然后 find_library
,而不是 target_link_directories
。参见 man ld
。
在您的项目中,没有外部共享 .so
也没有静态 .a
库。我认为根本没有理由使用 link_directories
。
how can I keep my codebase tidy and compile my project?
好吧,你可以努力工作并经常清理你的项目。记住定期锻炼、睡眠和健康饮食。
而不是set(CMAKE_CXX_STANDARD 11)
更喜欢target_set_properties(. .. CXX_STANDARD 11)
.
我是 CMake 的新手,所以如果我的问题是菜鸟问题,我深表歉意。
我正在尝试用 C++ 建立一个项目,其目录结构类似于我在 Java(src 目录和构建目录)中编码时 Maven 将创建的目录结构:
root
├── build (where to build)
├── CMakeLists.txt (main one)
├── compile_commands.json -> ./build/compile_commands.json
├── doc
├── Doxyfile
└── src
├── CMakeLists.txt
├── common
│ └── Terminal.hpp
├── fsa
│ ├── CMakeLists.txt
│ ├── Machine.cpp
│ ├── Machine.hpp
│ └── MachineState.hpp
└── main.cpp
我不知道如何正确设置 CMake 以便识别、编译和 link 所有文件。特别是,我认为我应该使用(混合)add_subdirectory()
、add_executable()
、link_directories()
、target_link_libraries()
、add_library()
和 target_include_directories()
,但是我不确定我是怎么做到的。
我稍后提供我的 CMakeLists.txt
文件,但是当我配置和编译时,我得到:
/usr/bin/ld: fsa/libfsalib.a(Machine.cpp.o): in function `Machine::addState(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, bool)':
Machine.cpp:(.text+0xd1): undefined reference to `MachineState::MachineState(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/elr1.dir/build.make:98: src/elr1] Error 1
make[1]: *** [CMakeFiles/Makefile2:115: src/CMakeFiles/elr1.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
我做错了什么? 编辑: 原来这是我的一个非常愚蠢的错误,我忘了添加一个实现。但是,仍然存在一些问题:
- 如果这个 project/cmake 结构是最佳实践,你能告诉我吗?
- 我不知道应该在哪里使用
link_directories()
和target_include_directories()
。 - 更一般地说,我怎样才能保持我的代码库整洁并编译我的项目? 提前致谢
我的命令是
to configure: "cmake -S /path_to_root_project -B /path_to_root_project/build -D CMAKE_EXPORT_COMPILE_COMMANDS=ON"
to compile: "cmake --build /path_to_root_project/build"
root_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
# set the project name
project(elr1 VERSION 0.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(src)
root_project/src/CMakeLists.txt:
add_subdirectory(fsa)
# add the executable
add_executable(elr1 main.cpp)
link_directories(fsa)
target_link_libraries(elr1 #target in which link
fsalib #library name
)
root_project/src/fsa/CMakeLists.txt:
add_library(fsalib #name
Machine.cpp #files
MachineState.hpp
)
target_include_directories(fsalib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
Can you please tip me if this project/cmake structure is best practice or not?
有 none 或无穷无尽的最佳实践,并且每天都有人发明新的最佳实践。特别是关于如何构建与 CMake 无关的项目。以您想要的方式构建它,然后您判断是最好的。你的结构看起来完全没问题。
看看无尽的google结果。 What's a good directory structure for larger C++ projects using Makefile? and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1204r0.html 项目。
至于CMake你可以看看终极版https://github.com/friendlyanon/cmake-init , https://github.com/cmake-lint/cmake-lint , https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1.
where i should use link_directories() and target_include_directories().
通常你应该更喜欢 target
东西,即 target_link_directories
而不是非目标。
使用 target_include_directories
将路径添加到 #include <thishere>
搜索路径。
使用target_link_directories
添加一个库路径到搜索路径target_link_libraries(... this_library_here)
。通常你想使用 add_library(... IMPORTED)
,然后 find_library
,而不是 target_link_directories
。参见 man ld
。
在您的项目中,没有外部共享 .so
也没有静态 .a
库。我认为根本没有理由使用 link_directories
。
how can I keep my codebase tidy and compile my project?
好吧,你可以努力工作并经常清理你的项目。记住定期锻炼、睡眠和健康饮食。
而不是set(CMAKE_CXX_STANDARD 11)
更喜欢target_set_properties(. .. CXX_STANDARD 11)
.