diff --git a/01-basic/README.adoc b/01-basic/README.adoc index 8c36bb5..9f8751e 100644 --- a/01-basic/README.adoc +++ b/01-basic/README.adoc @@ -3,7 +3,7 @@ The basic examples in this directory show how the setup a CMake project, set compile flags, create executables and libraries, and install them. -create an executable. The examples included are +The examples included are - hello-cmake. A hello world example. - hello-headers. A slighly more complicated hello world example, with using Hello class and seperate source and include folders. diff --git a/02-sub-projects/A-basic/CMakeLists.txt b/02-sub-projects/A-basic/CMakeLists.txt new file mode 100644 index 0000000..8314800 --- /dev/null +++ b/02-sub-projects/A-basic/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required (VERSION 2.6) + +project(subprojects) + +# Add sub directories +add_subdirectory(sublibrary1) +add_subdirectory(sublibrary2) +add_subdirectory(subbinary) diff --git a/02-sub-projects/A-basic/README.adoc b/02-sub-projects/A-basic/README.adoc new file mode 100644 index 0000000..7c3b396 --- /dev/null +++ b/02-sub-projects/A-basic/README.adoc @@ -0,0 +1,162 @@ += Basic Sub-Project + +:toc: +:toc-placement!: + +toc::[] + +[[intro]] +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]] +Concepts +~~~~~~~~ + +[[add-sub-dir]] +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]] +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]] +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]] +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 + +---- diff --git a/02-sub-projects/A-basic/subbinary/CMakeLists.txt b/02-sub-projects/A-basic/subbinary/CMakeLists.txt new file mode 100644 index 0000000..620a204 --- /dev/null +++ b/02-sub-projects/A-basic/subbinary/CMakeLists.txt @@ -0,0 +1,20 @@ +project(subbinary) + +# Include the inc directories from the sub projects +include_directories( + ${sublibrary1_SOURCE_DIR}/inc + ${sublibrary2_SOURCE_DIR}/inc + ) + +set(SOURCES + main.cpp +) + +# Create the executable +add_executable(${PROJECT_NAME} ${SOURCES}) + +# Link the static library from subproject1 +# This uses the project name to find out the library info +target_link_libraries(${PROJECT_NAME} + sublibrary1 +) diff --git a/02-sub-projects/A-basic/subbinary/main.cpp b/02-sub-projects/A-basic/subbinary/main.cpp new file mode 100644 index 0000000..64d660c --- /dev/null +++ b/02-sub-projects/A-basic/subbinary/main.cpp @@ -0,0 +1,13 @@ +#include "sublib1.h" +#include "sublib2.h" + +int main(int argc, char *argv[]) +{ + sublib1 hi; + hi.print(); + + sublib2 howdy; + howdy.print(); + + return 0; +} diff --git a/02-sub-projects/A-basic/sublibrary1/CMakeLists.txt b/02-sub-projects/A-basic/sublibrary1/CMakeLists.txt new file mode 100644 index 0000000..cd26f8e --- /dev/null +++ b/02-sub-projects/A-basic/sublibrary1/CMakeLists.txt @@ -0,0 +1,14 @@ +# Set the project name +project (sublibrary1) + +include_directories( + ${PROJECT_SOURCE_DIR}/inc + ) + +# Create a sources variable with a link to all cpp files to compile +set(SOURCES + src/sublib1.cpp +) + +# Add a library with the above sources +add_library(${PROJECT_NAME} ${SOURCES}) diff --git a/02-sub-projects/A-basic/sublibrary1/inc/sublib1.h b/02-sub-projects/A-basic/sublibrary1/inc/sublib1.h new file mode 100644 index 0000000..599d2d7 --- /dev/null +++ b/02-sub-projects/A-basic/sublibrary1/inc/sublib1.h @@ -0,0 +1,10 @@ +#ifndef __SUBLIB_1_H__ +#define __SUBLIB_1_H__ + +class sublib1 +{ +public: + void print(); +}; + +#endif diff --git a/02-sub-projects/A-basic/sublibrary1/src/sublib1.cpp b/02-sub-projects/A-basic/sublibrary1/src/sublib1.cpp new file mode 100644 index 0000000..2edf0c1 --- /dev/null +++ b/02-sub-projects/A-basic/sublibrary1/src/sublib1.cpp @@ -0,0 +1,8 @@ +#include + +#include "sublib1.h" + +void sublib1::print() +{ + std::cout << "Hello sub-library 1!" << std::endl; +} diff --git a/02-sub-projects/A-basic/sublibrary2/CMakeLists.txt b/02-sub-projects/A-basic/sublibrary2/CMakeLists.txt new file mode 100644 index 0000000..76325a2 --- /dev/null +++ b/02-sub-projects/A-basic/sublibrary2/CMakeLists.txt @@ -0,0 +1,6 @@ +# Set the project name +project (sublibrary2) + +include_directories( + ${PROJECT_SOURCE_DIR}/inc + ) diff --git a/02-sub-projects/A-basic/sublibrary2/inc/sublib2.h b/02-sub-projects/A-basic/sublibrary2/inc/sublib2.h new file mode 100644 index 0000000..2df61ac --- /dev/null +++ b/02-sub-projects/A-basic/sublibrary2/inc/sublib2.h @@ -0,0 +1,15 @@ +#ifndef __SUBLIB_2_H__ +#define __SUBLIB_2_H__ + +#include + +class sublib2 +{ +public: + void print() + { + std::cout << "Hello header only sub-library 2!" << std::endl; + } +}; + +#endif diff --git a/02-sub-projects/README.adoc b/02-sub-projects/README.adoc new file mode 100644 index 0000000..00b5c99 --- /dev/null +++ b/02-sub-projects/README.adoc @@ -0,0 +1,9 @@ += Sub-Project Examples + +Many large projects are made up of different libraries and binaries. These +can be organised into multiple folders and sub-projects to ease development. + +The examples included are + + - basic - This basic example includes a static library, a header only library + and an executable diff --git a/02-sub-projects/README.md b/02-sub-projects/README.md deleted file mode 100644 index 6b7868c..0000000 --- a/02-sub-projects/README.md +++ /dev/null @@ -1 +0,0 @@ -Examples showing how to create sub-projects in different directories \ No newline at end of file