I have the following project structure.
project
-> build
-> sdk
-> calculator
-> include
-> calculator.h
-> calculator_p.h
-> src
-> calculator.cpp
-> calculator_p.cpp
-> interfaces
-> icalculator.h
-> client
-> main.cpp
I want to create a library from sdk and use it in client, so client can see icalculator.h and calculator.h, but not calculator_p.h.
Official cmake documentation has very poor examples, unfortunelly. I digged through a lot of examples and I have to say that I'm even more lost than in the beggining.
Should I create only one CMakeLists.txt in sdk directory or another one in each calculator and interfaces?
EDIT:
This is what I came up with so far.
project/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(test_project)
set(CMAKE_CXX_STANDARD 17)
add_subdirectory(sdk)
add_subdirectory(client)
project/sdk/CMakeLists.txt
add_library(sdk_library SHARED
calculator/src/calculator.cpp
calculator/src/calculator_p.cpp)
target_include_directories(sdk_library PUBLIC interfaces/include)
target_include_directories(sdk_library PUBLIC calculator/include)
project/client/CMakeLists.txt
add_executable(client main.cpp)
target_link_libraries(client sdk_library)
I build and run from the build directory.
cmake ..
make client
./client/client
Related
I currently have a problem with my CMake configuration for a small project I am working on. I wanted to reconfigure the project and move all header files into their own path. When trying to link the header file to the library I cannot include the file in my .cpp in any way (client_session or client_session_handler)
This is my project setup
Headers
- client
- client_session_handler.h
- client_session.h
src
- client
- client_session_handler.cpp
- client_session.cpp
- CMakeLists.txt
main.cpp
- CMakeLists.txt
CMakeLists.txt
This is my client library setup
add_library (
client OBJECT
client_session.cpp
client_session_handler.cpp )
target_include_directories( client PUBLIC ${CMAKE_SOURCE_DIR}/headers)
This is my src cmake (There is other code but they haven't got any relevant .h files yet)
add_executable(rchat main.cpp)
add_subdirectory(client)
add_subdirectory(server)
add_subdirectory(helpers)
target_link_libraries(rchat
PUBLIC
client
server
helpers
wsock32
ws2_32
)
And finally my root CMakeLists
cmake_minimum_required(VERSION 3.5)
project(rchat LANGUAGES CXX)
add_subdirectory(src)
Overall I can't seem to include the client headers at all in my code, so any help would be appreciated.
For includes I've tried "client/client_session.h" "client_session.h" & <client/client_session.h>
Cheers.
You only link your library but never add the library's header to your executable target. Next to your target_link_libraries you may want to add headers to use in your "client" code, like this:
target_link_libraries(rchat ..libraries go here..)
target_include_directories(rchat PRIVATE "${PROJECT_SOURCE_DIR}/Headers/client")
I'm working on a CMake project with multiple subdirectories and I can't get it to work. My working directory is the following:
├───main.cpp
├───CMakeLists.txt
├───build
├───States
└───CMakeLists.txt
└───Elevator
├───CMakeLists.txt
Once I build the project, I get Elevator/Elevator.h: No such file or directory as an error. The way my project is set up, Elevator is included in States and apparently CMake isn't linking them properly.
My root CMakeLists.txt:
cmake_minimum_required(VERSION 3.21.4)
project(Test)
set(CMAKE_CPP_STANDARD 11)
set(CMAKE_CPP_STANDARD_REQUIRED True)
add_subdirectory(Elevator)
add_subdirectory(States)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC Elevator States)
The one in Elevator:
set(elevator_source_files
Elevator.cpp
Elevator.h
Set.cpp
Set.h
)
add_library(Elevator ${elevator_source_files})
The CMakeLists.txt in States:
set(state_source_files
State.h
State.cpp
InitialState.h
InitialState.cpp
EmergencyState.cpp
EmergencyState.h
IdleState.h
IdleState.cpp
MaintenanceState.h
MaintenanceState.cpp
MovingState.h
MovingState.cpp
AllStates.h
FSM.h
FSM.cpp
)
add_library(States ${state_source_files})
target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..)
target_link_libraries(States PUBLIC Elevator)
I'm still a novice so any help would be appreciated! It's worth noting that States.h includes Elevator with #include "Elevator/Elevator.h"
UPDATE: The project now builds and runs. I updated the CMake files in the description.
For #include "Elevator/Elevator.h" to work in the States library you need to include the folder containing the Elevator folder.
One way to fix this is to change
target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR})
to
target_include_directories(States PUBLIC ${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/..)
to have CMake add the State folder and its parent to the include directories.
I am following the basic tutorial by CMake https://cmake.org/cmake/help/v3.21/guide/tutorial/A%20Basic%20Starting%20Point.html
However, I want to run extra steps: moving the source codes files, output build and external lib into sub folders as below:
root/CMakeLists.txt
root/source/ => main.cpp and other cpp files
root/source/include/ => include header files
root/library => include library files for future use. In addition, I want to include some linux library such as pthread as well.
root/build/ => include output built binary
My CMakeList.txt so far:
cmake_minimum_required (VERSION 3.10)
project (Car VERSION 1.0)
#set build options or set C++ standard
set(CMAKE_CXX_STANDARD 11)
#set project binary folder:
SET(PROJECT_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build/)
#set project source folder:
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/source/include/
)
#add executable target name (if project is built as executable)
add_executable(${PROJECT_NAME} main.cxx modelX.cxx upgrade.cxx usage.cxx)
#configure header files to pass the version number to the source code (must add target_include_directories to the end of CMakeLists.txt)
configure_file(car.h modelX.h upgrade.h Usage.h)
#set target build
target_include_directories(Car Public "${PROJECT_BINARY_DIR}")
Thank you !
p.s: I found similar questions here: Add Source in a subdirectory to a cmake project.
However, I still can't make use of both suggested answers and the one below it yet.
I am trying to create a cmake project which has the following directory structure:
root_folder
lib
common_library_for_all_submodules
submodule_1
src
main.cpp
tests
main_test.cpp
submodule_2
src
main.cpp
tests
main_test.cpp
Being new to C++ and also to CMake I have the following confusions and would be really glad if someone can guide me in the right direction here.
Coming from a Java world I know that this is possible to create in a maven project using the modules tag in pom.xml. Is there an equivalent to this in CMake? If yes what to do we call it and can someone give me an example?
I want to then import this project into CLion and when I run the root project, all the submodules should be compiled and relevant tests be run.
Note: submodule_1 and submodule_2 are not using each other's code. They are entirely independent. But they will need to share some common libraries from the root_folder/lib
Thanks a lot in advance
You can use several CMakeLists.txt files, use add_subdirectory statement. To declare library (which will be used in another subproject) use add_library. To declare app - add_executable. To link library to app - target_link_libraries(app1 PRIVATE utils common). This is short and very common description-example. There are more options and parameters.
I'm attaching examples here:
CMakeLists.txt
project(Example)
add_subdirectory(3rd-party)
add_subdirectory(apps)
add_subdirectory(libs)
libs/CMakeLists.txt
add_subdirectory(common)
add_subdirectory(utils)
libs/utils/CMakeLists.txt
FILE(GLOB SOURCES *.cpp *.h)
add_library(utils STATIC ${SOURCES})
target_include_directories(utils PUBLIC .)
apps/CMakeLists.txt
add_subdirectory(app1)
add_subdirectory(app2)
apps/app1/CMakeLists.txt
FILE(GLOB_RECURSE SOURCES src/*.cpp src/*.h)
add_executable(app1 ${SOURCES})
target_link_libraries(app1 PRIVATE utils common)
In this example libraries utils and common are independent and could be built without each other and without apps
Suppose you want to do some unit testing on classes in an executable but you don't want to refactor them out into a lib where you can add the lib using target_link_libraries( target library ) in cmake.
How do you give the test class access to the other classes?
1) Build test project with the source files from the other project?
another thing
include_directories(${otherExeProjectDir})
set( SOURCE_FILES
main.cpp
tests.h
tests.cpp
${otherExeProjectDir}/otherclass1.h
${otherExeProjectDir}/otherclass2.h
)
2) Link test project with obj files from the other project?
some sort of add_library( otherclass.obj ) craziness?
3)
If your main executable source locations are simple or flat, then something like this could work:
cmake_minimum_required(VERSION 3.9)
project(tests)
# Get main executable source location properties
get_target_property(exe_sources exe SOURCES)
get_target_property(exe_source_dir exe SOURCE_DIR)
# Remove main entry point file
list(REMOVE_ITEM exe_sources main.cpp)
# Add test sources
add_executable(test1 test1.cpp)
# Add exe sources to test (assumes sources are relative paths)
foreach(src IN LISTS exe_sources)
target_sources(test1 PRIVATE "${exe_source_dir}/${src}")
endforeach()
# Add exe include directories to test
target_include_directories(test1 PRIVATE
${exe_source_dir}
$<TARGET_PROPERTY:exe,INCLUDE_DIRECTORIES>)
Otherwise the general solution is, unfortunately, to rely on some external information, e.g. top level source file locations or adding your own source properties to the main executable target.