Shows a hello world example which first creates and links a static library. This is a simplified example showing the library and binary in the same folder. Typically these would be in sub-projects as described in section 02-sub-projects
The files in this tutorial are below:
$ tree
.
├── CMakeLists.txt
├── include
│ └── static
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
-
CMakeLists.txt - Contains the CMake commands you wish to run
-
include/static/Hello.h - The header file to include
-
src/Hello.cpp - A source file to compile
-
src/main.cpp - The source file with main
The add_library() function is used to create a library from some source files. This is called as follows:
add_library(hello_library STATIC
src/Hello.cpp
)
This will be used to create a static library with the name libhello_library.a with the sources in the add_library call.
Note
|
As mentioned in the previous example, we pass the source files directly to the add_library call, as recommended for modern CMake. |
In this example, we include directories in the library using the target_include_directories() function with the scope set to PUBLIC.
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
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 directories for any targets that link this library.
-
PUBLIC - As above, it is included in this library and also any targets that link this library.
Tip
|
For public headers it is often a good idea to have your include folder be "namespaced" with sub-directories. The directory passed to target_include_directories will be the root of your include directory tree and your C++ files should include the path from there to your header. For this example you can see that we do it as follows: #include "static/Hello.h" Using this method means that there is less chance of header filename clashes when you use multiple libraries in your project. |
When creating an executable that will use your library you must tell the compiler about the library. This can be done using the target_link_libraries() function.
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello_library
)
This tells CMake to link the hello_library against the hello_binary executable during link time. It will also propagate any include directories with PUBLIC or INTERFACE scope from the linked library target.
An example of this being called by the compiler is
/usr/bin/c++ CMakeFiles/hello_binary.dir/src/main.cpp.o -o hello_binary -rdynamic libhello_library.a
$ 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/01-basic/C-static-library/build
$ make
Scanning dependencies of target hello_library
[ 50%] Building CXX object CMakeFiles/hello_library.dir/src/Hello.cpp.o
Linking CXX static library libhello_library.a
[ 50%] Built target hello_library
Scanning dependencies of target hello_binary
[100%] Building CXX object CMakeFiles/hello_binary.dir/src/main.cpp.o
Linking CXX executable hello_binary
[100%] Built target hello_binary
$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake hello_binary libhello_library.a Makefile
$ ./hello_binary
Hello Static Library!