-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
786 lines (721 loc) · 29 KB
/
CMakeLists.txt
File metadata and controls
786 lines (721 loc) · 29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
#
# Official repository: https://github.com/cppalliance/mrdocs
#
#-------------------------------------------------
#
# Project settings
#
#-------------------------------------------------
cmake_minimum_required(VERSION 3.13)
project(
MrDocs
VERSION 0.8.0
DESCRIPTION "C++ Documentation Tool"
HOMEPAGE_URL "https://github.com/cppalliance/mrdocs"
LANGUAGES CXX C
)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
option(MRDOCS_INSTALL "Configure install target" ON)
option(MRDOCS_PACKAGE "Build install package" ON)
option(MRDOCS_BUILD_SHARED "Link shared" ${BUILD_SHARED_LIBS})
option(MRDOCS_BUILD_TESTS "Build tests" ${BUILD_TESTING})
option(MRDOCS_BUILD_STRICT_TESTS "Enable strict tests" ON)
option(MRDOCS_EXPENSIVE_TESTS "Register expensive tests (adoc/html golden, self-doc)" ON)
# When strict tests are on, optional test dependencies become required
if (MRDOCS_BUILD_STRICT_TESTS)
set(REQUIRED_IF_STRICT REQUIRED)
else()
set(REQUIRED_IF_STRICT "")
endif()
option(MRDOCS_REQUIRE_GIT "Git is required: not being able to extract version build is an error" ON)
if (MRDOCS_BUILD_TESTS OR MRDOCS_INSTALL)
option(MRDOCS_BUILD_DOCS "Build documentation" ON)
else()
option(MRDOCS_BUILD_DOCS "Build documentation" OFF)
endif()
option(MRDOCS_GENERATE_REFERENCE "Generate MrDocs reference" ${MRDOCS_BUILD_DOCS})
option(MRDOCS_GENERATE_ANTORA_REFERENCE "Generate MrDocs reference in Antora module pages" OFF)
if (MRDOCS_BUILD_SHARED)
set(MRDOCS_LINK_MODE SHARED)
set(MRDOCS_LINK_MODE_DEFINITION -DMRDOCS_SHARED_LINK)
else()
set(MRDOCS_LINK_MODE_DEFINITION -DMRDOCS_STATIC_LINK)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(MRDOCS_GCC ON)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
set(MRDOCS_CLANG ON)
endif()
#-------------------------------------------------
#
# Generate project headers
#
#-------------------------------------------------
# Create include/mrdocs/Version.hpp from Version.hpp.in
if (MRDOCS_REQUIRE_GIT)
find_package(Git REQUIRED)
else()
find_package(Git QUIET)
endif()
set(PROJECT_VERSION_BUILD "")
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}") # default: plain semver
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND GIT_FOUND)
# Get full SHA
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_SHA_FULL
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_SHA_FULL_RV
ERROR_QUIET
)
if (NOT GIT_SHA_FULL_RV EQUAL 0)
message(FATAL_ERROR "Git was found but could not extract commit SHA")
endif()
set(PROJECT_VERSION_BUILD "${GIT_SHA_FULL}")
string(SUBSTRING "${GIT_SHA_FULL}" 0 12 GIT_SHA_SHORT)
# Are we exactly at a tag?
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_EXACT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_EXACT_TAG_RV
ERROR_QUIET
)
if (GIT_EXACT_TAG_RV EQUAL 0)
# On a tag: canonical release
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}")
else()
# Dirty working tree? (0 = clean, 1 = dirty)
execute_process(
COMMAND ${GIT_EXECUTABLE} diff --quiet --ignore-submodules
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_DIRTY_RV
ERROR_QUIET
)
set(_dirty_suffix "")
if (GIT_DIRTY_RV EQUAL 1)
set(_dirty_suffix ".modified")
endif()
set(PROJECT_VERSION_WITH_BUILD
"${PROJECT_VERSION}+${GIT_SHA_SHORT}${_dirty_suffix}")
endif()
else()
if (MRDOCS_REQUIRE_GIT)
message(FATAL_ERROR "Git is required to extract the version build")
endif()
set(PROJECT_VERSION_BUILD "")
set(PROJECT_VERSION_WITH_BUILD "${PROJECT_VERSION}")
endif()
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/mrdocs/Version.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/Version.hpp
@ONLY
)
# Create include/mrdocs/PublicSettings.hpp and related files from JSON config files
find_program(PYTHON_EXECUTABLE python3 python)
if (NOT PYTHON_EXECUTABLE)
message(FATAL_ERROR "Python is needed to configure mrdocs")
endif()
set(CONFIG_GEN_WORKING_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(CONFIG_GEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
set(CONFIG_GEN_CONFIG_JSON "${CMAKE_CURRENT_SOURCE_DIR}/src/lib/ConfigOptions.json")
set(CONFIG_GEN_SCRIPT_INFO "${CMAKE_CURRENT_SOURCE_DIR}/util/generate-config-info.py")
set(CONFIG_GEN_SCRIPT_SCHEMA "${CMAKE_CURRENT_SOURCE_DIR}/util/generate-yaml-schema.py")
set(CONFIG_GEN_COMMAND_INFO ${PYTHON_EXECUTABLE} ${CONFIG_GEN_SCRIPT_INFO} ${CONFIG_GEN_CONFIG_JSON} ${CONFIG_GEN_OUTPUT_DIR})
set(CONFIG_GEN_COMMAND_SCHEMA ${PYTHON_EXECUTABLE} ${CONFIG_GEN_SCRIPT_SCHEMA})
set(CONFIG_GEN_INPUT_FILES
${CONFIG_GEN_SCRIPT_INFO}
${CONFIG_GEN_CONFIG_JSON}
${CONFIG_GEN_SCRIPT_SCHEMA}
)
set(CONFIG_GEN_OUTPUT_FILES
${CONFIG_GEN_OUTPUT_DIR}/include/mrdocs/PublicSettings.hpp
${CONFIG_GEN_OUTPUT_DIR}/src/lib/Lib/PublicSettings.cpp
${CONFIG_GEN_OUTPUT_DIR}/src/tool/PublicToolArgs.hpp
${CONFIG_GEN_OUTPUT_DIR}/src/tool/PublicToolArgs.cpp
)
if (MRDOCS_DOCUMENTATION_BUILD)
# Create the files at configure time
execute_process(
COMMAND ${CONFIG_GEN_COMMAND_INFO}
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND ${CONFIG_GEN_COMMAND_SCHEMA}
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
set_source_files_properties(${CONFIG_GEN_OUTPUT_FILES} PROPERTIES GENERATED TRUE)
else()
# Create a custom command and target to generate the files at build time
add_custom_command(
OUTPUT ${CONFIG_GEN_OUTPUT_FILES}
COMMAND ${CONFIG_GEN_COMMAND_INFO}
COMMAND ${CONFIG_GEN_COMMAND_SCHEMA}
WORKING_DIRECTORY ${CONFIG_GEN_WORKING_DIR}
DEPENDS ${CONFIG_GEN_INPUT_FILES}
COMMENT "Generating Config Source Files"
VERBATIM
COMMAND_EXPAND_LISTS
)
endif()
#-------------------------------------------------
#
# Docs build
#
#-------------------------------------------------
if (MRDOCS_DOCUMENTATION_BUILD)
# Public headers from the source tree
set(SRC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
file(GLOB_RECURSE SRC_HEADER_FILES "${SRC_INCLUDE_DIR}/*.hpp")
# Public headers generated into the build tree
set(BIN_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
file(GLOB_RECURSE BIN_HEADER_FILES "${BIN_INCLUDE_DIR}/*.hpp")
# Merge both sets (source + generated)
set(ALL_HEADER_FILES ${SRC_HEADER_FILES} ${BIN_HEADER_FILES})
# Create a translation unit that includes all public headers
set(TEMP_CPP_FILE "${CMAKE_CURRENT_BINARY_DIR}/all_headers.cpp")
file(WRITE "${TEMP_CPP_FILE}" "// This file is generated automatically by CMake\n\n")
foreach(HEADER_FILE IN LISTS ALL_HEADER_FILES)
# Normalize to forward slashes so #include is portable
file(TO_CMAKE_PATH "${HEADER_FILE}" HEADER_FILE_FWD)
file(APPEND "${TEMP_CPP_FILE}" "#include \"${HEADER_FILE_FWD}\"\n")
endforeach()
# Library just to make compilers parse the headers
add_library(mrdocs-documentation-build STATIC "${TEMP_CPP_FILE}")
# Include dirs: source + generated
target_include_directories(mrdocs-documentation-build
PRIVATE
"${SRC_INCLUDE_DIR}"
"${BIN_INCLUDE_DIR}"
)
# Other defines so headers compile standalone
target_compile_definitions(mrdocs-documentation-build PRIVATE MRDOCS_STATIC_LINK)
# No other targets in documentation builds
return()
endif()
#-------------------------------------------------
#
# Dependencies
#
#-------------------------------------------------
set(CMAKE_FOLDER Dependencies)
# LLVM + Clang
if (LLVM_ROOT)
# LLVM_ROOT is absolute
get_filename_component(LLVM_ROOT "${LLVM_ROOT}" ABSOLUTE)
set(LLVM_ROOT "${LLVM_ROOT}" CACHE PATH "Root of LLVM install." FORCE)
if (NOT EXISTS "${LLVM_ROOT}")
message(FATAL_ERROR
"LLVM_ROOT (${LLVM_ROOT}) provided does not exist.\n"
"Please set LLVM_ROOT to the root of LLVM install.\n")
endif()
if (NOT EXISTS "${LLVM_ROOT}/lib/cmake/llvm")
message(FATAL_ERROR
"LLVM_ROOT (${LLVM_ROOT}) provided is invalid.\n"
"No <LLVM_ROOT>/lib/cmake/llvm found.\n"
"Please set LLVM_ROOT to the root of LLVM install.\n")
endif()
message(STATUS "LLVM_ROOT: ${LLVM_ROOT}")
endif()
if (Clang_ROOT)
# Clang_ROOT is absolute
get_filename_component(Clang_ROOT "${Clang_ROOT}" ABSOLUTE)
set(LLVM_ROOT "${LLVM_ROOT}" CACHE PATH "Root of Clang install." FORCE)
elseif (LLVM_ROOT)
# Clang_ROOT matches LLVM_ROOT by default
set(Clang_ROOT "${LLVM_ROOT}" CACHE PATH "Root of Clang install." FORCE)
endif()
find_package(LLVM REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)
set(LIBCXX_DIR "${LLVM_INCLUDE_DIR}/c++/v1" CACHE PATH
"Path to libc++ include directory")
message(STATUS "LIBCXX_DIR: ${LIBCXX_DIR}")
if (NOT EXISTS "${LIBCXX_DIR}")
message(FATAL_ERROR
"LIBCXX_DIR (${LIBCXX_DIR}) does not exist.\n"
"Please provide a LLVM with libc++ enabled\n")
endif()
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(HandleLLVMOptions)
add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs all)
string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# JerryScript
find_package(jerryscript REQUIRED CONFIG)
# Lua
find_package(Lua CONFIG REQUIRED)
unset(CMAKE_FOLDER)
#-------------------------------------------------
#
# mrdocs-core
#
#-------------------------------------------------
# Main library
file(
GLOB_RECURSE LIB_SOURCES CONFIGURE_DEPENDS
# Public
include/*.hpp
include/*.inc
include/*.ipp
# Private
src/lib/*.cpp
src/lib/*.hpp
src/lib/*.ipp
src/lib/*.natvis
# Natvis
include/*.natvis
SourceFileNames.cpp
)
list(APPEND LIB_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/Version.hpp
${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs/PublicSettings.hpp
${CMAKE_CURRENT_BINARY_DIR}/src/lib/Lib/PublicSettings.cpp
)
add_library(mrdocs-core ${LIB_SOURCES})
target_compile_features(mrdocs-core PUBLIC cxx_std_23)
target_include_directories(mrdocs-core
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
"${PROJECT_SOURCE_DIR}/src"
"${PROJECT_BINARY_DIR}/src"
)
target_compile_definitions(
mrdocs-core
PUBLIC
${MRDOCS_LINK_MODE_DEFINITION}
PRIVATE
-DMRDOCS_TOOL
)
# Dependencies
target_include_directories(mrdocs-core
SYSTEM PUBLIC
"$<BUILD_INTERFACE:${LLVM_INCLUDE_DIRS}>"
"$<BUILD_INTERFACE:${CLANG_INCLUDE_DIRS}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_include_directories(mrdocs-core
SYSTEM PRIVATE
"$<BUILD_INTERFACE:${JERRYSCRIPT_INCLUDE_DIRS}>"
"$<BUILD_INTERFACE:${jerryscript_ROOT}/include>"
"$<BUILD_INTERFACE:/usr/local/include>"
)
target_link_libraries(mrdocs-core PRIVATE jerryscript::jerry-core jerryscript::jerry-port)
target_link_libraries(mrdocs-core PRIVATE Lua::lua)
# Clang
if (CLANG_SIMPLE_LIBS)
target_link_libraries(mrdocs-core PUBLIC LLVM clang clang-cpp)
else()
target_link_libraries(mrdocs-core
PUBLIC
clangAST
clangBasic
clangFrontend
clangIndex
clangTooling
clangToolingCore
clangToolingInclusions)
endif()
# Windows, Win64
if (WIN32)
target_compile_definitions(
mrdocs-core
PUBLIC
-D_WIN32_WINNT=0x0601
-D_CRT_SECURE_NO_WARNINGS
-D_SILENCE_CXX20_CISO646_REMOVED_WARNING
)
if(MSVC)
get_target_property(LLVM_CONFIGURATION_TYPE LLVMCore IMPORTED_CONFIGURATIONS)
if (LLVM_CONFIGURATION_TYPE STREQUAL RELWITHDEBINFO)
# Handle Debug/RelWithDebInfo mismatch between mrdocs and LLVM
target_compile_definitions(mrdocs-core PUBLIC $<$<CONFIG:Debug>:-D_ITERATOR_DEBUG_LEVEL=0>)
target_compile_options(mrdocs-core PUBLIC $<$<CONFIG:Debug>:/MD>)
endif()
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win64") # 64-bit
target_compile_options(mrdocs-core PUBLIC /arch:AMD64)
endif()
target_compile_options(
mrdocs-core
PUBLIC
/permissive- # strict C++
/W4 # enable all warnings
/MP # multi-processor compilation
/EHs # C++ Exception handling
$<$<CONFIG:Debug>:/Oy-> # Disable frame pointer omission
)
endif()
endif ()
if (MRDOCS_CLANG)
target_compile_options(
mrdocs-core
PUBLIC
-Wno-unused-private-field
-Wno-unused-value
PRIVATE
-Wno-covered-switch-default
)
endif ()
if (MRDOCS_DOCUMENTATION_BUILD)
return()
endif()
# Replicate the clang resource directory structure within our own build,
# so that libclang will find it when executing directly from the build directory.
# The installed binary will use runtime path resolution to locate the resource directory
# relative to the executable, so both LLVM and MrDocs must be installed to the same prefix.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib/clang")
set(RESOURCE_DIR "lib/clang/${Clang_VERSION_MAJOR}")
file(CREATE_LINK "${LLVM_BINARY_DIR}/${RESOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_DIR}" SYMBOLIC)
#-------------------------------------------------
#
# Tool
#
#-------------------------------------------------
file(GLOB_RECURSE TOOL_SOURCES CONFIGURE_DEPENDS
src/tool/*.cpp
src/tool/*.hpp)
list(APPEND TOOL_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/src/tool/PublicToolArgs.hpp
${CMAKE_CURRENT_BINARY_DIR}/src/tool/PublicToolArgs.cpp)
add_executable(mrdocs ${TOOL_SOURCES})
target_include_directories(mrdocs
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
"${PROJECT_SOURCE_DIR}/include"
"${PROJECT_SOURCE_DIR}/src"
"${PROJECT_BINARY_DIR}/src"
)
target_compile_definitions(mrdocs PRIVATE -DMRDOCS_TOOL)
target_link_libraries(mrdocs PUBLIC mrdocs-core)
if (MRDOCS_CLANG)
target_compile_options(
mrdocs
PRIVATE
-Wno-covered-switch-default
)
endif ()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
source_group(TREE ${PROJECT_SOURCE_DIR}/include/mrdocs PREFIX "include" FILES ${INCLUDES})
source_group(TREE ${PROJECT_SOURCE_DIR}/source PREFIX "source" FILES ${SOURCES})
#-------------------------------------------------
#
# Tests
#
#-------------------------------------------------
if (MRDOCS_BUILD_TESTS)
#-------------------------------------------------
# Unit tests
#-------------------------------------------------
include(CTest)
file(GLOB_RECURSE TEST_SUITE_FILES CONFIGURE_DEPENDS src/test_suite/*.cpp src/test_suite/*.hpp)
file(GLOB_RECURSE UNIT_TEST_SOURCES CONFIGURE_DEPENDS src/test/*.cpp src/test/*.hpp)
add_executable(mrdocs-test ${TEST_SUITE_FILES} ${UNIT_TEST_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/src/tool/PublicToolArgs.cpp)
target_include_directories(mrdocs-test
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE
"${PROJECT_SOURCE_DIR}/src"
"${PROJECT_BINARY_DIR}/src"
)
target_link_libraries(mrdocs-test PUBLIC mrdocs-core)
if (MRDOCS_CLANG)
target_compile_options(mrdocs-test PRIVATE -Wno-covered-switch-default)
endif ()
target_compile_definitions(mrdocs-test PRIVATE -DMRDOCS_TEST_FILES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test-files")
add_test(NAME mrdocs-unit-tests COMMAND mrdocs-test --unit=true)
foreach (testgenerator IN ITEMS xml adoc html)
if (MRDOCS_EXPENSIVE_TESTS OR testgenerator STREQUAL "xml")
add_test(NAME mrdocs-golden-tests-${testgenerator}
COMMAND
mrdocs-test
--unit=false
--action=test
"${PROJECT_SOURCE_DIR}/test-files/golden-tests"
"--addons=${CMAKE_SOURCE_DIR}/share/mrdocs/addons"
--generator=${testgenerator}
"--stdlib-includes=${LIBCXX_DIR}"
"--libc-includes=${CMAKE_SOURCE_DIR}/share/mrdocs/headers/libc-stubs"
--log-level=warn
)
endif()
foreach (action IN ITEMS test create update)
add_custom_target(
mrdocs-${action}-test-fixtures-${testgenerator}
COMMAND
mrdocs-test
--unit=false
--action=${action}
"${PROJECT_SOURCE_DIR}/test-files/golden-tests"
"--addons=${CMAKE_SOURCE_DIR}/share/mrdocs/addons"
--generator=${testgenerator}
"--stdlib-includes=${LIBCXX_DIR}"
"--libc-includes=${CMAKE_SOURCE_DIR}/share/mrdocs/headers/libc-stubs"
--log-level=warn
DEPENDS mrdocs-test
)
endforeach ()
endforeach()
foreach (action IN ITEMS test create update)
add_custom_target(mrdocs-${action}-test-fixtures-all
DEPENDS
mrdocs-${action}-test-fixtures-xml
mrdocs-${action}-test-fixtures-adoc
mrdocs-${action}-test-fixtures-html
)
endforeach ()
#-------------------------------------------------
# Self-documentation test (warn-as-error toggled by strict flag)
#-------------------------------------------------
set(MRDOCS_SELF_DOC_OUTPUT "${CMAKE_BINARY_DIR}/docs/self-reference")
set(MRDOCS_SELF_DOC_TAGFILE "${MRDOCS_SELF_DOC_OUTPUT}/reference.tag.xml")
if (MRDOCS_EXPENSIVE_TESTS)
add_test(NAME mrdocs-self-doc
COMMAND
mrdocs
"${CMAKE_SOURCE_DIR}/CMakeLists.txt"
"--config=${CMAKE_SOURCE_DIR}/docs/mrdocs.yml"
"--output=${MRDOCS_SELF_DOC_OUTPUT}"
--generator=adoc
"--addons=${CMAKE_SOURCE_DIR}/share/mrdocs/addons"
"--stdlib-includes=${LIBCXX_DIR}"
"--stdlib-includes=${STDLIB_INCLUDE_DIR}"
"--libc-includes=${CMAKE_SOURCE_DIR}/share/mrdocs/headers/libc-stubs"
"--tagfile=${MRDOCS_SELF_DOC_TAGFILE}"
--multipage=true
--concurrency=16
--log-level=debug
$<$<BOOL:${MRDOCS_BUILD_STRICT_TESTS}>:--warn-as-error=true>
)
endif()
#-------------------------------------------------
# XML lint
#-------------------------------------------------
find_package(LibXml2 ${REQUIRED_IF_STRICT})
if (LibXml2_FOUND)
find_package(Java REQUIRED Runtime)
# FindJava
if (NOT Java_FOUND)
message(FATAL_ERROR "Java is needed to run xml-lint")
endif()
add_custom_command(
COMMAND ${Java_JAVA_EXECUTABLE} -jar ${CMAKE_CURRENT_SOURCE_DIR}/util/trang.jar
${CMAKE_CURRENT_SOURCE_DIR}/mrdocs.rnc ${CMAKE_CURRENT_BINARY_DIR}/mrdocs.rng
OUTPUT mrdocs.rng
DEPENDS mrdocs.rnc)
add_custom_target(mrdocs_rng ALL DEPENDS mrdocs.rng)
file(GLOB_RECURSE XML_SOURCES CONFIGURE_DEPENDS test-files/golden-tests/*.xml)
add_test(NAME xml-lint
COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --dropdtd --noout
--relaxng ${CMAKE_CURRENT_BINARY_DIR}/mrdocs.rng ${XML_SOURCES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
#-------------------------------------------------
# YAML schema check
#-------------------------------------------------
if (PYTHON_EXECUTABLE)
add_test(NAME yaml-schema-check
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/util/generate-yaml-schema.py --check
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
endif()
#-------------------------------------------------
#
# Docs
#
#-------------------------------------------------
if (MRDOCS_BUILD_DOCS)
#-------------------------------------------------
# Reference
#-------------------------------------------------
if (MRDOCS_GENERATE_REFERENCE)
include(share/cmake/MrDocs.cmake)
set(MRDOCS_REFERENCE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/docs/reference)
file(GLOB_RECURSE REFERENCE_SOURCES CONFIGURE_DEPENDS include/*.hpp include/*.inc)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
add_mrdocs(generate_reference
CONFIG docs/mrdocs.yml
COMMENT "Generate MrDocs reference"
OUTPUT ${MRDOCS_REFERENCE_OUTPUT_DIR}
${REFERENCE_SOURCES})
if (MRDOCS_GENERATE_ANTORA_REFERENCE)
set(MRDOCS_ANTORA_REFERENCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs/modules/ROOT/pages/reference)
add_custom_target(generate_antora_reference
COMMAND ${CMAKE_COMMAND} -E copy_directory ${MRDOCS_REFERENCE_OUTPUT_DIR} ${MRDOCS_ANTORA_REFERENCE_DIR}
DEPENDS generate_reference
COMMENT "Copy MrDocs reference to Antora")
endif()
endif()
#-------------------------------------------------
# Exposition
#-------------------------------------------------
find_program(NPM_EXECUTABLE npm)
find_program(NPX_EXECUTABLE npx)
if(NPM_EXECUTABLE AND NPX_EXECUTABLE)
message(STATUS "NPM found: ${NPM_EXECUTABLE}")
message(STATUS "NPX found: ${NPX_EXECUTABLE}")
set(DOCS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
set(DOCS_BUILD_DIR ${DOCS_SOURCE_DIR}/build/site)
set(DOCS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/doc/mrdocs/html)
# Add a custom target for generating documentation
add_custom_target(generate_docs
ALL
COMMAND ${CMAKE_COMMAND} -E echo "Install npm dependencies"
COMMAND ${NPM_EXECUTABLE} install
COMMAND ${CMAKE_COMMAND} -E echo "Run Antora"
COMMAND ${NPX_EXECUTABLE} antora antora-playbook.yml
WORKING_DIRECTORY ${DOCS_SOURCE_DIR}
COMMENT "Generating MrDocs documentation"
USES_TERMINAL
)
if (MRDOCS_GENERATE_REFERENCE AND MRDOCS_GENERATE_ANTORA_REFERENCE)
add_dependencies(generate_docs generate_antora_reference)
endif()
elseif (NOT NPM_EXECUTABLE AND NPX_EXECUTABLE)
message(WARNING "NPM not found. Unable to generate documentation.")
elseif (NPM_EXECUTABLE AND NOT NPX_EXECUTABLE)
message(WARNING "NPX not found. Unable to generate documentation.")
else()
message(WARNING "NPM and NPX not found. Unable to generate documentation.")
endif()
endif ()
#-------------------------------------------------
#
# Install
#
#-------------------------------------------------
if (MRDOCS_INSTALL)
#-------------------------------------------------
# bin
#-------------------------------------------------
install(TARGETS mrdocs
EXPORT mrdocs-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
set(MRDOCS_EXECUTABLE $<TARGET_FILE:mrdocs>)
#-------------------------------------------------
# lib
#-------------------------------------------------
install(TARGETS mrdocs-core
EXPORT mrdocs-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT development
)
install(EXPORT mrdocs-targets
FILE mrdocs-targets.cmake
NAMESPACE mrdocs::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mrdocs)
#-------------------------------------------------
# include
#-------------------------------------------------
foreach(MRDOCS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/mrdocs ${CMAKE_CURRENT_BINARY_DIR}/include/mrdocs)
foreach(MRDOCS_FILE_PATTERN "*.hpp" "*.ipp" "*.inc")
install(DIRECTORY ${MRDOCS_INCLUDE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT development
FILES_MATCHING
PATTERN ${MRDOCS_FILE_PATTERN})
endforeach()
endforeach()
#-------------------------------------------------
# share
#-------------------------------------------------
install(DIRECTORY ${LIBCXX_DIR}/
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs/headers/libcxx
FILES_MATCHING PATTERN "*")
install(DIRECTORY ${CMAKE_SOURCE_DIR}/share/mrdocs/headers/libc-stubs/
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs/headers/libc-stubs
FILES_MATCHING PATTERN "*")
foreach (share_mrdocs_dir addons)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/share/mrdocs/${share_mrdocs_dir}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs
FILES_MATCHING PATTERN "*")
endforeach ()
foreach (share_dir cmake gdb)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/share/${share_dir}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs
FILES_MATCHING PATTERN "*")
endforeach ()
#-------------------------------------------------
# doc
#-------------------------------------------------
if (MRDOCS_BUILD_DOCS AND NPM_EXECUTABLE AND NPX_EXECUTABLE)
if (EXISTS ${DOCS_BUILD_DIR})
install(DIRECTORY ${DOCS_BUILD_DIR}
DESTINATION ${CMAKE_INSTALL_DOCDIR}
COMPONENT documentation
)
endif()
endif()
#-------------------------------------------------
# lib/cmake
#-------------------------------------------------
set(CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/mrdocs)
# mrdocs-config-version.cmake
if (CMAKE_PROJECT_VERSION VERSION_LESS 1.0.0)
set(compatibility_mode SameMajorVersion)
else ()
set(compatibility_mode SameMinorVersion)
endif ()
write_basic_package_version_file(
mrdocs-config-version.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY ${compatibility_mode})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mrdocs-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mrdocs)
# mrdocs-config.cmake
set(INCLUDE_INSTALL_DIR include/)
set(LIB_INSTALL_DIR lib/)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/mrdocs-config.cmake.in # input file
${CMAKE_CURRENT_BINARY_DIR}/mrdocs-config.cmake # output file
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mrdocs
PATH_VARS CMAKE_INSTALL_LIBDIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mrdocs-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mrdocs)
endif ()
#-------------------------------------------------
#
# Packages
#
#-------------------------------------------------
if (MRDOCS_INSTALL AND MRDOCS_PACKAGE)
# Project description
set(CPACK_PACKAGE_VENDOR "mrdocs")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION})
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.adoc")
# Ignore files
FILE(READ .gitignore GITIGNORE_CONTENTS)
STRING(REGEX REPLACE ";" "\\\\;" GITIGNORE_CONTENTS "${GITIGNORE_CONTENTS}")
STRING(REGEX REPLACE "\n" ";" GITIGNORE_CONTENTS "${GITIGNORE_CONTENTS}")
set(CPACK_SOURCE_IGNORE_FILES ${GITIGNORE_CONTENTS})
# CPack variables
include(CPack)
endif ()