Apart from the name of the project, the root CMakeLists.txt file is unchanged. Let us first look at the CMakeLists.txt file in the src subdirectory, where all the additional work actually happens. We will highlight the changes with respect to the file in the previous recipe:
- We declare our SHARED library target and its sources for the messaging library. Note that compile definitions and link libraries are unchanged:
add_library(message-shared SHARED "")
target_sources(message-shared
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/Message.cpp
)
target_compile_definitions(message-shared
PUBLIC
$<$<BOOL:${UUID_FOUND}>:HAVE_UUID>
)
target_link_libraries(message-shared
PUBLIC
$<$<BOOL:${UUID_FOUND}>:PkgConfig::UUID>
)
- We also set target properties. We have added the ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/messageExport.h header file in the list of public headers given as argument to the PUBLIC_HEADER target property. The CXX_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN properties will be discussed in the next section:
set_target_properties(message-shared
PROPERTIES
POSITION_INDEPENDENT_CODE 1
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN 1
SOVERSION ${PROJECT_VERSION_MAJOR}
OUTPUT_NAME "message"
DEBUG_POSTFIX "_d"
PUBLIC_HEADER "Message.hpp;${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/messageExport.h"
MACOSX_RPATH ON
)
- We include the standard CMake module GenerateExportHeader.cmake module and invoke the generate_export_header function. This will generate the messageExport.h header file in a subdirectory of the build directory. We will discuss this function and the generated header in more detail very soon:
include(GenerateExportHeader)
generate_export_header(message-shared
BASE_NAME "message"
EXPORT_MACRO_NAME "message_EXPORT"
EXPORT_FILE_NAME "${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/messageExport.h"
DEPRECATED_MACRO_NAME "message_DEPRECATED"
NO_EXPORT_MACRO_NAME "message_NO_EXPORT"
STATIC_DEFINE "message_STATIC_DEFINE"
NO_DEPRECATED_MACRO_NAME "message_NO_DEPRECATED"
DEFINE_NO_DEPRECATED
)
- The export header should be included whenever the visibility of symbols is to be changed from its default – hidden – value. We have done that in the Message.hpp header file, since we want to expose some symbols in our library. Now we list the ${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR} directory as a PUBLIC include directory of the message-shared target:
target_include_directories(message-shared
PUBLIC
${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}
)
Now we can turn our attention to the generation of the static library:
- We add a library target to generate the static library. The same sources as for the shared library will be compiled to get this target:
add_library(message-static STATIC "")
target_sources(message-static
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/Message.cpp
)
- We set compiler definitions, include directories, and link libraries, exactly as we did for the shared library target. Note, however, that we added the message_STATIC_DEFINE compile definition. This is to make sure that our symbols are properly exposed:
target_compile_definitions(message-static
PUBLIC
message_STATIC_DEFINE
$<$<BOOL:${UUID_FOUND}>:HAVE_UUID>
)
target_include_directories(message-static
PUBLIC
${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}
)
target_link_libraries(message-static
PUBLIC
$<$<BOOL:${UUID_FOUND}>:PkgConfig::UUID>
)
- We also set properties on the message-static target. These will be discussed in the next section:
set_target_properties(message-static
PROPERTIES
POSITION_INDEPENDENT_CODE 1
ARCHIVE_OUTPUT_NAME "message"
DEBUG_POSTFIX "_sd"
RELEASE_POSTFIX "_s"
PUBLIC_HEADER "Message.hpp;${CMAKE_BINARY_DIR}/${INSTALL_INCLUDEDIR}/messageExport.h"
)
- In addition to the hello-world_wDSO executable target, which links against the message-shared library target, we define another executable target, hello-world_wAR. This links against the static library:
add_executable(hello-world_wAR hello-world.cpp)
target_link_libraries(hello-world_wAR
PUBLIC
message-static
)
- The installation directives now list the additional message-static and hello-world_wAR targets, but are otherwise unchanged:
install(
TARGETS
message-shared
message-static
hello-world_wDSO
hello-world_wAR
ARCHIVE
DESTINATION ${INSTALL_LIBDIR}
COMPONENT lib
RUNTIME
DESTINATION ${INSTALL_BINDIR}
COMPONENT bin
LIBRARY
DESTINATION ${INSTALL_LIBDIR}
COMPONENT lib
PUBLIC_HEADER
DESTINATION ${INSTALL_INCLUDEDIR}/message
COMPONENT dev
)