diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5a6c564b..5d51a055 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,7 +3,8 @@ # (BUILD_SHARED_LIBS). Also with the sanitizers, with -Wall -Wextra -Werror, # checking the headers it installs too (GAOL v5), with the minimum version of # CMake GAOL declares, and as a part of another project, brought in by -# FetchContent (tests/fetch_content). +# FetchContent (tests/fetch_content). The test cpack_stale_configure also runs +# with ccache in CC and Ninja outside PATH. # # The runners have no locale writing a decimal comma, which tests/numbers.cpp # reads and writes numbers under where there is one, and where there is none it @@ -258,6 +259,37 @@ jobs: - name: The test numbers ran under a locale writing a decimal comma run: sh .github/scripts/comma-locale.sh check build + # The test cpack_stale_configure configures copies of the tree with the + # compilers and the generator that configured GAOL: with a compiler given + # with an argument, which CMake keeps in CMAKE_C_COMPILER_ARG1, and Ninja + # outside PATH, where CMake finds it by CMAKE_MAKE_PROGRAM only. The test + # needs no build (GAOL v5) + launcher-ninja: + name: Ubuntu 24.04 x86_64 GCC, cpack_stale_configure with ccache in CC and Ninja outside PATH + runs-on: ubuntu-24.04 + timeout-minutes: 15 + steps: + - uses: actions/checkout@v7 + - name: ccache, and Ninja outside PATH + run: | + sudo apt-get update -q + sudo apt-get install -y -q ccache + curl -sSL -o "$RUNNER_TEMP/ninja-linux.zip" https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip + unzip -q "$RUNNER_TEMP/ninja-linux.zip" -d "$RUNNER_TEMP/ninja" + # A Ninja of the image, under the names CMake looks for in PATH + for name in ninja-build ninja samu; do + for program in $(which -a "$name"); do sudo rm -f "$program"; done + if command -v "$name"; then exit 1; fi + done + - name: Configure + run: CC="ccache gcc" CXX="ccache g++" cmake -S . -B build -G Ninja -DCMAKE_MAKE_PROGRAM="$RUNNER_TEMP/ninja/ninja" -DWITH_TESTS=ON + - name: The test cpack_stale_configure, which has to run, not be skipped + run: | + cd build + ctest -R cpack_stale_configure --no-tests=error > ctest.log 2>&1 || { cat ctest.log; exit 1; } + cat ctest.log + if grep -q Skipped ctest.log; then exit 1; fi + fetch-content: name: Ubuntu 24.04 x86_64 GCC, GAOL built by FetchContent runs-on: ubuntu-24.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index b3ceb2e5..483937c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -934,7 +934,12 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) # The archive of the sources: the files of the repository, without what git # ignores (.gitignore), the builds within the sources, the packages, and the # notes of the work on GAOL v5 (TODO.md, process.md, todo-notes/), which - # serve its maintainers, not the users of a version + # serve its maintainers, not the users of a version. CPack writes the CPACK_* + # variables into CPackConfig.cmake and CPackSourceConfig.cmake, which it reads + # when it runs: CPACK_VERBATIM_VARIABLES has it escape them, so that the + # backslashes of these regular expressions reach it as they are, where CMake + # 3 warned of an invalid escape sequence, \. (CMP0010, GAOL v5) + set(CPACK_VERBATIM_VARIABLES ON) set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME "gaol-${PROJECT_VERSION}") string(REGEX REPLACE "([][+.*()^$?|\\])" "\\\\\\1" _gaol_source_regex "${PROJECT_SOURCE_DIR}") @@ -958,7 +963,15 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) # warn while it configures only, so it does here, whether or not the archive # is made. A tree without configure, or with a configure that has no such # line, has nothing to compare (tests/cpack_stale_configure.cmake checks it, - # GAOL v5). + # GAOL v5). As the archive takes its name from the version CMake read when it + # configured, CPack includes cmake/gaol_package_source.cmake, which configures + # the build directory again first when VERSION.txt holds another version: + # Ninja does before package_source, the Makefile generators did not. + set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_SOURCE_DIR}/cmake/gaol_package_source.cmake") + set(CPACK_GAOL_VERSION "${PROJECT_VERSION}") + set(CPACK_GAOL_CMAKE_COMMAND "${CMAKE_COMMAND}") + set(CPACK_GAOL_SOURCE_DIR "${PROJECT_SOURCE_DIR}") + set(CPACK_GAOL_BINARY_DIR "${PROJECT_BINARY_DIR}") if(EXISTS "${PROJECT_SOURCE_DIR}/configure") file(STRINGS "${PROJECT_SOURCE_DIR}/configure" _gaol_configure_version REGEX "^PACKAGE_VERSION='" LIMIT_COUNT 1) if(_gaol_configure_version MATCHES "^PACKAGE_VERSION='([^']*)'") diff --git a/cmake/gaol_package_source.cmake b/cmake/gaol_package_source.cmake new file mode 100644 index 00000000..b1ee41a0 --- /dev/null +++ b/cmake/gaol_package_source.cmake @@ -0,0 +1,48 @@ +# ================================================================== +# The archive of the sources after a change of VERSION.txt (GAOL v5) +# ================================================================== +# +# CPack includes this file when it makes a package, once per generator +# (CPACK_PROJECT_CONFIG_FILE, set by CMakeLists.txt). The archive of the +# sources (package_source) takes its name and its version from +# CPackSourceConfig.cmake, which CMake writes in the build directory when it +# configures. Before package_source, Ninja configures again after a change of +# VERSION.txt (CMAKE_CONFIGURE_DEPENDS), but the Makefile generators run CPack +# at once: the archive was named after the old version, held the new +# VERSION.txt, and CMake did not say whether configure had been generated for +# it. So when VERSION.txt holds another version than the build directory was +# configured for, CMake configures it again here, which warns of a configure +# generated for another version, and the configuration it writes again is read +# in place of the old one. Only for the archive of the sources: the target +# package builds first, which configures again with every generator. +# +# Copyright (c) 2026 ENSTA, France +# +# Created 2026-10-06 by Jordan NININ + +# CPack reads this file without the policies of CMakeLists.txt: CMake 3 would +# warn of CMP0007 at the list() of gaol_read_version() otherwise +cmake_policy(PUSH) +cmake_policy(VERSION 3.14...3.25) + +# CPack sets CPACK_INSTALLED_DIRECTORIES for the archive of the sources only: +# the packages of the library install the build instead. The version compared +# is GAOL's own, CPACK_PACKAGE_VERSION being that of cpack -R when it is given +if(CPACK_INSTALLED_DIRECTORIES) + include("${CPACK_GAOL_SOURCE_DIR}/cmake/gaol_version.cmake") + gaol_read_version("${CPACK_GAOL_SOURCE_DIR}/VERSION.txt" _gaol_version _gaol_version_error) + # A VERSION.txt refused configures again too, which fails with its message + if(NOT _gaol_version STREQUAL CPACK_GAOL_VERSION) + message(STATUS "VERSION.txt no longer holds ${CPACK_GAOL_VERSION}, the version " + "${CPACK_GAOL_BINARY_DIR} was configured for: CMake configures it again") + execute_process( + COMMAND "${CPACK_GAOL_CMAKE_COMMAND}" -S "${CPACK_GAOL_SOURCE_DIR}" -B "${CPACK_GAOL_BINARY_DIR}" + RESULT_VARIABLE _gaol_status) + if(NOT _gaol_status EQUAL 0) + message(FATAL_ERROR "CMake did not configure ${CPACK_GAOL_BINARY_DIR} again (status ${_gaol_status})") + endif() + include("${CPACK_SOURCE_OUTPUT_CONFIG_FILE}") + endif() +endif() + +cmake_policy(POP) diff --git a/doc/building.md b/doc/building.md index d371a8a4..65289550 100644 --- a/doc/building.md +++ b/doc/building.md @@ -150,9 +150,11 @@ cmake --build build --target package The archive takes its name from the version CMake read when it configured, and CMake warns of a `configure` generated for another version at that moment. -After a change of `VERSION.txt`, configure the build directory again -(`cmake -S . -B build`) before `package_source`: Ninja does it by itself, the -Makefile generators do not. +After a change of `VERSION.txt`, `package_source` configures the build +directory again first, whatever the generator: Ninja does before it runs CPack, +and CPack does when `VERSION.txt` holds another version than the build +directory was configured for (`cmake/gaol_package_source.cmake`, GAOL v5), +where the Makefile generators ran CPack at once. The packages hold `libgaol` as the build compiled it: with `GAOL_FMA` `ON`, the default, only the processors that have the fused multiply-add diff --git a/doc/continuous-integration.md b/doc/continuous-integration.md index 2f955a5d..f622cacb 100644 --- a/doc/continuous-integration.md +++ b/doc/continuous-integration.md @@ -18,7 +18,9 @@ request (GAOL v5); `workflow_dispatch` runs them on any branch. The badges of with the compilers of Ubuntu 22.04 (GCC 11 and Clang 14 on x86_64, GCC 11 on arm64), whose images GitHub retires by April 2027, with GCC 9, which has no `__builtin_roundeven()` (see [3rd/README.md](../3rd/README.md)), and as a - shared library (`BUILD_SHARED_LIBS`). + shared library (`BUILD_SHARED_LIBS`); the test `cpack_stale_configure` also + runs with `CC="ccache gcc"` and a Ninja outside `PATH`, which it has to pass + on to the copies of the tree it configures. - **Linux containers:** - Debian 12 and 13 on amd64, arm64 and armhf, and Debian 12 on i386; - manylinux_2_28 on x86_64 and aarch64; diff --git a/doc/tests.md b/doc/tests.md index b30935a5..392c1ba6 100644 --- a/doc/tests.md +++ b/doc/tests.md @@ -700,19 +700,38 @@ mode there. itself, where the tree has a `configure`): a script, not a program (`tests/cpack_stale_configure.cmake`). CPack puts `configure` in the archive of the sources as it is committed, and `configure --version` gives the version - it was generated for: after a change of `VERSION.txt` without a new - generation of `configure`, the archive of the new version holds a - `configure` that says the old one. The script configures copies of the tree - with the compiler that built GAOL, and CMake has to warn of it, naming the - two versions, whether `configure` has the line ends of Unix or of Windows, - and not otherwise: not when `configure` was generated for the version - `VERSION.txt` holds, not when it has no line `PACKAGE_VERSION=`, and not - when there is no `configure`, which CMake has to configure all the same. The - version `configure` was generated for is asked of `configure --version`, not - read as `CMakeLists.txt` reads it. The copies are made of symbolic links to - the files of the tree, but for `CMakeLists.txt`, `VERSION.txt` and - `configure`, which are copied; the test takes a few seconds on an ordinary - machine, a configuration and four that reuse its checks (GAOL v5). + it was generated for: after a change of `VERSION.txt` without a new generation + of `configure`, the archive of the new version holds a `configure` that says + the old one. The script configures copies of the tree with the generator and + the compilers that built GAOL, and CMake has to warn of it, naming the two + versions, whether `configure` has the line ends of Unix or of Windows, and not + otherwise: not when `configure` was generated for the version `VERSION.txt` + holds, not when it has no line `PACKAGE_VERSION=`, and not when there is no + `configure`, which CMake has to configure all the same. Then a copy configured + for the version `configure` was generated for has its `VERSION.txt` changed, + and CPack, run as `package_source` runs it, has to configure it again, warn, + and name the archive after the new version + (`cmake/gaol_package_source.cmake`), which the Makefile generators did not do, + CMake giving no warning of its own meanwhile (CMake 3 warned of the + backslashes of `CPACK_SOURCE_IGNORE_FILES` in the configuration it writes for + CPack); the archive has to hold `keep.halo`, a file of the copy that these + regular expressions do not match, but would without their backslashes, as + CMake 4 read them without `CPACK_VERBATIM_VARIABLES`. The version `configure` + was generated for is asked of `configure --version`, not read as + `CMakeLists.txt` reads it. The copies are made of symbolic links to the files + of the tree, but for `CMakeLists.txt`, `VERSION.txt` and `configure`, which + are copied. The compilers are given to CMake as `CC` and `CXX` with their + arguments (`CC="ccache gcc"` leaves `ccache` in `CMAKE_C_COMPILER` and `gcc` + in `CMAKE_C_COMPILER_ARG1`), and the generator with its program + (`CMAKE_MAKE_PROGRAM`, for a Ninja outside `PATH`), which a job of + `.github/workflows/linux.yml` checks; without `sh`, or where the system makes + no symbolic link, the test says it is skipped. It takes a few seconds on an + ordinary machine, a configuration and five that reuse its checks, and an + archive: of the links themselves with CMake 3.28 and after (170 KB), of the + files of the directories they point to with CMake 3.14 and 3.16 (5.6 MB). Only + the CMake build has it: CPack makes the archive, and the autotools jobs of the + continuous integration compare `configure --version` with `VERSION.txt` + already (GAOL v5). - **The unit tests of GAOL 4:** `arithmetic_operators` (`check/arithmetic.cpp`), `assignment`, `constants`, `constructor`, `float_functions`, `generic_functions`, `input_output`, `interval_functions`, `misc`, diff --git a/manual/v5/gaol.tex b/manual/v5/gaol.tex index 7e00feb0..0a2530fa 100644 --- a/manual/v5/gaol.tex +++ b/manual/v5/gaol.tex @@ -532,7 +532,8 @@ \subsection{The archive of the sources and the packages}\label{sec:packages} from a clean checkout, and holds \file{configure} as it was generated. CMake warns, when it configures, if that was for another version than \file{VERSION.txt} holds: \cmd{configure --version} would give the old one - in the archive; + in the archive. After a change of \file{VERSION.txt}, \code{package\_source} + configures the build directory again first, whatever the generator; \item \code{package} gives \file{gaol-\var{version}-\var{system}.tar.gz}, what \cmd{cmake --install} installs, to extract anywhere, and on Linux \file{libgaol-dev\_\var{version}\_\var{arch}.deb}, the same files in diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 626466c5..464a9430 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -161,21 +161,32 @@ endif() # The warning of the CPack block of CMakeLists.txt, when the configure that the # archive of the sources holds was generated for another version than VERSION.txt # holds (GAOL v5): not a program, a script that configures copies of the tree -# with the compiler that built GAOL (cpack_stale_configure.cmake). Only the CMake -# build makes the archive; the copies are made of symbolic links, so the script -# runs on the machine that builds, where the system has them, and it asks the -# configure of the tree its version, so there has to be one. The time limit is -# that of a few configurations, on a slow machine. +# with the compilers that built GAOL, and makes the archive after a change of +# VERSION.txt (cpack_stale_configure.cmake). Only the CMake build makes the +# archive; the copies are made of symbolic links, so the script runs on the +# machine that builds, and it asks the configure of the tree its version, so +# there has to be one. The compilers are passed with their arguments, which +# CMake keeps apart: with CC="ccache gcc", CMAKE_C_COMPILER is ccache and +# CMAKE_C_COMPILER_ARG1 gcc. Without sh, or on a system that makes no symbolic +# link, the script says it is skipped, which CTest reads from CMake 3.16 (the +# test passes before). The time limit is that of a few configurations, on a +# slow machine. if(CMAKE_HOST_UNIX AND NOT CMAKE_CROSSCOMPILING AND EXISTS "${PROJECT_SOURCE_DIR}/configure") + foreach(_lang C CXX) + string(STRIP "${CMAKE_${_lang}_COMPILER_ARG1}" _gaol_arguments) + string(STRIP "${CMAKE_${_lang}_COMPILER} ${_gaol_arguments}" _gaol_${_lang}_compiler) + endforeach() add_test(NAME cpack_stale_configure COMMAND "${CMAKE_COMMAND}" "-DGAOL_SOURCE_DIR=${PROJECT_SOURCE_DIR}" "-DGAOL_WORK_DIR=${CMAKE_CURRENT_BINARY_DIR}/cpack_stale_configure" "-DGAOL_GENERATOR=${CMAKE_GENERATOR}" - "-DGAOL_C_COMPILER=${CMAKE_C_COMPILER}" - "-DGAOL_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-DGAOL_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}" + "-DGAOL_C_COMPILER=${_gaol_C_compiler}" + "-DGAOL_CXX_COMPILER=${_gaol_CXX_compiler}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cpack_stale_configure.cmake") - set_tests_properties(cpack_stale_configure PROPERTIES LABELS unit TIMEOUT 600) + set_tests_properties(cpack_stale_configure PROPERTIES LABELS unit TIMEOUT 600 + SKIP_REGULAR_EXPRESSION "cpack_stale_configure: skipped") endif() # Commented out: the tests run no thread (GAOL v5) diff --git a/tests/cpack_stale_configure.cmake b/tests/cpack_stale_configure.cmake index 8a3634eb..0b19f143 100644 --- a/tests/cpack_stale_configure.cmake +++ b/tests/cpack_stale_configure.cmake @@ -19,17 +19,33 @@ # - a configure without a line PACKAGE_VERSION=, and a tree without configure # (an archive of another kind): no warning, and CMake configures. # +# The archive takes its name from the version CMake read when it configured: +# the copy configured for the version configure was generated for, VERSION.txt +# then holds the next one, and CPack has to configure the build directory +# again before it makes the archive (cmake/gaol_package_source.cmake), warn, +# and name the archive after the new version, CMake giving no warning of its +# own in the files CPack reads. CPack runs as the target +# package_source runs it, in the build directory, whatever the generator: +# Ninja configured again before package_source, the Makefile generators did +# not. +# # A copy is made of symbolic links to the files and directories of the tree, # but for CMakeLists.txt, VERSION.txt and configure, which are copies: CMake # reads them from the copy, and the script never writes through a link, into # the tree. The version the committed configure was generated for is asked of # configure itself (configure --version, as a user of the archive sees it), not -# read as CMakeLists.txt reads it, so that the two do not share a mistake. +# read as CMakeLists.txt reads it, so that the two do not share a mistake. The +# copy is configured with the generator, its program and the compilers that +# built GAOL, the compilers given to CMake as CC and CXX, the way CMake reads +# them with their arguments (CC="ccache gcc"). Without sh, or where the system +# makes no symbolic link, the script says that it is skipped +# (SKIP_REGULAR_EXPRESSION of tests/CMakeLists.txt) rather than failing. # # ctest runs it (tests/CMakeLists.txt), and by hand: # # cmake -DGAOL_SOURCE_DIR= -DGAOL_WORK_DIR=/cpack_stale_configure \ -# -DGAOL_GENERATOR= -DGAOL_C_COMPILER= -DGAOL_CXX_COMPILER= \ +# -DGAOL_GENERATOR= [-DGAOL_MAKE_PROGRAM=] \ +# "-DGAOL_C_COMPILER=" "-DGAOL_CXX_COMPILER=" \ # -P tests/cpack_stale_configure.cmake # # Copyright (c) 2026 ENSTA, France @@ -43,14 +59,44 @@ foreach(_name GAOL_SOURCE_DIR GAOL_WORK_DIR GAOL_GENERATOR GAOL_C_COMPILER GAOL_ message(FATAL_ERROR "${_name} is not given (see the head of this file)") endif() endforeach() -# The script removes what it made in this directory, and nothing else +# The script removes the whole of this directory, when it starts, and when it +# passes or is skipped (a failure leaves it to be looked at): it has to be the +# directory of this test if(NOT GAOL_WORK_DIR MATCHES "/cpack_stale_configure$") message(FATAL_ERROR "GAOL_WORK_DIR, ${GAOL_WORK_DIR}, is not a directory of this test (cpack_stale_configure)") endif() -# The version configure was generated for, and the next one +set(_tree "${GAOL_WORK_DIR}/tree") +set(_build "${GAOL_WORK_DIR}/build") + +# Removes the directory, the links of the copy one by one first. file(REMOVE) +# and file(REMOVE_RECURSE) remove a symbolic link, not what it points to, +# which holds also for the links CPack copies into the build directory: nothing +# is ever removed through them +macro(remove_work_dir) + file(GLOB _links "${_tree}/*") + foreach(_path ${_links}) + file(REMOVE "${_path}") + endforeach() + file(REMOVE_RECURSE "${GAOL_WORK_DIR}") +endmacro() + +# Ends the script, which passes, saying why it is skipped: ctest reads the +# message (SKIP_REGULAR_EXPRESSION) +macro(skip why) + remove_work_dir() + message(STATUS "cpack_stale_configure: skipped, ${why}") + return() +endmacro() + +# The version configure was generated for, and the next one. Without sh, the +# status is the message of a command that could not start execute_process(COMMAND sh "${GAOL_SOURCE_DIR}/configure" --version OUTPUT_VARIABLE _output RESULT_VARIABLE _status) +string(TOLOWER "${_status}" _lower) +if(_lower MATCHES "no such file") + skip("sh did not run configure --version (${_status})") +endif() if(NOT _status EQUAL 0 OR NOT _output MATCHES "^gaol configure ([0-9]+)\\.([0-9]+)\\.([0-9]+)\n") message(FATAL_ERROR "configure --version, which tells the version configure was generated for, gave (status ${_status}):\n${_output}") endif() @@ -61,18 +107,16 @@ math(EXPR _next_micro "${_micro} + 1") set(_old "${_major}.${_minor}.${_micro}") set(_new "${_major}.${_minor}.${_next_micro}") -set(_tree "${GAOL_WORK_DIR}/tree") -set(_build "${GAOL_WORK_DIR}/build") - -# What a run left is removed with its links one by one, so that nothing is -# ever removed through them -file(GLOB _left "${_tree}/*") -foreach(_path ${_left}) - file(REMOVE "${_path}") -endforeach() -file(REMOVE_RECURSE "${GAOL_WORK_DIR}") +# What a run left +remove_work_dir() file(MAKE_DIRECTORY "${_tree}") +# Whether the system makes symbolic links here, which a file system may not +file(CREATE_LINK "${GAOL_SOURCE_DIR}/VERSION.txt" "${GAOL_WORK_DIR}/probe" RESULT _result SYMBOLIC) +if(NOT _result STREQUAL "0") + skip("the system made no symbolic link in ${GAOL_WORK_DIR}: ${_result}") +endif() +file(REMOVE "${GAOL_WORK_DIR}/probe") file(GLOB _entries RELATIVE "${GAOL_SOURCE_DIR}" "${GAOL_SOURCE_DIR}/*") foreach(_entry ${_entries}) # The three files to copy, and the hidden ones (.git...), which no @@ -92,16 +136,32 @@ foreach(_entry ${_entries}) endif() endforeach() file(COPY "${GAOL_SOURCE_DIR}/CMakeLists.txt" DESTINATION "${_tree}") +# A file the regular expressions of CPACK_SOURCE_IGNORE_FILES do not match, +# which the archive has to hold: \.lo$ read without its backslash, as CMake 4 +# read it without CPACK_VERBATIM_VARIABLES, matches it +file(WRITE "${_tree}/keep.halo" "Not ignored by CPack\n") + +# The program of the generator, which CMake looks for in PATH otherwise: Ninja +# can be elsewhere +set(_make_program) +if(NOT "${GAOL_MAKE_PROGRAM}" STREQUAL "") + set(_make_program "-DCMAKE_MAKE_PROGRAM=${GAOL_MAKE_PROGRAM}") +endif() + +# Writes in the VERSION.txt of the copy +function(write_version version) + file(REMOVE "${_tree}/VERSION.txt") + file(WRITE "${_tree}/VERSION.txt" "${version}\n") +endfunction() # Configures the copy as it is, in the same directory of build each time (the -# checks of the compiler are cached), with the compiler that built GAOL, and +# checks of the compiler are cached), with the compilers that built GAOL, and # checks its warning: is WARNS, with the versions it names, or SILENT function(check_configure title version expected) - file(REMOVE "${_tree}/VERSION.txt") - file(WRITE "${_tree}/VERSION.txt" "${version}\n") + write_version("${version}") execute_process( - COMMAND "${CMAKE_COMMAND}" -S "${_tree}" -B "${_build}" -G "${GAOL_GENERATOR}" - "-DCMAKE_C_COMPILER=${GAOL_C_COMPILER}" "-DCMAKE_CXX_COMPILER=${GAOL_CXX_COMPILER}" + COMMAND "${CMAKE_COMMAND}" -E env "CC=${GAOL_C_COMPILER}" "CXX=${GAOL_CXX_COMPILER}" + "${CMAKE_COMMAND}" -S "${_tree}" -B "${_build}" -G "${GAOL_GENERATOR}" ${_make_program} RESULT_VARIABLE _status OUTPUT_VARIABLE _output ERROR_VARIABLE _error) if(NOT _status EQUAL 0) message(FATAL_ERROR "${title}: CMake did not configure the copy (status ${_status}):\n${_output}\n${_error}") @@ -129,6 +189,39 @@ file(COPY "${GAOL_SOURCE_DIR}/configure" DESTINATION "${_tree}") check_configure("VERSION.txt ${_new}, configure generated for ${_old}" "${_new}" WARNS) check_configure("VERSION.txt ${_old}, configure generated for ${_old}" "${_old}" SILENT) +# The archive of the sources after a change of VERSION.txt, the build directory +# being configured for the version configure was generated for +write_version("${_new}") +execute_process(COMMAND "${CMAKE_CPACK_COMMAND}" --config CPackSourceConfig.cmake + WORKING_DIRECTORY "${_build}" RESULT_VARIABLE _status OUTPUT_VARIABLE _output ERROR_VARIABLE _error) +set(_title "VERSION.txt ${_new} after a configuration for ${_old}, package_source") +if(NOT _status EQUAL 0) + message(FATAL_ERROR "${_title}: CPack did not make the archive (status ${_status}):\n${_output}\n${_error}") +endif() +# Without a warning of CMake for the files CPack reads: those of GAOL, which it +# reads without the policies of CMakeLists.txt, and the configuration CMake +# writes for it (an invalid escape sequence with CMake 3, CMP0010) +if("${_output}\n${_error}" MATCHES "CMake Warning \\(dev\\)") + message(FATAL_ERROR "${_title}: CMake warned in a file CPack reads:\n${_output}\n${_error}") +endif() +string(REGEX REPLACE "[ \t\r\n]+" " " _text "${_output} ${_error}") +string(FIND "${_text}" "configure was generated for GAOL ${_old}, and VERSION.txt holds ${_new}:" _found) +if(_found EQUAL -1 OR NOT EXISTS "${_build}/gaol-${_new}.tar.gz" OR EXISTS "${_build}/gaol-${_old}.tar.gz") + file(GLOB _archives RELATIVE "${_build}" "${_build}/*.tar.gz") + message(FATAL_ERROR "${_title}: CPack did not configure again, warn and make gaol-${_new}.tar.gz " + "(archives made: ${_archives}):\n${_output}\n${_error}") +endif() +execute_process(COMMAND "${CMAKE_COMMAND}" -E tar tzf "gaol-${_new}.tar.gz" + WORKING_DIRECTORY "${_build}" OUTPUT_VARIABLE _list) +if(NOT _list MATCHES "(^|\n)gaol-${_new}/VERSION\\.txt\n") + message(FATAL_ERROR "${_title}: gaol-${_new}.tar.gz holds no gaol-${_new}/VERSION.txt") +endif() +if(NOT _list MATCHES "(^|\n)gaol-${_new}/keep\\.halo\n") + message(FATAL_ERROR "${_title}: gaol-${_new}.tar.gz holds no gaol-${_new}/keep.halo, which " + "CPACK_SOURCE_IGNORE_FILES does not match (were its backslashes lost?)") +endif() +message(STATUS "${_title}: WARNS and gaol-${_new}.tar.gz, as expected") + # The same, with the line ends of Windows file(READ "${GAOL_SOURCE_DIR}/configure" _script) string(REPLACE "\n" "\r\n" _script "${_script}") @@ -143,8 +236,4 @@ check_configure("VERSION.txt ${_new}, configure without PACKAGE_VERSION=" "${_ne file(REMOVE "${_tree}/configure") check_configure("VERSION.txt ${_new}, no configure" "${_new}" SILENT) -file(GLOB _made "${_tree}/*") -foreach(_path ${_made}) - file(REMOVE "${_path}") -endforeach() -file(REMOVE_RECURSE "${GAOL_WORK_DIR}") +remove_work_dir()