Common files used by multiple targets

Hi, I’m trying to port a project from a custom build system that generate Makefile to CMake. I am a novice of CMake but I’m studying :stuck_out_tongue:

The project builds multiple executable and each executable is build from a set of *.cpp compiled with a common set of flags and definitions plus a specific set of *.cpp files compiled specifically for the executable. Right now the files compiled with the common set of flags are placed all in one place so that when all executables are built they will find object files already compiled by the previous executable (if they have files in common) but all the executable can be built individually if needed. I’m not sure how much compile time is saved with this but I wanted to try and keep it.

Right now I was thinking of something like:

Given the following structure:

β”œβ”€β”€ bar_main.cpp
β”œβ”€β”€ foo_main.cpp
β”œβ”€β”€ x
β”‚   β”œβ”€β”€ file_x_1.cpp
β”‚   β”œβ”€β”€ file_x_1.h
β”‚   β”œβ”€β”€ file_x_2.cpp
β”‚   β”œβ”€β”€ file_x_2.h
β”‚   β”œβ”€β”€ file_x_3.cpp
β”‚   └── file_x_3.h
β”œβ”€β”€ y
β”‚   β”œβ”€β”€ file_y_1.cpp
β”‚   β”œβ”€β”€ file_y_1.h
β”‚   β”œβ”€β”€ file_y_2.cpp
β”‚   β”œβ”€β”€ file_y_2.h
β”‚   β”œβ”€β”€ file_bar_1.cpp
β”‚   └── file_bar_1.h
└── z
    β”œβ”€β”€ file_foo_1.cpp
    └── file_foo_1.h

I had something like the following CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

# definition of target foo
add_library(foo_common OBJECT x/file_x_1.cpp x/file_x_3.cpp y/file_y_1.cpp y/file_y_2.cpp)
target_compile_definitions(foo_common ...)

add_library(sfoo STATIC z/file_foo_1.cpp)
target_compile_definitions(sfoo ...)
target_link_libraries(sfoo PUBLIC foo_common)

add_executable(foo foo_main.cpp)
target_link_libraries(foo sfoo)

# definition of target bar
add_library(bar_common OBJECT a/file_x_1.cpp a/file_x_2.cpp y/file_y_1.cpp)
target_compile_definitions(bar_common ...)

add_library(sbar STATIC y/file_bar_1.cpp)
target_compile_definitions(sbar ...)
target_link_libraries(sbar PUBLIC bar_common)

add_executable(bar bar_main.cpp)
target_link_libraries(barr sbar)

So the question in the end are two:

  • Is this the correct way to build targets where a set of files are compiled with a set of compile flags while other files are built with another set of flags? Or am I using the tool in a way that was not though for it?
  • Can the β€œcommon” files be compiled and reused by other targets? So in this example if I build the executable foo first then when I compile bar it will find the files x/file_x_1 and y/file_y_1.cpp already built and re-use them; I heard of tools like ccache which should do exactly that but at the moment the project should build also with MSVC and I think ccache doesn’t work with it :confused:

Sorry for the long post :stuck_out_tongue:

What you have looks sufficient to me. I’d use OBJECT files for internal organization and STATIC for organization which others might care about (such as reuse and linking).