Skip to content

Instantly share code, notes, and snippets.

@vishvanathan-k
Last active February 28, 2022 19:28
Show Gist options
  • Save vishvanathan-k/98c233e3651be6697de64e104c0c138b to your computer and use it in GitHub Desktop.
Save vishvanathan-k/98c233e3651be6697de64e104c0c138b to your computer and use it in GitHub Desktop.
CMake file to build a Static C++ library with debug and release mode configuration

Guide

Project File Structure

SomeLibraryName/
|
|--- src/
|    |--- main.cpp
|    |--- main.hpp # add aditional files here
|--- include/
|    |--- SomeLibraryname.hpp #The main library file you will ship.
|--- CMakeLists.txt
|--- README.md #recommended, not mandatory

PLEASE refrain from declaring any logic in the include/SomeLibraryname.h , just declare method name, parameters, and return type.

Your logic for the methods declared in include/SomeLibraryname.h, should be in src/main.cpp , you can also use src/main.hpp to add logic

Building

mkdir build && cd build

After running the above command now, run

cmake ..

This will run CMake to build the debug version of library.

To package the library into library headers

cmake --build . --target install

You will get something like this

../install/
├── cmake
│   ├── SomeLibraryConfig-debug.cmake
│   ├── SomeLibraryConfig-release.cmake
│   └── SomeLibraryConfig.cmake
├── include
│   └── PhyC
│       └── PhyC.hpp
└── lib64
    └── libPhyC.a
4 directories, 6 files

The libPhyCd.a is static library file

Use cmake -DCMAKE_BUILD_TYPE={DEBUG or RELEASE} .. to change between release and debug mode

Packaging the Library

After the generating install folder, zip the folder and ship it.

cmake_minimum_required(VERSION 3.20)
project("{PROJECT NAME}" DESCRIPTION "{PROJECT DESCRIPTION}")
if (NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
message(STATUS "This project has a top-level one called [${CMAKE_PROJECT_NAME}]")
else()
message(STATUS "This project is a top-level one")
endif()
# here you can see how instead of writing "SomeLibrary"
# we can just use the PROJECT_NAME variable
add_library(${PROJECT_NAME} STATIC)
target_sources(${PROJECT_NAME}
PRIVATE
src/main.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE
# where the library itself will look for its internal headers
${CMAKE_CURRENT_SOURCE_DIR}/src
PUBLIC
# where top-level project will look for the library's public headers
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
# where external projects will look for the library's public headers
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# note that it is not CMAKE_INSTALL_PREFIX we are checking here
if(DEFINED CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
message(
STATUS
"CMAKE_INSTALL_PREFIX is not set\n"
"Default value: ${CMAKE_INSTALL_PREFIX}\n"
"Will set it to ${CMAKE_SOURCE_DIR}/install"
)
set(CMAKE_INSTALL_PREFIX
"${CMAKE_SOURCE_DIR}/install"
CACHE PATH "Where the library will be installed to" FORCE
)
else()
message(
STATUS
"CMAKE_INSTALL_PREFIX was already set\n"
"Current value: ${CMAKE_INSTALL_PREFIX}"
)
endif()
# without it public headers won't get installed
set(public_headers
include/PhyC.hpp
)
# note that ${public_headers} has to be in quotes
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${public_headers}")
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "d")
# definitions of CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_INCLUDEDIR and others
include(GNUInstallDirs)
# paths for binaries and headers
install(TARGETS ${PROJECT_NAME}
EXPORT "${PROJECT_NAME}Config"
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # lib
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # bin
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # include
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} # include/SomeLibrary
)
# CMake config name, namespace and path
install(
EXPORT "${PROJECT_NAME}Config"
FILE "${PROJECT_NAME}Config.cmake"
NAMESPACE some::
DESTINATION cmake
)
@vishvanathan-k
Copy link
Author

vishvanathan-k commented Jul 20, 2021

For more Configurations , Please Refer this blog

@lhksoft
Copy link

lhksoft commented Feb 28, 2022

Tx, I'm a beginner, but the real command at the commandline is :

for DEBUG

md build
cd build
cmake -DCMAKE_BUILD_TYPE=DEBUG ..
cmake --build . --config Debug --target install

for RELEASE

md build
cd build
cmake -DCMAKE_BUILD_TYPE=RELEASE ..
cmake --build . --config Release --target install

CMake always builds for Debug, for Release you need to explecitly give the proper parameters
But tx anyhow, your guide helped me a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment