= Basic Sub-Project :toc: :toc-placement!: toc::[] # Introduction This example shows how to setup a CMake project that includes sub-projects. The top level CMakeLists.txt calls the CMakeLists.txt in the sub directories to create the following: * sublibrary1 - A static library * sublibrary2 - A header only library * subbinary - An executable The files included in this example are: ``` . ├── CMakeLists.txt ├── subbinary │   ├── CMakeLists.txt │   └── main.cpp ├── sublibrary1 │   ├── CMakeLists.txt │   ├── inc │   │   └── sublib1.h │   └── src │   └── sublib1.cpp └── sublibrary2 ├── CMakeLists.txt └── inc └── sublib2.h ``` * CMakeLists.txt - Top level CMakeLists.txt * subbinary/CMakeLists.txt - to make the executable * subbinary/main.cpp - source for the executable * sublibrary1/CMakeLists.txt - to make a static library * sublibrary1/inc/sublib1.h * sublibrary1/src/sublib2.cpp * sublibrary2/CMakeLists.txt - to setup header only library * sublibrary2/inc/sublib2.h # Concepts ## Adding a Sub-Directory A CMakeLists.txt file can include and call sub-directories which include a CMakeLists.txt files. [source,cmake] ---- add_subdirectory(sublibrary1) add_subdirectory(sublibrary2) add_subdirectory(subbinary) ---- ## Referencing Sub-Project Directories When a project is created using the `project()` command, CMake will automatically create a number of variables which can be used to reference details about the project. These variables can then be used by other sub-projects or the main project. For exampe, to include header files between projects. [source,cmake] ---- include_directories( ${sublibrary1_SOURCE_DIR}/inc ${sublibrary2_SOURCE_DIR}/inc ) ---- The variables created by CMake include: [cols=",",options="header",] |======================================================================= |Variable |Info |PROJECT_NAME | The name of the project set by the current `project()`. |CMAKE_PROJECT_NAME |the name of the first project set by the `project()` command, i.e. the top level project. |PROJECT_SOURCE_DIR |The source director of the current project. |PROJECT_BINARY_DIR |The build directory for the current project. |name_SOURCE_DIR | The source directory of the project called "name". In this example the source directories created would be `sublibrary1_SOURCE_DIR`, `sublibrary2_SOURCE_DIR`, and `subbinary_SOURCE_DIR` |name_BINARY_DIR | The binary directory of the project called "name". In this example the binary directories created would be `sublibrary1_BINARY_DIR`, `sublibrary2_BINARY_DIR`, and `subbinary_BINARY_DIR` |======================================================================= ## Referencing Libraries from Sub-Projects If a sub-project creates a library, it can be referenced by other projects by calling the name of the project in the `target_link_libraries()` command. This means that you don't have to reference the full path of the new library and it is added as a dependency. [source,cmake] ---- target_link_libraries(subbinary sublibrary1 ) ---- # Building the example [source,bash] ---- $ mkdir build $ cd build/ $ cmake .. -- The C compiler identification is GNU 4.8.4 -- The CXX compiler identification is GNU 4.8.4 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/matrim/workspace/cmake-examples/02-sub-projects/A-basic/build $ make Scanning dependencies of target sublibrary1 [ 50%] Building CXX object sublibrary1/CMakeFiles/sublibrary1.dir/src/sublib1.cpp.o Linking CXX static library libsublibrary1.a [ 50%] Built target sublibrary1 Scanning dependencies of target subbinary [100%] Building CXX object subbinary/CMakeFiles/subbinary.dir/main.cpp.o Linking CXX executable subbinary [100%] Built target subbinary ----