Always specify the minimum required version of cmake
cmake_minimum_required(VERSION 3.9)
You must declare a project. cmake says it's mandatory, and it will define the convenient variables PROJECT_NAME , PROJECT_VERSION and PROJECT_DESCRIPTION (this last variable requires cmake 3.9):
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
Announce a new library target. Please avoid using file(GLOB...) . This feature does not provide mastery during the compilation process. If you are lazy, copy and paste the output of ls -1 sources/*.cpp :
add_library(mylib SHARED sources/animation.cpp sources/buffers.cpp [...] )
Set the VERSION property (optional, but this is good practice):
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
You can also set SOVERSION to the primary VERSION number. So libmylib.so.1 will be symbolic libmylib.so.1.0.0 on libmylib.so.1.0.0 .
set_target_properties(mylib PROPERTIES SOVERSION 1)
Declare the public API of your library. This API will be installed for the third-party application. It is recommended that you isolate it in the project tree (for example, put it in the include/ directory). Please note that private headers should not be set, and I highly recommend placing them along with the source files.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
If you work with subdirectories, it is not very convenient to include a relative path, for example "../include/mylib.h" . So, pass the top directory to the included directories:
target_include_directories(mylib PRIVATE .)
or
target_include_directories(mylib PRIVATE include) target_include_directories(mylib PRIVATE src)
Create an installation rule for your library. I suggest using the CMAKE_INSTALL_*DIR variables defined in GNUInstallDirs :
include(GNUInstallDirs)
And declare the files to install:
install(TARGETS mylib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
You can also export the pkg-config file. These files allow a third-party application to easily import your library:
Create a template file named mylib.pc.in (see mylib.pc.in pc (5) for more information):
prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: @PROJECT_NAME@ Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Requires: Libs: -L${libdir} -lmylib Cflags: -I${includedir}
In your CMakeLists.txt add a rule for the @ macros extension ( @ONLY ask cmake not to expand the variables of the form ${VAR} ):
configure_file(mylib.pc.in mylib.pc @ONLY)
Finally, install the generated file:
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
You can also use the CMake EXPORT function . However, this function is only compatible with cmake and it is difficult for me to use it.
Finally, the whole CMakeLists.txt should look like this:
cmake_minimum_required(VERSION 3.9) project(mylib VERSION 1.0.1 DESCRIPTION "mylib description") include(GNUInstallDirs) add_library(mylib SHARED src/mylib.c) set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 1 PUBLIC_HEADER api/mylib.h) configure_file(mylib.pc.in mylib.pc @ONLY) target_include_directories(mylib PRIVATE .) install(TARGETS mylib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)