How to use different include directories in different components (with help of @ruslo and @steveire):
In the main CMakeLists.txt add components in the right order:
add_subdirectory(Component1)
add_subdirectory(Component2)
In the Component1/CMakeLists.txt add a property to the generated library::
cmake_minimum_required(VERSION 2.8.11)
...
add_library(Component1 ${Component1_SOURCES})
target_include_directories(Component1 INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
... other required includes
)
In the Component2/CMakeLists.txt use target_include_directories
for the Component2:
cmake_minimum_required(VERSION 2.8.11)
...
add_executable(Component2 ${Component2_SOURCES})
target_link_libraries(Component2 Component1)
Regarding exact list of files to be compiled. Frankly speaking I don't see any problem in this area. Simply specify them explicitly in the add_executable
or add_library
directives:
add_binary(Component1Binary test1.c test2.c test5.c)
But I should mention that traditionally CMake uses slightly different layout for compiled artifacts. It places either compiled artifacts right within the source directory, or you may create a totally separated directory and it will put all compiled artifacts there, completely reproducing your project structure. Take a look:
MyProject/
CMakeLists.txt <- the top-level CMakeLists.txt. It may simply `add_subdirectory()`s (for each of its `Components`) and configure project-wide settings
Component1/
CMakeLists.txt <- this is intented to build artifact(s) for Component1
src1-1.c
src1-1.h
...
Component2/
CMakeLists.txt <- this is intented to build artifact(s) for Component2
src2-1.c
src2-1.h
...
now you may create an empty directory with an arbitrary name (say, build.release
) anywhere in your filesystem (usually somewhere within MyProject but not necessary), then cd
to that directory and call cmake like this:
cmake [cmake flags like -DCMAKE_BUILD_TYPE=Release and others] path/to/the/MyProject
CMake then creates all required Makefile-s and other build artifacts in this directory and you may call make
(or ninja
if you've chosen to use ninja
instead of make
) and all build artifacts would reside in that directory, reproducing the original structure of MyProject
:
build.release/
Component1/
src1-1.o
...
Component1.a
Component2/
src2-1.o
...
Component2Exe
etc
More on $<BUILD_INTERFACE:...>
stuff is in docs, How to set include_directories from a CMakeLists.txt file? etc. The feature is relatively new and I still not sure that I did everything absolutely correctly (the test example does compile though).