Quellcode durchsuchen

cmake: Reorganize a bit for maintainability

Stick the project files list and compile options up at the top, as those
are only bits most people would need to edit. Move the implementation
details down below. For readability's sake, switch the project files
list to use relative paths and then convert them to absolute at
generation time.

Developer-facing settings are now prefixed with HYDROGEN_*, e.g.,
HYDROGEN_TARGET_ARCH, to avoid potential clashes when libhydrogen is
built as part of a larger project.
Michael Smith vor 6 Jahren
Ursprung
Commit
c96f3874b8
2 geänderte Dateien mit 87 neuen und 54 gelöschten Zeilen
  1. 87 54
      CMakeLists.txt
  2. 0 0
      cmake/hydrogen-config.cmake.in

+ 87 - 54
CMakeLists.txt

@@ -1,26 +1,60 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.12)
 
-project(hydrogen
-        LANGUAGES C)
+project(hydrogen LANGUAGES C)
 
 include(CMakePackageConfigHelpers)
 include(GNUInstallDirs)
 
-if(NOT CMAKE_CROSSCOMPILING)
-    set(default_build_arch native)
-endif()
+string(TOUPPER "${PROJECT_NAME}" setting_prefix)
+function(get_setting setting_name setting_type setting_description)
+    string(TOUPPER "${setting_prefix}_${setting_name}" setting_external_name)
+    set("${setting_external_name}" "" CACHE "${setting_type}" "${setting_description}")
+    set("${setting_name}" "${${setting_external_name}}" PARENT_SCOPE)
+endfunction()
+
+# Project files
+
+set(source_files
+        "${PROJECT_NAME}.c"
+        "impl/common.h"
+        "impl/core.h"
+        "impl/gimli-core.h"
+        "impl/gimli-core/portable.h"
+        "impl/gimli-core/sse2.h"
+        "impl/hash.h"
+        "impl/${PROJECT_NAME}_p.h"
+        "impl/kdf.h"
+        "impl/kx.h"
+        "impl/pwhash.h"
+        "impl/random.h"
+        "impl/secretbox.h"
+        "impl/sign.h"
+        "impl/x25519.h")
+
+set(header_files
+        "${PROJECT_NAME}.h")
+
+set(test_files
+        "tests/tests.c")
 
-set(BUILD_ARCH "${default_build_arch}" CACHE STRING
-        "Target system architecture (fed to the compiler's -march=...)")
+# Compile options
+
+get_setting(target_arch STRING "Target system architecture (fed to the compiler's -march=...).")
+if(NOT target_arch AND NOT CMAKE_CROSSCOMPILING)
+    set(target_arch native)
+endif()
 
 set(compile_options
+        # GNU, Clang
         $<$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:GNU>>:
             # Optimizations
-            -Os $<$<BOOL:${BUILD_ARCH}>:-march=${BUILD_ARCH}> -fno-exceptions
+            -Os $<$<BOOL:${target_arch}>:-march=${target_arch}> -fno-exceptions
             # Warnings
             -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align
             -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas
             -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits>
+
+        # MSVC
         $<$<C_COMPILER_ID:MSVC>:
             # Optimizations
             /Os /EHsc
@@ -31,76 +65,65 @@ set(compile_options
             /wd4310 # suppress warning "cast truncates constant value"
         >)
 
-set(source_files
-        "${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.c"
-        "${PROJECT_SOURCE_DIR}/impl/common.h"
-        "${PROJECT_SOURCE_DIR}/impl/core.h"
-        "${PROJECT_SOURCE_DIR}/impl/gimli-core.h"
-        "${PROJECT_SOURCE_DIR}/impl/gimli-core/portable.h"
-        "${PROJECT_SOURCE_DIR}/impl/gimli-core/sse2.h"
-        "${PROJECT_SOURCE_DIR}/impl/hash.h"
-        "${PROJECT_SOURCE_DIR}/impl/${PROJECT_NAME}_p.h"
-        "${PROJECT_SOURCE_DIR}/impl/kdf.h"
-        "${PROJECT_SOURCE_DIR}/impl/kx.h"
-        "${PROJECT_SOURCE_DIR}/impl/pwhash.h"
-        "${PROJECT_SOURCE_DIR}/impl/random.h"
-        "${PROJECT_SOURCE_DIR}/impl/secretbox.h"
-        "${PROJECT_SOURCE_DIR}/impl/sign.h"
-        "${PROJECT_SOURCE_DIR}/impl/x25519.h")
-set(header_files
-        "${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.h")
-set(test_files
-        "${PROJECT_SOURCE_DIR}/tests/tests.c")
+# Prefix project files with the project root
 
-set(config_file_name "${PROJECT_NAME}-config.cmake")
-set(config_template_file "${PROJECT_SOURCE_DIR}/${config_file_name}.in")
-set(config_file "${PROJECT_BINARY_DIR}/${config_file_name}")
+function(prefix_project_paths list_name)
+    list(TRANSFORM "${list_name}"
+            PREPEND "${PROJECT_SOURCE_DIR}/"
+            OUTPUT_VARIABLE prefixed_list)
+    set("project_${list_name}" ${prefixed_list} PARENT_SCOPE)
+endfunction()
 
-set(targets_export_name "${PROJECT_NAME}-targets")
-set(targets_export_file_name "${targets_export_name}.cmake")
-set(targets_export_file "${PROJECT_BINARY_DIR}/${targets_export_file_name}")
-
-set(install_config_dir "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}")
-
-set(tests_executable "${PROJECT_NAME}-tests")
-set(tests_done_target "${tests_executable}-done")
-set(tests_done_file "${PROJECT_BINARY_DIR}/${tests_executable}.done")
+prefix_project_paths(source_files)
+prefix_project_paths(header_files)
+prefix_project_paths(test_files)
 
 # Main library
 
 add_library("${PROJECT_NAME}")
 add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")
 
-target_sources("${PROJECT_NAME}" PRIVATE ${source_files})
+target_sources("${PROJECT_NAME}" PRIVATE ${project_source_files})
 
 target_include_directories("${PROJECT_NAME}" PUBLIC
         $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
         $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
 
-target_compile_options(${PROJECT_NAME} PRIVATE ${compile_options})
+target_compile_options("${PROJECT_NAME}" PRIVATE ${compile_options})
 
 # Installation
 
+set(targets_export_name "${PROJECT_NAME}-targets")
+
 install(TARGETS "${PROJECT_NAME}"
         EXPORT "${targets_export_name}"
         LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
         ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
 
-install(FILES ${header_files}
+install(FILES ${project_header_files}
         DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 
 # CMake find_package() support
 
+set(install_config_dir "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}")
+
+set(targets_export_file_name "${targets_export_name}.cmake")
+set(targets_export_file "${PROJECT_BINARY_DIR}/${targets_export_file_name}")
+
 install(EXPORT "${targets_export_name}"
         FILE "${targets_export_file_name}"
         NAMESPACE "${PROJECT_NAME}::"
         DESTINATION "${install_config_dir}")
 
+set(config_file_name "${PROJECT_NAME}-config.cmake")
+set(config_template_file "${PROJECT_SOURCE_DIR}/cmake/${config_file_name}.in")
+set(config_file "${PROJECT_BINARY_DIR}/${config_file_name}")
+
 CONFIGURE_PACKAGE_CONFIG_FILE("${config_template_file}" "${config_file}"
         INSTALL_DESTINATION "${install_config_dir}")
 
-install(FILES ${config_file}
-        DESTINATION ${install_config_dir})
+install(FILES "${config_file}"
+        DESTINATION "${install_config_dir}")
 
 export(EXPORT "${targets_export_name}"
         FILE "${targets_export_file}"
@@ -110,23 +133,33 @@ export(PACKAGE "${PROJECT_NAME}")
 
 # Tests
 
+set(tests_executable "${PROJECT_NAME}-tests")
+set(tests_run_target "${PROJECT_NAME}-run-tests")
+set(tests_run_file "${PROJECT_BINARY_DIR}/${tests_run_target}.done")
+
 enable_testing()
-add_executable("${tests_executable}" ${test_files})
+add_executable("${tests_executable}" ${project_test_files})
 target_compile_options("${tests_executable}" PRIVATE ${compile_options})
 target_link_libraries("${tests_executable}" "${PROJECT_NAME}")
 add_test(NAME "${tests_executable}" COMMAND "${tests_executable}")
 
-# Auto-run tests on build (unless cross-compiling)
-
-if(NOT CMAKE_CROSSCOMPILING)
-    add_custom_command(OUTPUT "${tests_done_file}"
+if(CMAKE_CROSSCOMPILING)
+    # Disable tests executable by default when cross-compiling (as it will fail
+    # to build when, e.g., cross-compiling for Arduino/AVR).
+    set_target_properties("${tests_executable}"
+            PROPERTIES
+                EXCLUDE_FROM_ALL 1
+                EXCLUDE_FROM_DEFAULT_BUILD 1)
+else()
+    # Otherwise, auto-run the tests on build.
+    add_custom_command(OUTPUT "${tests_run_file}"
             DEPENDS "${tests_executable}"
             COMMAND cmake
-                ARGS -E remove "${tests_done_file}"
+                ARGS -E remove "${tests_run_file}"
             COMMAND ctest
                 ARGS -C $<CONFIGURATION> --output-on-failure
             COMMAND cmake
-                ARGS -E touch "${tests_done_file}"
+                ARGS -E touch "${tests_run_file}"
             WORKING_DIRECTORY "${PROJECT_BINARY_DIR}")
-    add_custom_target("${tests_done_target}" ALL DEPENDS "${tests_done_file}")
+    add_custom_target("${tests_run_target}" ALL DEPENDS "${tests_run_file}")
 endif()

+ 0 - 0
hydrogen-config.cmake.in → cmake/hydrogen-config.cmake.in