Add a basic sub-project example

This commit is contained in:
ttroy50
2015-11-23 23:15:31 +00:00
parent 43965819c4
commit 4eaf503ac7
12 changed files with 266 additions and 2 deletions

View File

@@ -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.

View File

@@ -0,0 +1,8 @@
cmake_minimum_required (VERSION 2.6)
project(subprojects)
# Add sub directories
add_subdirectory(sublibrary1)
add_subdirectory(sublibrary2)
add_subdirectory(subbinary)

View File

@@ -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
----

View File

@@ -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
)

View File

@@ -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;
}

View File

@@ -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})

View File

@@ -0,0 +1,10 @@
#ifndef __SUBLIB_1_H__
#define __SUBLIB_1_H__
class sublib1
{
public:
void print();
};
#endif

View File

@@ -0,0 +1,8 @@
#include <iostream>
#include "sublib1.h"
void sublib1::print()
{
std::cout << "Hello sub-library 1!" << std::endl;
}

View File

@@ -0,0 +1,6 @@
# Set the project name
project (sublibrary2)
include_directories(
${PROJECT_SOURCE_DIR}/inc
)

View File

@@ -0,0 +1,15 @@
#ifndef __SUBLIB_2_H__
#define __SUBLIB_2_H__
#include <iostream>
class sublib2
{
public:
void print()
{
std::cout << "Hello header only sub-library 2!" << std::endl;
}
};
#endif

View File

@@ -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

View File

@@ -1 +0,0 @@
Examples showing how to create sub-projects in different directories