I'm new to CMake so I apologize if my question turns out to be a noob one.
I'm trying to set up a project in C++ with a directory structure similar to what Maven would create if I was coding in Java (src directory and build directory):
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
I don't know how to properly set CMake so to recognize, compile and link all the files. In particular, I think I should use (a mix of) add_subdirectory()
, add_executable()
, link_directories()
, target_link_libraries()
, add_library()
and target_include_directories()
, but I'm not sure I got how.
I provide later my CMakeLists.txt
files, but when I configure and compile, I get:
/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
What do I do wrong? EDIT: turned out it was a very stupid mistake of mine, I forgot to add an implementation. However, some questions remain:
- Can you please tip me if this project/cmake structure is best practice or not?
- I dind't get the where i should use
link_directories()
andtarget_include_directories()
. - More in general, how can I keep my codebase tidy and compile my project? Thanks in advance
My commands are
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}
)