I am working on a simulation project: Taking an embedded C codebase from a target platform and trying to simulate it on a Host computer for debugging or single stepping into the code.
OS: Ubuntu Linux 14.04, IDE: CodeLite, Makefile Generator: Cmake. I am confused about how to write CMakeLists.txt for the project. Following is the structure of codebase (it's all written in C):
|ARQSim\
|-->ARQSim.h
|-->ARQSim.c
|-->BaseStationCode\
| |->downlink.c
| |->neoncopy.c
| |->armCore\
| | |->common\
| | | |->Bsconfig.h
| | | |->config.h
| | |->MacSource\
| | | |->lib\
| | | | |->arqCommon.h
| | | | |->OverTheAir.h
| | | |->source\
| | | | |->beacon.c
| | | | |->proxyDhcp.c
| | | | |->ARQ\
| | | | | |->arqCommon.c
| | | | | |->arqInterface.c
| | | | | |->fragmentation\
| | | | | | |->fragBookkeeping.c
| | | | | | |->fragProcessAck.c
| | | | | |->reassembly\
| | | | | | |->reasmBookkeeping.c
| | | | | | |->reasmProcessAck.c
I am totally new to Cmake. I have read up a lot of resources on CMake and threads here on StackOverflow. But I get confused every time. Few questions I have:
An example based on the structure of code mentioned above would be appreciated.
In Qt Creator, go to File → Open File or Project… and choose CMakeLists. txt from the source folder you want to build. Qt Creator will prompt you for the location of the binary folder, calling it the “build directory”. By default, it suggests a path adjacent to the source folder.
CMakeLists. txt is placed at the root of the source tree of any application, library it will work for. If there are multiple modules, and each module can be compiled and built separately, CMakeLists. txt can be inserted into the sub folder.
CMakeLists. txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both). When you create a new project, CLion generates CMakeLists. txt file automatically and places it in the project root directory.
Do I need only one
CMakeLists.txt
at root directory or every directory needs a differentCMakeLists.txt
file?
You would typically have one at each level of the tree where it makes sense
eg:
root/
+--- CMakeLists.txt // your root CMakeLists
+--- foo/
| +--- CMakeLists.txt // foo component's CMakeLists
| +--- foo.c
| +--- tests/
| +--- CMakeLists.txt // foo test's CMakeLists
| +--- foo_tests.c
+--- bar/
+--- CMakeLists.txt // bar component's CMakeLists
+--- bar.c
+--- bar_impl/ // no CMakeLists for this dir, it is part of bar
| +--- bar_impl.c
+--- tests/
+--- CMakeLists.txt // bar test's CMakeLists
+--- bar_tests.c
In your project root CMakeLists.txt
you specify minimum cmake requirement, the project name, and include the subdirectories which have your various components in them
root/CMakeLists.txt
:
cmake_minimum_required (VERSION 3.5)
project (my_project C)
add_subdirectory(foo)
add_subdirectory(bar)
Then in each component subdirectory, you have another CMakeLists.txt
file where you add libraries, executables etc
root/foo/CMakeLists.txt
:
add_library(foo foo.c)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(tests)
root/foo/tests/CMakeLists.txt
:
add_executable(foo_test foo_tests.c)
target_link_libraries(foo_test foo)
You follow this structure for bar etc...
root/bar/CMakeLists.txt
:
add_library(bar
bar.c
bar_impl/bar_impl.c)
target_include_directories(bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bar foo)
add_subdirectory(tests)
root/bar/tests/CMakeLists.txt
:
add_executable(bar_test bar_tests.c)
target_link_libraries(bar_test bar)
To bootstrap your build, you point cmake at your root/CMakeLists.txt
cd root
mkdir build
cd build
cmake ..
(or use your ide's build manager to generate its build configuration)
For details on the various functions I've used here, consult the documentation:
cmake_minimum_required
project
add_subdirectory
target_include_directories
target_link_libraries
Finally, to answer your second question:
How to add the source files recursively in CMakeLists.txt?
This is not recommended (see this discussion for further details).
It is better to explicitly list each file you want to include in your target.
Note that if you have source files in several separate directories, yet they all belong in the same logical target, then you don't need a CMakeLists.txt
file for each directory - just list the subdirectory in the filename
Example:
foo/
+--- foo.c
+--- bar.c
+--- baz/
+--- baz.c
+--- bang.c
If you want a single target foo
for all the above files, you would create it as follows:
add_library(foo
foo.c
bar.c
baz/baz.c
baz/bang.c)
Or if you really wanted to use a variable to store the list of SRCS
set(SRCS
foo.c
bar.c
baz/baz.c
baz/bang.c)
add_library(foo ${SRCS})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With