Below is a step‐by‐step explanation of this CMakeLists.txt file. It builds a shared library named swmm-output
that exposes functions (like reading/writing SWMM’s binary output data), handles error management, and sets up an export header for cross‐platform symbol exporting. It also installs headers and library artifacts in a structured way and copies the built library for local testing when BUILD_TESTS is enabled.
1. Overall Purpose
# CMakeLists.txt - CMake configuration file for swmm/outfile
#
# Created: July 11, 2019
#
# Author: Michael E. Tryby
# US EPA ORD/CESER
- This file configures how the swmm-output library (in
swmm/outfile
) is built, installed, and exported. - The library will be named
swmm-output
in the final build artifacts.
2. Configure File Groups
set(SWMM_OUT_PUBLIC_HEADERS
include/swmm_output.h
include/swmm_output_enums.h
include/swmm_output_export.h
)
SWMM_OUT_PUBLIC_HEADERS
: a list of public header files that will be installed and included by other projects linking to swmm-output.- These typically define the library’s external API (like
swmm_output.h
).
3. Define the Library Target
add_library(swmm-output
SHARED
swmm_output.c
errormanager.c
)
- Creates a shared library target named
swmm-output
from sourcesswmm_output.c
anderrormanager.c
. - This library is intended to be dynamically linked, so it’s
SHARED
.
3.1 Include Directories
target_include_directories(swmm-output
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${INCLUDE_DIST}>
)
- Tells CMake to add the
include/
folder during the build (so the library can find its own headers) and to use${INCLUDE_DIST}
as the install-time include path. BUILD_INTERFACE
means the include path is used while building this library;INSTALL_INTERFACE
is used after installation, so dependent projects can also find the library’s headers.
4. Generate Export Header
include(GenerateExportHeader)
generate_export_header(swmm-output
BASE_NAME swmm_output
EXPORT_MACRO_NAME EXPORT_OUT_API
EXPORT_FILE_NAME swmm_output_export.h
STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC
)
GenerateExportHeader
is a CMake module that automatically generates a header defining export macros (likeEXPORT_OUT_API
) for different platforms (Windows, Linux, etc.).- This solves the typical problem of specifying
__declspec(dllexport)
vs.__declspec(dllimport)
on Windows or empty macros on Linux.
- This solves the typical problem of specifying
BASE_NAME swmm_output
=> the base name for macros in the generated file.EXPORT_MACRO_NAME EXPORT_OUT_API
=> the macro used in the code (e.g.,EXPORT_OUT_API void somefunction();
).- The file
swmm_output_export.h
is generated in the current binary directory.
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/swmm_output_export.h
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include
)
- Copies that generated file into the
include/
directory so it becomes part of the codebase (and is presumably versioned or installed).
5. Installation Rules
5.1 Install the Library
install(TARGETS swmm-output
EXPORT
swmm-outputTargets
RUNTIME
DESTINATION "${TOOL_DIST}"
LIBRARY
DESTINATION "${TOOL_DIST}"
ARCHIVE
DESTINATION "${LIBRARY_DIST}"
FRAMEWORK
DESTINATION "${TOOL_DIST}"
)
- Installs the swmm-output library to different destinations depending on the build artifact type:
RUNTIME
(i.e. the.dll
on Windows) goes to$TOOL_DIST
,LIBRARY
(i.e. shared objects on Linux or.dylib
on macOS) also goes to$TOOL_DIST
,ARCHIVE
(the.lib
static library import library on Windows or.a
on Linux) to$LIBRARY_DIST
,FRAMEWORK
also to$TOOL_DIST
(applies to macOS frameworks).
EXPORT swmm-outputTargets
: means a usage file will be created that tracks how to link to swmm-output. This is used in the next step.
5.2 Export the Library’s Targets
install(
EXPORT
swmm-outputTargets
DESTINATION
"${CONFIG_DIST}"
FILE
swmm-output-config.cmake
)
- This writes out a file named
swmm-output-config.cmake
with the target export data (like library path, include dirs, etc.) to${CONFIG_DIST}
. - Another CMake project can do
find_package(swmm-output CONFIG)
to import swmm-output library references.
5.3 Install the Public Headers
install(
FILES
${SWMM_OUT_PUBLIC_HEADERS}
DESTINATION
"${INCLUDE_DIST}"
)
- Copies the public headers we defined earlier (
swmm_output.h
,swmm_output_enums.h
,swmm_output_export.h
) into${INCLUDE_DIST}
.
6. Additional Commands
6.1 Copying the Library for Testing
if(BUILD_TESTS)
add_custom_command(TARGET swmm-output POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:swmm-output>
${CMAKE_BINARY_DIR}/bin/$<CONFIGURATION>/$<TARGET_FILE_NAME:swmm-output>
)
endif()
- If
BUILD_TESTS
is set, after building swmm-output, it runs a POST_BUILD command to copy the built library into **${CMAKE_BINARY_DIR}/bin/<CONFIG>/**
. - This might be for local test executables that expect the DLL or
.so
in a known folder.
7. Putting It All Together
In summary, this CMakeLists.txt
file:
- Creates a library named
swmm-output
fromswmm_output.c
anderrormanager.c
. - Uses CMake’s
GenerateExportHeader
to manage export macros for cross-platform shared library builds. - Installs:
- The library (
DLL/.so/.dylib
) to$TOOL_DIST
, - The library’s import/export config to
$CONFIG_DIST
, - The library’s public headers to
$INCLUDE_DIST
.
- The library (
- If building tests, it copies the resulting library into a local bin directory to be used by test executables.
Hence, developers and end-users can link to swmm-output
by finding its installed config (swmm-output-config.cmake
) and including the installed headers.