From a719a8f8ced88f5a3f9e92d0afdac865e8b2ae2b Mon Sep 17 00:00:00 2001 From: Kong Date: Sun, 17 Mar 2024 15:57:05 +0800 Subject: [PATCH] Update project --- .github/workflows/cmake-multi-platform.yml | 2 +- CMakeLists.txt | 73 ++++++++++---------- CMakePresets.json | 79 ++-------------------- README.md | 4 +- cmake/CheckPathParentheses.cmake | 10 +++ cmake/Doxygen.cmake | 39 +++++++++++ cmake/InstallArtifacts.cmake | 13 +++- cmake/NoInSourceBuilds.cmake | 13 ++++ 8 files changed, 116 insertions(+), 117 deletions(-) create mode 100644 cmake/CheckPathParentheses.cmake create mode 100644 cmake/Doxygen.cmake create mode 100644 cmake/NoInSourceBuilds.cmake diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index 571ed16..dfa99b3 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -68,7 +68,7 @@ jobs: - name: Install working-directory: ${{ github.workspace }} run: | - cmake --build --preset "DEFAULT-${{ matrix.build_type }}" --target "install_project" + cmake --build --preset "DEFAULT-${{ matrix.build_type }}" --target "install_app" - name: Execute Test working-directory: ${{ github.workspace }}/.out/install/DEFAULT-${{ matrix.build_type }}/bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 95f49f7..80506e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,25 @@ cmake_minimum_required(VERSION 3.25 FATAL_ERROR) +########################################################################### +# BEGIN: CACHES AND OPTIONS # +########################################################################### +option(PROJECT_BUILD_DOC "Generate documentation." FALSE) +option(DEFAULT_BUILD_SHARED_LIBS "Default option for build shared libs." TRUE) +set(DEFAULT_CPP_STANDARD 20 CACHE STRING "Default value for cmake cxx standard.") +set(VCPKG_CACHE_LOCATION "${CMAKE_CURRENT_LIST_DIR}/.cache/.vcpkg" CACHE PATH "Default path for vcpkg cache root.") +set(CONAN_CACHE_LOCATION "${CMAKE_CURRENT_LIST_DIR}/.cache/.conan" CACHE PATH "Default path for conan cache root.") +########################################################################### +# END: CACHES AND OPTIONS # +########################################################################### +include(cmake/CheckPathParentheses.cmake) include(cmake/VcpkgHandle.cmake) project(app LANGUAGES CXX VERSION 1.2.3) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD ${DEFAULT_CPP_STANDARD}) include(cmake/ConanHandle.cmake) +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) +set(BUILD_SHARED_LIBS ${DEFAULT_BUILD_SHARED_LIBS}) if(MSVC) add_compile_options(/Zc:__cplusplus /EHsc) @@ -20,51 +35,31 @@ if(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") add_compile_options("-fsanitize=address") endif() +include(cmake/NoInSourceBuilds.cmake) +include(cmake/InstallArtifacts.cmake) include(GNUInstallDirs) -set(BUILD_SHARED_LIBS TRUE) - find_package(CURL CONFIG REQUIRED GLOBAL) find_package(fmt CONFIG REQUIRED GLOBAL) find_package(ZLIB CONFIG REQUIRED GLOBAL) +########################################################################### +# BEGIN: SOURCE STRUCTURE # +########################################################################### add_subdirectory(src) +########################################################################### +# END: SOURCE STRUCTURE # +########################################################################### -install(TARGETS app RUNTIME COMPONENT "app_exe" DESTINATION ${CMAKE_INSTALL_BINDIR}) - -install(FILES $ COMPONENT "app_dll" DESTINATION ${CMAKE_INSTALL_BINDIR}) +########################################################################### +# BEGIN: INSTALL # +########################################################################### +install_target(EXEs app) +########################################################################### +# END: INSTALL # +########################################################################### -if(MINGW AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") - get_filename_component(mingw_path ${CMAKE_CXX_COMPILER} PATH) - file(GLOB mingw_runtimes "${mingw_path}/*.dll") - list(FILTER mingw_runtimes EXCLUDE REGEX "fortran") - set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${mingw_runtimes}) - install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT "app_dll") +if(PROJECT_BUILD_DOC) + include(cmake/Doxygen.cmake) # Need download Doxygen and Graphviz + doxygen(include doc) endif() - -if(NOT WIN32) - install( - CODE [[ - file(GET_RUNTIME_DEPENDENCIES - RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS - UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS - EXECUTABLES $ - LIBRARIES $ - DIRECTORIES $ - PRE_INCLUDE_REGEXES $ - POST_INCLUDE_REGEXES $ - ) - foreach(DEP_LIB ${RESOLVED_DEPS}) - file(INSTALL ${DEP_LIB} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin FOLLOW_SYMLINK_CHAIN) - endforeach() - ]] - COMPONENT "app_dll" - ) -endif() - -add_custom_target( - install_project - COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --component "app_dll" --config "${CMAKE_BUILD_TYPE}" - COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --component "app_exe" --config "${CMAKE_BUILD_TYPE}" - DEPENDS app -) diff --git a/CMakePresets.json b/CMakePresets.json index 2790b85..e4c1f7e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -94,32 +94,10 @@ "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" - } - }, - { - "name": "x64", - "description": "64bit build (on windows)", - "hidden": true, + }, "architecture": { "value": "x64", "strategy": "external" - }, - "toolset": { - "strategy": "external", - "value": "host=x64" - } - }, - { - "name": "x86", - "description": "32bit build (on windows)", - "hidden": true, - "architecture": { - "value": "x86", - "strategy": "external" - }, - "toolset": { - "strategy": "external", - "value": "host=x86" } }, { @@ -127,8 +105,7 @@ "description": "DEFAULT debug build using default generator", "inherits": [ "base", - "debug", - "x64" + "debug" ] }, { @@ -136,26 +113,7 @@ "description": "DEFAULT release build using default generator", "inherits": [ "base", - "release", - "x64" - ] - }, - { - "name": "DEFAULT-DEV-X86", - "description": "DEFAULT debug build using default generator", - "inherits": [ - "base", - "debug", - "x86" - ] - }, - { - "name": "DEFAULT-REL-X86", - "description": "DEFAULT release build using default generator", - "inherits": [ - "base", - "release", - "x86" + "release" ] }, { @@ -165,8 +123,7 @@ "base", "ninja-generator", "debug", - "compiler-msvc", - "x64" + "compiler-msvc" ] }, { @@ -176,8 +133,7 @@ "base", "ninja-generator", "release", - "compiler-msvc", - "x64" + "compiler-msvc" ] }, { @@ -187,8 +143,7 @@ "base", "ninja-generator", "sanitize", - "compiler-msvc", - "x64" + "compiler-msvc" ] }, { @@ -304,20 +259,6 @@ "release" ] }, - { - "name": "DEFAULT-DEV-X86", - "configurePreset": "DEFAULT-DEV-X86", - "inherits": [ - "debug" - ] - }, - { - "name": "DEFAULT-REL-X86", - "configurePreset": "DEFAULT-REL-X86", - "inherits": [ - "release" - ] - }, { "name": "MSVC-DEV", "configurePreset": "MSVC-DEV", @@ -391,14 +332,6 @@ "name": "DEFAULT-REL", "configurePreset": "DEFAULT-REL" }, - { - "name": "DEFAULT-DEV-X86", - "configurePreset": "DEFAULT-DEV-X86" - }, - { - "name": "DEFAULT-REL-X86", - "configurePreset": "DEFAULT-REL-X86" - }, { "name": "MSVC-DEV", "configurePreset": "MSVC-DEV" diff --git a/README.md b/README.md index e625a64..8382d97 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ It is not necessary to use both modules at the same time, if you want to use onl ## REQUIREMENTS - CMake (version >= 3.25.0) -- Python3 (version >= 3.6) (* only for `conan`) +- Python3 (version >= 3.6) (* only used for `conan`) ## TODO Automatically copies the dynamic library (`.dll`) from `conan` to the same directory as the corresponding executable. @@ -37,7 +37,7 @@ git clone https://github.com/traversebitree/vcpkg-handle-cmake.git cd vcpkg-handle-cmake cmake --preset="DEFAULT-REL" cmake --build --preset "DEFAULT-REL" -cmake --build --preset "DEFAULT-REL" --target "install_project" +cmake --build --preset "DEFAULT-REL" --target "install_app" ./.out/install/DEFAULT-REL/bin/app ``` diff --git a/cmake/CheckPathParentheses.cmake b/cmake/CheckPathParentheses.cmake new file mode 100644 index 0000000..bf14170 --- /dev/null +++ b/cmake/CheckPathParentheses.cmake @@ -0,0 +1,10 @@ +include_guard(GLOBAL) + +block() +cmake_path(ABSOLUTE_PATH CMAKE_CURRENT_SOURCE_DIR OUTPUT_VARIABLE CURRENT_PATH) +string(FIND "${CURRENT_PATH}" "(" FIND_L_INDEX) +string(FIND "${CURRENT_PATH}" ")" FIND_R_INDEX) +if((NOT FIND_L_INDEX EQUAL -1) OR (NOT FIND_R_INDEX EQUAL -1)) + message(FATAL_ERROR "Parentheses in the path.") +endif() +endblock() diff --git a/cmake/Doxygen.cmake b/cmake/Doxygen.cmake new file mode 100644 index 0000000..07f9d45 --- /dev/null +++ b/cmake/Doxygen.cmake @@ -0,0 +1,39 @@ +include_guard(GLOBAL) + +find_package(Doxygen REQUIRED) + +include(FetchContent) +FetchContent_Declare( + doxygen-awesome-css + GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css.git + SOURCE_DIR + "${_DOXYAWS_BIN_DIR}" + DOWNLOAD_DIR + "${_DOXYAWS_DOWNLOAD_DIR}" + BINARY_DIR + "${_DOXYAWS_BUILD_DIR}" + GIT_TAG v2.3.1 +) +FetchContent_MakeAvailable(doxygen-awesome-css) + +function(Doxygen input_dir out_dir) + set(_DOXYGEN_NAME "doxygen") + set(DOXYGEN_HTML_OUTPUT ${PROJECT_BINARY_DIR}/${out_dir}) + set(DOXYGEN_USE_MDFILE_AS_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md") + set(DOXYGEN_USE_MATHJAX YES) # better formula rendering + set(DOXYGEN_JAVADOC_AUTOBRIEF "YES") # for short '///' docstring support + set(DOXYGEN_BUILTIN_STL_SUPPORT YES) + set(DOXYGEN_EXTRACT_LOCAL_CLASSES NO) + set(DOXYGEN_GENERATE_HTML "YES") + set(DOXYGEN_GENERATE_TREEVIEW "YES") + set(DOXYGEN_HAVE_DOT "YES") + set(DOXYGEN_DOT_IMAGE_FORMAT "svg") + set(DOXYGEN_DOT_TRANSPARENT "YES") + set(DOXYGEN_HTML_EXTRA_STYLESHEET "${doxygen-awesome-css_SOURCE_DIR}/doxygen-awesome.css;\ + ${doxygen-awesome-css_SOURCE_DIR}/doxygen-awesome-sidebar-only.css" + ) + set(DOXYGEN_DISABLE_INDEX "NO") + set(DOXYGEN_FULL_SIDEBAR "NO") + set(DOXYGEN_HTML_COLORSTYLE "LIGHT") + doxygen_add_docs(${_DOXYGEN_NAME} ${PROJECT_SOURCE_DIR}/${input_dir} COMMENT "Generate HTML documentation") +endfunction() diff --git a/cmake/InstallArtifacts.cmake b/cmake/InstallArtifacts.cmake index 709681b..c6d1967 100644 --- a/cmake/InstallArtifacts.cmake +++ b/cmake/InstallArtifacts.cmake @@ -17,6 +17,9 @@ function(install_target) foreach(tgt IN ITEMS ${${prefix}_EXEs}) install_exe(${tgt}) endforeach() + foreach(asset_dir IN ITEMS ${${prefix}_ASSETs}) + install_assets(${asset_dir}) + endforeach() endfunction() macro(install_exe tgt) @@ -36,13 +39,14 @@ macro(install_exe tgt) file(GET_RUNTIME_DEPENDENCIES RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS + EXECUTABLES $ LIBRARIES $ DIRECTORIES $ PRE_INCLUDE_REGEXES $ POST_INCLUDE_REGEXES $ ) foreach(DEP_LIB \${RESOLVED_DEPS}) - file(INSTALL \${DEP_LIB} DESTINATION \${CMAKE_INSTALL_PREFIX}/bin) + file(INSTALL \${DEP_LIB} DESTINATION \${CMAKE_INSTALL_PREFIX}/bin FOLLOW_SYMLINK_CHAIN) endforeach() " COMPONENT "${tgt}_dll" @@ -53,10 +57,15 @@ macro(install_exe tgt) install_${tgt} COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --component "${tgt}_dll" --config "${CMAKE_BUILD_TYPE}" COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --component "${tgt}_exe" --config "${CMAKE_BUILD_TYPE}" + COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --component "assets" --config "${CMAKE_BUILD_TYPE}" DEPENDS ${tgt} ) endmacro() macro(install_assets asset_dir) - install(DIRECTORY "${asset_dir}" COMPONENT "assets" DESTINATION ${CMAKE_INSTALL_BINDIR}) + if(IS_DIRECTORY "${asset_dir}") + install(DIRECTORY "${asset_dir}" COMPONENT "assets" DESTINATION ${CMAKE_INSTALL_BINDIR}) + else() + install(FILES "${asset_dir}" COMPONENT "assets" DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() endmacro() diff --git a/cmake/NoInSourceBuilds.cmake b/cmake/NoInSourceBuilds.cmake new file mode 100644 index 0000000..29525fa --- /dev/null +++ b/cmake/NoInSourceBuilds.cmake @@ -0,0 +1,13 @@ +include_guard(GLOBAL) +if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + message( + FATAL_ERROR + "\n" + "In-source builds are not allowed.\n" + "Instead, provide a path to build tree like so:\n" + "cmake -B \n" + "\n" + "To remove files you accidentally created execute:\n" + "rm -rf CMakeFiles CMakeCache.txt\n" + ) +endif()