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, The basic examples in this directory show how the setup a CMake project,
set compile flags, create executables and libraries, and install them. 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-cmake. A hello world example.
- hello-headers. A slighly more complicated hello world example, with using Hello class and seperate source and include folders. - 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