# CMakeList to compile and link an executable using Boost

I'm beginner with CMake and C++ compilation but it's seems that unlike Java I need to be very explicit with my CMakeList.txt in order to link src with correct header and libraries in my project.

Here is my CMakeList.txt

cmake_minimum_required(VERSION 3.4)
project(AwesomeScheduler)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY${CMAKE_BINARY_DIR}/../bin)

find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIRS}) set(SOCKET_SOUCE_FILES src/socket.cpp header/socket.h) set(DISPTACHER_SOURCE_FILES src/dispatcher.cpp header/dispatcher.h header/util.h) set(ENDUSER_SOURCE_FILES src/end-user.cpp header/end-user.h header/util.h) set(TASKPROPERTIES_SOURCE_FILES src/task_properties.cpp header/task_properties.h) add_executable(Dispatcher${SOCKET_SOUCE_FILES} ${DISPTACHER_SOURCE_FILES}) add_executable(EndUser${SOCKET_SOUCE_FILES} ${ENDUSER_SOURCE_FILES}${TASKPROPERTIES_SOURCE_FILES})
target_link_libraries(EndUser ${Boost_LIBRARIES})  The compilation works well and I get my two executables but I wonder if there is a way less verbose to get the same result? • I wonder if there is a way less verbose to get the same result? In my opinion not really. There is globbing which can save you from typing a few file names but I would not bother. When you get to larger projects (I have ones with 1000s of source files) you may use functions and macros in CMake however for a simple example like this it would not help. – drescherjm Apr 30 '16 at 21:21 • Thank you for your answer, I am now wondering why g ++ is not able to automatically link headers files that are specified in the "cpp" sources ? – melkir Apr 30 '16 at 22:20 • You do not need to specify the headers if you do not plan to use an IDE for your project. I primarily use Visual Studio for my projects and if I do not specify the headers they do not show up in the solution view (making it harder to navigate in the ide) however the code will build fine. – drescherjm Apr 30 '16 at 22:26 • honestly it's a pretty good looking, readable cmake file. – Nicolas Holthaus May 1 '16 at 0:20 • I agree. What you have is about right, not too simple, not too complex. – doug65536 May 5 '16 at 23:34 ## 1 Answer As commented by @drescherjm and @NicolasHolthaus your example code already looks pretty good. If you are getting less verbose, you will always loose some information. Minimal Version To demonstrate this, let's take a look at a minimal version of your code: cmake_minimum_required(VERSION 3.4) project(AwesomeScheduler) set(CMAKE_CXX_STANDARD 14) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")

find_package(Boost REQUIRED COMPONENTS system filesystem)



I have

• moved the source files into the add_executable() calls
• used the IMPORTED targets from Boost, which implicitly declares the header paths also
• done some cosmetic changes to the global settings
• used the more cross-platform CMAKE_CXX_STANDARD setting
• using .. from the binary dir looks odd, I assumed something relative to the source dir

Something in Between

Because grouping the source files and adding the header files has its advantages in respect of readability, maintainability and CMake's own abilities during build environment generation, here is what I would have done in the setup you have described here:

cmake_minimum_required(VERSION 3.4)
project(AwesomeScheduler)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin") find_package(Boost REQUIRED COMPONENTS system filesystem) set( SOCKET_SOUCE_FILES src/socket.cpp header/socket.h ) set( ENDUSER_SOURCE_FILES src/end-user.cpp header/end-user.h src/task_properties.cpp header/task_properties.h header/util.h ) set( DISPTACHER_SOURCE_FILES src/dispatcher.cpp header/dispatcher.h header/util.h ) add_library(Socket OBJECT${SOCKET_SOUCE_FILES})

add_executable(Dispatcher ${DISPTACHER_SOURCE_FILES}$<TARGET_OBJECTS:Socket>)

add_executable(EndUser ${ENDUSER_SOURCE_FILES}$<TARGET_OBJECTS:Socket>)


Now you have

• the possibility to
• the headers getting checked for availability and added to IDE projects during generation
• the grouping of Socket sources into a object library with e.g. it's own set of target properties to be modified
• no global include directory anymore, but target specific include directories

• on this small project with only one header folder it might be oversized, but if your code gets larger you should definitely think about the directory structure of your code
• So it could look something like

AwesomeScheduler/
CMakeLists.txt
Dispatcher/
CMakeLists.txt
src/
dispatcher.cpp
dispatcher.h
EndUser/
CMakeLists.txt
src/
end-user.cpp
end-user.h
lib/
Socket/
CMakeLists.txt
src/
socket.cpp
include/
socket.h
include/
util.h


References