Skip to content

Commit f555ee1

Browse files
committed
docs: mrdocs build generates headers at configure time
1 parent ad1e7ba commit f555ee1

File tree

7 files changed

+186
-2977
lines changed

7 files changed

+186
-2977
lines changed

CMakeLists.txt

Lines changed: 147 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
# Project settings
1515
#
1616
#-------------------------------------------------
17-
1817
cmake_minimum_required(VERSION 3.13)
1918
project(
2019
MrDocs
@@ -52,32 +51,166 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
5251
set(MRDOCS_CLANG ON)
5352
endif()
5453

54+
#-------------------------------------------------
55+
#
56+
# Generate project headers
57+
#
58+
#-------------------------------------------------
59+
# Create include/mrdocs/Version.hpp from Version.hpp.in
60+
if (MRDOCS_REQUIRE_GIT)
61+
find_package(Git REQUIRED)
62+
else()
63+
find_package(Git QUIET)
64+
endif()
65+
set(PROJECT_VERSION_BUILD "")
66+
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}") # default: plain semver
67+
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND GIT_FOUND)
68+
# Get full SHA
69+
execute_process(
70+
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
71+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
72+
OUTPUT_VARIABLE GIT_SHA_FULL
73+
OUTPUT_STRIP_TRAILING_WHITESPACE
74+
RESULT_VARIABLE GIT_SHA_FULL_RV
75+
ERROR_QUIET
76+
)
77+
if (NOT GIT_SHA_FULL_RV EQUAL 0)
78+
message(FATAL_ERROR "Git was found but could not extract commit SHA")
79+
endif()
80+
set(PROJECT_VERSION_BUILD "${GIT_SHA_FULL}")
81+
string(SUBSTRING "${GIT_SHA_FULL}" 0 12 GIT_SHA_SHORT)
82+
83+
# Are we exactly at a tag?
84+
execute_process(
85+
COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match HEAD
86+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
87+
OUTPUT_VARIABLE GIT_EXACT_TAG
88+
OUTPUT_STRIP_TRAILING_WHITESPACE
89+
RESULT_VARIABLE GIT_EXACT_TAG_RV
90+
ERROR_QUIET
91+
)
92+
if (GIT_EXACT_TAG_RV EQUAL 0)
93+
# On a tag: canonical release
94+
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}")
95+
else()
96+
# Dirty working tree? (0 = clean, 1 = dirty)
97+
execute_process(
98+
COMMAND ${GIT_EXECUTABLE} diff --quiet --ignore-submodules
99+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
100+
RESULT_VARIABLE GIT_DIRTY_RV
101+
ERROR_QUIET
102+
)
103+
set(_dirty_suffix "")
104+
if (GIT_DIRTY_RV EQUAL 1)
105+
set(_dirty_suffix ".modified")
106+
endif()
107+
set(PROJECT_VERSION_WITH_BUILD
108+
"${PROJECT_VERSION}+${GIT_SHA_SHORT}${_dirty_suffix}")
109+
endif()
110+
else()
111+
if (MRDOCS_REQUIRE_GIT)
112+
message(FATAL_ERROR "Git is required to extract the version build")
113+
endif()
114+
set(PROJECT_VERSION_BUILD "")
115+
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}")
116+
endif()
117+
configure_file(
118+
${CMAKE_CURRENT_SOURCE_DIR}/include/mrdocs/Version.hpp.in
119+
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/Version.hpp
120+
@ONLY
121+
)
122+
123+
# Create include/mrdocs/PublicSettings.hpp and related files from JSON config files
124+
find_program(PYTHON_EXECUTABLE python3 python)
125+
if (NOT PYTHON_EXECUTABLE)
126+
message(FATAL_ERROR "Python is needed to configure mrdocs")
127+
endif()
128+
set(CONFIG_GEN_WORKING_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
129+
set(CONFIG_GEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
130+
set(CONFIG_GEN_CONFIG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/src/lib/ConfigOptions.json")
131+
set(CONFIG_GEN_SCRIPT_INFO "${CMAKE_CURRENT_SOURCE_DIR}/util/generate-config-info.py")
132+
set(CONFIG_GEN_SCRIPT_SCHEMA "${CMAKE_CURRENT_SOURCE_DIR}/util/generate-yaml-schema.py")
133+
set(CONFIG_GEN_COMMAND_INFO ${PYTHON_EXECUTABLE} ${CONFIG_GEN_SCRIPT_INFO} ${CONFIG_GEN_CONFIG_JSON} ${CONFIG_GEN_OUTPUT_DIR})
134+
set(CONFIG_GEN_COMMAND_SCHEMA ${PYTHON_EXECUTABLE} ${CONFIG_GEN_SCRIPT_SCHEMA})
135+
set(CONFIG_GEN_INPUT_FILES
136+
${CONFIG_GEN_SCRIPT_INFO}
137+
${CONFIG_GEN_CONFIG_JSON}
138+
${CONFIG_GEN_SCRIPT_SCHEMA}
139+
)
140+
set(CONFIG_GEN_OUTPUT_FILES
141+
${CONFIG_GEN_OUTPUT_DIR}/include/mrdocs/PublicSettings.hpp
142+
${CONFIG_GEN_OUTPUT_DIR}/src/lib/Lib/PublicSettings.cpp
143+
${CONFIG_GEN_OUTPUT_DIR}/src/tool/PublicToolArgs.hpp
144+
${CONFIG_GEN_OUTPUT_DIR}/src/tool/PublicToolArgs.cpp
145+
)
146+
if (MRDOCS_DOCUMENTATION_BUILD)
147+
# Create the files at configure time
148+
execute_process(
149+
COMMAND ${CONFIG_GEN_COMMAND_INFO}
150+
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
151+
COMMAND_ERROR_IS_FATAL ANY
152+
)
153+
execute_process(
154+
COMMAND ${CONFIG_GEN_COMMAND_SCHEMA}
155+
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
156+
COMMAND_ERROR_IS_FATAL ANY
157+
)
158+
set_source_files_properties(${CONFIG_GEN_OUTPUT_FILES} PROPERTIES GENERATED TRUE)
159+
else()
160+
# Create a custom command and target to generate the files at build time
161+
add_custom_command(
162+
OUTPUT ${CONFIG_GEN_OUTPUT_FILES}
163+
COMMAND ${CONFIG_GEN_COMMAND_INFO}
164+
COMMAND ${CONFIG_GEN_COMMAND_SCHEMA}
165+
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
166+
DEPENDS ${CONFIG_GEN_INPUT_FILES}
167+
COMMENT "Generating Config Source Files"
168+
VERBATIM
169+
COMMAND_EXPAND_LISTS
170+
)
171+
endif()
172+
55173
#-------------------------------------------------
56174
#
57175
# Docs build
58176
#
59177
#-------------------------------------------------
60178
if (MRDOCS_DOCUMENTATION_BUILD)
61-
# Glob all header files
62-
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
63-
file(GLOB_RECURSE HEADER_FILES_LIST "${INCLUDE_DIR}/*.hpp")
179+
# Public headers from the source tree
180+
set(SRC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
181+
file(GLOB_RECURSE SRC_HEADER_FILES "${SRC_INCLUDE_DIR}/*.hpp")
182+
183+
# Public headers generated into the build tree
184+
set(BIN_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
185+
file(GLOB_RECURSE BIN_HEADER_FILES "${BIN_INCLUDE_DIR}/*.hpp")
186+
187+
# Merge both sets (source + generated)
188+
set(ALL_HEADER_FILES ${SRC_HEADER_FILES} ${BIN_HEADER_FILES})
64189

65-
# Create a temporary source file that includes all header files
190+
# Create a translation unit that includes all public headers
66191
set(TEMP_CPP_FILE "${CMAKE_CURRENT_BINARY_DIR}/all_headers.cpp")
67-
file(WRITE ${TEMP_CPP_FILE} "// This file is generated automatically by CMake\n\n")
68-
foreach(HEADER_FILE ${HEADER_FILES_LIST})
69-
file(APPEND ${TEMP_CPP_FILE} "#include \"${HEADER_FILE}\"\n")
192+
file(WRITE "${TEMP_CPP_FILE}" "// This file is generated automatically by CMake\n\n")
193+
194+
foreach(HEADER_FILE IN LISTS ALL_HEADER_FILES)
195+
# Normalize to forward slashes so #include is portable
196+
file(TO_CMAKE_PATH "${HEADER_FILE}" HEADER_FILE_FWD)
197+
file(APPEND "${TEMP_CPP_FILE}" "#include \"${HEADER_FILE_FWD}\"\n")
70198
endforeach()
71199

72-
# Create a custom target for MrDocs
73-
add_library(mrdocs-documentation-build STATIC ${TEMP_CPP_FILE})
200+
# Library just to make compilers parse the headers
201+
add_library(mrdocs-documentation-build STATIC "${TEMP_CPP_FILE}")
74202

75-
# Set any other target properties here
76-
target_include_directories(mrdocs-documentation-build PRIVATE ${INCLUDE_DIR})
77-
target_link_libraries(mrdocs-documentation-build PRIVATE an_external_library)
203+
# Include dirs: source + generated
204+
target_include_directories(mrdocs-documentation-build
205+
PRIVATE
206+
"${SRC_INCLUDE_DIR}"
207+
"${BIN_INCLUDE_DIR}"
208+
)
209+
210+
# Other defines so headers compile standalone
78211
target_compile_definitions(mrdocs-documentation-build PRIVATE MRDOCS_STATIC_LINK)
79212

80-
# Don't create any other targets
213+
# No other targets in documentation builds
81214
return()
82215
endif()
83216

@@ -151,68 +284,13 @@ if (NOT DUKTAPE_FOUND)
151284
find_package(Duktape REQUIRED CONFIG)
152285
endif()
153286

154-
# python
155-
find_program(PYTHON_EXECUTABLE python3 python)
156-
if (NOT PYTHON_EXECUTABLE)
157-
message(FATAL_ERROR "Python is needed to configure mrdocs")
158-
endif()
159-
160287
unset(CMAKE_FOLDER)
161288

162289
#-------------------------------------------------
163290
#
164291
# mrdocs-core
165292
#
166293
#-------------------------------------------------
167-
# Create include/mrdocs/Version.hpp from Version.hpp.in
168-
find_package(Git QUIET)
169-
if (GIT_FOUND)
170-
execute_process(
171-
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
172-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
173-
OUTPUT_VARIABLE PROJECT_VERSION_BUILD
174-
OUTPUT_STRIP_TRAILING_WHITESPACE
175-
)
176-
# Check if PROJECT_VERSION_BUILD is populated
177-
if (NOT PROJECT_VERSION_BUILD AND MRDOCS_REQUIRE_GIT)
178-
message(FATAL_ERROR "Git was found but could not extract the version build")
179-
endif()
180-
set(PROJECT_VERSION_BUILD "${PROJECT_VERSION_BUILD}")
181-
else()
182-
if (MRDOCS_REQUIRE_GIT)
183-
message(FATAL_ERROR "Git is required to extract the version build")
184-
endif()
185-
set(PROJECT_VERSION_BUILD "")
186-
endif()
187-
configure_file(
188-
${CMAKE_CURRENT_SOURCE_DIR}/include/mrdocs/Version.hpp.in
189-
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/Version.hpp
190-
@ONLY
191-
)
192-
193-
# Config files for mrdocs-core
194-
add_custom_command(
195-
COMMAND
196-
${PYTHON_EXECUTABLE}
197-
${CMAKE_CURRENT_SOURCE_DIR}/util/generate-config-info.py
198-
src/lib/ConfigOptions.json
199-
${CMAKE_CURRENT_BINARY_DIR}
200-
COMMAND
201-
${PYTHON_EXECUTABLE}
202-
${CMAKE_CURRENT_SOURCE_DIR}/util/generate-yaml-schema.py
203-
VERBATIM
204-
DEPENDS
205-
${CMAKE_CURRENT_SOURCE_DIR}/util/generate-config-info.py
206-
src/lib/ConfigOptions.json
207-
OUTPUT
208-
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/PublicSettings.hpp
209-
${CMAKE_CURRENT_BINARY_DIR}/src/lib/Lib/PublicSettings.cpp
210-
${CMAKE_CURRENT_BINARY_DIR}/src/tool/PublicToolArgs.hpp
211-
${CMAKE_CURRENT_BINARY_DIR}/src/tool/PublicToolArgs.cpp
212-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
213-
COMMENT "Generating Config Source Files"
214-
)
215-
216294
# Main library
217295
file(
218296
GLOB_RECURSE LIB_SOURCES CONFIGURE_DEPENDS

docs/config-headers/README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)