mirror of
https://github.com/ttroy50/cmake-examples.git
synced 2025-12-18 20:24:35 +03:00
2
.gitignore
vendored
2
.gitignore
vendored
@@ -59,3 +59,5 @@ install_manifest.txt
|
||||
|
||||
/**/build
|
||||
/**/build.*
|
||||
|
||||
.tags
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
language: cpp
|
||||
services:
|
||||
- docker
|
||||
sudo: required
|
||||
compiler:
|
||||
- gcc
|
||||
before_install:
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get update && sudo apt-get install -y cmake libboost-all-dev libprotobuf-dev protobuf-compiler cppcheck ninja-build clang; fi
|
||||
- docker pull matrim/cmake-examples:3.4.3
|
||||
script:
|
||||
- ./test.sh
|
||||
- docker run --rm -v $PWD:/data/code -it matrim/cmake-examples:3.4.3 /data/code/test.sh
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Set the minimum version of CMake that can be used
|
||||
# To find the cmake version run
|
||||
# $ cmake --version
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (hello_cmake)
|
||||
|
||||
@@ -35,7 +35,7 @@ of CMake that is supported.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
----
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
# Set the minimum version of CMake that can be used
|
||||
# To find the cmake version run
|
||||
# $ cmake --version
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (hello_headers)
|
||||
|
||||
# Set the direcoties that should be included in the build command
|
||||
# when running g++ these will be included as -I/directory/path/
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
# Create a sources variable with a link to all cpp files to compile
|
||||
set(SOURCES
|
||||
src/Hello.cpp
|
||||
@@ -20,4 +14,10 @@ set(SOURCES
|
||||
|
||||
|
||||
# Add an executable with the above sources
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
add_executable(hello_headers ${SOURCES})
|
||||
|
||||
# Set the direcoties that should be included in the build command for this target
|
||||
# when running g++ these will be included as -I/directory/path/
|
||||
target_include_directories(hello_headers
|
||||
PRIVATE ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
@@ -55,19 +55,6 @@ directory where you ran the cmake command.
|
||||
|PROJECT_BINARY_DIR |The build directory for the current project.
|
||||
|=======================================================================
|
||||
|
||||
## Including Directories
|
||||
|
||||
When you have different include folders, you can make your compiler aware of them using the
|
||||
+include_directories()+ function. This will add these directories to the
|
||||
compiler with the -I flag e.g. `-I/directory/path`
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
----
|
||||
|
||||
## Source Files Variable
|
||||
|
||||
Creating a variable which includes the source files allows you to be
|
||||
@@ -96,6 +83,20 @@ file(GLOB SOURCES "src/*.cpp")
|
||||
----
|
||||
====
|
||||
|
||||
## Including Directories
|
||||
|
||||
When you have different include folders, you can make your compiler aware of them using the
|
||||
+target_include_directories()+ link:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html[function]. When compiling this target this will add these directories to the compiler with the -I flag e.g. `-I/directory/path`
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
target_include_directories(target
|
||||
PRIVATE ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
----
|
||||
|
||||
The +PRIVATE+ identifier specifies the scope of the include. This is important for libraries and is exlpained in the next example. More details on the function is available link:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html[here]
|
||||
|
||||
# Building the Example
|
||||
|
||||
## Standard Output
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(hello_library)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
############################################################
|
||||
# Create a library
|
||||
############################################################
|
||||
@@ -18,6 +14,11 @@ set(library_SOURCES
|
||||
#Generate the static library from the library sources
|
||||
add_library(hello_library STATIC ${library_SOURCES})
|
||||
|
||||
target_include_directories(hello_library
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
|
||||
############################################################
|
||||
# Create an executable
|
||||
############################################################
|
||||
@@ -32,5 +33,5 @@ add_executable(hello_binary ${binary_SOURCES})
|
||||
|
||||
# link the new hello_library target with the hello_binary target
|
||||
target_link_libraries( hello_binary
|
||||
hello_library
|
||||
PRIVATE hello_library
|
||||
)
|
||||
|
||||
@@ -46,6 +46,29 @@ add_library(hello_library STATIC ${library_SOURCES})
|
||||
This will be used to create a static library with the name libhello_library.a with
|
||||
the sources from the +library_SOURCES+ variable.
|
||||
|
||||
## Populating Including Directories
|
||||
|
||||
In this example, we include directories in the library using the +target_include_directories()+ function with the scope set to +PUBLIC+.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
target_include_directories(hello_library
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
----
|
||||
|
||||
This will cause the included directory used in the following places:
|
||||
|
||||
* When compiling the library
|
||||
* When compiling any additional target that links the library.
|
||||
|
||||
The meaning of scopes are:
|
||||
|
||||
* +PRIVATE_ - the directory is added to this target's include directories
|
||||
* +INTERFACE+ - the directory is added to the include directores for any targets that link this library.
|
||||
* +PUBLIC+ - As above, it is included int his library and also any targets that link this library.
|
||||
|
||||
|
||||
## Linking a Library
|
||||
|
||||
When creating an executable that will use your library you must tell the compiler
|
||||
@@ -56,12 +79,13 @@ about the library. This can be done using the +target_link_library()+ function.
|
||||
add_executable(hello_binary ${binary_SOURCES})
|
||||
|
||||
target_link_libraries( hello_binary
|
||||
hello_library
|
||||
PRIVATE hello_library
|
||||
)
|
||||
----
|
||||
|
||||
This tells CMake to link the hello_library against the hello_binary executable
|
||||
during link time.
|
||||
during link time. It will also propogate any include directries with +PUBLIC+ or +INTERFACE+ scope
|
||||
from the linked library target.
|
||||
|
||||
An example of this being called by the compiler is
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(hello_library)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
############################################################
|
||||
# Create a library
|
||||
############################################################
|
||||
@@ -17,6 +13,11 @@ set(library_SOURCES
|
||||
|
||||
#Generate the shared library from the library sources
|
||||
add_library(hello_library SHARED ${library_SOURCES})
|
||||
add_library(hello::library ALIAS hello_library)
|
||||
|
||||
target_include_directories(hello_library
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
############################################################
|
||||
# Create an executable
|
||||
@@ -32,5 +33,5 @@ add_executable(hello_binary ${binary_SOURCES})
|
||||
|
||||
# link the new hello_library target with the hello_binary target
|
||||
target_link_libraries( hello_binary
|
||||
hello_library
|
||||
PRIVATE hello::library
|
||||
)
|
||||
@@ -6,7 +6,9 @@ toc::[]
|
||||
|
||||
# Introduction
|
||||
|
||||
Shows a hello world example which first creates and links a shared library
|
||||
Shows a hello world example which first creates and links a shared library.
|
||||
|
||||
This also shows how to create an link:https://cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#alias-targets[alias target]
|
||||
|
||||
The files in this tutorial are below:
|
||||
|
||||
@@ -31,7 +33,6 @@ $ tree
|
||||
|
||||
## Adding a Shared Library
|
||||
|
||||
|
||||
As with the previous example on static libraries, the +add_library()+ function
|
||||
is also used to create a shared library from some source files.
|
||||
This is called as follows:
|
||||
@@ -48,6 +49,17 @@ add_library(hello_library SHARED ${library_SOURCES})
|
||||
This will be used to create a shared library with the name libhello_library.so with
|
||||
the sources from the +library_SOURCES+ variable.
|
||||
|
||||
## Alias Target
|
||||
|
||||
As the name suggests an link:https://cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#alias-targets[alias target] is an alternative name for a target that can be used instead of the real target name in read-only contexts.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_library(hello::library ALIAS hello_library)
|
||||
----
|
||||
|
||||
As shown below, this allows you to reference the target using the alias name when linking it against other targets.
|
||||
|
||||
## Linking a Shared Library
|
||||
|
||||
Linking a shared library is the same as linking a static library. When creating your
|
||||
@@ -58,12 +70,11 @@ executable use the the +target_link_library()+ function to point to your library
|
||||
add_executable(hello_binary ${binary_SOURCES})
|
||||
|
||||
target_link_libraries( hello_binary
|
||||
hello_library
|
||||
hello::library
|
||||
)
|
||||
----
|
||||
|
||||
This tells CMake to link the hello_library against the hello_binary executable
|
||||
during link time.
|
||||
This tells CMake to link the hello_library against the hello_binary executable using the alias target name.
|
||||
|
||||
An example of this being called by the linker is
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(cmake_examples_install)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
############################################################
|
||||
# Create a library
|
||||
############################################################
|
||||
@@ -18,6 +14,11 @@ set(library_SOURCES
|
||||
#Generate the shared library from the library sources
|
||||
add_library(cmake_examples_inst SHARED ${library_SOURCES})
|
||||
|
||||
|
||||
target_include_directories(cmake_examples_inst
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
############################################################
|
||||
# Create an executable
|
||||
############################################################
|
||||
@@ -32,7 +33,7 @@ add_executable(cmake_examples_inst_bin ${binary_SOURCES})
|
||||
|
||||
# link the new hello_library target with the hello_binary target
|
||||
target_link_libraries( cmake_examples_inst_bin
|
||||
cmake_examples_inst
|
||||
PRIVATE cmake_examples_inst
|
||||
)
|
||||
|
||||
############################################################
|
||||
|
||||
@@ -80,7 +80,7 @@ install (FILES cmake-examples.conf
|
||||
|
||||
Install a configuration file to the destination +${CMAKE_INSTALL_PREFIX}/etc+
|
||||
|
||||
After `make install` has been run, CMake generated an install_manifest.txt file
|
||||
After `make install` has been run, CMake generates an install_manifest.txt file
|
||||
which includes details on all installed files.
|
||||
|
||||
[NOTE]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Set the minimum version of CMake that can be used
|
||||
# To find the cmake version run
|
||||
# $ cmake --version
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set a default build type if none was specified
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set a default C++ compile flag
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
|
||||
@@ -8,3 +8,7 @@ project (compile_flags)
|
||||
|
||||
# Add an executable
|
||||
add_executable(cmake_examples_compile_flags main.cpp)
|
||||
|
||||
target_compile_definitions(cmake_examples_compile_flags
|
||||
PRIVATE EX3
|
||||
)
|
||||
|
||||
@@ -6,8 +6,10 @@ toc::[]
|
||||
|
||||
# Introduction
|
||||
|
||||
CMake supports setting compile flags using the +CMAKE_C_FLAGS+ and +CMAKE_CXX_FLAGS+
|
||||
variables. Similarly linker flags can be set using the +CMAKE_LINKER_FLAGS+.
|
||||
CMake supports setting compile flags in a number of different ways:
|
||||
|
||||
* using +target_compile_definitions()+ function
|
||||
* using the +CMAKE_C_FLAGS+ and +CMAKE_CXX_FLAGS+ variables.
|
||||
|
||||
The files in this tutorial are below:
|
||||
|
||||
@@ -23,22 +25,24 @@ $ tree
|
||||
|
||||
# Concepts
|
||||
|
||||
# Set Per-Target C++ Flags
|
||||
|
||||
## Set C++ Flag
|
||||
|
||||
Similar to the build type a C++ compiler flag can be set using the following methods.
|
||||
|
||||
- Using a gui tool such as ccmake / cmake-gui
|
||||
|
||||
image::cmake-gui-set-cxx-flag.png[cmake-gui set cxx flag]
|
||||
|
||||
- Passing into cmake
|
||||
The recommended way to set C++ flags in modern CMake is to use per-target flags which can be populated to other targets
|
||||
through the +target_compile_definitions()+ link:https://cmake.org/cmake/help/v3.0/command/target_compile_definitions.html?highlight=target_compile_definitions[function]. This will populate the link:https://cmake.org/cmake/help/v3.0/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.html#prop_tgt:INTERFACE_COMPILE_DEFINITIONS[INTERFACE_COMPILE_DEFINITIONS] for the library and push the definition to the linked target depending on the scope.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
|
||||
target_compile_definitions(cmake_examples_compile_flags
|
||||
PRIVATE EX3
|
||||
)
|
||||
----
|
||||
|
||||
This will cause the compiler to add the definition +-DEX3+ when compiling the target.
|
||||
|
||||
In the target was a library, and the scope +PUBLIC+ or +INTERFACE+ has been choosen the definition would also be included in any executables that link this target.
|
||||
|
||||
For compiler options you can also use the +target_compile_options()+ link:https://cmake.org/cmake/help/v3.0/command/target_compile_options.html[function].
|
||||
|
||||
## Set Default C++ Flags
|
||||
|
||||
The default `CMAKE_CXX_FLAGS` is either empty or contains the appropriate flags
|
||||
@@ -52,6 +56,11 @@ top level CMakeLists.txt
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
|
||||
----
|
||||
|
||||
Similarly to +CMAKE_CXX_FLAGS+ other options include:
|
||||
|
||||
* Setting C compiler flags using +CMAKE_C_FLAGS+
|
||||
* Setting linker flags using +CMAKE_LINKER_FLAGS+.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The values `CACHE STRING "Set C++ Compiler Flags" FORCE` from the above command
|
||||
@@ -60,6 +69,24 @@ are used to force this variable to be set in the CMakeCache.txt file.
|
||||
For more details, see https://cmake.org/cmake/help/v3.0/command/set.html[here]
|
||||
====
|
||||
|
||||
|
||||
Once set the +CMAKE_C_FLAGS+ and +CMAKE_CXX_FLAGS+ will set a compler flag / definiton globally for all targets in this directory or any included sub-directories. This method is not recommended for general usage now and the +target_compile_definitions+ function is preferred.
|
||||
|
||||
### Set CMake Flags
|
||||
|
||||
Similar to the build type a global C++ compiler flag can be set using the following methods.
|
||||
|
||||
- Using a gui tool such as ccmake / cmake-gui
|
||||
|
||||
image::cmake-gui-set-cxx-flag.png[cmake-gui set cxx flag]
|
||||
|
||||
- Passing into cmake
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
|
||||
----
|
||||
|
||||
# Building the Example
|
||||
|
||||
[source,bash]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (third_party_include)
|
||||
@@ -10,9 +10,6 @@ find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
|
||||
# check if boost was found
|
||||
if(Boost_FOUND)
|
||||
message ("boost found")
|
||||
|
||||
# Include the boost headers
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
else()
|
||||
message (FATAL_ERROR "Cannot find Boost")
|
||||
endif()
|
||||
@@ -20,8 +17,14 @@ endif()
|
||||
# Add an executable
|
||||
add_executable(third_party_include main.cpp)
|
||||
|
||||
# Include the boost headers
|
||||
target_include_directories( third_party_include
|
||||
PRIVATE ${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# link against the boost libraries
|
||||
target_link_libraries( third_party_include
|
||||
PRIVATE
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ A basic example of finding boost is below:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
find_package(Boost 1.54.0 REQUIRED COMPONENTS filesystem system)
|
||||
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
|
||||
----
|
||||
|
||||
The arguments are:
|
||||
@@ -91,6 +91,27 @@ The variables exported in this example include:
|
||||
In some cases you can also check these variables by examining the cache using
|
||||
ccmake or cmake-gui.
|
||||
|
||||
## Alias variables
|
||||
|
||||
Some modern CMake libraries export +ALIAS+ targets in their module files. For example, starting from v3.5+ of CMake, the
|
||||
Boost module supports this. Similar to using your own ALIAS target for libraires, an +ALIAS+ in a module can make referencing found targets eaiser.
|
||||
|
||||
In the case of Boost, you could replace the following from this example:
|
||||
|
||||
* `Boost_INCLUDE_DIRS` with `Boost::boost` for header only libraries
|
||||
* `Boost_FILESYSTEM_LIBRARY` with `Boost::filesystem`
|
||||
* `Boost_SYSTEM_LIBRARY` with `Boost::system`. If you include `Boost::filesystem` it automatically includes `Boost::system`
|
||||
|
||||
Using the new alias sytem, to replicate this example you only have to link the following:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
target_link_libraries( third_party_include
|
||||
PRIVATE
|
||||
Boost::filesystem
|
||||
)
|
||||
----
|
||||
|
||||
# Building the Example
|
||||
|
||||
[source,bash]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Set the minimum version of CMake that can be used
|
||||
# To find the cmake version run
|
||||
# $ cmake --version
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (hello_cmake)
|
||||
|
||||
# Add an executable
|
||||
add_executable(hello_cmake main.cpp)
|
||||
add_executable(hello_cmake main.cpp)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Set the minimum version of CMake that can be used
|
||||
# To find the cmake version run
|
||||
# $ cmake --version
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (hello_cmake)
|
||||
|
||||
# Add an executable
|
||||
add_executable(hello_cmake main.cpp)
|
||||
add_executable(hello_cmake main.cpp)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
|
||||
project(subprojects)
|
||||
|
||||
|
||||
@@ -63,14 +63,12 @@ add_subdirectory(subbinary)
|
||||
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.
|
||||
to reference the source directory for a different project you can use.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
include_directories(
|
||||
${sublibrary1_SOURCE_DIR}/inc
|
||||
${sublibrary2_SOURCE_DIR}/inc
|
||||
)
|
||||
${sublibrary1_SOURCE_DIR}
|
||||
${sublibrary2_SOURCE_DIR}
|
||||
----
|
||||
|
||||
The variables created by CMake include:
|
||||
@@ -97,6 +95,28 @@ In this example the binary directories created would be `sublibrary1_BINARY_DIR`
|
||||
|
||||
|=======================================================================
|
||||
|
||||
## Header only Libraries
|
||||
|
||||
If you have a library that is created as a header only library, cmake supports the +INTERFACE+
|
||||
target to allow creating a target without any build output. More details can be found from
|
||||
link:https://cmake.org/cmake/help/v3.4/command/add_library.html#interface-libraries[here]
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
----
|
||||
|
||||
When creating the target you can also include directories for that target using
|
||||
the +INTERFACE+ scope. The +INTERFACE+ scope is use to make target requirements that are used in any Libraries
|
||||
that link this target but not in the complation of the target itself.
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
INTERFACE
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
----
|
||||
|
||||
## Referencing Libraries from Sub-Projects
|
||||
|
||||
@@ -108,10 +128,42 @@ is added as a dependency.
|
||||
[source,cmake]
|
||||
----
|
||||
target_link_libraries(subbinary
|
||||
PUBLIC
|
||||
sublibrary1
|
||||
)
|
||||
----
|
||||
|
||||
Alternatively, you can create an alias target which allows you to reference the
|
||||
target in read only contexts.
|
||||
|
||||
To create an alias target run:
|
||||
|
||||
[source,cmake]
|
||||
----
|
||||
add_library(sublibrary2)
|
||||
add_library(sub::lib2 ALIAS sublibrary2)
|
||||
----
|
||||
|
||||
To reference the alias, just it as follows:
|
||||
[source,cmake]
|
||||
----
|
||||
target_link_libraries(subbinary
|
||||
sublibrary1
|
||||
)
|
||||
----
|
||||
|
||||
## Include directories from sub-projects
|
||||
|
||||
When adding the libraries from the sub-projects, starting from cmake v3, there is
|
||||
no need to add the projects include directores in the include directories of the
|
||||
binary using them.
|
||||
|
||||
This is controlled by the scope in the `target_include_directories()` command when creating
|
||||
the libraries. In this example because the subbinary executable links the sublibrary1
|
||||
and sublibrary2 libraries it will automatically include the `${sublibrary1_SOURCE_DIR}/inc`
|
||||
and `${sublibrary2_SOURCE_DIR}/inc` folders as they are exported with the
|
||||
+PUBLIC+ and +INTERFACE+ scopes of the libraries.
|
||||
|
||||
# Building the example
|
||||
|
||||
[source,bash]
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
project(subbinary)
|
||||
|
||||
# Include the inc directories from the sub projects
|
||||
include_directories(
|
||||
${sublibrary1_SOURCE_DIR}/inc
|
||||
${sublibrary2_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
)
|
||||
@@ -13,8 +7,16 @@ set(SOURCES
|
||||
# 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
|
||||
# Link the static library from subproject1 using it's alias sub::lib1
|
||||
# Link the header only library from subproject2 using it's alias sub::lib2
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
sublibrary1
|
||||
sub::lib1
|
||||
sub::lib2
|
||||
)
|
||||
|
||||
# Include the inc directories from the sub projects
|
||||
include_directories( ${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${sublibrary1_SOURCE_DIR}/inc
|
||||
${sublibrary2_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# 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
|
||||
@@ -12,3 +8,8 @@ set(SOURCES
|
||||
|
||||
# Add a library with the above sources
|
||||
add_library(${PROJECT_NAME} ${SOURCES})
|
||||
add_library(sub::lib1 ALIAS ${PROJECT_NAME})
|
||||
|
||||
include_directories( ${PROJECT_NAME}
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Set the project name
|
||||
project (sublibrary2)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
add_library(sub::lib2 ALIAS ${PROJECT_NAME})
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
INTERFACE
|
||||
${PROJECT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (cf_example)
|
||||
@@ -17,10 +17,13 @@ configure_file(ver.h.in ${PROJECT_BINARY_DIR}/ver.h)
|
||||
# This file can only use the @VARIABLE@ syntax in the file
|
||||
configure_file(path.h.in ${PROJECT_BINARY_DIR}/path.h @ONLY)
|
||||
|
||||
# include the directory with the new files
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
|
||||
# Add an executable
|
||||
add_executable(cf_example
|
||||
main.cpp
|
||||
)
|
||||
|
||||
# include the directory with the new files
|
||||
target_include_directories( cf_example
|
||||
PUBLIC
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (protobuf_example)
|
||||
@@ -9,8 +9,6 @@ find_package(Protobuf REQUIRED)
|
||||
# check if protobuf was found
|
||||
if(PROTOBUF_FOUND)
|
||||
message ("protobuf found")
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
else()
|
||||
message (FATAL_ERROR "Cannot find Protobuf")
|
||||
endif()
|
||||
@@ -28,6 +26,14 @@ add_executable(protobuf_example
|
||||
${PROTO_SRCS}
|
||||
${PROTO_HDRS})
|
||||
|
||||
target_include_directories(protobuf_example
|
||||
PUBLIC
|
||||
${PROTOBUF_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
# link the exe against the libraries
|
||||
target_link_libraries(protobuf_example
|
||||
${PROTOBUF_LIBRARIES})
|
||||
PUBLIC
|
||||
${PROTOBUF_LIBRARIES}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
|
||||
project(cppcheck_analysis)
|
||||
|
||||
@@ -23,4 +23,4 @@ if( CPPCHECK_FOUND )
|
||||
ADD_DEPENDENCIES(analysis ${ALL_ANALYSIS_TARGETS})
|
||||
set_target_properties(analysis PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
message("analysis analysis targets are ${ALL_ANALYSIS_TARGETS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# Set the project name
|
||||
project (boost_unit_test)
|
||||
@@ -35,6 +35,9 @@ target_link_libraries(unit_tests
|
||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
)
|
||||
|
||||
add_definitions (-DBOOST_TEST_DYN_LINK)
|
||||
target_compile_definitions(unit_tests
|
||||
PRIVATE
|
||||
BOOST_TEST_DYN_LINK
|
||||
)
|
||||
|
||||
add_test(test_all unit_tests)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(cmake_examples_deb)
|
||||
|
||||
@@ -39,6 +39,7 @@ add_executable(cmake_examples_deb_bin ${binary_SOURCES})
|
||||
|
||||
# link the new hello_library target with the hello_binary target
|
||||
target_link_libraries( cmake_examples_deb_bin
|
||||
PUBLIC
|
||||
cmake_examples_deb
|
||||
)
|
||||
|
||||
|
||||
24
README.adoc
24
README.adoc
@@ -18,16 +18,20 @@ more complex use cases.
|
||||
|
||||
These examples have been tested on Ubuntu 14.04 but should work under any Linux system that supports CMake.
|
||||
|
||||
This branch works with the CMake version 3.x onwards. For examples that use CMake version 2.x see the branch link:https://github.com/ttroy50/cmake-examples/tree/v2-style-includes[v2-style-includes].
|
||||
|
||||
image:https://travis-ci.org/ttroy50/cmake-examples.svg?branch=master["Build Status", link="https://travis-ci.org/ttroy50/cmake-examples"]
|
||||
|
||||
# Requirements
|
||||
|
||||
The basic requirements for most examples are:
|
||||
|
||||
* CMake
|
||||
* CMake v3.x
|
||||
* A c++ compiler (defaults to gcc)
|
||||
* make
|
||||
|
||||
## Installation on Ubuntu
|
||||
|
||||
The easiest way to install the above on Ubuntu is as follows
|
||||
|
||||
[source,bash]
|
||||
@@ -59,11 +63,29 @@ Some specific examples may require other tools including:
|
||||
|
||||
$ sudo apt-get install ninja-build
|
||||
|
||||
## Docker
|
||||
|
||||
Docker containers with all requirements and various versions of CMake are generated to help make testing the examples easier. These are available from the docker hub repository link:https://hub.docker.com/r/matrim/cmake-examples/[matrim/cmake-examples].
|
||||
|
||||
To build the full set of cmake-examples test cases you can run:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
docker run -it matrim/cmake-examples:3.4.3
|
||||
git clone https://github.com/ttroy50/cmake-examples.git
|
||||
cd cmake-examples
|
||||
./test.sh
|
||||
----
|
||||
|
||||
For more details on build and running the docker containers link:here[dockerfiles].
|
||||
|
||||
# Other Links
|
||||
|
||||
There are many CMake tutorials and examples online. The list below includes links
|
||||
to some of these which I have found helpful in my CMake journey.
|
||||
|
||||
* http://www.kdab.com/~stephen/moderncmake.pdf[Modern CMake Slides]
|
||||
* https://rix0r.nl/blog/2015/08/13/cmake-guide/[rix0r Modern CMake Blog]
|
||||
* https://cmake.org/cmake-tutorial/[Official CMake Tutorial]
|
||||
* https://cmake.org/Wiki/Main_Page[Official CMake Wiki]
|
||||
* https://cmake.org/Wiki/CMake_Useful_Variables[CMake Useful Variables]
|
||||
|
||||
Reference in New Issue
Block a user