diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-05-24 17:57:40 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-05-24 17:57:40 (GMT) |
commit | bf75369ed40f0adfe687396573b804ae6209161d (patch) | |
tree | d0641606013b83fcf56438b7d5fe44bd6c8ca4f7 | |
parent | 38f2562d5b159cdf7ce4340911c1adb30b3a003e (diff) | |
parent | c3b9d9b756c84961208ad3086f5f123828fc5400 (diff) | |
download | CMake-bf75369ed40f0adfe687396573b804ae6209161d.zip CMake-bf75369ed40f0adfe687396573b804ae6209161d.tar.gz CMake-bf75369ed40f0adfe687396573b804ae6209161d.tar.bz2 |
Merge branch 'master' into cmp0082-exclude-from-all
1081 files changed, 17012 insertions, 5333 deletions
diff --git a/.clang-tidy b/.clang-tidy index 5e513fb..dda86b0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -19,6 +19,7 @@ modernize-*,\ performance-*,\ readability-*,\ -readability-convert-member-functions-to-static,\ +-readability-function-cognitive-complexity,\ -readability-function-size,\ -readability-identifier-naming,\ -readability-implicit-bool-conversion,\ diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 0000000..ba0fba6 --- /dev/null +++ b/.codespellrc @@ -0,0 +1,9 @@ +[codespell] +check-filenames = +check-hidden = +count = +# Disable warnings about binary files +quiet-level = 2 +builtin = clear,rare,en-GB_to_en-US +skip = */.git,*/build,*/Copyright.txt,*/doxygen.config,*/Modules/Internal/CPack/NSIS.template.in,*/Source/CursesDialog/form/*,*/Source/kwsys/*,*/Tests/RunCMake/CPack/tests/DMG_SLA/German.*,*/Utilities/cm* +ignore-words-list = aci,ake,ans,ba,cconfiguration,conly,dependees,dne,dum,earch,ect,filetest,fo,helpfull,hiden,isnt,keypair,nd,ned,nin,nknown,ot,pard,seh,ser,te,upto,varn,vas,wee diff --git a/.gitattributes b/.gitattributes index fac38df..79a0f04 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ .git* export-ignore .hooks* export-ignore +.codespellrc export-ignore .editorconfig export-ignore # Custom attribute to mark sources as using our C code style. @@ -9,6 +9,13 @@ CMakeUserPresets.json # Visual Studio work directory .vs/ +# Visual Studio build directory +out/ # Visual Studio Code .vscode/ + +# CLion work directory +.idea/ +# CLion build directories +cmake-build-*/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d0b3b1e..aac1d9c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,15 +46,15 @@ prep:source-package: prep:doc-package: extends: - - .fedora33_sphinx_package + - .fedora34_sphinx_package - .cmake_prep_doc_linux - .linux_builder_tags_qt - .cmake_doc_artifacts - .run_only_for_package -.upload:source-package: +upload:source-package: extends: - - .rsync_upload + - .rsync_upload_binary - .run_only_for_package dependencies: - prep:source-package @@ -63,25 +63,65 @@ prep:doc-package: variables: RSYNC_DESTINATION: dev +# Documentation builds + +build:help:master: + extends: + - .cmake_org_help + - .run_only_for_continuous_master + +upload:help:master: + extends: + - .rsync_upload_help + - .run_only_for_continuous_master + variables: + RSYNC_DESTINATION: git-master + dependencies: + - build:help:master + needs: + - build:help:master + +build:help:stage: + extends: + - .cmake_org_help + - .run_only_for_continuous_stage + +upload:help:stage: + extends: + - .rsync_upload_help + - .run_only_for_continuous_stage + variables: + RSYNC_DESTINATION: git-stage + dependencies: + - build:help:stage + needs: + - build:help:stage + # Lint builds -build:debian10-iwyu: +lint:codespell: + extends: + - .cmake_codespell_linux + - .linux_builder_tags + - .run_automatically + +lint:debian10-iwyu: extends: - .debian10_iwyu - .cmake_build_linux - .linux_builder_tags - .run_automatically -build:fedora33-tidy: +lint:fedora34-tidy: extends: - - .fedora33_tidy + - .fedora34_tidy - .cmake_build_linux - .linux_builder_tags_qt - .run_automatically -build:fedora33-sphinx: +lint:fedora34-sphinx: extends: - - .fedora33_sphinx + - .fedora34_sphinx - .cmake_build_linux - .linux_builder_tags_qt - .run_automatically @@ -115,10 +155,7 @@ test:debian10-ninja: - .cmake_test_linux_release - .linux_builder_tags_qt - .run_dependent - dependencies: - - build:centos6-x86_64 - needs: - - build:centos6-x86_64 + - .needs_centos6_x86_64 test:debian10-aarch64-ninja: extends: @@ -126,23 +163,17 @@ test:debian10-aarch64-ninja: - .cmake_test_linux_release - .linux_builder_tags_aarch64_qt - .run_dependent - dependencies: - - build:centos7-aarch64 - needs: - - build:centos7-aarch64 + - .needs_centos7_aarch64 variables: CMAKE_CI_NO_MR: "true" -test:fedora33-makefiles: +test:fedora34-makefiles: extends: - - .fedora33_makefiles + - .fedora34_makefiles - .cmake_test_linux_release - .linux_builder_tags_qt - .run_dependent - dependencies: - - build:centos6-x86_64 - needs: - - build:centos6-x86_64 + - .needs_centos6_x86_64 test:cuda10.2-nvidia: extends: @@ -150,41 +181,255 @@ test:cuda10.2-nvidia: - .cmake_test_linux_release - .linux_builder_tags_cuda - .run_dependent - dependencies: - - build:centos6-x86_64 - needs: - - build:centos6-x86_64 + - .needs_centos6_x86_64 -build:fedora33-ninja: +build:fedora34-ninja: extends: - - .fedora33_ninja + - .fedora34_ninja - .cmake_build_linux - .cmake_build_artifacts - .linux_builder_tags_qt - .run_manually -test:fedora33-ninja: +test:fedora34-ninja: extends: - - .fedora33_ninja + - .fedora34_ninja - .cmake_test_linux - .linux_builder_tags_x11 - .cmake_test_artifacts - .run_dependent dependencies: - - build:fedora33-ninja + - build:fedora34-ninja needs: - - build:fedora33-ninja + - build:fedora34-ninja -test:fedora33-ninja-multi: +test:fedora34-ninja-multi: extends: - - .fedora33_ninja_multi + - .fedora34_ninja_multi - .cmake_test_linux_external - .linux_builder_tags_qt - .run_dependent dependencies: - - test:fedora33-ninja + - test:fedora34-ninja needs: - - test:fedora33-ninja + - test:fedora34-ninja + +test:intel2016-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2016_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2016-el7 + +test:intel2016u1-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2016u1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2016u1-el7 + +test:intel2016u2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2016u2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2016u2-el7 + +test:intel2017-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017-el7 + +test:intel2017u1-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u1-el7 + +test:intel2017u2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u2-el7 + +test:intel2017u3-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u3_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u3-el7 + +test:intel2017u4-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u4_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u4-el7 + +test:intel2017u5-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u5_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u5-el7 + +test:intel2017u6-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u6_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u6-el7 + +test:intel2017u7-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u7_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u7-el7 + +test:intel2017u8-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2017u8_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2017u8-el7 + +test:intel2018-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2018_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2018-el7 + +test:intel2018u1-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2018u1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2018u1-el7 + +test:intel2018u2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2018u2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2018u2-el7 + +test:intel2018u3-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2018u3_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2018u3-el7 + +test:intel2018u4-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2018u4_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2018u4-el7 + +test:intel2019-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2019_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2019-el7 + +test:intel2019u1-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2019u1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2019u1-el7 + +test:intel2019u2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2019u2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2019u2-el7 + +test:intel2019u3-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2019u3_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2019u3-el7 + +test:intel2019u4-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2019u4_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2019u4-el7 + +test:intel2020-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2020_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2020-el8 + +test:intel2020u2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2020u2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2020u2-el8 + +test:intel2020u4-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2020u4_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2020u4-el8 + +test:intel2021.1.1-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2021.1.1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.1-el8 + +test:intel2021.1.2-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2021.1.2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.2-el8 + +test:intel2021.2.0-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2021.2.0_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.2.0-el8 + +test:oneapi2021.1.1-makefiles: + extends: + - .cmake_test_linux_inteloneapi_makefiles + variables: + CMAKE_CI_BUILD_NAME: oneapi2021.1.1_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.1-el8 + +test:oneapi2021.1.2-makefiles: + extends: + - .cmake_test_linux_inteloneapi_makefiles + variables: + CMAKE_CI_BUILD_NAME: oneapi2021.1.2_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.2-el8 + +test:oneapi2021.2.0-makefiles: + extends: + - .cmake_test_linux_inteloneapi_makefiles + variables: + CMAKE_CI_BUILD_NAME: oneapi2021.2.0_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.2.0-el8 build:linux-x86_64-package: extends: @@ -199,9 +444,9 @@ build:linux-x86_64-package: needs: - prep:doc-package -.upload:linux-x86_64-package: +upload:linux-x86_64-package: extends: - - .rsync_upload + - .rsync_upload_binary - .run_only_for_package dependencies: - build:linux-x86_64-package @@ -223,9 +468,9 @@ build:linux-aarch64-package: needs: - prep:doc-package -.upload:linux-aarch64-package: +upload:linux-aarch64-package: extends: - - .rsync_upload + - .rsync_upload_binary - .run_only_for_package dependencies: - build:linux-aarch64-package @@ -335,9 +580,9 @@ build:macos-package: needs: - prep:doc-package -.upload:macos-package: +upload:macos-package: extends: - - .rsync_upload + - .rsync_upload_binary - .run_only_for_package dependencies: - build:macos-package @@ -358,9 +603,9 @@ build:macos10.10-package: needs: - prep:doc-package -.upload:macos10.10-package: +upload:macos10.10-package: extends: - - .rsync_upload + - .rsync_upload_binary - .run_only_for_package dependencies: - build:macos10.10-package diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml index bf8e8b6..edd313f 100644 --- a/.gitlab/artifacts.yml +++ b/.gitlab/artifacts.yml @@ -97,3 +97,12 @@ paths: # Take the install tree. - build/install-doc/ + +.cmake_org_help_artifacts: + artifacts: + expire_in: 1d + paths: + - build/html + exclude: + - build/html/.buildinfo + - build/html/objects.inv diff --git a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake index 023cc9e..4d8dde6 100644 --- a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake +++ b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake @@ -1,10 +1,12 @@ set(CMake_TEST_FindALSA "ON" CACHE BOOL "") -set(CMake_TEST_FindBLAS "ON" CACHE BOOL "") +set(CMake_TEST_FindBLAS "All" CACHE STRING "") +set(CMake_TEST_FindBLAS_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindBoost "ON" CACHE BOOL "") set(CMake_TEST_FindBoost_Python "ON" CACHE BOOL "") set(CMake_TEST_FindBZip2 "ON" CACHE BOOL "") set(CMake_TEST_FindCups "ON" CACHE BOOL "") set(CMake_TEST_FindCURL "ON" CACHE BOOL "") +set(CMake_TEST_FindDevIL "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen_Dot "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen "ON" CACHE BOOL "") set(CMake_TEST_FindEXPAT "ON" CACHE BOOL "") @@ -22,7 +24,8 @@ set(CMake_TEST_FindIconv "ON" CACHE BOOL "") set(CMake_TEST_FindIntl "ON" CACHE BOOL "") set(CMake_TEST_FindJPEG "ON" CACHE BOOL "") set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "") -set(CMake_TEST_FindLAPACK "ON" CACHE BOOL "") +set(CMake_TEST_FindLAPACK "All" CACHE STRING "") +set(CMake_TEST_FindLAPACK_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindLibArchive "ON" CACHE BOOL "") set(CMake_TEST_FindLibinput "ON" CACHE BOOL "") set(CMake_TEST_FindLibLZMA "ON" CACHE BOOL "") @@ -45,6 +48,7 @@ set(CMake_TEST_FindPatch "ON" CACHE BOOL "") set(CMake_TEST_FindPNG "ON" CACHE BOOL "") set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "") set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "") +set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "") set(CMake_TEST_FindPython "ON" CACHE BOOL "") set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "") set(CMake_TEST_FindPython_PyPy "ON" CACHE BOOL "") diff --git a/.gitlab/ci/configure_debian10_ninja.cmake b/.gitlab/ci/configure_debian10_ninja.cmake index 74d9f12..732624a 100644 --- a/.gitlab/ci/configure_debian10_ninja.cmake +++ b/.gitlab/ci/configure_debian10_ninja.cmake @@ -1,10 +1,12 @@ set(CMake_TEST_FindALSA "ON" CACHE BOOL "") -set(CMake_TEST_FindBLAS "ON" CACHE BOOL "") +set(CMake_TEST_FindBLAS "All" CACHE STRING "") +set(CMake_TEST_FindBLAS_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindBoost "ON" CACHE BOOL "") set(CMake_TEST_FindBoost_Python "ON" CACHE BOOL "") set(CMake_TEST_FindBZip2 "ON" CACHE BOOL "") set(CMake_TEST_FindCups "ON" CACHE BOOL "") set(CMake_TEST_FindCURL "ON" CACHE BOOL "") +set(CMake_TEST_FindDevIL "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen_Dot "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen "ON" CACHE BOOL "") set(CMake_TEST_FindEXPAT "ON" CACHE BOOL "") @@ -22,7 +24,8 @@ set(CMake_TEST_FindIconv "ON" CACHE BOOL "") set(CMake_TEST_FindIntl "ON" CACHE BOOL "") set(CMake_TEST_FindJPEG "ON" CACHE BOOL "") set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "") -set(CMake_TEST_FindLAPACK "ON" CACHE BOOL "") +set(CMake_TEST_FindLAPACK "All" CACHE STRING "") +set(CMake_TEST_FindLAPACK_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindLibArchive "ON" CACHE BOOL "") set(CMake_TEST_FindLibinput "ON" CACHE BOOL "") set(CMake_TEST_FindLibLZMA "ON" CACHE BOOL "") @@ -45,6 +48,7 @@ set(CMake_TEST_FindPatch "ON" CACHE BOOL "") set(CMake_TEST_FindPNG "ON" CACHE BOOL "") set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "") set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "") +set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "") set(CMake_TEST_FindPython "ON" CACHE BOOL "") set(CMake_TEST_FindPython_IronPython "ON" CACHE BOOL "") set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "") diff --git a/.gitlab/ci/configure_fedora33_tidy.cmake b/.gitlab/ci/configure_fedora33_tidy.cmake deleted file mode 100644 index 9052fdc..0000000 --- a/.gitlab/ci/configure_fedora33_tidy.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "") - -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora33_common.cmake") diff --git a/.gitlab/ci/configure_fedora33_common.cmake b/.gitlab/ci/configure_fedora34_common.cmake index dee78ab..4484e26 100644 --- a/.gitlab/ci/configure_fedora33_common.cmake +++ b/.gitlab/ci/configure_fedora34_common.cmake @@ -1,5 +1,6 @@ set(BUILD_CursesDialog ON CACHE BOOL "") set(BUILD_QtDialog ON CACHE BOOL "") +set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "") set(CMake_TEST_JQ "/usr/bin/jq" CACHE PATH "") set(CMake_TEST_JSON_SCHEMA ON CACHE BOOL "") diff --git a/.gitlab/ci/configure_fedora33_makefiles.cmake b/.gitlab/ci/configure_fedora34_makefiles.cmake index db2d005..48786e4 100644 --- a/.gitlab/ci/configure_fedora33_makefiles.cmake +++ b/.gitlab/ci/configure_fedora34_makefiles.cmake @@ -1,10 +1,12 @@ set(CMake_TEST_FindALSA "ON" CACHE BOOL "") -set(CMake_TEST_FindBLAS "ON" CACHE BOOL "") +set(CMake_TEST_FindBLAS "All" CACHE STRING "") +set(CMake_TEST_FindBLAS_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindBoost "ON" CACHE BOOL "") set(CMake_TEST_FindBoost_Python "ON" CACHE BOOL "") set(CMake_TEST_FindBZip2 "ON" CACHE BOOL "") set(CMake_TEST_FindCups "ON" CACHE BOOL "") set(CMake_TEST_FindCURL "ON" CACHE BOOL "") +set(CMake_TEST_FindDevIL "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen_Dot "ON" CACHE BOOL "") set(CMake_TEST_FindDoxygen "ON" CACHE BOOL "") set(CMake_TEST_FindEXPAT "ON" CACHE BOOL "") @@ -22,7 +24,8 @@ set(CMake_TEST_FindIconv "ON" CACHE BOOL "") set(CMake_TEST_FindIntl "ON" CACHE BOOL "") set(CMake_TEST_FindJPEG "ON" CACHE BOOL "") set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "") -set(CMake_TEST_FindLAPACK "ON" CACHE BOOL "") +set(CMake_TEST_FindLAPACK "All" CACHE STRING "") +set(CMake_TEST_FindLAPACK_STATIC "Generic" CACHE STRING "") set(CMake_TEST_FindLibArchive "ON" CACHE BOOL "") set(CMake_TEST_FindLibinput "ON" CACHE BOOL "") set(CMake_TEST_FindLibLZMA "ON" CACHE BOOL "") @@ -45,6 +48,7 @@ set(CMake_TEST_FindPatch "ON" CACHE BOOL "") set(CMake_TEST_FindPNG "ON" CACHE BOOL "") set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "") set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "") +set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "") set(CMake_TEST_FindPython "ON" CACHE BOOL "") set(CMake_TEST_FindPython_NumPy "ON" CACHE BOOL "") set(CMake_TEST_FindPython_PyPy "ON" CACHE BOOL "") diff --git a/.gitlab/ci/configure_fedora33_ninja.cmake b/.gitlab/ci/configure_fedora34_ninja.cmake index 883f425..37bc189 100644 --- a/.gitlab/ci/configure_fedora33_ninja.cmake +++ b/.gitlab/ci/configure_fedora34_ninja.cmake @@ -4,4 +4,4 @@ set(CMake_TEST_GUI "ON" CACHE BOOL "") # Cover compilation with C++11 only and not higher standards. set(CMAKE_CXX_STANDARD "11" CACHE STRING "") -include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora33_common.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") diff --git a/.gitlab/ci/configure_fedora33_ninja_multi.cmake b/.gitlab/ci/configure_fedora34_ninja_multi.cmake index efb4b84..efb4b84 100644 --- a/.gitlab/ci/configure_fedora33_ninja_multi.cmake +++ b/.gitlab/ci/configure_fedora34_ninja_multi.cmake diff --git a/.gitlab/ci/configure_fedora33_sphinx.cmake b/.gitlab/ci/configure_fedora34_sphinx.cmake index 90d159b..90d159b 100644 --- a/.gitlab/ci/configure_fedora33_sphinx.cmake +++ b/.gitlab/ci/configure_fedora34_sphinx.cmake diff --git a/.gitlab/ci/configure_fedora33_sphinx_package.cmake b/.gitlab/ci/configure_fedora34_sphinx_package.cmake index e839de8..e839de8 100644 --- a/.gitlab/ci/configure_fedora33_sphinx_package.cmake +++ b/.gitlab/ci/configure_fedora34_sphinx_package.cmake diff --git a/.gitlab/ci/configure_fedora34_tidy.cmake b/.gitlab/ci/configure_fedora34_tidy.cmake new file mode 100644 index 0000000..9c79303 --- /dev/null +++ b/.gitlab/ci/configure_fedora34_tidy.cmake @@ -0,0 +1,3 @@ +set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake") diff --git a/.gitlab/ci/configure_intelclassic_makefiles.cmake b/.gitlab/ci/configure_intelclassic_makefiles.cmake new file mode 100644 index 0000000..469b825 --- /dev/null +++ b/.gitlab/ci/configure_intelclassic_makefiles.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/configure_intelcompiler_common.cmake") diff --git a/.gitlab/ci/configure_intelcompiler_common.cmake b/.gitlab/ci/configure_intelcompiler_common.cmake new file mode 100644 index 0000000..79f657b --- /dev/null +++ b/.gitlab/ci/configure_intelcompiler_common.cmake @@ -0,0 +1,6 @@ +set(CMake_TEST_FindBLAS "Intel10_64lp" CACHE STRING "") +set(CMake_TEST_FindBLAS_STATIC "Intel10_64lp" CACHE STRING "") +set(CMake_TEST_FindLAPACK "Intel10_64lp" CACHE STRING "") +set(CMake_TEST_FindLAPACK_STATIC "Intel10_64lp" CACHE STRING "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/configure_inteloneapi_makefiles.cmake b/.gitlab/ci/configure_inteloneapi_makefiles.cmake new file mode 100644 index 0000000..469b825 --- /dev/null +++ b/.gitlab/ci/configure_inteloneapi_makefiles.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/configure_intelcompiler_common.cmake") diff --git a/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake index 9c30a4b..e1ae81e 100644 --- a/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake +++ b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake @@ -1,4 +1,7 @@ set(CMake_TEST_WIX_NO_VERIFY "ON" CACHE BOOL "") set(CMake_TEST_GUI "ON" CACHE BOOL "") +set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "") +set(CMake_TEST_IPO_WORKS_C "ON" CACHE BOOL "") +set(CMake_TEST_IPO_WORKS_CXX "ON" CACHE BOOL "") include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_common.cmake") diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake index a68a693..b885a6a 100644 --- a/.gitlab/ci/ctest_exclusions.cmake +++ b/.gitlab/ci/ctest_exclusions.cmake @@ -13,15 +13,6 @@ if (CTEST_CMAKE_GENERATOR MATCHES "Visual Studio") "^ExternalProjectUpdateSetup$") endif () -if (CMAKE_HOST_WIN32) - list(APPEND test_exclusions - # This test often fails with an undiagnosed subtle race due to the test - # re-using the same objects for many files. Some copy operations fail - # to open their input with ERROR_SHARING_VIOLATION. - "^Module.ExternalData$" - ) -endif() - string(REPLACE ";" "|" test_exclusions "${test_exclusions}") if (test_exclusions) set(test_exclusions "(${test_exclusions})") diff --git a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh b/.gitlab/ci/docker/debian10-aarch64/install_deps.sh index d84b3c8..fea502e 100755 --- a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh +++ b/.gitlab/ci/docker/debian10-aarch64/install_deps.sh @@ -45,6 +45,7 @@ apt-get install -y \ libgif-dev \ libgl1-mesa-dev \ libglew-dev \ + libgrpc++-dev libgrpc-dev \ libgsl-dev \ libgtest-dev \ libgtk2.0-dev \ @@ -56,7 +57,7 @@ apt-get install -y \ libopenmpi-dev openmpi-bin \ libpng-dev \ libpq-dev postgresql-server-dev-11 \ - libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler \ + libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc \ libsdl-dev \ libsqlite3-dev \ libtiff-dev \ diff --git a/.gitlab/ci/docker/debian10/install_deps.sh b/.gitlab/ci/docker/debian10/install_deps.sh index e6c9ba0..4bb03bc 100755 --- a/.gitlab/ci/docker/debian10/install_deps.sh +++ b/.gitlab/ci/docker/debian10/install_deps.sh @@ -45,6 +45,7 @@ apt-get install -y \ libgif-dev \ libgl1-mesa-dev \ libglew-dev \ + libgrpc++-dev libgrpc-dev \ libgsl-dev \ libgtest-dev \ libgtk2.0-dev \ @@ -56,7 +57,7 @@ apt-get install -y \ libopenmpi-dev openmpi-bin \ libpng-dev \ libpq-dev postgresql-server-dev-11 \ - libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler \ + libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc \ libsdl-dev \ libsqlite3-dev \ libtiff-dev \ diff --git a/.gitlab/ci/docker/fedora33/Dockerfile b/.gitlab/ci/docker/fedora34/Dockerfile index 8ebcb9e..af2322d 100644 --- a/.gitlab/ci/docker/fedora33/Dockerfile +++ b/.gitlab/ci/docker/fedora34/Dockerfile @@ -1,10 +1,10 @@ -FROM fedora:33 as rvm-build +FROM fedora:34 as rvm-build MAINTAINER Ben Boeckel <ben.boeckel@kitware.com> COPY install_rvm.sh /root/install_rvm.sh RUN sh /root/install_rvm.sh -FROM fedora:33 +FROM fedora:34 MAINTAINER Ben Boeckel <ben.boeckel@kitware.com> COPY install_deps.sh /root/install_deps.sh diff --git a/.gitlab/ci/docker/fedora33/install_deps.sh b/.gitlab/ci/docker/fedora34/install_deps.sh index cdfe35e..dfd7db8 100755 --- a/.gitlab/ci/docker/fedora33/install_deps.sh +++ b/.gitlab/ci/docker/fedora34/install_deps.sh @@ -6,7 +6,8 @@ set -e dnf install --setopt=install_weak_deps=False -y \ ncurses-devel \ openssl-devel \ - qt5-qtbase-devel + qt5-qtbase-devel \ + qt6-qtbase-devel # Install development tools. dnf install --setopt=install_weak_deps=False -y \ @@ -19,7 +20,12 @@ dnf install --setopt=install_weak_deps=False -y \ dnf install --setopt=install_weak_deps=False -y \ python3-sphinx \ texinfo \ - qt5-qttools-devel + qt5-qttools-devel \ + qt6-qttools-devel + +# Install lint tools. +dnf install --setopt=install_weak_deps=False -y \ + codespell # Tools needed for the test suite. dnf install --setopt=install_weak_deps=False -y \ @@ -46,6 +52,7 @@ dnf install --setopt=install_weak_deps=False -y \ glew-devel \ gmock \ gnutls-devel \ + grpc-devel grpc-plugins \ gsl-devel \ gtest-devel \ gtk2-devel \ @@ -61,13 +68,14 @@ dnf install --setopt=install_weak_deps=False -y \ libuv-devel \ libxml2-devel \ libxslt-devel \ + mpich-devel \ openmpi-devel \ patch \ perl \ protobuf-devel protobuf-c-devel protobuf-lite-devel \ pypy2 pypy2-devel \ pypy3 pypy3-devel \ - python2 python2-devel python2-numpy \ + python2 python2-devel \ python3 python3-devel python3-numpy \ python3-jsmin python3-jsonschema \ ruby rubygems ruby-devel \ @@ -80,3 +88,9 @@ dnf install --setopt=install_weak_deps=False -y \ xz-devel dnf clean all + +# Fedora no longer packages python2 numpy. +curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py +python2 get-pip.py +rm get-pip.py +pip2.7 install numpy diff --git a/.gitlab/ci/docker/fedora33/install_ispc.sh b/.gitlab/ci/docker/fedora34/install_ispc.sh index fdc14b5..fdc14b5 100755 --- a/.gitlab/ci/docker/fedora33/install_ispc.sh +++ b/.gitlab/ci/docker/fedora34/install_ispc.sh diff --git a/.gitlab/ci/docker/fedora33/install_rvm.sh b/.gitlab/ci/docker/fedora34/install_rvm.sh index 6d4fa97..6d4fa97 100755 --- a/.gitlab/ci/docker/fedora33/install_rvm.sh +++ b/.gitlab/ci/docker/fedora34/install_rvm.sh diff --git a/.gitlab/ci/env.sh b/.gitlab/ci/env.sh new file mode 100644 index 0000000..7634f5d --- /dev/null +++ b/.gitlab/ci/env.sh @@ -0,0 +1,14 @@ +quietly() { + readonly log="/tmp/quietly-$RANDOM.log" + if ! "$@" >"$log" 2>&1; then + ret=$? + cat "$log" + rm -f "$log" + exit $ret + fi + rm -f "$log" +} + +if test -r ".gitlab/ci/env_${CMAKE_CONFIGURATION}.sh"; then + source ".gitlab/ci/env_${CMAKE_CONFIGURATION}.sh" +fi diff --git a/.gitlab/ci/env_fedora33_makefiles.cmake b/.gitlab/ci/env_fedora34_makefiles.cmake index 1d0efa7..aa84e23 100644 --- a/.gitlab/ci/env_fedora33_makefiles.cmake +++ b/.gitlab/ci/env_fedora34_makefiles.cmake @@ -1,2 +1,2 @@ set(ENV{MY_RUBY_HOME} "/usr/local/rvm/rubies/ruby-2.7.0") -set(ENV{PATH} "/usr/lib64/openmpi/bin:$ENV{PATH}") +set(ENV{PATH} "/usr/lib64/mpich/bin:$ENV{PATH}") diff --git a/.gitlab/ci/env_intelclassic_common.sh b/.gitlab/ci/env_intelclassic_common.sh new file mode 100644 index 0000000..22b1d03 --- /dev/null +++ b/.gitlab/ci/env_intelclassic_common.sh @@ -0,0 +1,9 @@ +source .gitlab/ci/env_intelcompiler_license.sh + +if test -r /opt/intel/oneapi/setvars.sh; then + source /opt/intel/oneapi/setvars.sh +elif test -r /opt/intel/bin/compilervars.sh; then + source /opt/intel/bin/compilervars.sh intel64 +fi + +export CC=icc CXX=icpc FC=ifort diff --git a/.gitlab/ci/env_intelclassic_makefiles.sh b/.gitlab/ci/env_intelclassic_makefiles.sh new file mode 100644 index 0000000..d1ff85e --- /dev/null +++ b/.gitlab/ci/env_intelclassic_makefiles.sh @@ -0,0 +1 @@ +source .gitlab/ci/env_intelclassic_common.sh diff --git a/.gitlab/ci/env_intelcompiler_license.sh b/.gitlab/ci/env_intelcompiler_license.sh new file mode 100644 index 0000000..54743b2 --- /dev/null +++ b/.gitlab/ci/env_intelcompiler_license.sh @@ -0,0 +1,8 @@ +if test -n "$CMAKE_CI_INTELCOMPILER_LICENSE"; then + if test -d /opt/intel/licenses; then + mv "$CMAKE_CI_INTELCOMPILER_LICENSE" /opt/intel/licenses/ci.lic + else + rm "$CMAKE_CI_INTELCOMPILER_LICENSE" + fi + unset CMAKE_CI_INTELCOMPILER_LICENSE +fi diff --git a/.gitlab/ci/env_inteloneapi_common.sh b/.gitlab/ci/env_inteloneapi_common.sh new file mode 100644 index 0000000..beaf3fe --- /dev/null +++ b/.gitlab/ci/env_inteloneapi_common.sh @@ -0,0 +1,7 @@ +source .gitlab/ci/env_intelcompiler_license.sh + +if test -r /opt/intel/oneapi/setvars.sh; then + source /opt/intel/oneapi/setvars.sh +fi + +export CC=icx CXX=icpx FC=ifx diff --git a/.gitlab/ci/env_inteloneapi_makefiles.sh b/.gitlab/ci/env_inteloneapi_makefiles.sh new file mode 100644 index 0000000..eefcdda --- /dev/null +++ b/.gitlab/ci/env_inteloneapi_makefiles.sh @@ -0,0 +1 @@ +source .gitlab/ci/env_inteloneapi_common.sh diff --git a/.gitlab/ci/gitlab_ci.cmake b/.gitlab/ci/gitlab_ci.cmake index f863a27..f166215 100644 --- a/.gitlab/ci/gitlab_ci.cmake +++ b/.gitlab/ci/gitlab_ci.cmake @@ -17,7 +17,11 @@ if ("$ENV{CMAKE_CONFIGURATION}" STREQUAL "") endif () # Set the build metadata. -set(CTEST_BUILD_NAME "$ENV{CI_PROJECT_NAME}-$ENV{CMAKE_CONFIGURATION}") +if(NOT "$ENV{CMAKE_CI_BUILD_NAME}" STREQUAL "") + set(CTEST_BUILD_NAME "$ENV{CI_PROJECT_NAME}-$ENV{CMAKE_CI_BUILD_NAME}") +else() + set(CTEST_BUILD_NAME "$ENV{CI_PROJECT_NAME}-$ENV{CMAKE_CONFIGURATION}") +endif() set(CTEST_SITE "gitlab-ci") set(ctest_model "Experimental") diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index 2670ba5..dcaa643 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -5,7 +5,7 @@ ### Release .linux_prep_source: - image: "fedora:33" + image: "fedora:34" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci" @@ -30,10 +30,22 @@ variables: BOOTSTRAP_ARGS: '-- "-DCMake_DOC_ARTIFACT_PREFIX=$CI_PROJECT_DIR/build/install-doc"' +.needs_centos6_x86_64: + dependencies: + - build:centos6-x86_64 + needs: + - build:centos6-x86_64 + +.needs_centos7_aarch64: + dependencies: + - build:centos7-aarch64 + needs: + - build:centos7-aarch64 + ### Debian .debian10: - image: "kitware/cmake:ci-debian10-x86_64-2021-04-06" + image: "kitware/cmake:ci-debian10-x86_64-2021-05-11" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci" @@ -48,7 +60,7 @@ CMake_SKIP_INSTALL: 1 .debian10_aarch64: - image: "kitware/cmake:ci-debian10-aarch64-2021-04-06" + image: "kitware/cmake:ci-debian10-aarch64-2021-05-11" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci" @@ -56,8 +68,8 @@ ### Fedora -.fedora33: - image: "kitware/cmake:ci-fedora33-x86_64-2021-04-06" +.fedora34: + image: "kitware/cmake:ci-fedora34-x86_64-2021-05-21" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes" @@ -65,28 +77,28 @@ #### Lint builds -.fedora33_tidy: - extends: .fedora33 +.fedora34_tidy: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_tidy + CMAKE_CONFIGURATION: fedora34_tidy CTEST_NO_WARNINGS_ALLOWED: 1 CMake_SKIP_INSTALL: 1 -.fedora33_sphinx: - extends: .fedora33 +.fedora34_sphinx: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_sphinx + CMAKE_CONFIGURATION: fedora34_sphinx CTEST_NO_WARNINGS_ALLOWED: 1 CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx" CMake_SKIP_INSTALL: 1 -.fedora33_sphinx_package: - extends: .fedora33 +.fedora34_sphinx_package: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_sphinx_package + CMAKE_CONFIGURATION: fedora34_sphinx_package CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx" #### Build and test @@ -105,29 +117,50 @@ CMAKE_CONFIGURATION: debian10_aarch64_ninja CTEST_NO_WARNINGS_ALLOWED: 1 -.fedora33_ninja: - extends: .fedora33 +.fedora34_ninja: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_ninja + CMAKE_CONFIGURATION: fedora34_ninja CTEST_NO_WARNINGS_ALLOWED: 1 -.fedora33_ninja_multi: - extends: .fedora33 +.fedora34_ninja_multi: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_ninja_multi + CMAKE_CONFIGURATION: fedora34_ninja_multi CTEST_NO_WARNINGS_ALLOWED: 1 CMAKE_GENERATOR: "Ninja Multi-Config" -.fedora33_makefiles: - extends: .fedora33 +.fedora34_makefiles: + extends: .fedora34 variables: - CMAKE_CONFIGURATION: fedora33_makefiles + CMAKE_CONFIGURATION: fedora34_makefiles CTEST_NO_WARNINGS_ALLOWED: 1 CMAKE_GENERATOR: "Unix Makefiles" +### Intel Compiler + +.intelcompiler: + image: "kitware/intelcompiler:$CMAKE_CI_INTELCOMPILER_IMAGE_TAG" + environment: + name: intel-compiler + variables: + CMAKE_ARCH: x86_64 + +.intelclassic_makefiles: + extends: .intelcompiler + variables: + CMAKE_CONFIGURATION: intelclassic_makefiles + CMAKE_GENERATOR: "Unix Makefiles" + +.inteloneapi_makefiles: + extends: .intelcompiler + variables: + CMAKE_CONFIGURATION: inteloneapi_makefiles + CMAKE_GENERATOR: "Unix Makefiles" + ### CUDA builds .cuda10.2: @@ -195,6 +228,7 @@ ## Linux-specific scripts .before_script_linux: &before_script_linux + - source .gitlab/ci/env.sh - .gitlab/ci/cmake.sh - .gitlab/ci/ninja.sh - export PATH=$PWD/.gitlab:$PWD/.gitlab/cmake/bin:$PATH @@ -224,6 +258,13 @@ interruptible: true +.cmake_codespell_linux: + stage: build + extends: .fedora34 + script: + - codespell + interruptible: true + .cmake_build_linux: stage: build @@ -251,6 +292,7 @@ stage: build script: + - source .gitlab/ci/env.sh # Bootstrap. - mkdir -p build/ # Exclude documentation. A job dependency provides it for packaging. @@ -313,3 +355,38 @@ - sccache --show-stats interruptible: true + +.cmake_test_linux_intelclassic_makefiles: + extends: + - .intelclassic_makefiles + - .cmake_test_linux_release + - .linux_builder_tags_qt + - .run_manually + - .needs_centos6_x86_64 + variables: + CMAKE_CI_JOB_NIGHTLY: "true" + +.cmake_test_linux_inteloneapi_makefiles: + extends: + - .inteloneapi_makefiles + - .cmake_test_linux_release + - .linux_builder_tags_qt + - .run_manually + - .needs_centos6_x86_64 + variables: + CMAKE_CI_JOB_NIGHTLY: "true" + +### Documentation + +.cmake_org_help: + stage: build + extends: + - .fedora34 + - .linux_builder_tags + - .cmake_org_help_artifacts + script: + - *before_script_linux + - mkdir -p build/ + - cd build/ + - cmake ../Utilities/Sphinx -GNinja -DSPHINX_HTML=ON -DSPHINX_FLAGS="-A versionswitch=1" + - ninja diff --git a/.gitlab/rules.yml b/.gitlab/rules.yml index 256f567..4846fea 100644 --- a/.gitlab/rules.yml +++ b/.gitlab/rules.yml @@ -6,7 +6,9 @@ when: never - if: '$CMAKE_CI_NIGHTLY == "true"' when: on_success - - if: '($CMAKE_CI_PROJECT_CONTINUOUS_BRANCH != "" && $CI_COMMIT_BRANCH == $CMAKE_CI_PROJECT_CONTINUOUS_BRANCH && $CMAKE_CI_JOB_CONTINUOUS == "true")' + - if: '$CMAKE_CI_JOB_NIGHTLY == "true"' + when: never + - if: '$CMAKE_CI_PROJECT_CONTINUOUS_BRANCH != null && $CI_COMMIT_BRANCH != null && $CMAKE_CI_PROJECT_CONTINUOUS_BRANCH == $CI_COMMIT_BRANCH && $CMAKE_CI_JOB_CONTINUOUS == "true"' when: delayed start_in: 5 minutes - if: '($CMAKE_CI_NO_MR == "true" && $CI_MERGE_REQUEST_ID)' @@ -24,7 +26,9 @@ when: never - if: '$CMAKE_CI_NIGHTLY == "true"' when: on_success - - if: '($CMAKE_CI_PROJECT_CONTINUOUS_BRANCH != "" && $CI_COMMIT_BRANCH == $CMAKE_CI_PROJECT_CONTINUOUS_BRANCH && $CMAKE_CI_JOB_CONTINUOUS == "true")' + - if: '$CMAKE_CI_JOB_NIGHTLY == "true"' + when: never + - if: '$CMAKE_CI_PROJECT_CONTINUOUS_BRANCH != null && $CI_COMMIT_BRANCH != null && $CMAKE_CI_PROJECT_CONTINUOUS_BRANCH == $CI_COMMIT_BRANCH && $CMAKE_CI_JOB_CONTINUOUS == "true"' when: on_success - if: '($CMAKE_CI_NO_MR == "true" && $CI_MERGE_REQUEST_ID)' when: never @@ -43,6 +47,8 @@ when: always - if: '$CMAKE_CI_NIGHTLY == "true"' when: on_success + - if: '$CMAKE_CI_JOB_NIGHTLY == "true"' + when: never - if: '($CMAKE_CI_NO_MR == "true" && $CI_MERGE_REQUEST_ID)' when: never - if: '$CI_MERGE_REQUEST_ID' @@ -56,3 +62,15 @@ - if: '$CMAKE_CI_PACKAGE == "true"' when: on_success - when: never + +.run_only_for_continuous_master: + rules: + - if: '$CMAKE_CI_PROJECT_MAIN_BRANCH != null && $CI_COMMIT_BRANCH != null && $CMAKE_CI_PROJECT_MAIN_BRANCH == $CI_COMMIT_BRANCH' + when: on_success + - when: never + +.run_only_for_continuous_stage: + rules: + - if: '$CMAKE_CI_PROJECT_CONTINUOUS_BRANCH != null && $CI_COMMIT_BRANCH != null && $CMAKE_CI_PROJECT_CONTINUOUS_BRANCH == $CI_COMMIT_BRANCH' + when: on_success + - when: never diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml index 8b8daa1..693388d 100644 --- a/.gitlab/upload.yml +++ b/.gitlab/upload.yml @@ -1,9 +1,10 @@ # Steps for uploading artifacts -.rsync_upload: - image: "fedora:32" +.rsync_upload_binary: + image: "fedora:34" stage: upload tags: + - cmake - docker - linux - build @@ -16,3 +17,21 @@ - chmod 400 $RSYNC_BINARY_KEY - ssh-keygen -y -f $RSYNC_BINARY_KEY > $RSYNC_BINARY_KEY.pub - rsync -tv --recursive -e "ssh -i $RSYNC_BINARY_KEY -o StrictHostKeyChecking=no -o LogLevel=ERROR" build/ kitware@cmake.org:$RSYNC_DESTINATION/ + +.rsync_upload_help: + stage: upload + image: "fedora:34" + tags: + - cmake + - docker + - linux + - build + environment: + name: rsync-upload + + script: + - ls build/html/index.html + - dnf install -y --setopt=install_weak_deps=False rsync openssh-clients + - chmod 400 $RSYNC_HELP_KEY + - ssh-keygen -y -f $RSYNC_HELP_KEY > $RSYNC_HELP_KEY.pub + - rsync -tv --recursive --delete -e "ssh -i $RSYNC_HELP_KEY -o StrictHostKeyChecking=no -o LogLevel=ERROR" build/html/ kitware@cmake.org:$RSYNC_DESTINATION/ diff --git a/Auxiliary/vim/cmake.vim.in b/Auxiliary/vim/cmake.vim.in index 3471b54..6edc040 100644 --- a/Auxiliary/vim/cmake.vim.in +++ b/Auxiliary/vim/cmake.vim.in @@ -9,7 +9,7 @@ " Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com> " Last Change: @DATE@ " -" Licence: The CMake license applies to this file. See +" License: The CMake license applies to this file. See " https://cmake.org/licensing " This implies that distribution with Vim is allowed diff --git a/Auxiliary/vim/indent/cmake.vim b/Auxiliary/vim/indent/cmake.vim index 33e583d..f7ab24a 100644 --- a/Auxiliary/vim/indent/cmake.vim +++ b/Auxiliary/vim/indent/cmake.vim @@ -5,7 +5,7 @@ " Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com> " Last Change: 2017 Aug 30 " -" Licence: The CMake license applies to this file. See +" License: The CMake license applies to this file. See " https://cmake.org/licensing " This implies that distribution with Vim is allowed diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 955beae..611f72a 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -9,7 +9,7 @@ " Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com> " Last Change: 2020 oct. 28 " -" Licence: The CMake license applies to this file. See +" License: The CMake license applies to this file. See " https://cmake.org/licensing " This implies that distribution with Vim is allowed @@ -92,6 +92,7 @@ syn keyword cmakeProperty contained \ AUTOUIC_EXECUTABLE \ AUTOUIC_OPTIONS \ AUTOUIC_SEARCH_PATHS + \ AUTOUIC_SOURCE_GROUP \ BINARY_DIR \ BUILDSYSTEM_TARGETS \ BUILD_RPATH diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake index 31c2fe4..9357804 100644 --- a/CMakeCPack.cmake +++ b/CMakeCPack.cmake @@ -133,6 +133,9 @@ if(CMake_INSTALL_COMPONENTS) if(SPHINX_QTHELP) list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-qthelp) endif() + if(SPHINX_LATEXPDF) + list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-latexpdf) + endif() if(CMake_BUILD_DEVELOPER_REFERENCE) if(CMake_BUILD_DEVELOPER_REFERENCE_HTML) list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-developer-reference-html) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2fcf2e..44b433a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -cmake_minimum_required(VERSION 3.1...3.18 FATAL_ERROR) +cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR) set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake) project(CMake) @@ -579,6 +579,7 @@ macro (CMAKE_BUILD_UTILITIES) set(LIBLZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmliblzma/liblzma/api") set(LIBLZMA_LIBRARY cmliblzma) + set(HAVE_LZMA_STREAM_ENCODER_MT 1) endif() endif() @@ -643,7 +644,11 @@ macro (CMAKE_BUILD_UTILITIES) #--------------------------------------------------------------------- # Build libuv library. if(CMAKE_USE_SYSTEM_LIBUV) - find_package(LibUV 1.10.0) + if(WIN32) + find_package(LibUV 1.38.0) + else() + find_package(LibUV 1.10.0) + endif() if(NOT LIBUV_FOUND) message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBUV is ON but a libuv is not found!") diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3006214..a6a2082 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -38,7 +38,7 @@ To contribute patches: #. Push the topic branch to a personal repository fork on GitLab. #. Create a GitLab Merge Request targeting the upstream ``master`` branch (even if the change is intended for merge to the ``release`` branch). - Check the box labelled "Allow commits from members who can merge to the + Check the box labeled "Allow commits from members who can merge to the target branch". This will allow maintainers to make minor edits on your behalf. diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index 4c8267d..238ca15 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -7,6 +7,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION "warning LNK4221" "warning LNK4204" # Occurs by race condition with objects in small libs "variable .var_args[2]*. is used before its value is set" + "warning: variable .__d[01]. was set but never used" # FD_ZERO on NVHPC "jobserver unavailable" "warning: \\(Long double usage is reported only once for each file" "warning: To disable this warning use" diff --git a/Help/command/DEVICE_LINK_OPTIONS.txt b/Help/command/DEVICE_LINK_OPTIONS.txt index 1297cd0..3d50208 100644 --- a/Help/command/DEVICE_LINK_OPTIONS.txt +++ b/Help/command/DEVICE_LINK_OPTIONS.txt @@ -1,3 +1,5 @@ +Host And Device Specific Link Options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. versionadded:: 3.18 When a device link step is involved, which is controlled by diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index 97eecfc..aae1c38 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -11,8 +11,8 @@ The general signature is: |FIND_XXX| ( <VAR> name | |NAMES| - [HINTS path1 [path2 ... ENV var]] - [PATHS path1 [path2 ... ENV var]] + [HINTS [path | ENV var]... ] + [PATHS [path | ENV var]... ] [PATH_SUFFIXES suffix1 [suffix2 ...]] [DOC "cache documentation string"] [REQUIRED] diff --git a/Help/command/LINK_OPTIONS_LINKER.txt b/Help/command/LINK_OPTIONS_LINKER.txt index 3f66181..e71e5ea 100644 --- a/Help/command/LINK_OPTIONS_LINKER.txt +++ b/Help/command/LINK_OPTIONS_LINKER.txt @@ -1,3 +1,6 @@ +Handling Compiler Driver Differences +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + To pass options to the linker tool, each compiler driver has its own syntax. The ``LINKER:`` prefix and ``,`` separator can be used to specify, in a portable way, options to pass to the linker tool. ``LINKER:`` is replaced by the diff --git a/Help/command/OPTIONS_SHELL.txt b/Help/command/OPTIONS_SHELL.txt index 4051ffe..4171f01 100644 --- a/Help/command/OPTIONS_SHELL.txt +++ b/Help/command/OPTIONS_SHELL.txt @@ -1,11 +1,15 @@ -The final set of compile or link options used for a target is constructed by +Option De-duplication +^^^^^^^^^^^^^^^^^^^^^ + +The final set of options used for a target is constructed by accumulating options from the current target and the usage requirements of its dependencies. The set of options is de-duplicated to avoid repetition. .. versionadded:: 3.12 While beneficial for individual options, the de-duplication step can break - up option groups. For example, ``-D A -D B`` becomes ``-D A B``. One may - specify a group of options using shell-like quoting along with a ``SHELL:`` - prefix. The ``SHELL:`` prefix is dropped, and the rest of the option string - is parsed using the :command:`separate_arguments` ``UNIX_COMMAND`` mode. - For example, ``"SHELL:-D A" "SHELL:-D B"`` becomes ``-D A -D B``. + up option groups. For example, ``-option A -option B`` becomes + ``-option A B``. One may specify a group of options using shell-like + quoting along with a ``SHELL:`` prefix. The ``SHELL:`` prefix is dropped, + and the rest of the option string is parsed using the + :command:`separate_arguments` ``UNIX_COMMAND`` mode. For example, + ``"SHELL:-option A" "SHELL:-option B"`` becomes ``-option A -option B``. diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index c0b9593..569f1e8 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -271,21 +271,28 @@ The options are: ``DEPFILE`` .. versionadded:: 3.7 - Specify a ``.d`` depfile for the :generator:`Ninja` generator and - :ref:`Makefile Generators`. - A ``.d`` file holds dependencies usually emitted by the custom - command itself. - Using ``DEPFILE`` with other generators than :generator:`Ninja` or - :ref:`Makefile Generators` is an error. + Specify a ``.d`` depfile for the :generator:`Ninja`, :generator:`Xcode` and + :ref:`Makefile <Makefile Generators>` generators. The depfile may use + "generator expressions" with the syntax ``$<...>``. See the + :manual:`generator-expressions(7) <cmake-generator-expressions(7)>` manual + for available expressions. A ``.d`` file holds dependencies usually emitted + by the custom command itself. + + Using ``DEPFILE`` with other generators than :generator:`Ninja`, + :generator:`Xcode` or :ref:`Makefile <Makefile Generators>` is an error. .. versionadded:: 3.20 Added the support of :ref:`Makefile Generators`. + .. versionadded:: 3.21 + Added the support of :generator:`Xcode` generator and + :manual:`generator expressions <cmake-generator-expressions(7)>`. + If the ``DEPFILE`` argument is relative, it should be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the ``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR` (see policy :policy:`CMP0116`. This policy is always ``NEW`` for - :ref:`Makefile Generators`). + :ref:`Makefile <Makefile Generators>` and :generator:`Xcode` generators). .. note:: diff --git a/Help/command/build_command.rst b/Help/command/build_command.rst index 6659005..a03979d 100644 --- a/Help/command/build_command.rst +++ b/Help/command/build_command.rst @@ -8,23 +8,29 @@ This is mainly intended for internal use by the :module:`CTest` module. build_command(<variable> [CONFIGURATION <config>] + [PARALLEL_LEVEL <parallel>] [TARGET <target>] [PROJECT_NAME <projname>] # legacy, causes warning ) Sets the given ``<variable>`` to a command-line string of the form:: - <cmake> --build . [--config <config>] [--target <target>...] [-- -i] + <cmake> --build . [--config <config>] [--parallel <parallel>] [--target <target>...] [-- -i] where ``<cmake>`` is the location of the :manual:`cmake(1)` command-line -tool, and ``<config>`` and ``<target>`` are the values provided to the -``CONFIGURATION`` and ``TARGET`` options, if any. The trailing ``-- -i`` -option is added for :ref:`Makefile Generators` if policy :policy:`CMP0061` -is not set to ``NEW``. +tool, and ``<config>``, ``<parallel>`` and ``<target>`` are the values +provided to the ``CONFIGURATION``, ``PARALLEL_LEVEL`` and ``TARGET`` +options, if any. The trailing ``-- -i`` option is added for +:ref:`Makefile Generators` if policy :policy:`CMP0061` is not set to +``NEW``. When invoked, this ``cmake --build`` command line will launch the underlying build system tool. +.. versionadded:: 3.21 + The ``PARALLEL_LEVEL`` argument can be used to set the ``--parallel`` + flag. + .. code-block:: cmake build_command(<cachevariable> <makecommand>) diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst index 99f874b..2859f6b 100644 --- a/Help/command/cmake_language.rst +++ b/Help/command/cmake_language.rst @@ -190,7 +190,7 @@ For example, the code: .. code-block:: cmake cmake_language(DEFER CALL message "${deferred_message}") - cmake_language(DEFER ID_VAR id CALL message "Cancelled Message") + cmake_language(DEFER ID_VAR id CALL message "Canceled Message") cmake_language(DEFER CANCEL_CALL ${id}) message("Immediate Message") set(deferred_message "Deferred Message") @@ -201,7 +201,7 @@ prints:: Deferred Message The ``Cancelled Message`` is never printed because its command is -cancelled. The ``deferred_message`` variable reference is not evaluated +canceled. The ``deferred_message`` variable reference is not evaluated until the call site, so it can be set after the deferred call is scheduled. In order to evaluate variable references immediately when scheduling a diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst index c3b3e73..d159770 100644 --- a/Help/command/cmake_minimum_required.rst +++ b/Help/command/cmake_minimum_required.rst @@ -5,21 +5,21 @@ Require a minimum version of cmake. .. code-block:: cmake - cmake_minimum_required(VERSION <min>[...<max>] [FATAL_ERROR]) + cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR]) .. versionadded:: 3.12 - The optional ``<max>`` version. + The optional ``<policy_max>`` version. Sets the minimum required version of cmake for a project. Also updates the policy settings as explained below. -``<min>`` and the optional ``<max>`` are each CMake versions of the form -``major.minor[.patch[.tweak]]``, and the ``...`` is literal. +``<min>`` and the optional ``<policy_max>`` are each CMake versions of the +form ``major.minor[.patch[.tweak]]``, and the ``...`` is literal. If the running version of CMake is lower than the ``<min>`` required version it will stop processing the project and report an error. -The optional ``<max>`` version, if specified, must be at least the -``<min>`` version and affects policy settings as described below. +The optional ``<policy_max>`` version, if specified, must be at least the +``<min>`` version and affects policy settings as described in `Policy Settings`_. If the running version of CMake is older than 3.12, the extra ``...`` dots will be seen as version component separators, resulting in the ``...<max>`` part being ignored and preserving the pre-3.12 behavior @@ -40,8 +40,15 @@ with an error instead of just a warning. they may affect. See also policy :policy:`CMP0000`. Calling ``cmake_minimum_required()`` inside a :command:`function` - limits some effects to the function scope when invoked. Such calls - should not be made with the intention of having global effects. + limits some effects to the function scope when invoked. For example, + the :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable won't be set + in the calling scope. Functions do not introduce their own policy + scope though, so policy settings of the caller *will* be affected + (see below). Due to this mix of things that do and do not affect the + calling scope, calling ``cmake_minimum_required()`` inside a function + is generally discouraged. + +.. _`Policy Settings`: Policy Settings ^^^^^^^^^^^^^^^ diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst index a8999f3..193180d 100644 --- a/Help/command/cmake_path.rst +++ b/Help/command/cmake_path.rst @@ -687,7 +687,8 @@ When the ``NORMALIZE`` option is specified, the path is :ref:`normalized <Normalization>` after the path computation. Because ``cmake_path()`` does not access the filesystem, symbolic links are -not resolved. To compute a real path with symbolic links resolved, use the +not resolved and any leading tilde is not expanded. To compute a real path +with symbolic links resolved and leading tildes expanded, use the :command:`file(REAL_PATH)` command instead. Native Conversion diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst index d00f08b..086668c 100644 --- a/Help/command/configure_file.rst +++ b/Help/command/configure_file.rst @@ -36,8 +36,30 @@ or depending on whether ``VAR`` is set in CMake to any value not considered a false constant by the :command:`if` command. The "..." content on the line after the variable name, if any, is processed as above. -Input file lines of the form ``#cmakedefine01 VAR`` will be replaced with -either ``#define VAR 1`` or ``#define VAR 0`` similarly. + +Unlike lines of the form ``#cmakedefine VAR ...``, in lines of the form +``#cmakedefine01 VAR``, ``VAR`` itself will expand to ``VAR 0`` or ``VAR 1`` +rather than being assigned the value ``...``. Therefore, input lines of the form + +.. code-block:: c + + #cmakedefine01 VAR + +will be replaced with either + +.. code-block:: c + + #define VAR 0 + +or + +.. code-block:: c + + #define VAR 1 + +Input lines of the form ``#cmakedefine01 VAR ...`` will expand +as ``#cmakedefine01 VAR ... 0`` or ``#cmakedefine01 VAR ... 0``, +which may lead to undefined behavior. .. versionadded:: 3.10 The result lines (with the exception of the ``#undef`` comments) can be diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst index 4d6dc5a..e05df1a 100644 --- a/Help/command/ctest_build.rst +++ b/Help/command/ctest_build.rst @@ -7,6 +7,7 @@ Perform the :ref:`CTest Build Step` as a :ref:`Dashboard Client`. ctest_build([BUILD <build-dir>] [APPEND] [CONFIGURATION <config>] + [PARALLEL_LEVEL <parallel>] [FLAGS <flags>] [PROJECT_NAME <project-name>] [TARGET <target-name>] @@ -42,6 +43,13 @@ The options are: Otherwise the ``-C <cfg>`` option given to the :manual:`ctest(1)` command will be used, if any. +``PARALLEL_LEVEL <parallel>`` + .. versionadded:: 3.21 + + Specify the parallel level of the underlying build system. If not + specified, the :envvar:`CMAKE_BUILD_PARALLEL_LEVEL` environment + variable will be checked. + ``FLAGS <flags>`` Pass additional arguments to the underlying build command. If not specified the ``CTEST_BUILD_FLAGS`` variable will be checked. diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst index b4493a0..c61d01e 100644 --- a/Help/command/ctest_test.rst +++ b/Help/command/ctest_test.rst @@ -25,6 +25,7 @@ Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`. [RETURN_VALUE <result-var>] [CAPTURE_CMAKE_ERROR <result-var>] [REPEAT <mode>:<n>] + [OUTPUT_JUNIT <file>] [QUIET] ) @@ -150,6 +151,15 @@ The options are: Store in the ``<result-var>`` variable -1 if there are any errors running the command and prevent ctest from returning non-zero if an error occurs. +``OUTPUT_JUNIT`` + .. versionadded:: 3.21 + + Write test results to ``<file>`` in JUnit XML format. If ``<file>`` is a + relative path it will be placed in the build directory. If ``<file>>`` + already exists it will be overwritten. Note that the resulting JUnit XML + file is **not** uploaded to CDash because it would be redundant with + CTest's ``Test.xml`` file. + ``QUIET`` .. versionadded:: 3.3 @@ -160,3 +170,83 @@ The options are: See also the :variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE` and :variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE` variables. + +.. _`Additional Test Measurements`: + +Additional Test Measurements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CTest can parse the output of your tests for extra measurements to report +to CDash. + +When run as a :ref:`Dashboard Client`, CTest will include these custom +measurements in the ``Test.xml`` file that gets uploaded to CDash. + +Check the `CDash test measurement documentation +<https://github.com/Kitware/CDash/blob/master/docs/test_measurements.md>`_ +for more information on the types of test measurements that CDash recognizes. + +The following example demonstrates how to output a variety of custom test +measurements. + +.. code-block:: c++ + + std::cout << + "<DartMeasurement type=\"numeric/double\" name=\"score\">28.3</DartMeasurement>" + << std::endl; + + std::cout << + "<DartMeasurement type=\"text/string\" name=\"color\">red</DartMeasurement>" + << std::endl; + + std::cout << + "<DartMeasurement type=\"text/link\" name=\"CMake URL\">https://cmake.org</DartMeasurement>" + << std::endl; + + std::cout << + "<DartMeasurement type=\"text/preformatted\" name=\"Console Output\">" << + "line 1.\n" << + " \033[31;1m line 2. Bold red, and indented!\033[0;0ml\n" << + "line 3. Not bold or indented...\n" << + "</DartMeasurement>" << std::endl; + +Image Measurements +"""""""""""""""""" + +The following example demonstrates how to upload test images to CDash. + +.. code-block:: c++ + + std::cout << + "<DartMeasurementFile type=\"image/jpg\" name=\"TestImage\">" << + "/dir/to/test_img.jpg</DartMeasurementFile>" << std::endl; + + std::cout << + "<DartMeasurementFile type=\"image/gif\" name=\"ValidImage\">" << + "/dir/to/valid_img.gif</DartMeasurementFile>" << std::endl; + + std::cout << + "<DartMeasurementFile type=\"image/png\" name=\"AlgoResult\"> << + "/dir/to/img.png</DartMeasurementFile>" + << std::endl; + +Images will be displayed together in an interactive comparison mode on CDash +if they are provided with two or more of the following names. + +* ``TestImage`` +* ``ValidImage`` +* ``BaselineImage`` +* ``DifferenceImage2`` + +By convention, ``TestImage`` is the image generated by your test, and +``ValidImage`` (or ``BaselineImage``) is basis of comparison used to determine +if the test passed or failed. + +If another image name is used it will be displayed by CDash as a static image +separate from the interactive comparison UI. + +Attached Files +"""""""""""""" + +To associate other types of files with a test, use the +:prop_test:`ATTACHED_FILES` or :prop_test:`ATTACHED_FILES_ON_FAIL` test properties. diff --git a/Help/command/file.rst b/Help/command/file.rst index 31de610..f46e55a 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -38,7 +38,8 @@ Synopsis `Filesystem`_ file({`GLOB`_ | `GLOB_RECURSE`_} <out-var> [...] [<globbing-expr>...]) - file(`RENAME`_ <oldname> <newname>) + file(`RENAME`_ <oldname> <newname> [...]) + file(`COPY_FILE`_ <oldname> <newname> [...]) file({`REMOVE`_ | `REMOVE_RECURSE`_ } [<files>...]) file(`MAKE_DIRECTORY`_ [<dir>...]) file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...]) @@ -49,7 +50,7 @@ Synopsis file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...]) `Path Conversion`_ - file(`REAL_PATH`_ <path> <out-var> [BASE_DIRECTORY <dir>]) + file(`REAL_PATH`_ <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE]) file(`RELATIVE_PATH`_ <out-var> <directory> <file>) file({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>) @@ -675,11 +676,46 @@ Examples of recursive globbing include:: .. code-block:: cmake - file(RENAME <oldname> <newname>) + file(RENAME <oldname> <newname> + [RESULT <result>] + [NO_REPLACE]) Move a file or directory within a filesystem from ``<oldname>`` to ``<newname>``, replacing the destination atomically. +The options are: + +``RESULT <result>`` + Set ``<result>`` variable to ``0`` on success or an error message otherwise. + If ``RESULT`` is not specified and the operation fails, an error is emitted. + +``NO_REPLACE`` + If the ``<newname>`` path already exists, do not replace it. + If ``RESULT <result>`` is used, the result variable will be + set to ``NO_REPLACE``. Otherwise, an error is emitted. + +.. _COPY_FILE: + +.. code-block:: cmake + + file(COPY_FILE <oldname> <newname> + [RESULT <result>] + [ONLY_IF_DIFFERENT]) + +Copy a file from ``<oldname>`` to ``<newname>``. Directories are not +supported. Symlinks are ignored and ``<oldfile>``'s content is read and +written to ``<newname>`` as a new file. + +The options are: + +``RESULT <result>`` + Set ``<result>`` variable to ``0`` on success or an error message otherwise. + If ``RESULT`` is not specified and the operation fails, an error is emitted. + +``ONLY_IF_DIFFERENT`` + If the ``<newname>`` path already exists, do not replace it if it is the + same as ``<oldname>``. Otherwise, an error is emitted. + .. _REMOVE: .. _REMOVE_RECURSE: @@ -888,16 +924,26 @@ Path Conversion .. code-block:: cmake - file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>]) + file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE]) .. versionadded:: 3.19 Compute the absolute path to an existing file or directory with symlinks resolved. -If the provided ``<path>`` is a relative path, it is evaluated relative to the -given base directory ``<dir>``. If no base directory is provided, the default -base directory will be :variable:`CMAKE_CURRENT_SOURCE_DIR`. +``BASE_DIRECTORY <dir>`` + If the provided ``<path>`` is a relative path, it is evaluated relative to the + given base directory ``<dir>``. If no base directory is provided, the default + base directory will be :variable:`CMAKE_CURRENT_SOURCE_DIR`. + +``EXPAND_TILDE`` + .. versionadded:: 3.21 + + If the ``<path>`` is ``~`` or starts with ``~/``, the ``~`` is replaced by + the user's home directory. The path to the home directory is obtained from + environment variables. On Windows, the ``USERPROFILE`` environment variable + is used, falling back to the ``HOME`` environment variable if ``USERPROFILE`` + is not defined. On all other platforms, only ``HOME`` is used. .. _RELATIVE_PATH: @@ -1024,7 +1070,7 @@ If neither ``NETRC`` option is given CMake will check variables For ``https://`` URLs CMake must be built with OpenSSL support. ``TLS/SSL`` certificates are not checked by default. Set ``TLS_VERIFY`` to ``ON`` to check certificates. If neither ``TLS`` option is given CMake will check -variables ``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively. +variables :variable:`CMAKE_TLS_VERIFY` and ``CMAKE_TLS_CAINFO``, respectively. Additional options to ``DOWNLOAD`` are: diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst index 8de6deb..d9f54ca 100644 --- a/Help/command/foreach.rst +++ b/Help/command/foreach.rst @@ -14,9 +14,12 @@ semicolon or whitespace. All commands between ``foreach`` and the matching ``endforeach`` are recorded without being invoked. Once the ``endforeach`` is evaluated, the recorded list of commands is invoked once for each item in ``<items>``. -At the beginning of each iteration the variable ``loop_var`` will be set +At the beginning of each iteration the variable ``<loop_var>`` will be set to the value of the current item. +The scope of ``<loop_var>`` is restricted to the loop scope. See policy +:policy:`CMP0124` for details. + The commands :command:`break` and :command:`continue` provide means to escape from the normal control flow. diff --git a/Help/command/install.rst b/Help/command/install.rst index 35207f4..2259176 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -619,7 +619,7 @@ Custom Installation Logic .. code-block:: cmake install([[SCRIPT <file>] [CODE <code>]] - [COMPONENT <component>] [EXCLUDE_FROM_ALL] [...]) + [COMPONENT <component>] [EXCLUDE_FROM_ALL] [ALL_COMPONENTS] [...]) The ``SCRIPT`` form will invoke the given CMake script files during installation. If the script file name is a relative path it will be @@ -634,6 +634,12 @@ example, the code will print a message during installation. +The option ``ALL_COMPONENTS`` + .. versionadded:: 3.21 + + Run the custom installation script code for every component of a + component-specific installation. + .. versionadded:: 3.14 ``<file>`` or ``<code>`` may use "generator expressions" with the syntax ``$<...>`` (in the case of ``<file>``, this refers to their use in the file @@ -724,7 +730,7 @@ executable from the installation tree using the imported target name ``mp_myexe`` as if the target were built in its own tree. .. note:: - This command supercedes the :command:`install_targets` command and + This command supersedes the :command:`install_targets` command and the :prop_tgt:`PRE_INSTALL_SCRIPT` and :prop_tgt:`POST_INSTALL_SCRIPT` target properties. It also replaces the ``FILES`` forms of the :command:`install_files` and :command:`install_programs` commands. diff --git a/Help/command/install_files.rst b/Help/command/install_files.rst index ff074a8..494f3d0 100644 --- a/Help/command/install_files.rst +++ b/Help/command/install_files.rst @@ -5,7 +5,7 @@ install_files Use the :command:`install(FILES)` command instead. -This command has been superceded by the :command:`install` command. It is +This command has been superseded by the :command:`install` command. It is provided for compatibility with older CMake code. The ``FILES`` form is directly replaced by the ``FILES`` form of the :command:`install` command. The regexp form can be expressed more clearly using the ``GLOB`` diff --git a/Help/command/install_programs.rst b/Help/command/install_programs.rst index fab6482..eafae89 100644 --- a/Help/command/install_programs.rst +++ b/Help/command/install_programs.rst @@ -5,7 +5,7 @@ install_programs Use the :command:`install(PROGRAMS)` command instead. -This command has been superceded by the :command:`install` command. It is +This command has been superseded by the :command:`install` command. It is provided for compatibility with older CMake code. The ``FILES`` form is directly replaced by the ``PROGRAMS`` form of the :command:`install` command. The regexp form can be expressed more clearly using the ``GLOB`` diff --git a/Help/command/install_targets.rst b/Help/command/install_targets.rst index c9efdce..9355f8d 100644 --- a/Help/command/install_targets.rst +++ b/Help/command/install_targets.rst @@ -5,7 +5,7 @@ install_targets Use the :command:`install(TARGETS)` command instead. -This command has been superceded by the :command:`install` command. It is +This command has been superseded by the :command:`install` command. It is provided for compatibility with older CMake code. :: diff --git a/Help/command/project.rst b/Help/command/project.rst index 6c931b6..8a6bc1e 100644 --- a/Help/command/project.rst +++ b/Help/command/project.rst @@ -20,12 +20,18 @@ Sets the name of the project, and stores it in the variable ``CMakeLists.txt`` also stores the project name in the variable :variable:`CMAKE_PROJECT_NAME`. -Also sets the variables +Also sets the variables: -* :variable:`PROJECT_SOURCE_DIR`, - :variable:`<PROJECT-NAME>_SOURCE_DIR` -* :variable:`PROJECT_BINARY_DIR`, - :variable:`<PROJECT-NAME>_BINARY_DIR` +:variable:`PROJECT_SOURCE_DIR`, :variable:`<PROJECT-NAME>_SOURCE_DIR` + Absolute path to the source directory for the project. + +:variable:`PROJECT_BINARY_DIR`, :variable:`<PROJECT-NAME>_BINARY_DIR` + Absolute path to the binary directory for the project. + +:variable:`PROJECT_IS_TOP_LEVEL`, :variable:`<PROJECT-NAME>_IS_TOP_LEVEL` + .. versionadded:: 3.21 + + Boolean value indicating whether the project is top-level. Further variables are set by the optional arguments described in the following. If any of these arguments is not used, then the corresponding variables are diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst index b941812..47e8e13 100644 --- a/Help/cpack_gen/archive.rst +++ b/Help/cpack_gen/archive.rst @@ -82,7 +82,8 @@ CPack generators which are essentially archives at their core. These include: See also the :variable:`CPACK_THREADS` variable. -.. note:: + .. versionadded:: 3.21 - Official CMake binaries available on ``cmake.org`` ship with a ``liblzma`` - that does not support parallel compression. + Official CMake binaries available on ``cmake.org`` now ship + with a ``liblzma`` that supports parallel compression. + Older versions did not. diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst index 03c4ea8..d8d53ec 100644 --- a/Help/cpack_gen/deb.rst +++ b/Help/cpack_gen/deb.rst @@ -289,7 +289,7 @@ List of CPack DEB generator specific variables: * Default : "optional" .. versionadded:: 3.5 - Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY`` varables. + Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY`` variables. See https://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities diff --git a/Help/cpack_gen/dmg.rst b/Help/cpack_gen/dmg.rst index 4c662a6..64e9769 100644 --- a/Help/cpack_gen/dmg.rst +++ b/Help/cpack_gen/dmg.rst @@ -51,7 +51,7 @@ on macOS: .. versionadded:: 3.6 - Default behaviour is to include a symlink to ``/Applications`` in the DMG. + Default behavior is to include a symlink to ``/Applications`` in the DMG. Set this option to ``ON`` to avoid adding the symlink. .. variable:: CPACK_DMG_SLA_DIR @@ -103,6 +103,12 @@ on macOS: - Default: ``CPACK_PACKAGE_FILE_NAME-<component>`` +.. variable:: CPACK_DMG_FILESYSTEM + + The filesystem format. Common values are ``APFS`` and ``HFS+``. + See ``man hdiutil`` for a full list of supported formats. + Defaults to ``HFS+``. + .. variable:: CPACK_COMMAND_HDIUTIL Path to the ``hdiutil(1)`` command used to operate on disk image files on diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst index de1f3b5..02e33ba 100644 --- a/Help/cpack_gen/nsis.rst +++ b/Help/cpack_gen/nsis.rst @@ -195,3 +195,9 @@ on Windows Nullsoft Scriptable Install System. If set, trim down the size of the control to the size of the branding text string. Allowed values for this variable are ``LEFT``, ``CENTER`` or ``RIGHT``. If not specified, the default behavior is ``LEFT``. + +.. variable:: CPACK_NSIS_EXECUTABLE + + .. versionadded:: 3.21 + + If set, specify the name of the NSIS executable. Default is ``makensis``. diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index d019161..3db8177 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -39,7 +39,10 @@ to the file specified by the ``<DEP_FILE>`` placeholder, and write module dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. The module dependencies should be written in the format described -by the `P1689r3`_ paper. +by the `P1689r3`_ paper, with the following updates: + +* Omit the ``outputs``, ``inputs``, and ``depends`` fields from + each entry in the ``rules`` array. They are unused. Compiler writers may try out their scanning functionality using the `cxx-modules-sandbox`_ test project, modified to set variables diff --git a/Help/dev/review.rst b/Help/dev/review.rst index 8326e70..198e100 100644 --- a/Help/dev/review.rst +++ b/Help/dev/review.rst @@ -20,8 +20,10 @@ creating a *merge request* ("MR"). The new MR will appear on the process is managed by the merge request page for the change. During the review process, the MR submitter should address review comments -or test failures by updating the MR with a (force-)push of the topic -branch. The update initiates a new round of review. +or test failures by updating their local topic branch to fix their commits +(e.g. via ``git commit --amend`` or ``git rebase -i``), and then issuing a +(force-)push of the topic branch to their remote (e.g. ``git push --force``). +This will automatically initiate a new round of review on the existing MR. We recommend that users enable the "Remove source branch when merge request is accepted" option when creating the MR or by editing it. @@ -254,7 +256,8 @@ The preferred form for references to other commits is The author date of the commit, in its original time zone, formatted as ``CCYY-MM-DD``. ``git-log(1)`` shows the original time zone by default. -This may be generated with +This may be generated with ``git show -s --pretty=reference <commit>`` with +Git 2.25 and newer. Older versions of Git can generate the same format via ``git show -s --date=short --pretty="format:%h (%s, %ad)" <commit>``. If the commit is a fix for the mentioned commit, consider using a ``Fixes:`` diff --git a/Help/envvar/CUDAHOSTCXX.rst b/Help/envvar/CUDAHOSTCXX.rst index 963f9d1..cf65927 100644 --- a/Help/envvar/CUDAHOSTCXX.rst +++ b/Help/envvar/CUDAHOSTCXX.rst @@ -15,6 +15,10 @@ ignored if the :variable:`CMAKE_CUDA_HOST_COMPILER` variable is defined. This environment variable is primarily meant for use with projects that enable ``CUDA`` as a first-class language. +.. note:: + + Ignored when using :ref:`Visual Studio Generators`. + .. versionadded:: 3.13 The :module:`FindCUDA` module will use this variable to initialize its ``CUDA_HOST_COMPILER`` setting. diff --git a/Help/generator/VS_TOOLSET_HOST_ARCH.txt b/Help/generator/VS_TOOLSET_HOST_ARCH.txt index e361719..069638b 100644 --- a/Help/generator/VS_TOOLSET_HOST_ARCH.txt +++ b/Help/generator/VS_TOOLSET_HOST_ARCH.txt @@ -8,4 +8,4 @@ See the :variable:`CMAKE_GENERATOR_TOOLSET` variable for details. .. versionadded:: 3.14 - Added suport for ``host=x86`` option. + Added support for ``host=x86`` option. diff --git a/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt b/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt index 9a9e40e..d277b54 100644 --- a/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt +++ b/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.15) project(MathFunctions) +# make cache variables for install destinations +include(GNUInstallDirs) + # specify the C++ standard set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -12,26 +15,26 @@ add_library(MathFunctions STATIC MathFunctions.cxx) target_include_directories(MathFunctions PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" - "$<INSTALL_INTERFACE:include>" + "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" ) # install the target and create export-set install(TARGETS MathFunctions EXPORT MathFunctionsTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # install header file -install(FILES MathFunctions.h DESTINATION include) +install(FILES MathFunctions.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # generate and install export file install(EXPORT MathFunctionsTargets FILE MathFunctionsTargets.cmake NAMESPACE MathFunctions:: - DESTINATION lib/cmake/MathFunctions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) # include CMakePackageConfigHelpers macro @@ -58,14 +61,14 @@ write_basic_package_version_file( # create config file configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" - INSTALL_DESTINATION lib/cmake/MathFunctions + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) # install config files install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" - DESTINATION lib/cmake/MathFunctions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) # generate the export targets for the build tree diff --git a/Help/guide/importing-exporting/MathFunctionsComponents/Addition/CMakeLists.txt b/Help/guide/importing-exporting/MathFunctionsComponents/Addition/CMakeLists.txt index 17ad952..9de935e 100644 --- a/Help/guide/importing-exporting/MathFunctionsComponents/Addition/CMakeLists.txt +++ b/Help/guide/importing-exporting/MathFunctionsComponents/Addition/CMakeLists.txt @@ -7,24 +7,24 @@ add_library(MathFunctions::Addition ALIAS Addition) target_include_directories(Addition PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" - $<INSTALL_INTERFACE:include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) # install the target and create export-set install(TARGETS Addition EXPORT AdditionTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # install header file -install(FILES Addition.h DESTINATION include) +install(FILES Addition.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # generate and install export file install(EXPORT AdditionTargets FILE MathFunctionsAdditionTargets.cmake NAMESPACE MathFunctions:: - DESTINATION lib/cmake/MathFunctions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) diff --git a/Help/guide/importing-exporting/MathFunctionsComponents/CMakeLists.txt b/Help/guide/importing-exporting/MathFunctionsComponents/CMakeLists.txt index fd95e28..90ee89f 100644 --- a/Help/guide/importing-exporting/MathFunctionsComponents/CMakeLists.txt +++ b/Help/guide/importing-exporting/MathFunctionsComponents/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.15) project(MathFunctionsComponents) +# make cache variables for install destinations +include(GNUInstallDirs) + # specify the C++ standard set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -24,7 +27,7 @@ write_basic_package_version_file( # create config file configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" - INSTALL_DESTINATION lib/cmake/MathFunctions + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions NO_CHECK_REQUIRED_COMPONENTS_MACRO ) @@ -32,5 +35,5 @@ configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" - DESTINATION lib/cmake/MathFunctions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) diff --git a/Help/guide/importing-exporting/MathFunctionsComponents/SquareRoot/CMakeLists.txt b/Help/guide/importing-exporting/MathFunctionsComponents/SquareRoot/CMakeLists.txt index be5ae65..517c5e2 100644 --- a/Help/guide/importing-exporting/MathFunctionsComponents/SquareRoot/CMakeLists.txt +++ b/Help/guide/importing-exporting/MathFunctionsComponents/SquareRoot/CMakeLists.txt @@ -7,24 +7,24 @@ add_library(MathFunctions::SquareRoot ALIAS SquareRoot) target_include_directories(SquareRoot PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" - "$<INSTALL_INTERFACE:include>" + "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" ) # install the target and create export-set install(TARGETS SquareRoot EXPORT SquareRootTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) # install header file -install(FILES SquareRoot.h DESTINATION include) +install(FILES SquareRoot.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # generate and install export file install(EXPORT SquareRootTargets FILE MathFunctionsSquareRootTargets.cmake NAMESPACE MathFunctions:: - DESTINATION lib/cmake/MathFunctions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions ) diff --git a/Help/guide/importing-exporting/index.rst b/Help/guide/importing-exporting/index.rst index 2e6e06d..dd3efb8 100644 --- a/Help/guide/importing-exporting/index.rst +++ b/Help/guide/importing-exporting/index.rst @@ -202,6 +202,10 @@ project. Start by specifying the :command:`cmake_minimum_required` version and :language: cmake :end-before: # create library +The :module:`GNUInstallDirs` module is included in order to provide the +project with the flexibility to install into different platform layouts by +making the directories available as cache variables. + Create a library called ``MathFunctions`` with the :command:`add_library` command: @@ -636,7 +640,7 @@ We can use the :command:`find_package` command: :start-after: # find MathFunctions :end-before: # create executable -Create an exectuable: +Create an executable: .. literalinclude:: Downstream/CMakeLists.txt :language: cmake diff --git a/Help/guide/tutorial/Step12/CMakeLists.txt b/Help/guide/tutorial/Step12/CMakeLists.txt index eca79d9..1b0c826 100644 --- a/Help/guide/tutorial/Step12/CMakeLists.txt +++ b/Help/guide/tutorial/Step12/CMakeLists.txt @@ -110,6 +110,7 @@ write_basic_package_version_file( # install the configuration file install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake DESTINATION lib/cmake/MathFunctions ) diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt index 0947e41..8e23b77 100644 --- a/Help/manual/OPTIONS_BUILD.txt +++ b/Help/manual/OPTIONS_BUILD.txt @@ -76,6 +76,14 @@ native build system to choose a compiler or SDK. See the :variable:`CMAKE_GENERATOR_PLATFORM` variable for details. +``--toolchain <path-to-file>`` + Specify the cross compiling toolchain file, equivalent to setting + :variable:`CMAKE_TOOLCHAIN_FILE` variable. + +``--install-prefix <directory>`` + Specify the installation directory, used by the + :variable:`CMAKE_INSTALL_PREFIX` variable. Must be an absolute path. + ``-Wno-dev`` Suppress developer warnings. diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst index 2c2b04c..2b0de11 100644 --- a/Help/manual/cmake-compile-features.7.rst +++ b/Help/manual/cmake-compile-features.7.rst @@ -261,6 +261,7 @@ following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the versions specified for each: * ``Cray``: Cray Compiler Environment version 8.1+. +* ``Fujitsu``: Fujitsu HPC compiler 4.0+. * ``PGI``: PGI version 12.10+. * ``NVHPC``: NVIDIA HPC compilers version 11.0+. * ``TI``: Texas Instruments compiler. diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index af9a8ab..fe146de 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -350,6 +350,24 @@ look. PATHS ${PC_Foo_LIBRARY_DIRS} ) +Alternatively, if the library is available with multiple configurations, you can +use :module:`SelectLibraryConfigurations` to automatically set the +``Foo_LIBRARY`` variable instead: + +.. code-block:: cmake + + find_library(Foo_LIBRARY_RELEASE + NAMES foo + PATHS ${PC_Foo_LIBRARY_DIRS}/Release + ) + find_library(Foo_LIBRARY_DEBUG + NAMES foo + PATHS ${PC_Foo_LIBRARY_DIRS}/Debug + ) + + include(SelectLibraryConfigurations) + select_library_configurations(Foo) + If you have a good way of getting the version (from a header file, for example), you can use that information to set ``Foo_VERSION`` (although note that find modules have traditionally used ``Foo_VERSION_STRING``, diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst index 89739b7..0e530bc 100644 --- a/Help/manual/cmake-file-api.7.rst +++ b/Help/manual/cmake-file-api.7.rst @@ -443,7 +443,8 @@ Version 1 does not exist to avoid confusion with that from "hasInstallRule": true, "minimumCMakeVersion": { "string": "3.14" - } + }, + "jsonFile": "<file>" }, { "source": "sub", @@ -453,7 +454,8 @@ Version 1 does not exist to avoid confusion with that from "targetIndexes": [ 1 ], "minimumCMakeVersion": { "string": "3.14" - } + }, + "jsonFile": "<file>" } ], "projects": [ @@ -569,6 +571,13 @@ The members specific to ``codemodel`` objects are: :command:`install` rules, i.e. whether a ``make install`` or equivalent rule is available. + ``jsonFile`` + A JSON string specifying a path relative to the codemodel file + to another JSON file containing a + `"codemodel" version 2 "directory" object`_. + + This field was added in codemodel version 2.3. + ``projects`` A JSON array of entries corresponding to the top-level project and sub-projects defined in the build system. Each (sub-)project @@ -633,6 +642,187 @@ The members specific to ``codemodel`` objects are: to another JSON file containing a `"codemodel" version 2 "target" object`_. +"codemodel" version 2 "directory" object +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A codemodel "directory" object is referenced by a `"codemodel" version 2`_ +object's ``directories`` array. Each "directory" object is a JSON object +with members: + +``paths`` + A JSON object containing members: + + ``source`` + A string specifying the path to the source directory, represented + with forward slashes. If the directory is inside the top-level + source directory then the path is specified relative to that + directory (with ``.`` for the top-level source directory itself). + Otherwise the path is absolute. + + ``build`` + A string specifying the path to the build directory, represented + with forward slashes. If the directory is inside the top-level + build directory then the path is specified relative to that + directory (with ``.`` for the top-level build directory itself). + Otherwise the path is absolute. + +``installers`` + A JSON array of entries corresponding to :command:`install` rules. + Each entry is a JSON object containing members: + + ``component`` + A string specifying the component selected by the corresponding + :command:`install` command invocation. + + ``destination`` + Optional member that is present for specific ``type`` values below. + The value is a string specifying the install destination path. + The path may be absolute or relative to the install prefix. + + ``paths`` + Optional member that is present for specific ``type`` values below. + The value is a JSON array of entries corresponding to the paths + (files or directories) to be installed. Each entry is one of: + + * A string specifying the path from which a file or directory + is to be installed. The portion of the path not preceded by + a ``/`` also specifies the path (name) to which the file + or directory is to be installed under the destination. + + * A JSON object with members: + + ``from`` + A string specifying the path from which a file or directory + is to be installed. + + ``to`` + A string specifying the path to which the file or directory + is to be installed under the destination. + + In both cases the paths are represented with forward slashes. If + the "from" path is inside the top-level directory documented by the + corresponding ``type`` value, then the path is specified relative + to that directory. Otherwise the path is absolute. + + ``type`` + A string specifying the type of installation rule. The value is one + of the following, with some variants providing additional members: + + ``file`` + An :command:`install(FILES)` or :command:`install(PROGRAMS)` call. + The ``destination`` and ``paths`` members are populated, with paths + under the top-level *source* directory expressed relative to it. + The ``isOptional`` member may exist. + This type has no additional members. + + ``directory`` + An :command:`install(DIRECTORY)` call. + The ``destination`` and ``paths`` members are populated, with paths + under the top-level *source* directory expressed relative to it. + The ``isOptional`` member may exist. + This type has no additional members. + + ``target`` + An :command:`install(TARGETS)` call. + The ``destination`` and ``paths`` members are populated, with paths + under the top-level *build* directory expressed relative to it. + The ``isOptional`` member may exist. + This type has additional members ``targetId``, ``targetIndex``, + ``targetIsImportLibrary``, and ``targetInstallNamelink``. + + ``export`` + An :command:`install(EXPORT)` call. + The ``destination`` and ``paths`` members are populated, with paths + under the top-level *build* directory expressed relative to it. + The ``paths`` entries refer to files generated automatically by + CMake for installation, and their actual values are considered + private implementation details. + This type has additional members ``exportName`` and ``exportTargets``. + + ``script`` + An :command:`install(SCRIPT)` call. + This type has additional member ``scriptFile``. + + ``code`` + An :command:`install(CODE)` call. + This type has no additional members. + + ``isExcludeFromAll`` + Optional member that is present with boolean value ``true`` when + :command:`install` is called with the ``EXCLUDE_FROM_ALL`` option. + + ``isForAllComponents`` + Optional member that is present with boolean value ``true`` when + :command:`install(SCRIPT|CODE)` is called with the + ``ALL_COMPONENTS`` option. + + ``isOptional`` + Optional member that is present with boolean value ``true`` when + :command:`install` is called with the ``OPTIONAL`` option. + This is allowed when ``type`` is ``file``, ``directory``, or ``target``. + + ``targetId`` + Optional member that is present when ``type`` is ``target``. + The value is a string uniquely identifying the target to be installed. + This matches the ``id`` member of the target in the main + "codemodel" object's ``targets`` array. + + ``targetIndex`` + Optional member that is present when ``type`` is ``target``. + The value is an unsigned integer 0-based index into the main "codemodel" + object's ``targets`` array for the target to be installed. + + ``targetIsImportLibrary`` + Optional member that is present when ``type`` is ``target`` and + the installer is for a Windows DLL import library file or for an + AIX linker import file. If present, it has boolean value ``true``. + + ``targetInstallNamelink`` + Optional member that is present when ``type`` is ``target`` and + the installer corresponds to a target that may use symbolic links + to implement the :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` + target properties. + The value is a string indicating how the installer is supposed to + handle the symlinks: ``skip`` means the installer should skip the + symlinks and install only the real file, and ``only`` means the + installer should install only the symlinks and not the real file. + In all cases the ``paths`` member lists what it actually installs. + + ``exportName`` + Optional member that is present when ``type`` is ``export``. + The value is a string specifying the name of the export. + + ``exportTargets`` + Optional member that is present when ``type`` is ``export``. + The value is a JSON array of entries corresponding to the targets + included in the export. Each entry is a JSON object with members: + + ``id`` + A string uniquely identifying the target. This matches + the ``id`` member of the target in the main "codemodel" + object's ``targets`` array. + + ``index`` + An unsigned integer 0-based index into the main "codemodel" + object's ``targets`` array for the target. + + ``scriptFile`` + Optional member that is present when ``type`` is ``script``. + The value is a string specifying the path to the script file on disk, + represented with forward slashes. If the file is inside the top-level + source directory then the path is specified relative to that directory. + Otherwise the path is absolute. + + ``backtrace`` + Optional member that is present when a CMake language backtrace to + the :command:`install` or other command invocation that added this + installer is available. The value is an unsigned integer 0-based + index into the ``backtraceGraph`` member's ``nodes`` array. + +``backtraceGraph`` + A `"codemodel" version 2 "backtrace graph"`_ whose nodes are referenced + from ``backtrace`` members elsewhere in this "directory" object. + "codemodel" version 2 "target" object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -964,40 +1154,48 @@ with members: with forward slashes. ``backtraceGraph`` - A JSON object describing the graph of backtraces whose nodes are - referenced from ``backtrace`` members elsewhere. The members are: + A `"codemodel" version 2 "backtrace graph"`_ whose nodes are referenced + from ``backtrace`` members elsewhere in this "target" object. - ``nodes`` - A JSON array listing nodes in the backtrace graph. Each entry - is a JSON object with members: +"codemodel" version 2 "backtrace graph" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ``file`` - An unsigned integer 0-based index into the backtrace ``files`` array. +The ``backtraceGraph`` member of a `"codemodel" version 2 "directory" object`_, +or `"codemodel" version 2 "target" object`_ is a JSON object describing a +graph of backtraces. Its nodes are referenced from ``backtrace`` members +elsewhere in the containing object. The backtrace graph object members are: - ``line`` - An optional member present when the node represents a line within - the file. The value is an unsigned integer 1-based line number. +``nodes`` + A JSON array listing nodes in the backtrace graph. Each entry + is a JSON object with members: - ``command`` - An optional member present when the node represents a command - invocation within the file. The value is an unsigned integer - 0-based index into the backtrace ``commands`` array. + ``file`` + An unsigned integer 0-based index into the backtrace ``files`` array. - ``parent`` - An optional member present when the node is not the bottom of - the call stack. The value is an unsigned integer 0-based index - of another entry in the backtrace ``nodes`` array. + ``line`` + An optional member present when the node represents a line within + the file. The value is an unsigned integer 1-based line number. - ``commands`` - A JSON array listing command names referenced by backtrace nodes. - Each entry is a string specifying a command name. + ``command`` + An optional member present when the node represents a command + invocation within the file. The value is an unsigned integer + 0-based index into the backtrace ``commands`` array. - ``files`` - A JSON array listing CMake language files referenced by backtrace nodes. - Each entry is a string specifying the path to a file, represented - with forward slashes. If the file is inside the top-level source - directory then the path is specified relative to that directory. - Otherwise the path is absolute. + ``parent`` + An optional member present when the node is not the bottom of + the call stack. The value is an unsigned integer 0-based index + of another entry in the backtrace ``nodes`` array. + +``commands`` + A JSON array listing command names referenced by backtrace nodes. + Each entry is a string specifying a command name. + +``files`` + A JSON array listing CMake language files referenced by backtrace nodes. + Each entry is a string specifying the path to a file, represented + with forward slashes. If the file is inside the top-level source + directory then the path is specified relative to that directory. + Otherwise the path is absolute. Object Kind "cache" ------------------- @@ -1244,7 +1442,7 @@ The members specific to ``toolchains`` objects are: ``language`` A JSON string specifying the toolchain language, like C or CXX. Language - names are the same as langauge names that can be passed to the + names are the same as language names that can be passed to the :command:`project` command. Because CMake only supports a single toolchain per language, this field can be used as a key. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 7bc490f..775067a 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -940,6 +940,29 @@ which is just the string ``tgt``. :ref:`Target Usage Requirements` this is the consuming target rather than the target specifying the requirement. +.. genex:: $<TARGET_RUNTIME_DLLS:tgt> + + List of DLLs that the target depends on at runtime. This is determined by + the locations of all the ``SHARED`` and ``MODULE`` targets in the target's + transitive dependencies. Using this generator expression on targets other + than executables, ``SHARED`` libraries, and ``MODULE`` libraries is an error. + On non-DLL platforms, it evaluates to an empty string. + + This generator expression can be used to copy all of the DLLs that a target + depends on into its output directory in a ``POST_BUILD`` custom command. For + example: + + .. code-block:: cmake + + find_package(foo REQUIRED) + + add_executable(exe main.c) + target_link_libraries(exe PRIVATE foo::foo foo::bar) + add_custom_command(TARGET exe POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe> + COMMAND_EXPAND_LISTS + ) + .. genex:: $<INSTALL_PREFIX> Content of the install prefix when the target is exported via diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 17c1a1e..141eeaa 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -185,6 +185,7 @@ They are normally called through the :command:`find_package` command. /module/FindMPEG /module/FindMPEG2 /module/FindMPI + /module/FindMsys /module/FindODBC /module/FindOpenACC /module/FindOpenAL diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index bd6b2f0..62ccb01 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -51,6 +51,18 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used to determine whether to report an error on use of deprecated macros or functions. +Policies Introduced by CMake 3.21 +================================= + +.. toctree:: + :maxdepth: 1 + + CMP0125: find_(path|file|library|program) have consistent behavior for cache variables. </policy/CMP0125> + CMP0124: foreach() loop variables are only available in the loop scope. </policy/CMP0124> + CMP0123: ARMClang cpu/arch compile and link flags must be set explicitly. </policy/CMP0123> + CMP0122: UseSWIG use standard library name conventions for csharp language. </policy/CMP0122> + CMP0121: The list command detects invalid indices. </policy/CMP0121> + Policies Introduced by CMake 3.20 ================================= diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 467818d..57c8ccf 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -39,7 +39,7 @@ The root object recognizes the following fields: ``version`` A required integer representing the version of the JSON schema. - The supported versions are ``1`` and ``2``. + The supported versions are ``1``, ``2``, and ``3``. ``cmakeMinimumRequired`` @@ -70,17 +70,17 @@ The root object recognizes the following fields: ``configurePresets`` An optional array of `Configure Preset`_ objects. - This is allowed in preset files specifying version 1 or above. + This is allowed in preset files specifying version ``1`` or above. ``buildPresets`` An optional array of `Build Preset`_ objects. - This is allowed in preset files specifying version 2 or above. + This is allowed in preset files specifying version ``2`` or above. ``testPresets`` An optional array of `Test Preset`_ objects. - This is allowed in preset files specifying version 2 or above. + This is allowed in preset files specifying version ``2`` or above. Configure Preset ^^^^^^^^^^^^^^^^ @@ -119,6 +119,11 @@ that may contain the following fields: This field can also be a string, which is equivalent to an array containing one string. +``condition`` + + An optional `Condition`_ object. This is allowed in preset files specifying + version ``3`` or above. + ``vendor`` An optional map containing vendor-specific information. CMake does not @@ -140,7 +145,9 @@ that may contain the following fields: An optional string representing the generator to use for the preset. If ``generator`` is not specified, it must be inherited from the - ``inherits`` preset (unless this preset is ``hidden``). + ``inherits`` preset (unless this preset is ``hidden``). In version ``3`` + or above, this field may be omitted to fall back to regular generator + discovery procedure. Note that for Visual Studio generators, unlike in the command line ``-G`` argument, you cannot include the platform name in the generator name. Use @@ -175,13 +182,29 @@ that may contain the following fields: ignore the field, but the IDE can use them to set up the environment before invoking CMake. +``toolchainFile`` + + An optional string representing the path to the toolchain file. + This field supports `macro expansion`_. If a relative path is specified, + it is calculated relative to the build directory, and if not found, + relative to the source directory. Takes precedence over any `CMAKE_TOOLCHAIN_FILE` + value. This is allowed in preset files specifying version ``3`` or above. + ``binaryDir`` An optional string representing the path to the output binary directory. This field supports `macro expansion`_. If a relative path is specified, it is calculated relative to the source directory. If ``binaryDir`` is not specified, it must be inherited from the ``inherits`` preset (unless this - preset is ``hidden``). + preset is ``hidden``). In version ``3`` or above, this field may be + omitted. + +``installDir`` + + An optional string representing the path to the installation directory. + This field supports `macro expansion`_. If a relative path is specified, + it is calculated relative to the source directory. This is allowed in + preset files specifying version ``3`` or above. ``cmakeExecutable`` @@ -338,6 +361,11 @@ that may contain the following fields: This field can also be a string, which is equivalent to an array containing one string. +``condition`` + + An optional `Condition`_ object. This is allowed in preset files specifying + version ``3`` or above. + ``vendor`` An optional map containing vendor-specific information. CMake does not @@ -457,6 +485,11 @@ that may contain the following fields: This field can also be a string, which is equivalent to an array containing one string. +``condition`` + + An optional `Condition`_ object. This is allowed in preset files specifying + version ``3`` or above. + ``vendor`` An optional map containing vendor-specific information. CMake does not @@ -782,6 +815,103 @@ that may contain the following fields: Equivalent to passing ``--no-tests=ignore`` on the command line. +Condition +^^^^^^^^^ + +The ``condition`` field of a preset, allowed in preset files specifying version +``3`` or above, is used to determine whether or not the preset is enabled. For +example, this can be used to disable a preset on platforms other than Windows. +``condition`` may be either a boolean, ``null``, or an object. If it is a +boolean, the boolean indicates whether the preset is enabled or disabled. If it +is ``null``, the preset is enabled, but the ``null`` condition is not inherited +by any presets that may inherit from the preset. Sub-conditions (for example in +a ``not``, ``anyOf``, or ``allOf`` condition) may not be ``null``. If it is an +object, it has the following fields: + +``type`` + + A required string with one of the following values: + + ``"const"`` + + Indicates that the condition is constant. This is equivalent to using a + boolean in place of the object. The condition object will have the + following additional fields: + + ``value`` + + A required boolean which provides a constant value for the condition's + evaluation. + + ``"equals"`` + + ``"notEquals"`` + + Indicates that the condition compares two strings to see if they are equal + (or not equal). The condition object will have the following additional + fields: + + ``lhs`` + + First string to compare. This field supports macro expansion. + + ``rhs`` + + Second string to compare. This field supports macro expansion. + + ``"inList"`` + + ``"notInList"`` + + Indicates that the condition searches for a string in a list of strings. + The condition object will have the following additional fields: + + ``string`` + + A required string to search for. This field supports macro expansion. + + ``list`` + + A required list of strings to search. This field supports macro + expansion, and uses short-circuit evaluation. + + ``"matches"`` + + ``"notMatches"`` + + Indicates that the condition searches for a regular expression in a string. + The condition object will have the following additional fields: + + ``string`` + + A required string to search. This field supports macro expansion. + + ``regex`` + + A required regular expression to search for. This field supports macro + expansion. + + ``"anyOf"`` + + ``"allOf"`` + + Indicates that the condition is an aggregation of zero or more nested + conditions. The condition object will have the following additional fields: + + ``conditions`` + + A required array of condition objects. These conditions use short-circuit + evaluation. + + ``"not"`` + + Indicates that the condition is an inversion of another condition. The + condition object will have the following additional fields: + + ``condition`` + + A required condition object. + Macro Expansion ^^^^^^^^^^^^^^^ @@ -823,6 +953,12 @@ Recognized macros include: test presets, this will evaluate to the generator specified by ``configurePreset``. +``${hostSystemName}`` + + The name of the host operating system. Contains the same value as + :variable:`CMAKE_HOST_SYSTEM_NAME`. This is allowed in preset files + specifying version ``3`` or above. + ``${dollar}`` A literal dollar sign (``$``). diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index af170da..4f2c1b0 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -21,6 +21,7 @@ Properties of Global Scope /prop_gbl/AUTOMOC_SOURCE_GROUP /prop_gbl/AUTOMOC_TARGETS_FOLDER /prop_gbl/AUTORCC_SOURCE_GROUP + /prop_gbl/AUTOUIC_SOURCE_GROUP /prop_gbl/CMAKE_C_KNOWN_FEATURES /prop_gbl/CMAKE_CUDA_KNOWN_FEATURES /prop_gbl/CMAKE_CXX_KNOWN_FEATURES @@ -402,7 +403,9 @@ Properties on Targets /prop_tgt/XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY /prop_tgt/XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY /prop_tgt/XCODE_EMBED_type + /prop_tgt/XCODE_EMBED_type_CODE_SIGN_ON_COPY /prop_tgt/XCODE_EMBED_type_PATH + /prop_tgt/XCODE_EMBED_type_REMOVE_HEADERS_ON_COPY /prop_tgt/XCODE_EXPLICIT_FILE_TYPE /prop_tgt/XCODE_GENERATE_SCHEME /prop_tgt/XCODE_LINK_BUILD_PHASE_MODE diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index 1ededee..a941310 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -96,8 +96,8 @@ Cross Compiling =============== If :manual:`cmake(1)` is invoked with the command line parameter -``-DCMAKE_TOOLCHAIN_FILE=path/to/file``, the file will be loaded early to set -values for the compilers. +``--toolchain path/to/file`` or ``-DCMAKE_TOOLCHAIN_FILE=path/to/file``, the +file will be loaded early to set values for the compilers. The :variable:`CMAKE_CROSSCOMPILING` variable is set to true when CMake is cross-compiling. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 4317dd4..33beba9 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -130,6 +130,7 @@ Variables that Provide Information /variable/PROJECT-NAME_BINARY_DIR /variable/PROJECT-NAME_DESCRIPTION /variable/PROJECT-NAME_HOMEPAGE_URL + /variable/PROJECT-NAME_IS_TOP_LEVEL /variable/PROJECT-NAME_SOURCE_DIR /variable/PROJECT-NAME_VERSION /variable/PROJECT-NAME_VERSION_MAJOR @@ -139,6 +140,7 @@ Variables that Provide Information /variable/PROJECT_BINARY_DIR /variable/PROJECT_DESCRIPTION /variable/PROJECT_HOMEPAGE_URL + /variable/PROJECT_IS_TOP_LEVEL /variable/PROJECT_NAME /variable/PROJECT_SOURCE_DIR /variable/PROJECT_VERSION @@ -243,6 +245,7 @@ Variables that Change Behavior /variable/CMAKE_SYSTEM_LIBRARY_PATH /variable/CMAKE_SYSTEM_PREFIX_PATH /variable/CMAKE_SYSTEM_PROGRAM_PATH + /variable/CMAKE_TLS_VERIFY /variable/CMAKE_USER_MAKE_RULES_OVERRIDE /variable/CMAKE_WARN_DEPRECATED /variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION @@ -644,6 +647,7 @@ Variables for CTest /variable/CTEST_RESOURCE_SPEC_FILE /variable/CTEST_RUN_CURRENT_SCRIPT /variable/CTEST_SCP_COMMAND + /variable/CTEST_SCRIPT_DIRECTORY /variable/CTEST_SITE /variable/CTEST_SUBMIT_URL /variable/CTEST_SOURCE_DIRECTORY diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 02828ac..2d639b6 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -381,9 +381,9 @@ Options ``--preset <preset>``, ``--preset=<preset>`` Reads a :manual:`preset <cmake-presets(7)>` from ``<path-to-source>/CMakePresets.json`` and - ``<path-to-source>/CMakeUserPresets.json``. The preset specifies the - generator and the build directory, and optionally a list of variables and - other arguments to pass to CMake. The current working directory must contain + ``<path-to-source>/CMakeUserPresets.json``. The preset may specify the + generator and the build directory, and a list of variables and other + arguments to pass to CMake. The current working directory must contain CMake preset files. The :manual:`CMake GUI <cmake-gui(1)>` can also recognize ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. For full details on these files, see :manual:`cmake-presets(7)`. @@ -575,6 +575,12 @@ Available commands are: ``true`` if the generator supports toolsets and ``false`` otherwise. ``platformSupport`` ``true`` if the generator supports platforms and ``false`` otherwise. + ``supportedPlatforms`` + .. versionadded:: 3.21 + + Optional member that may be present when the generator supports + platform specification via :variable:`CMAKE_GENERATOR_PLATFORM` + (``-A ...``). The value is a list of platforms known to be supported. ``extraGenerators`` A list of strings with all the extra generators compatible with the generator. @@ -702,7 +708,7 @@ Available commands are: ``remove [-f] <file>...`` .. deprecated:: 3.17 - Remove the file(s). The planned behaviour was that if any of the + Remove the file(s). The planned behavior was that if any of the listed files already do not exist, the command returns a non-zero exit code, but no message is logged. The ``-f`` option changes the behavior to return a zero exit code (i.e. success) in such situations instead. diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 175359d..811997c 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -134,6 +134,12 @@ Options This option tells CTest to write all its output to a ``<file>`` log file. +``--output-junit <file>`` + Write test results in JUnit format. + + This option tells CTest to write test results to a ``<file>`` JUnit XML file. + If ``<file>`` already exists it will be overwritten. + ``-N,--show-only[=<format>]`` Disable actual execution of tests. @@ -155,7 +161,10 @@ Options Run tests with labels matching regular expression. This option tells CTest to run only the tests whose labels match the - given regular expression. + given regular expression. When more than one ``-L`` option is given, + a test will only be run if each regular expression matches at least one + of the test's labels (i.e. the multiple ``-L`` labels form an ``AND`` + relationship). See `Label Matching`_. ``-R <regex>, --tests-regex <regex>`` Run tests matching regular expression. @@ -173,7 +182,10 @@ Options Exclude tests with labels matching regular expression. This option tells CTest to NOT run the tests whose labels match the - given regular expression. + given regular expression. When more than one ``-LE`` option is given, + a test will only be excluded if each regular expression matches at least one + of the test's labels (i.e. the multiple ``-LE`` labels form an ``AND`` + relationship). See `Label Matching`_. ``-FA <regex>, --fixture-exclude-any <regex>`` Exclude fixtures matching ``<regex>`` from automatically adding any tests to @@ -398,6 +410,46 @@ Specify the directory in which to look for tests. .. include:: OPTIONS_HELP.txt +.. _`Label Matching`: + +Label Matching +============== + +Tests may have labels attached to them. Tests may be included +or excluded from a test run by filtering on the labels. +Each individual filter is a regular expression applied to +the labels attached to a test. + +When ``-L`` is used, in order for a test to be included in a +test run, each regular expression must match at least one +label. Using more than one ``-L`` option means "match **all** +of these". + +The ``-LE`` option works just like ``-L``, but excludes tests +rather than including them. A test is excluded if each regular +expression matches at least one label. + +If a test has no labels attached to it, then ``-L`` will never +include that test, and ``-LE`` will never exclude that test. +As an example of tests with labels, consider five tests, +with the following labels: + +* *test1* has labels *tuesday* and *production* +* *test2* has labels *tuesday* and *test* +* *test3* has labels *wednesday* and *production* +* *test4* has label *wednesday* +* *test5* has labels *friday* and *test* + +Running ``ctest`` with ``-L tuesday -L test`` will select *test2*, which has +both labels. Running CTest with ``-L test`` will select *test2* and +*test5*, because both of them have a label that matches that regular +expression. + +Because the matching works with regular expressions, take note that +running CTest with ``-L es`` will match all five tests. +To select the *tuesday* and *wednesday* tests together, use a single +regular expression that matches either of them, like ``-L "tue|wed"``. + .. _`Label and Subproject Summary`: Label and Subproject Summary @@ -1043,6 +1095,8 @@ Configuration settings include: * `CTest Script`_ variable: :variable:`CTEST_TEST_TIMEOUT` * :module:`CTest` module variable: ``DART_TESTING_TIMEOUT`` +To report extra test values to CDash, see :ref:`Additional Test Measurements`. + .. _`CTest Coverage Step`: CTest Coverage Step @@ -1619,4 +1673,4 @@ See Also .. include:: LINKS.txt -.. _`CDash`: http://cdash.org/ +_`CDash`: https://cdash.org diff --git a/Help/manual/presets/example.json b/Help/manual/presets/example.json index dfc2910..346f342 100644 --- a/Help/manual/presets/example.json +++ b/Help/manual/presets/example.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "cmakeMinimumRequired": { "major": 3, "minor": 20, @@ -35,6 +35,17 @@ "displayName": "Ninja Multi-Config", "description": "Default build using Ninja Multi-Config generator", "generator": "Ninja Multi-Config" + }, + { + "name": "windows-only", + "inherits": "default", + "displayName": "Windows-only configuration", + "description": "This build is only available on Windows", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } } ], "buildPresets": [ diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index f8faf3d..767e80b 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -11,7 +11,7 @@ }, "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, "vendor": { "$ref": "#/definitions/vendor" }, - "configurePresets": { "$ref": "#/definitions/configurePresets"} + "configurePresets": { "$ref": "#/definitions/configurePresetsV1"} }, "additionalProperties": false }, @@ -23,9 +23,23 @@ }, "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, "vendor": { "$ref": "#/definitions/vendor" }, - "configurePresets": { "$ref": "#/definitions/configurePresets"}, - "buildPresets": { "$ref": "#/definitions/buildPresets"}, - "testPresets": { "$ref": "#/definitions/testPresets"} + "configurePresets": { "$ref": "#/definitions/configurePresetsV1"}, + "buildPresets": { "$ref": "#/definitions/buildPresetsV2"}, + "testPresets": { "$ref": "#/definitions/testPresetsV2"} + }, + "additionalProperties": false + }, + { + "properties": { + "version": { + "const": 3, + "description": "A required integer representing the version of the JSON schema." + }, + "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, + "vendor": { "$ref": "#/definitions/vendor" }, + "configurePresets": { "$ref": "#/definitions/configurePresetsV3"}, + "buildPresets": { "$ref": "#/definitions/buildPresetsV3"}, + "testPresets": { "$ref": "#/definitions/testPresetsV3"} }, "additionalProperties": false } @@ -58,7 +72,34 @@ "description": "An optional map containing vendor-specific information. CMake does not interpret the contents of this field except to verify that it is a map if it does exist. However, the keys should be a vendor-specific domain name followed by a /-separated path. For example, the Example IDE 1.0 could use example.com/ExampleIDE/1.0. The value of each field can be anything desired by the vendor, though will typically be a map.", "properties": {} }, - "configurePresets": { + "configurePresetsItemsV3": { + "type": "array", + "description": "A configure preset object.", + "items": { + "type": "object", + "description": "A configure preset object.", + "properties": { + "binaryDir": { + "type": "string", + "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, the path is calculated using regular methods." + }, + "generator": { + "type": "string", + "description": "An optional string representing the generator to use for the preset. If generator is not specified, the normal generator discovery procedure is used. Note that for Visual Studio generators, unlike in the command line -G argument, you cannot include the platform name in the generator name. Use the architecture field instead." + }, + "toolchainFile": { + "type": "string", + "description": "An optional string representing the path to the toolchain file. This field supports macro expansion. If a relative path is specified, it is calculated relative to the build directory, and if not found, relative to the source directory." + }, + "installDir": { + "type": "string", + "description": "An optional string representing the path to the installation directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory." + }, + "condition": { "$ref": "#/definitions/topCondition" } + } + } + }, + "configurePresetsItemsV1": { "type": "array", "description": "An optional array of configure preset objects.", "items": { @@ -302,6 +343,37 @@ }, "additionalProperties": false } + } + } + }, + "configurePresetsV3": { + "type": "array", + "description": "An optional array of configure preset objects.", + "allOf": [ + { "$ref": "#/definitions/configurePresetsItemsV1" }, + { "$ref": "#/definitions/configurePresetsItemsV3" } + ], + "items": { + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "generator": {}, + "architecture": {}, + "toolset": {}, + "toolchainFile": {}, + "binaryDir": {}, + "installDir": {}, + "cmakeExecutable": {}, + "cacheVariables": {}, + "environment": {}, + "warnings": {}, + "errors": {}, + "debug": {}, + "condition": {} }, "required": [ "name" @@ -309,7 +381,48 @@ "additionalProperties": false } }, - "buildPresets": { + "configurePresetsV1": { + "type": "array", + "description": "An optional array of configure preset objects.", + "allOf": [ + { "$ref": "#/definitions/configurePresetsItemsV1" } + ], + "items": { + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "generator": {}, + "architecture": {}, + "toolset": {}, + "binaryDir": {}, + "cmakeExecutable": {}, + "cacheVariables": {}, + "environment": {}, + "warnings": {}, + "errors": {}, + "debug": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "buildPresetsItemsV3": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "items": { + "type": "object", + "properties": { + "condition": { "$ref": "#/definitions/topCondition" } + } + } + }, + "buildPresetsItemsV2": { "type": "array", "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", "items": { @@ -427,11 +540,84 @@ }, "required": [ "name" + ] + } + }, + "buildPresetsV3": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "allOf": [ + { "$ref": "#/definitions/buildPresetsItemsV3" }, + { "$ref": "#/definitions/buildPresetsItemsV2" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "jobs": {}, + "targets": {}, + "configuration": {}, + "cleanFirst": {}, + "verbose": {}, + "nativeToolOptions": {}, + "condition": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "buildPresetsV2": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "allOf": [ + { "$ref": "#/definitions/buildPresetsItemsV2" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "jobs": {}, + "targets": {}, + "configuration": {}, + "cleanFirst": {}, + "verbose": {}, + "nativeToolOptions": {} + }, + "required": [ + "name" ], "additionalProperties": false } }, - "testPresets": { + "testPresetsItemsV3": { + "type": "array", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "items": { + "type": "object", + "properties": { + "condition": { "$ref": "#/definitions/topCondition" } + } + } + }, + "testPresetsItemsV2": { "type": "array", "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", "items": { @@ -743,9 +929,312 @@ }, "required": [ "name" + ] + } + }, + "testPresetsV3": { + "type": "array", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "allOf": [ + { "$ref": "#/definitions/testPresetsItemsV2" }, + { "$ref": "#/definitions/testPresetsItemsV3" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "configuration": {}, + "overwriteConfigurationFile": {}, + "output": {}, + "filter": {}, + "execution": {}, + "condition": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "testPresetsV2": { + "type": "array", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "allOf": [ + { "$ref": "#/definitions/testPresetsItemsV2" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "configuration": {}, + "overwriteConfigurationFile": {}, + "output": {}, + "filter": {}, + "execution": {} + }, + "required": [ + "name" ], "additionalProperties": false } + }, + "condition": { + "anyOf": [ + { + "type": "boolean", + "description": "A boolean which provides a constant value for the condition's evaluation." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "const" + }, + "value": { + "type": "boolean", + "description": "A required boolean which provides a constant value for the condition's evaluation." + } + }, + "required": [ + "type", + "value" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "equals" + }, + "lhs": { + "type": "string", + "description": "First string to compare. This field supports macro expansion." + }, + "rhs": { + "type": "string", + "description": "Second string to compare. This field supports macro expansion." + } + }, + "required": [ + "type", + "lhs", + "rhs" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "notEquals" + }, + "lhs": { + "type": "string", + "description": "First string to compare. This field supports macro expansion." + }, + "rhs": { + "type": "string", + "description": "Second string to compare. This field supports macro expansion." + } + }, + "required": [ + "type", + "lhs", + "rhs" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "inList" + }, + "string": { + "type": "string", + "description": "A required string to search for. This field supports macro expansion." + }, + "list": { + "type": "array", + "description": "A required list of strings to search. This field supports macro expansion, and uses short-circuit evaluation.", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "string", + "list" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "notInList" + }, + "string": { + "type": "string", + "description": "A required string to search for. This field supports macro expansion." + }, + "list": { + "type": "array", + "description": "A required list of strings to search. This field supports macro expansion, and uses short-circuit evaluation.", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "string", + "list" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "matches" + }, + "string": { + "type": "string", + "description": "A required string to search. This field supports macro expansion." + }, + "regex": { + "type": "string", + "description": "A required regular expression to search for. This field supports macro expansion." + } + }, + "required": [ + "type", + "string", + "regex" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "notMatches" + }, + "string": { + "type": "string", + "description": "A required string to search. This field supports macro expansion." + }, + "regex": { + "type": "string", + "description": "A required regular expression to search for. This field supports macro expansion." + } + }, + "required": [ + "type", + "string", + "regex" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "anyOf" + }, + "conditions": { + "type": "array", + "description": "A required array of condition objects. These conditions use short-circuit evaluation.", + "items": { "$ref": "#/definitions/condition" } + } + }, + "required": [ + "type", + "conditions" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "allOf" + }, + "conditions": { + "type": "array", + "description": "A required array of condition objects. These conditions use short-circuit evaluation.", + "items": { "$ref": "#/definitions/condition" } + } + }, + "required": [ + "type", + "conditions" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "A required string specifying the type of the condition.", + "const": "not" + }, + "condition": { "$ref": "#/definitions/condition" } + }, + "required": [ + "type", + "condition" + ], + "additionalProperties": false + } + ] + }, + "topCondition": { + "anyOf": [ + { "$ref": "#/definitions/condition" }, + { + "type": "null", + "description": "Null indicates that the condition always evaluates to true and is not inherited." + } + ] } } } diff --git a/Help/module/FindMsys.rst b/Help/module/FindMsys.rst new file mode 100644 index 0000000..fc5495c --- /dev/null +++ b/Help/module/FindMsys.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindMsys.cmake diff --git a/Help/policy/CMP0104.rst b/Help/policy/CMP0104.rst index 7c7a16e..b125729 100644 --- a/Help/policy/CMP0104.rst +++ b/Help/policy/CMP0104.rst @@ -41,7 +41,7 @@ Examples .. code-block:: cmake - set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72) + set_target_properties(tgt PROPERTIES CUDA_ARCHITECTURES "35;50;72") Generates code for real and virtual architectures ``30``, ``50`` and ``72``. diff --git a/Help/policy/CMP0110.rst b/Help/policy/CMP0110.rst index 25a0008..6977d41 100644 --- a/Help/policy/CMP0110.rst +++ b/Help/policy/CMP0110.rst @@ -8,7 +8,7 @@ CMP0110 :command:`add_test` can now (officially) create tests with whitespace and other special characters in its name. Before CMake version 3.19 that was not allowed, however, it was possible to work around this limitation by explicitly -putting escaped quotes arount the test's name in the ``add_test`` command. +putting escaped quotes around the test's name in the ``add_test`` command. Although never officially supported several projects in the wild found and implemented this workaround. However, the new change which officially allows diff --git a/Help/policy/CMP0121.rst b/Help/policy/CMP0121.rst new file mode 100644 index 0000000..326e7d5 --- /dev/null +++ b/Help/policy/CMP0121.rst @@ -0,0 +1,21 @@ +CMP0121 +------- + +.. versionadded:: 3.21 + +The :command:`list` command now detects invalid indices. + +Prior to CMake version 3.21, the :command:`list` command's ``GET``, +``INSERT``, ``SUBLIST``, and ``REMOVE_AT`` subcommands did not detect invalid +index arguments. + +The ``OLD`` behavior of this policy is for invalid indices to be treated as +their integer value (if any) at the start of the string. For example, +``2good4you`` is a ``2`` and ``not_an_integer`` is a ``0``. The ``NEW`` +behavior is for invalid indices to trigger an error. + +This policy was introduced in CMake version 3.21. CMake version |release| +warns when the policy is not set and uses ``OLD`` behavior. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/policy/CMP0122.rst b/Help/policy/CMP0122.rst new file mode 100644 index 0000000..1ff8c48 --- /dev/null +++ b/Help/policy/CMP0122.rst @@ -0,0 +1,17 @@ +CMP0122 +------- + +.. versionadded:: 3.21 + +:module:`UseSWIG` use library name conventions for ``CSharp`` language. + +Starting with CMake 3.21, :module:`UseSWIG` generates now a library using +default naming conventions. This policy provides compatibility with projects +that expect the legacy behavior. + +This policy was introduced in CMake version 3.21. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/policy/CMP0123.rst b/Help/policy/CMP0123.rst new file mode 100644 index 0000000..e09b5ec --- /dev/null +++ b/Help/policy/CMP0123.rst @@ -0,0 +1,32 @@ +CMP0123 +------- + +.. versionadded:: 3.21 + +``ARMClang`` cpu/arch compile and link flags must be set explicitly. + +CMake 3.20 and lower automatically maps the :variable:`CMAKE_SYSTEM_PROCESSOR` +variable and an undocumented ``CMAKE_SYSTEM_ARCH`` to compile and link options +for ``ARMClang``. For example, the ``-mcpu=cortex-m33`` flag is added when +:variable:`CMAKE_SYSTEM_PROCESSOR` equals ``cortex-m33``. CMake requires +projects to set either variable or it raises a fatal error. However, the +project may need to additionally specify CPU features using e.g. +``-mcpu=cortex-m33+nodsp``, conflicting with the ``-mcpu=cortex-m33`` added +by CMake. This results in either link errors or unusable binaries. + +CMake 3.21 and above prefer instead to not add any cpu/arch compile and link +flags automatically. Instead, projects must specify them explicitly. +This policy provides compatibility for projects that have not been updated. + +The ``OLD`` behavior of this policy requires projects that use ``ARMClang`` +to set either :variable:`CMAKE_SYSTEM_PROCESSOR` or ``CMAKE_SYSTEM_ARCH`` +and it automatically adds a compile option ``-mcpu=`` or ``-march=`` and +a link option ``--cpu=`` based on those variables. The ``NEW`` behavior +does not add compile or link options, and projects are responsible for +setting correct options. + +This policy was introduced in CMake version 3.21. CMake version |release| +warns when the policy is not set and uses ``OLD`` behavior. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/policy/CMP0124.rst b/Help/policy/CMP0124.rst new file mode 100644 index 0000000..88d03e3 --- /dev/null +++ b/Help/policy/CMP0124.rst @@ -0,0 +1,20 @@ +CMP0124 +------- + +.. versionadded:: 3.21 + +The loop variables created by :command:`foreach` command have now their scope +restricted to the loop scope. + +Starting with CMake 3.21, the :command:`foreach` command ensures that the loop +variables have their scope restricted to the loop scope. + +The ``OLD`` behavior for this policy let the loop variables to exist, with an +empty value, in the outer scope of loop scope. + +This policy was introduced in CMake version 3.21. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn when the policy +is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/policy/CMP0125.rst b/Help/policy/CMP0125.rst new file mode 100644 index 0000000..19571dc --- /dev/null +++ b/Help/policy/CMP0125.rst @@ -0,0 +1,25 @@ +CMP0125 +------- + +.. versionadded:: 3.21 + +The :command:`find_file`, :command:`find_path`, :command:`find_library` and +:command:`find_program` commands handle cache variables in the same way +regardless of whether they are defined on the command line, with or without a +type, or using the :command:`set` command. + +Starting with CMake 3.21, the :command:`find_file`, :command:`find_path`, +:command:`find_library`, and :command:`find_program` commands ensure that the +cache variables will be used in the same way regardless how they were defined +and the result will be always successful if the searched artifact exists. + +The ``OLD`` behavior for this policy is to have the find commands' behaviors +differ depending on how the cache variable is defined. The ``NEW`` behavior for +this policy is to have consistent behavior. + +This policy was introduced in CMake version 3.21. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn when the policy +is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst index 2e32320..07c732b 100644 --- a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst +++ b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst @@ -3,15 +3,16 @@ AUTOGEN_SOURCE_GROUP .. versionadded:: 3.9 -Name of the :command:`source_group` for :prop_tgt:`AUTOMOC` and -:prop_tgt:`AUTORCC` generated files. +Name of the :command:`source_group` for :prop_tgt:`AUTOMOC`, +:prop_tgt:`AUTORCC` and :prop_tgt:`AUTOUIC` generated files. -Files generated by :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTORCC` are not always -known at configure time and therefore can't be passed to -:command:`source_group`. -:prop_gbl:`AUTOGEN_SOURCE_GROUP` an be used instead to generate or select -a source group for :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTORCC` generated files. +Files generated by :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC` and +:prop_tgt:`AUTOUIC` are not always known at configure time and therefore can't +be passed to :command:`source_group`. +:prop_gbl:`AUTOGEN_SOURCE_GROUP` can be used instead to generate or select +a source group for :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC` and +:prop_tgt:`AUTOUIC` generated files. -For :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTORCC` specific overrides see -:prop_gbl:`AUTOMOC_SOURCE_GROUP` and :prop_gbl:`AUTORCC_SOURCE_GROUP` -respectively. +For :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC` and :prop_tgt:`AUTOUIC` specific +overrides see :prop_gbl:`AUTOMOC_SOURCE_GROUP`, :prop_gbl:`AUTORCC_SOURCE_GROUP` +and :prop_gbl:`AUTOUIC_SOURCE_GROUP` respectively. diff --git a/Help/prop_gbl/AUTOUIC_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOUIC_SOURCE_GROUP.rst new file mode 100644 index 0000000..79ebfe0 --- /dev/null +++ b/Help/prop_gbl/AUTOUIC_SOURCE_GROUP.rst @@ -0,0 +1,9 @@ +AUTOUIC_SOURCE_GROUP +-------------------- + +.. versionadded:: 3.21 + +Name of the :command:`source_group` for :prop_tgt:`AUTOUIC` generated files. + +When set this is used instead of :prop_gbl:`AUTOGEN_SOURCE_GROUP` for +files generated by :prop_tgt:`AUTOUIC`. diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst index 7166381..2bd0feb 100644 --- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst @@ -24,6 +24,12 @@ The features known to this version of CMake are: ``c_std_11`` Compiler mode is at least C 11. +``c_std_17`` + Compiler mode is at least C 17. + +``c_std_23`` + Compiler mode is at least C 23. + ``c_function_prototypes`` Function prototypes, as defined in ``ISO/IEC 9899:1990``. diff --git a/Help/prop_sf/GENERATED.rst b/Help/prop_sf/GENERATED.rst index 6ef4580..216dfe8 100644 --- a/Help/prop_sf/GENERATED.rst +++ b/Help/prop_sf/GENERATED.rst @@ -32,9 +32,10 @@ The :ref:`Makefile Generators` will remove ``GENERATED`` files during ``make clean``. Generated sources may be hidden in some IDE tools, while in others they might -be shown. For the special case of sources generated by CMake's :prop_tgt:`AUTOMOC` -or :prop_tgt:`AUTORCC` functionality, the :prop_gbl:`AUTOGEN_SOURCE_GROUP`, -:prop_gbl:`AUTOMOC_SOURCE_GROUP` and :prop_gbl:`AUTORCC_SOURCE_GROUP` target +be shown. For the special case of sources generated by CMake's :prop_tgt:`AUTOMOC`, +:prop_tgt:`AUTORCC` or :prop_tgt:`AUTOUIC` functionality, the +:prop_gbl:`AUTOGEN_SOURCE_GROUP`, :prop_gbl:`AUTOMOC_SOURCE_GROUP`, +:prop_gbl:`AUTORCC_SOURCE_GROUP` and :prop_gbl:`AUTOUIC_SOURCE_GROUP` target properties may influence where the generated sources are grouped in the project's file lists. diff --git a/Help/prop_test/FIXTURES_REQUIRED.rst b/Help/prop_test/FIXTURES_REQUIRED.rst index d92808a..f850830 100644 --- a/Help/prop_test/FIXTURES_REQUIRED.rst +++ b/Help/prop_test/FIXTURES_REQUIRED.rst @@ -35,9 +35,9 @@ The concept of a fixture is different to that of a resource specified by set of tests which share setup and cleanup requirements, whereas a resource lock has the effect of ensuring a particular set of tests do not run in parallel. Some situations may need both, such as setting up a database, -serialising test access to that database and deleting the database again at the +serializing test access to that database and deleting the database again at the end. For such cases, tests would populate both ``FIXTURES_REQUIRED`` and -:prop_test:`RESOURCE_LOCK` to combine the two behaviours. Names used for +:prop_test:`RESOURCE_LOCK` to combine the two behaviors. Names used for :prop_test:`RESOURCE_LOCK` have no relationship with names of fixtures, so note that a resource lock does not imply a fixture and vice versa. diff --git a/Help/prop_tgt/COMPILE_OPTIONS.rst b/Help/prop_tgt/COMPILE_OPTIONS.rst index 0cd6836..4bc190a 100644 --- a/Help/prop_tgt/COMPILE_OPTIONS.rst +++ b/Help/prop_tgt/COMPILE_OPTIONS.rst @@ -15,3 +15,5 @@ Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. + +.. include:: ../command/OPTIONS_SHELL.txt diff --git a/Help/prop_tgt/CUDA_ARCHITECTURES.rst b/Help/prop_tgt/CUDA_ARCHITECTURES.rst index d56b769..a3191e8 100644 --- a/Help/prop_tgt/CUDA_ARCHITECTURES.rst +++ b/Help/prop_tgt/CUDA_ARCHITECTURES.rst @@ -25,7 +25,7 @@ Examples .. code-block:: cmake - set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72) + set_target_properties(tgt PROPERTIES CUDA_ARCHITECTURES "35;50;72") Generates code for real and virtual architectures ``30``, ``50`` and ``72``. diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst index 3f0d242..e22b775 100644 --- a/Help/prop_tgt/C_STANDARD.rst +++ b/Help/prop_tgt/C_STANDARD.rst @@ -11,7 +11,7 @@ flag such as ``-std=gnu11`` to the compile line. For compilers that have no notion of a C standard level, such as Microsoft Visual C++ before VS 16.7, this property has no effect. -Supported values are ``90``, ``99`` and ``11``. +Supported values are ``90``, ``99``, ``11``, ``17``, ``23``. If the value requested does not result in a compile flag being added for the compiler in use, a previous standard flag will be added instead. This diff --git a/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst b/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst index 5c6778d..dc2dc9e 100644 --- a/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst +++ b/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst @@ -10,5 +10,6 @@ to re-link this target. Logical target-level dependencies will not be affected so the linked shared libraries will still be brought up to date before this target is built. -This property is initialized by the value of the variable -CMAKE_LINK_DEPENDS_NO_SHARED if it is set when a target is created. +This property is initialized by the value of the +:variable:`CMAKE_LINK_DEPENDS_NO_SHARED` variable if it is set when a +target is created. diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst index 8c0dfc4..27eadf9 100644 --- a/Help/prop_tgt/LINK_OPTIONS.rst +++ b/Help/prop_tgt/LINK_OPTIONS.rst @@ -28,3 +28,9 @@ for more on defining buildsystem properties. .. note:: This property must be used in preference to :prop_tgt:`LINK_FLAGS` property. + +.. include:: ../command/DEVICE_LINK_OPTIONS.txt + +.. include:: ../command/OPTIONS_SHELL.txt + +.. include:: ../command/LINK_OPTIONS_LINKER.txt diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst index 2f4a3ba..f5d9437 100644 --- a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst +++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst @@ -20,3 +20,5 @@ for more on defining buildsystem properties. This property must be used in preference to :prop_tgt:`STATIC_LIBRARY_FLAGS` property. + +.. include:: ../command/OPTIONS_SHELL.txt diff --git a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst index a6484f2..619377a 100644 --- a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst +++ b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst @@ -9,4 +9,4 @@ If the target contains Swift source files, this specifies the directory in which the modules will be placed. When this property is not set, the modules will be placed in the build directory corresponding to the target's source directory. If the variable :variable:`CMAKE_Swift_MODULE_DIRECTORY` is set when a target is -created its value is used to initialise this property. +created its value is used to initialize this property. diff --git a/Help/prop_tgt/UNITY_BUILD_UNIQUE_ID.rst b/Help/prop_tgt/UNITY_BUILD_UNIQUE_ID.rst index 2c95e02..d288dd3 100644 --- a/Help/prop_tgt/UNITY_BUILD_UNIQUE_ID.rst +++ b/Help/prop_tgt/UNITY_BUILD_UNIQUE_ID.rst @@ -50,6 +50,6 @@ be used to avoid that with code like the following: return MY_UNITY_ID::i; } -The pseudononymous namespace is used within a truly anonymous namespace. +The pseudonymous namespace is used within a truly anonymous namespace. On many platforms, this maintains the invariant that the symbols within do not get external linkage when performing a unity build. diff --git a/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY.rst b/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY.rst index 7b68126..2a4d666 100644 --- a/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY.rst +++ b/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY.rst @@ -6,3 +6,8 @@ XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY Tell the :generator:`Xcode` generator to perform code signing for all the frameworks and libraries that are embedded using the :prop_tgt:`XCODE_EMBED_FRAMEWORKS <XCODE_EMBED_<type>>` property. + +.. versionadded:: 3.21 + +This property was generalized to other types of embedded items. See +:prop_tgt:`XCODE_EMBED_<type>_CODE_SIGN_ON_COPY` for the more general form. diff --git a/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY.rst b/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY.rst index 29f8c5c..04daa85 100644 --- a/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY.rst +++ b/Help/prop_tgt/XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY.rst @@ -6,3 +6,9 @@ XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY Tell the :generator:`Xcode` generator to remove headers from all the frameworks that are embedded using the :prop_tgt:`XCODE_EMBED_FRAMEWORKS <XCODE_EMBED_<type>>` property. + +.. versionadded:: 3.21 + +This property was generalized to other types of embedded items. See +:prop_tgt:`XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY` for the more +general form. diff --git a/Help/prop_tgt/XCODE_EMBED_type.rst b/Help/prop_tgt/XCODE_EMBED_type.rst index 90c5bc7..a1af56f 100644 --- a/Help/prop_tgt/XCODE_EMBED_type.rst +++ b/Help/prop_tgt/XCODE_EMBED_type.rst @@ -5,10 +5,20 @@ XCODE_EMBED_<type> Tell the :generator:`Xcode` generator to embed the specified list of items into the target bundle. ``<type>`` specifies the embed build phase to use. +See the Xcode documentation for the base location of each ``<type>``. + +The supported values for ``<type>`` are: + +``FRAMEWORKS`` + The specified items will be added to the ``Embed Frameworks`` build phase. + The items can be CMake target names or paths to frameworks or libraries. + +``APP_EXTENSIONS`` + .. versionadded:: 3.21 + + The specified items will be added to the ``Embed App Extensions`` build phase. + They must be CMake target names. -Currently, the only supported value for ``<type>`` is ``FRAMEWORKS``. -The specified items will be added to the ``Embed Frameworks`` build phase. -The items can be CMake target names or paths to frameworks or libraries. See also :prop_tgt:`XCODE_EMBED_<type>_PATH`, -:prop_tgt:`XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY` and -:prop_tgt:`XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY`. +:prop_tgt:`XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY` and +:prop_tgt:`XCODE_EMBED_<type>_CODE_SIGN_ON_COPY`. diff --git a/Help/prop_tgt/XCODE_EMBED_type_CODE_SIGN_ON_COPY.rst b/Help/prop_tgt/XCODE_EMBED_type_CODE_SIGN_ON_COPY.rst new file mode 100644 index 0000000..7ec0385 --- /dev/null +++ b/Help/prop_tgt/XCODE_EMBED_type_CODE_SIGN_ON_COPY.rst @@ -0,0 +1,18 @@ +XCODE_EMBED_<type>_CODE_SIGN_ON_COPY +------------------------------------ + +.. versionadded:: 3.20 + +Boolean property used only by the :generator:`Xcode` generator. It specifies +whether to perform code signing for the items that are embedded using the +:prop_tgt:`XCODE_EMBED_<type>` property. + +The supported values for ``<type>`` are: + +``FRAMEWORKS`` + +``APP_EXTENSIONS`` + .. versionadded:: 3.21 + +If a ``XCODE_EMBED_<type>_CODE_SIGN_ON_COPY`` property is not defined on the +target, no code signing on copy will be performed for that ``<type>``. diff --git a/Help/prop_tgt/XCODE_EMBED_type_PATH.rst b/Help/prop_tgt/XCODE_EMBED_type_PATH.rst index 887cf57..a6f980d 100644 --- a/Help/prop_tgt/XCODE_EMBED_type_PATH.rst +++ b/Help/prop_tgt/XCODE_EMBED_type_PATH.rst @@ -3,7 +3,16 @@ XCODE_EMBED_<type>_PATH .. versionadded:: 3.20 -Tell the :generator:`Xcode` generator the relative path to use when embedding -the items specified by :prop_tgt:`XCODE_EMBED_<type>`. The path is relative +This property is used only by the :generator:`Xcode` generator. When defined, +it specifies the relative path to use when embedding the items specified by +:prop_tgt:`XCODE_EMBED_<type>`. The path is relative to the base location of the ``Embed XXX`` build phase associated with +``<type>``. See the Xcode documentation for the base location of each ``<type>``. + +The supported values for ``<type>`` are: + +``FRAMEWORKS`` + +``APP_EXTENSIONS`` + .. versionadded:: 3.21 diff --git a/Help/prop_tgt/XCODE_EMBED_type_REMOVE_HEADERS_ON_COPY.rst b/Help/prop_tgt/XCODE_EMBED_type_REMOVE_HEADERS_ON_COPY.rst new file mode 100644 index 0000000..75c8eae --- /dev/null +++ b/Help/prop_tgt/XCODE_EMBED_type_REMOVE_HEADERS_ON_COPY.rst @@ -0,0 +1,20 @@ +XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY +----------------------------------------- + +.. versionadded:: 3.20 + +Boolean property used only by the :generator:`Xcode` generator. It specifies +whether to remove headers from all the frameworks that are embedded using the +:prop_tgt:`XCODE_EMBED_<type>` property. + +The supported values for ``<type>`` are: + +``FRAMEWORKS`` + If the ``XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY`` property is not + defined, headers will not be removed on copy by default. + +``APP_EXTENSIONS`` + .. versionadded:: 3.21 + + If the ``XCODE_EMBED_APP_EXTENSIONS_REMOVE_HEADERS_ON_COPY`` property is not + defined, headers WILL be removed on copy by default. diff --git a/Help/release/3.15.rst b/Help/release/3.15.rst index e68e7d3..6b1a800 100644 --- a/Help/release/3.15.rst +++ b/Help/release/3.15.rst @@ -40,7 +40,7 @@ Languages customize the Swift module name. * The :prop_sf:`Swift_DIAGNOSTICS_FILE` source property was added to - indicate where to write the serialised Swift diagnostics. + indicate where to write the serialized Swift diagnostics. The Swift support is experimental, not considered stable, and may change in future releases of CMake. diff --git a/Help/release/3.16.rst b/Help/release/3.16.rst index 84d96cd..28273a7 100644 --- a/Help/release/3.16.rst +++ b/Help/release/3.16.rst @@ -233,7 +233,7 @@ Deprecated and Removed Features instead. * The :module:`GetPrerequisites` module has been deprecated, as it has been - superceded by :command:`file(GET_RUNTIME_DEPENDENCIES)`. + superseded by :command:`file(GET_RUNTIME_DEPENDENCIES)`. * The ``CPACK_INSTALL_SCRIPT`` variable has been deprecated in favor of the new, more accurately named :variable:`CPACK_INSTALL_SCRIPTS` variable. diff --git a/Help/release/3.6.rst b/Help/release/3.6.rst index f0add07..b798f0d 100644 --- a/Help/release/3.6.rst +++ b/Help/release/3.6.rst @@ -170,7 +170,7 @@ CPack is used for dependency auto detection. * The :cpack_gen:`CPack DEB Generator` learned how to generate - ``DEBIAN/shlibs`` contorl file when package contains shared libraries. + ``DEBIAN/shlibs`` control file when package contains shared libraries. * The :cpack_gen:`CPack DEB Generator` learned how to generate ``DEBIAN/postinst`` and ``DEBIAN/postrm`` files if the package installs diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/ARMClang-cpu-arch-flags.rst b/Help/release/dev/ARMClang-cpu-arch-flags.rst new file mode 100644 index 0000000..5e885fe --- /dev/null +++ b/Help/release/dev/ARMClang-cpu-arch-flags.rst @@ -0,0 +1,7 @@ +ARMClang-cpu-arch-flags +----------------------- + +* ``ARMClang`` cpu/arch compile and link flags are no longer added + automatically based on the :variable:`CMAKE_SYSTEM_PROCESSOR` + variable or the undocumented ``CMAKE_SYSTEM_ARCH`` variable. + They must be specified explicitly. See policy :policy:`CMP0123`. diff --git a/Help/release/dev/FindDevIL-imported-targets.rst b/Help/release/dev/FindDevIL-imported-targets.rst new file mode 100644 index 0000000..aa0929e --- /dev/null +++ b/Help/release/dev/FindDevIL-imported-targets.rst @@ -0,0 +1,4 @@ +FindDevIL +--------- + +* The :module:`FindDevIL` module now provides imported targets. diff --git a/Help/release/dev/FindIconv-version.rst b/Help/release/dev/FindIconv-version.rst new file mode 100644 index 0000000..3546d86 --- /dev/null +++ b/Help/release/dev/FindIconv-version.rst @@ -0,0 +1,4 @@ +FindIconv-version +----------------- + +* The :module:`FindIconv` module now has version support. diff --git a/Help/release/dev/FindIntl-version.rst b/Help/release/dev/FindIntl-version.rst new file mode 100644 index 0000000..5365cf1 --- /dev/null +++ b/Help/release/dev/FindIntl-version.rst @@ -0,0 +1,4 @@ +FindIntl-version +---------------- + +* The :module:`FindIntl` module now has version support. diff --git a/Help/release/dev/FindMsys.rst b/Help/release/dev/FindMsys.rst new file mode 100644 index 0000000..d237c4e --- /dev/null +++ b/Help/release/dev/FindMsys.rst @@ -0,0 +1,6 @@ +FindMsys +-------- + +* The :module:`FindMsys` module was added to find MSYS installations. + Like :module:`FindCygwin`, it is used automatically by some other + find modules to locate UNIX-style tools on Windows. diff --git a/Help/release/dev/UseJava-RESOURCES-NAMESPACE.rst b/Help/release/dev/UseJava-RESOURCES-NAMESPACE.rst new file mode 100644 index 0000000..caa07e7 --- /dev/null +++ b/Help/release/dev/UseJava-RESOURCES-NAMESPACE.rst @@ -0,0 +1,5 @@ +UseJava-RESOURCES-NAMESPACE +--------------------------- + +* The :module:`UseJava` module command ``add_jar`` gained option RESOURCES + allow explicit naming of resources with non-optional namespace. diff --git a/Help/release/dev/UseSWIG-csharp.rst b/Help/release/dev/UseSWIG-csharp.rst new file mode 100644 index 0000000..dbbeaf1 --- /dev/null +++ b/Help/release/dev/UseSWIG-csharp.rst @@ -0,0 +1,5 @@ +UseSWIG-csharp +-------------- + +* The :module:`UseSWIG` module use now standard library name conventions for + ``CSharp`` language. See policy :policy:`CMP0122`. diff --git a/Help/release/dev/UseSWIG-dependencies.rst b/Help/release/dev/UseSWIG-dependencies.rst new file mode 100644 index 0000000..b5a38c3 --- /dev/null +++ b/Help/release/dev/UseSWIG-dependencies.rst @@ -0,0 +1,6 @@ +UseSWIG-dependencies +-------------------- + +* :module:`UseSWIG` module gained the capability, for + :generator:`Xcode` generator, to use `swig` tool to generate implicit + dependencies. diff --git a/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst b/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst new file mode 100644 index 0000000..4c4d48c --- /dev/null +++ b/Help/release/dev/Xcode-add_custom_command-DEPFILE.rst @@ -0,0 +1,5 @@ +Xcode-add_custom_command-DEPFILE +-------------------------------- + +* The :command:`add_custom_command` command gained ``DEPFILE`` support on + :generator:`Xcode` generator. diff --git a/Help/release/dev/add_custom_command-DEPFILE-genex.rst b/Help/release/dev/add_custom_command-DEPFILE-genex.rst new file mode 100644 index 0000000..52e5e9f --- /dev/null +++ b/Help/release/dev/add_custom_command-DEPFILE-genex.rst @@ -0,0 +1,5 @@ +add_custom_command-DEPFILE-genex +-------------------------------- + +* The :command:`add_custom_command` command ``DEPFILE`` option learned to + support :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/release/dev/c-std.rst b/Help/release/dev/c-std.rst new file mode 100644 index 0000000..44daa85 --- /dev/null +++ b/Help/release/dev/c-std.rst @@ -0,0 +1,6 @@ +c-std +----- + +* :prop_tgt:`C_STANDARD` and the + :manual:`Compile Features <cmake-compile-features(7)>` functionality gained + support for C17 and C23. diff --git a/Help/release/dev/capabilties-generator-platforms.rst b/Help/release/dev/capabilties-generator-platforms.rst new file mode 100644 index 0000000..5de2b67 --- /dev/null +++ b/Help/release/dev/capabilties-generator-platforms.rst @@ -0,0 +1,6 @@ +capabilties-generator-platforms +------------------------------- + +* The :manual:`cmake(1)` ``-E capabilities`` output now contains for each + generator a ``supportedPlatforms`` field listing platform known to + be supported in :variable:`CMAKE_GENERATOR_PLATFORM`. diff --git a/Help/release/dev/cmake-install-prefix-command.rst b/Help/release/dev/cmake-install-prefix-command.rst new file mode 100644 index 0000000..2de5d91 --- /dev/null +++ b/Help/release/dev/cmake-install-prefix-command.rst @@ -0,0 +1,8 @@ +cmake-install-prefix-command +---------------------------- + +* The :manual:`cmake(1)` command gained the ``--install-prefix <dir>`` + command line option to specify the location of the install prefix. + +* :manual:`cmake-presets(7)` configure preset gained support for specifying + the install prefix. diff --git a/Help/release/dev/cmake-presets-condition.rst b/Help/release/dev/cmake-presets-condition.rst new file mode 100644 index 0000000..aa01bc1 --- /dev/null +++ b/Help/release/dev/cmake-presets-condition.rst @@ -0,0 +1,4 @@ +cmake-presets-condition +----------------------- + +* :manual:`cmake-presets(7)` now support conditional enabling of presets. diff --git a/Help/release/dev/cmake-presets-host-system-name.rst b/Help/release/dev/cmake-presets-host-system-name.rst new file mode 100644 index 0000000..8036939 --- /dev/null +++ b/Help/release/dev/cmake-presets-host-system-name.rst @@ -0,0 +1,5 @@ +cmake-presets-host-system-name +------------------------------ + +* :manual:`cmake-presets(7)` gained support for a new ``${hostSystemName}`` + macro. diff --git a/Help/release/dev/cmake-presets-optional-generator-and-binarydir.rst b/Help/release/dev/cmake-presets-optional-generator-and-binarydir.rst new file mode 100644 index 0000000..7973489 --- /dev/null +++ b/Help/release/dev/cmake-presets-optional-generator-and-binarydir.rst @@ -0,0 +1,5 @@ +cmake-presets-optional-generator-and-binarydir +---------------------------------------------- + +* :manual:`cmake-presets(7)` now support omitting the ``generator`` and + ``binaryDir`` fields. diff --git a/Help/release/dev/cmake-system-name-version.rst b/Help/release/dev/cmake-system-name-version.rst new file mode 100644 index 0000000..9cfe401 --- /dev/null +++ b/Help/release/dev/cmake-system-name-version.rst @@ -0,0 +1,10 @@ +cmake-system-name-version +------------------------- + +* :variable:`CMAKE_HOST_SYSTEM_NAME`'s undocumented version-stripping behavior + has been moved earlier, before :command:`project` or + :command:`enable_language` is called. +* :variable:`CMAKE_SYSTEM_NAME`'s undocumented version-stripping behavior has + been removed entirely. If it is set by a ``-D`` flag or by a + :manual:`toolchain file <cmake-toolchains(7)>`, it is left unaltered, even if + it still contains a version number. diff --git a/Help/release/dev/cmake-toolchain-command.rst b/Help/release/dev/cmake-toolchain-command.rst new file mode 100644 index 0000000..111ca49 --- /dev/null +++ b/Help/release/dev/cmake-toolchain-command.rst @@ -0,0 +1,5 @@ +cmake-toolchain-command +---------------------------- + +* The :manual:`cmake(1)` command gained the ``--toolchain <path/to/file>`` + command line option to specify a toolchain file. diff --git a/Help/release/dev/cpack-dmg-filesystem.rst b/Help/release/dev/cpack-dmg-filesystem.rst new file mode 100644 index 0000000..e2a4742 --- /dev/null +++ b/Help/release/dev/cpack-dmg-filesystem.rst @@ -0,0 +1,5 @@ +cpack-dmg-filesystem +-------------------- + +* The :cpack_gen:`CPack DragNDrop Generator` gained option + :variable:`CPACK_DMG_FILESYSTEM` to control the ``.dmg`` filesystem. diff --git a/Help/release/dev/cpack-nsis-executable-name.rst b/Help/release/dev/cpack-nsis-executable-name.rst new file mode 100644 index 0000000..a3818db --- /dev/null +++ b/Help/release/dev/cpack-nsis-executable-name.rst @@ -0,0 +1,6 @@ +cpack-nsis-executable-name +-------------------------- + +* The :cpack_gen:`CPack NSIS Generator` gained a new variable + :variable:`CPACK_NSIS_EXECUTABLE` to specify the makensis + executable to use instead of the default one. diff --git a/Help/release/dev/ctest-output-junit.rst b/Help/release/dev/ctest-output-junit.rst new file mode 100644 index 0000000..66df19d --- /dev/null +++ b/Help/release/dev/ctest-output-junit.rst @@ -0,0 +1,5 @@ +ctest-output-junit +------------------ + +* :manual:`ctest(1)` gained a ``--output-junit`` option to write test results + to a JUnit XML file. diff --git a/Help/release/dev/cxx-module-extensions.rst b/Help/release/dev/cxx-module-extensions.rst new file mode 100644 index 0000000..b9d0a8a --- /dev/null +++ b/Help/release/dev/cxx-module-extensions.rst @@ -0,0 +1,4 @@ +cxx-module-extensions +--------------------- + +* Source file extensions ``.ixx`` and ``.cppm`` are now treated as C++. diff --git a/Help/release/dev/file-COPY_FILE.rst b/Help/release/dev/file-COPY_FILE.rst new file mode 100644 index 0000000..2f0cdf0 --- /dev/null +++ b/Help/release/dev/file-COPY_FILE.rst @@ -0,0 +1,4 @@ +file-COPY_ONLY +-------------- + +* The :command:`file(COPY_FILE)` command was added to copy a file to another. diff --git a/Help/release/dev/file-REAL_PATH-EXPAND_TILDE.rst b/Help/release/dev/file-REAL_PATH-EXPAND_TILDE.rst new file mode 100644 index 0000000..cdf1efa --- /dev/null +++ b/Help/release/dev/file-REAL_PATH-EXPAND_TILDE.rst @@ -0,0 +1,5 @@ +file-REAL_PATH-EXPAND_TILDE +--------------------------- + +* The :command:`file(REAL_PATH)` command gained the option ``EXPAND_TILDE`` to + replace any leading tilde with the path to the user's home directory. diff --git a/Help/release/dev/file-RENAME.rst b/Help/release/dev/file-RENAME.rst new file mode 100644 index 0000000..6c1314d --- /dev/null +++ b/Help/release/dev/file-RENAME.rst @@ -0,0 +1,6 @@ +file-RENAME +----------- + +* The :command:`file(RENAME)` command learned to optionally capture + failure in a result variable. It also gained a ``NO_REPLACE`` + option to fail if the destination exists. diff --git a/Help/release/dev/fileapi-codemodel-directory.rst b/Help/release/dev/fileapi-codemodel-directory.rst new file mode 100644 index 0000000..f6515fd --- /dev/null +++ b/Help/release/dev/fileapi-codemodel-directory.rst @@ -0,0 +1,10 @@ +fileapi-codemodel-directory +--------------------------- + +* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has + component been updated to 2.3. + +* The :manual:`cmake-file-api(7)` "codemodel" version 2 gained a + new "directory" object containing directory-level information. + This includes a list of installers generated by the :command:`install` + command. diff --git a/Help/release/dev/find_item-consistent-behavior.rst b/Help/release/dev/find_item-consistent-behavior.rst new file mode 100644 index 0000000..43905e7 --- /dev/null +++ b/Help/release/dev/find_item-consistent-behavior.rst @@ -0,0 +1,6 @@ +find_item-consistent-behavior +----------------------------- + +* The :command:`find_file`, :command:`find_path`, :command:`find_program`, + and :command:`find_library` commands handle cache variables in the same way + regardless how they are defined. See policy :policy:`CMP0125` for details. diff --git a/Help/release/dev/foreach-variable-scope.rst b/Help/release/dev/foreach-variable-scope.rst new file mode 100644 index 0000000..29a57bb --- /dev/null +++ b/Help/release/dev/foreach-variable-scope.rst @@ -0,0 +1,5 @@ +foreach-variable-scope +---------------------- + +* The :command:`foreach` command restrict loop variables to the loop scope. + See policy :policy:`CMP0124` for details. diff --git a/Help/release/dev/fujitsu-compiler-support.rst b/Help/release/dev/fujitsu-compiler-support.rst new file mode 100644 index 0000000..c6f8cfb --- /dev/null +++ b/Help/release/dev/fujitsu-compiler-support.rst @@ -0,0 +1,11 @@ +fujitsu-compiler-support +------------------------ + +* Addition of the ``Fujitsu`` compiler ID operating in traditional ``Trad`` + mode and ``FujitsuClang`` operating in ``Clang`` mode. +* The :module:`FindOpenMP` module learned to support ``Fujitsu`` and + ``FujitsuClang``. +* The :module:`FindMPI` module learned to support ``Fujitsu`` and + ``FujitsuClang`` in both host and cross compiling modes. +* The :module:`FindBLAS` and :module:`FindLAPACK` modules learned to support + the serial ``Fujitsu SSL2`` and parallel ``Fujitsu SSL2BLAMP`` libraries. diff --git a/Help/release/dev/generate-cmake-build-command-parallel.rst b/Help/release/dev/generate-cmake-build-command-parallel.rst new file mode 100644 index 0000000..1b8dd40 --- /dev/null +++ b/Help/release/dev/generate-cmake-build-command-parallel.rst @@ -0,0 +1,6 @@ +generate-cmake-build-command-parallel +------------------------------------- + +* The :command:`build_command` command gained a ``PARALLEL_LEVEL`` option. + +* The :command:`ctest_build` command gained a ``PARALLEL_LEVEL`` option. diff --git a/Help/release/dev/ifw-default-version-operator.rst b/Help/release/dev/ifw-default-version-operator.rst new file mode 100644 index 0000000..4aeace2 --- /dev/null +++ b/Help/release/dev/ifw-default-version-operator.rst @@ -0,0 +1,7 @@ +ifw-default-version-operator +---------------------------- + +* Names given as ``DEPENDS`` or ``DEPENDENCIES`` arguments to + :command:`cpack_ifw_configure_component` or + :command:`cpack_ifw_configure_component_group` may now contain hyphens. + This requires QtIFW 3.1 or later. diff --git a/Help/release/dev/install-script-all-components.rst b/Help/release/dev/install-script-all-components.rst new file mode 100644 index 0000000..e421d3d --- /dev/null +++ b/Help/release/dev/install-script-all-components.rst @@ -0,0 +1,7 @@ +install-script-all-components +----------------------------- + +* The :command:`install(SCRIPT|CODE)` command + supports a new option ``ALL_COMPONENTS`` which allows + the corresponding code to run for every component of + a per component installation. diff --git a/Help/release/dev/list-index-arg-parsing.rst b/Help/release/dev/list-index-arg-parsing.rst new file mode 100644 index 0000000..2ea525b --- /dev/null +++ b/Help/release/dev/list-index-arg-parsing.rst @@ -0,0 +1,7 @@ +list-index-arg-parsing +---------------------- + +* The :command:`list` command's ``GET``, ``INSERT``, ``SUBLIST``, and + ``REMOVE_AT`` subcommands now error with invalid (i.e., non-integer) values + are given as any of their index arguments based on the setting of policy + :policy:`CMP0121`. diff --git a/Help/release/dev/lzma-threads.rst b/Help/release/dev/lzma-threads.rst new file mode 100644 index 0000000..a481cfa --- /dev/null +++ b/Help/release/dev/lzma-threads.rst @@ -0,0 +1,7 @@ +lzma-threads +------------ + +* The precompiled binaries provided on + `cmake.org <https://cmake.org/download/>`_ now support + ``liblzma`` multi-threading. See the :variable:`CPACK_THREADS` and + :variable:`CPACK_ARCHIVE_THREADS` variables. diff --git a/Help/release/dev/message-color.rst b/Help/release/dev/message-color.rst new file mode 100644 index 0000000..4acf15e --- /dev/null +++ b/Help/release/dev/message-color.rst @@ -0,0 +1,4 @@ +message-color +------------- + +* Messages printed to a terminal now may be colored by message type. diff --git a/Help/release/dev/msys.rst b/Help/release/dev/msys.rst new file mode 100644 index 0000000..ece5de7 --- /dev/null +++ b/Help/release/dev/msys.rst @@ -0,0 +1,4 @@ +msys +---- + +* CMake now supports the MSYS runtime environment, much like CYGWIN. diff --git a/Help/release/dev/nmake-utf8.rst b/Help/release/dev/nmake-utf8.rst new file mode 100644 index 0000000..ebbb45b --- /dev/null +++ b/Help/release/dev/nmake-utf8.rst @@ -0,0 +1,5 @@ +nmake-utf8 +---------- + +* The :generator:`NMake Makefiles` generator now encodes the generated + makefiles as UTF-8 with a BOM when using ``nmake`` from VS 9 or above. diff --git a/Help/release/dev/project-is-top-level.rst b/Help/release/dev/project-is-top-level.rst new file mode 100644 index 0000000..568afe0 --- /dev/null +++ b/Help/release/dev/project-is-top-level.rst @@ -0,0 +1,6 @@ +project-is-top-level +-------------------- + +* :command:`project` now sets variables :variable:`PROJECT_IS_TOP_LEVEL` and + :variable:`<PROJECT-NAME>_IS_TOP_LEVEL` to indicate whether it was called + in a top level ``CMakeLists.txt`` file. diff --git a/Help/release/dev/runtime-dll-deps.rst b/Help/release/dev/runtime-dll-deps.rst new file mode 100644 index 0000000..831410f --- /dev/null +++ b/Help/release/dev/runtime-dll-deps.rst @@ -0,0 +1,4 @@ +runtime-dll-deps +---------------- + +* A new :genex:`TARGET_RUNTIME_DLLS` generator expression was added. diff --git a/Help/release/dev/xcode_app_extensions.rst b/Help/release/dev/xcode_app_extensions.rst new file mode 100644 index 0000000..7be7d82 --- /dev/null +++ b/Help/release/dev/xcode_app_extensions.rst @@ -0,0 +1,11 @@ +xcode_app_extensions +-------------------- + +* The :prop_tgt:`XCODE_EMBED_APP_EXTENSIONS <XCODE_EMBED_<type>>` target property + was added to tell the :generator:`Xcode` generator to embed app extensions + such as iMessage sticker packs. + Aspects of the embedding can be customized with the + :prop_tgt:`XCODE_EMBED_APP_EXTENSIONS_PATH <XCODE_EMBED_<type>>`, + :prop_tgt:`XCODE_EMBED_APP_EXTENSIONS_CODE_SIGN_ON_COPY <XCODE_EMBED_<type>_CODE_SIGN_ON_COPY>` and + :prop_tgt:`XCODE_EMBED_APP_EXTENSIONS_REMOVE_HEADERS_ON_COPY <XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY>` + properties. diff --git a/Help/release/index.rst b/Help/release/index.rst index 95b41fb..5dfca05 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -7,6 +7,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst index 6c0c61b..0b0b114 100644 --- a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst +++ b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst @@ -8,7 +8,7 @@ Switch between strict and relaxed automoc mode. By default, :prop_tgt:`AUTOMOC` behaves exactly as described in the documentation of the :prop_tgt:`AUTOMOC` target property. When set to ``TRUE``, it accepts more input and tries to find the correct input file for -``moc`` even if it differs from the documented behaviour. In this mode it +``moc`` even if it differs from the documented behavior. In this mode it e.g. also checks whether a header file is intended to be processed by moc when a ``"foo.moc"`` file has been included. diff --git a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst index d5fcb7d..9817b1a 100644 --- a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst +++ b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst @@ -23,3 +23,7 @@ is read-only and changes to it are undefined behavior. :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``, it does not make sense to set ``CMAKE_CUDA_HOST_COMPILER`` without also setting ``CMAKE_CUDA_COMPILER`` to NVCC. + +.. note:: + + Ignored when using :ref:`Visual Studio Generators`. diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst index 53ad2f3..45f2d32 100644 --- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst +++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst @@ -63,3 +63,27 @@ Supported pairs are: Specify an alternative ``VCTargetsPath`` value for Visual Studio project files. This allows use of VS platform extension configuration files (``.props`` and ``.targets``) that are not installed with VS. + +Visual Studio Toolset Customization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +**These are unstable interfaces with no compatibility guarantees** +because they hook into undocumented internal CMake implementation details. +Institutions may use these to internally maintain support for non-public +Visual Studio platforms and toolsets, but must accept responsibility to +make updates as changes are made to CMake. + +Additional ``key=value`` pairs are available: + +``customFlagTableDir=<path>`` + .. versionadded:: 3.21 + + Specify the absolute path to a directory from which to load custom + flag tables stored as JSON documents with file names of the form + ``<platform>_<toolset>_<tool>.json`` or ``<platform>_<tool>.json``, + where ``<platform>`` is the :variable:`CMAKE_VS_PLATFORM_NAME`, + ``<toolset>`` is the :variable:`CMAKE_VS_PLATFORM_TOOLSET`, + and ``<tool>`` is the tool for which the flag table is meant. + **This naming pattern is an internal CMake implementation detail.** + The ``<tool>`` names are undocumented. The format of the ``.json`` + flag table files is undocumented. diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst index 89d9e27..0abedde 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst @@ -19,6 +19,8 @@ include: Cray = Cray Compiler (cray.com) Embarcadero, Borland = Embarcadero (embarcadero.com) Flang = Flang LLVM Fortran Compiler + Fujitsu = Fujitsu HPC compiler (Trad mode) + FujitsuClang = Fujitsu HPC compiler (Clang mode) G95 = G95 Fortran (g95.org) GNU = GNU Compiler Collection (gcc.gnu.org) GHS = Green Hills Software (www.ghs.com) diff --git a/Help/variable/CMAKE_LANG_FLAGS.rst b/Help/variable/CMAKE_LANG_FLAGS.rst index 14b2694..11864f8 100644 --- a/Help/variable/CMAKE_LANG_FLAGS.rst +++ b/Help/variable/CMAKE_LANG_FLAGS.rst @@ -15,3 +15,6 @@ This is initialized for each language from environment variables: Initialized by the :envvar:`CUDAFLAGS` environment variable. * ``CMAKE_Fortran_FLAGS``: Initialized by the :envvar:`FFLAGS` environment variable. + +This value is a command-line string fragment. Therefore, multiple options +should be separated by spaces, and options with spaces should be quoted. diff --git a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst index 67ff2cb..ca13a29 100644 --- a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst +++ b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst @@ -12,6 +12,8 @@ the contents of a ``xxxFLAGS`` environment variable will be prepended, where ``xxx`` will be language-specific but not necessarily the same as ``<LANG>`` (e.g. :envvar:`CXXFLAGS` for ``CXX``, :envvar:`FFLAGS` for ``Fortran``, and so on). +This value is a command-line string fragment. Therefore, multiple options +should be separated by spaces, and options with spaces should be quoted. See also the configuration-specific :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable. diff --git a/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst index f466468..8d6b533 100644 --- a/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst +++ b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst @@ -2,4 +2,5 @@ CMAKE_MINIMUM_REQUIRED_VERSION ------------------------------ The ``<min>`` version of CMake given to the most recent call to the -:command:`cmake_minimum_required(VERSION)` command. +:command:`cmake_minimum_required(VERSION)` command in the current +variable scope or any parent variable scope. diff --git a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst index 3694973..6036c04 100644 --- a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst +++ b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst @@ -5,6 +5,6 @@ CMAKE_Swift_MODULE_DIRECTORY Swift module output directory. -This variable is used to initialise the :prop_tgt:`Swift_MODULE_DIRECTORY` +This variable is used to initialize the :prop_tgt:`Swift_MODULE_DIRECTORY` property on all the targets. See the target property for additional information. diff --git a/Help/variable/CMAKE_TLS_VERIFY.rst b/Help/variable/CMAKE_TLS_VERIFY.rst new file mode 100644 index 0000000..24f8a25 --- /dev/null +++ b/Help/variable/CMAKE_TLS_VERIFY.rst @@ -0,0 +1,17 @@ +CMAKE_TLS_VERIFY +---------------- + +Specify the default value for the :command:`file(DOWNLOAD)` and +:command:`file(UPLOAD)` commands' ``TLS_VERIFY`` options. +If not set, the default is *off*. + +This setting is also used by the :module:`ExternalProject` module +for internal calls to :command:`file(DOWNLOAD)`. + +TLS verification can help provide confidence that one is connecting +to the desired server. When downloading known content, one should +also use file hashes to verify it. + +.. code-block:: cmake + + set(CMAKE_TLS_VERIFY TRUE) diff --git a/Help/variable/CMAKE_TOOLCHAIN_FILE.rst b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst index 168ee74..e462c5e 100644 --- a/Help/variable/CMAKE_TOOLCHAIN_FILE.rst +++ b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst @@ -7,3 +7,6 @@ This variable is specified on the command line when cross-compiling with CMake. It is the path to a file which is read early in the CMake run and which specifies locations for compilers and toolchain utilities, and other target platform and compiler related information. + +Relative paths are allowed and are interpreted first as relative to the +build directory, and if not found, relative to the source directory. diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst index 74db6b1..a19e7e1 100644 --- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst +++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst @@ -9,10 +9,9 @@ The :ref:`Visual Studio Generators` for VS 2010 and above support using a standalone (non-installed) NVIDIA CUDA toolkit. The path may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of the form ``cuda=C:\path\to\cuda``. The given directory must at least -contain a folder ``.\nvcc`` and must provide Visual Studio integration -files in path ``.\CUDAVisualStudioIntegration\extras\ -visual_studio_integration\MSBuildExtensions\``. One can create a standalone -CUDA toolkit directory by either opening a installer with 7zip or -copying the files that are extracted by the running installer. -The value may be empty if no path to a standalone CUDA Toolkit was -specified. +contain the nvcc compiler in path ``.\bin`` and must provide Visual Studio +integration files in path ``.\extras\visual_studio_integration\ +MSBuildExtensions\``. One can create a standalone CUDA toolkit directory by +either opening a installer with 7zip or copying the files that are extracted +by the running installer. The value may be empty if no path to a standalone +CUDA Toolkit was specified. diff --git a/Help/variable/CTEST_SCRIPT_DIRECTORY.rst b/Help/variable/CTEST_SCRIPT_DIRECTORY.rst new file mode 100644 index 0000000..77d4e58 --- /dev/null +++ b/Help/variable/CTEST_SCRIPT_DIRECTORY.rst @@ -0,0 +1,5 @@ +CTEST_SCRIPT_DIRECTORY +---------------------- + +The directory containing the top-level CTest script. +The concept is similar to :variable:`CMAKE_SOURCE_DIR`. diff --git a/Help/variable/EXECUTABLE_OUTPUT_PATH.rst b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst index 26d3e92..245b9eb 100644 --- a/Help/variable/EXECUTABLE_OUTPUT_PATH.rst +++ b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst @@ -3,6 +3,6 @@ EXECUTABLE_OUTPUT_PATH Old executable location variable. -The target property :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` supercedes this +The target property :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` supersedes this variable for a target if it is set. Executable targets are otherwise placed in this directory. diff --git a/Help/variable/PROJECT-NAME_IS_TOP_LEVEL.rst b/Help/variable/PROJECT-NAME_IS_TOP_LEVEL.rst new file mode 100644 index 0000000..953e978 --- /dev/null +++ b/Help/variable/PROJECT-NAME_IS_TOP_LEVEL.rst @@ -0,0 +1,11 @@ +<PROJECT-NAME>_IS_TOP_LEVEL +--------------------------- + +.. versionadded:: 3.21 + +A boolean variable indicating whether the named project was called in a top +level ``CMakeLists.txt`` file. + +To obtain the value from the most recent call to :command:`project` in +the current directory scope or above, see the +:variable:`PROJECT_IS_TOP_LEVEL` variable. diff --git a/Help/variable/PROJECT_IS_TOP_LEVEL.rst b/Help/variable/PROJECT_IS_TOP_LEVEL.rst new file mode 100644 index 0000000..e5eb6c1 --- /dev/null +++ b/Help/variable/PROJECT_IS_TOP_LEVEL.rst @@ -0,0 +1,21 @@ +PROJECT_IS_TOP_LEVEL +-------------------- + +.. versionadded:: 3.21 + +A boolean variable indicating whether :command:`project` was called in a top +level ``CMakeLists.txt`` file. + +Some modules should only be included as part of the top level +``CMakeLists.txt`` file to not cause unintended side effects in the build +tree, and this variable can be used to conditionally execute such code. For +example, consider the :module:`CTest` module, which creates targets and +options: + +.. code-block:: cmake + + project(MyProject) + ... + if(PROJECT_IS_TOP_LEVEL) + include(CTest) + endif() diff --git a/Modules/CMakeASM_NASMInformation.cmake b/Modules/CMakeASM_NASMInformation.cmake index 97cb488..27b93ec 100644 --- a/Modules/CMakeASM_NASMInformation.cmake +++ b/Modules/CMakeASM_NASMInformation.cmake @@ -38,6 +38,15 @@ if(NOT CMAKE_ASM_NASM_COMPILE_OBJECT) set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> <FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>") endif() +set(CMAKE_DEPFILE_FLAGS_ASM_NASM "-MD <DEP_FILE> -MT <DEP_TARGET>") + +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake") + # dependencies are computed by the compiler itself + set(CMAKE_ASM_NASM_DEPFILE_FORMAT gcc) + set(CMAKE_ASM_NASM_DEPENDS_USE_COMPILER TRUE) +endif() + # Load the generic ASMInformation file: set(ASM_DIALECT "_NASM") include(CMakeASMInformation) diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index 7f73891..754f235 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -9,6 +9,8 @@ set(CMAKE_C_COMPILE_FEATURES "@CMAKE_C_COMPILE_FEATURES@") set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@") set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@") set(CMAKE_C11_COMPILE_FEATURES "@CMAKE_C11_COMPILE_FEATURES@") +set(CMAKE_C17_COMPILE_FEATURES "@CMAKE_C17_COMPILE_FEATURES@") +set(CMAKE_C23_COMPILE_FEATURES "@CMAKE_C23_COMPILE_FEATURES@") set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@") set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@") diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 14e1282..75e9d1a 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -33,13 +33,16 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ @CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@ -#if !defined(__STDC__) -# if (defined(_MSC_VER) && !defined(__clang__)) \ - || (defined(__ibmxl__) || defined(__IBMC__)) +#if !defined(__STDC__) && !defined(__clang__) +# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__) # define C_DIALECT "90" # else # define C_DIALECT # endif +#elif __STDC_VERSION__ > 201710L +# define C_DIALECT "23" +#elif __STDC_VERSION__ >= 201710L +# define C_DIALECT "17" #elif __STDC_VERSION__ >= 201000L # define C_DIALECT "11" #elif __STDC_VERSION__ >= 199901L diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 5fd54c1..541d207 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -9,15 +9,15 @@ endif() set(CMAKE_INCLUDE_FLAG_CUDA "-I") # Set implicit links early so compiler-specific modules can use them. -set(__IMPLICT_LINKS ) +set(__IMPLICIT_LINKS) foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) - string(APPEND __IMPLICT_LINKS " -L\"${dir}\"") + string(APPEND __IMPLICIT_LINKS " -L\"${dir}\"") endforeach() foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) if(${lib} MATCHES "/") - string(APPEND __IMPLICT_LINKS " \"${lib}\"") + string(APPEND __IMPLICIT_LINKS " \"${lib}\"") else() - string(APPEND __IMPLICT_LINKS " -l${lib}") + string(APPEND __IMPLICIT_LINKS " -l${lib}") endif() endforeach() @@ -110,17 +110,10 @@ include(CMakeCommonLanguageInclude) # CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION # CMAKE_CUDA_LINK_EXECUTABLE -if(CMAKE_CUDA_HOST_COMPILER AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - # FIXME: This is too late for the Platform/Windows-NVIDIA-CUDA module to - # see it, so we do not support CMAKE_CUDA_HOST_COMPILER on Windows. - # Move this to Compiler/NVIDIA-CUDA and update the VS generator too. - string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>") -endif() - # create a shared library if(NOT CMAKE_CUDA_CREATE_SHARED_LIBRARY) set(CMAKE_CUDA_CREATE_SHARED_LIBRARY - "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}") + "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") endif() # create a shared module copy the shared library rule by default @@ -160,32 +153,32 @@ endif() # compile a cu file into an executable if(NOT CMAKE_CUDA_LINK_EXECUTABLE) set(CMAKE_CUDA_LINK_EXECUTABLE - "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}") + "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") endif() # Add implicit host link directories that contain device libraries # to the device link line. -set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) -if(__IMPLICT_DLINK_DIRS) - list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) +set(__IMPLICIT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +if(__IMPLICIT_DLINK_DIRS) + list(REMOVE_ITEM __IMPLICIT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) endif() -set(__IMPLICT_DLINK_FLAGS ) -foreach(dir ${__IMPLICT_DLINK_DIRS}) +set(__IMPLICIT_DLINK_FLAGS) +foreach(dir ${__IMPLICIT_DLINK_DIRS}) if(EXISTS "${dir}/libcurand_static.a") - string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") + string(APPEND __IMPLICIT_DLINK_FLAGS " -L\"${dir}\"") endif() endforeach() -unset(__IMPLICT_DLINK_DIRS) +unset(__IMPLICIT_DLINK_DIRS) #These are used when linking relocatable (dc) cuda code if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_DLINK_FLAGS}") endif() if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE) set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_DLINK_FLAGS}") endif() # Used when device linking is handled by CMake. @@ -193,6 +186,6 @@ if(NOT CMAKE_CUDA_DEVICE_LINK_COMPILE) set(CMAKE_CUDA_DEVICE_LINK_COMPILE "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> -D__CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__ -D__NV_EXTRA_INITIALIZATION=\"\" -D__NV_EXTRA_FINALIZATION=\"\" -DREGISTERLINKBINARYFILE=\\\"<REGISTER_FILE>\\\" -DFATBINFILE=\\\"<FATBINARY>\\\" ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c \"${CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT}/bin/crt/link.stub\" -o <OBJECT>") endif() -unset(__IMPLICT_DLINK_FLAGS) +unset(__IMPLICIT_DLINK_FLAGS) set(CMAKE_CUDA_INFORMATION_LOADED 1) diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 45acfe7..d0ce77a 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -44,7 +44,7 @@ if(CMAKE_COMPILER_IS_MINGW) set(MINGW 1) endif() set(CMAKE_CXX_COMPILER_ID_RUN 1) -set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm) set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) foreach (lang C OBJC OBJCXX) diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake index 2dc75d6..05174de 100644 --- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake +++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake @@ -8,7 +8,7 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR) set(${_VAR} - FAIL_REGEX "[Uu]nrecogni[sz]ed .*option" # GNU, NAG + FAIL_REGEX "[Uu]nrecogni[sz]ed .*option" # GNU, NAG, Fujitsu FAIL_REGEX "switch .* is no longer supported" # GNU FAIL_REGEX "unknown .*option" # Clang FAIL_REGEX "optimization flag .* not supported" # Clang diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 214d58a..850fc14 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -18,7 +18,7 @@ function(compiler_id_detection outvar lang) file(GLOB lang_files "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake") set(nonlang CXX) - if (lang STREQUAL CXX) + if ("x${lang}" STREQUAL "xCXX") set(nonlang C) endif() @@ -66,6 +66,7 @@ function(compiler_id_detection outvar lang) PGI Cray TI + FujitsuClang Fujitsu GHS ) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index e7de9cc..e360d31 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -11,6 +11,9 @@ if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR endif() if(${CMAKE_GENERATOR} MATCHES "Visual Studio") + if(DEFINED ENV{CUDAHOSTCXX} OR DEFINED CMAKE_CUDA_HOST_COMPILER) + message(WARNING "Visual Studio does not support specifying CUDAHOSTCXX or CMAKE_CUDA_HOST_COMPILER. Using the C++ compiler provided by Visual Studio.") + endif() else() if(NOT CMAKE_CUDA_COMPILER) set(CMAKE_CUDA_COMPILER_INIT NOTFOUND) @@ -31,19 +34,21 @@ else() set(CMAKE_CUDA_COMPILER_LIST nvcc) endif() + set(_CMAKE_CUDA_COMPILER_PATHS "$ENV{CUDA_PATH}/bin") _cmake_find_compiler(CUDA) + unset(_CMAKE_CUDA_COMPILER_PATHS) else() _cmake_find_compiler_path(CUDA) endif() mark_as_advanced(CMAKE_CUDA_COMPILER) -endif() -#Allow the user to specify a host compiler -if(NOT $ENV{CUDAHOSTCXX} STREQUAL "") - get_filename_component(CMAKE_CUDA_HOST_COMPILER $ENV{CUDAHOSTCXX} PROGRAM) - if(NOT EXISTS ${CMAKE_CUDA_HOST_COMPILER}) - message(FATAL_ERROR "Could not find compiler set in environment variable CUDAHOSTCXX:\n$ENV{CUDAHOSTCXX}.\n${CMAKE_CUDA_HOST_COMPILER}") + #Allow the user to specify a host compiler except for Visual Studio + if(NOT $ENV{CUDAHOSTCXX} STREQUAL "") + get_filename_component(CMAKE_CUDA_HOST_COMPILER $ENV{CUDAHOSTCXX} PROGRAM) + if(NOT EXISTS ${CMAKE_CUDA_HOST_COMPILER}) + message(FATAL_ERROR "Could not find compiler set in environment variable CUDAHOSTCXX:\n$ENV{CUDAHOSTCXX}.\n${CMAKE_CUDA_HOST_COMPILER}") + endif() endif() endif() diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake index c03a85f..ee7fedb 100644 --- a/Modules/CMakeDetermineCompileFeatures.cmake +++ b/Modules/CMakeDetermineCompileFeatures.cmake @@ -4,12 +4,14 @@ function(cmake_determine_compile_features lang) - if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features) + if("x${lang}" STREQUAL "xC" AND COMMAND cmake_record_c_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_C90_COMPILE_FEATURES) set(CMAKE_C99_COMPILE_FEATURES) set(CMAKE_C11_COMPILE_FEATURES) + set(CMAKE_C17_COMPILE_FEATURES) + set(CMAKE_C23_COMPILE_FEATURES) include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") @@ -20,6 +22,12 @@ function(cmake_determine_compile_features lang) return() endif() + if (CMAKE_C17_COMPILE_FEATURES AND CMAKE_C23_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_C23_COMPILE_FEATURES ${CMAKE_C17_COMPILE_FEATURES}) + endif() + if (CMAKE_C11_COMPILE_FEATURES AND CMAKE_C17_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_C17_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES}) + endif() if (CMAKE_C99_COMPILE_FEATURES AND CMAKE_C11_COMPILE_FEATURES) list(REMOVE_ITEM CMAKE_C11_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES}) endif() @@ -32,6 +40,8 @@ function(cmake_determine_compile_features lang) ${CMAKE_C90_COMPILE_FEATURES} ${CMAKE_C99_COMPILE_FEATURES} ${CMAKE_C11_COMPILE_FEATURES} + ${CMAKE_C17_COMPILE_FEATURES} + ${CMAKE_C23_COMPILE_FEATURES} ) endif() @@ -39,10 +49,12 @@ function(cmake_determine_compile_features lang) set(CMAKE_C90_COMPILE_FEATURES ${CMAKE_C90_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_C17_COMPILE_FEATURES ${CMAKE_C17_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_C23_COMPILE_FEATURES ${CMAKE_C23_COMPILE_FEATURES} PARENT_SCOPE) message(CHECK_PASS "done") - elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features) + elseif("x${lang}" STREQUAL "xCXX" AND COMMAND cmake_record_cxx_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_CXX98_COMPILE_FEATURES) @@ -98,7 +110,7 @@ function(cmake_determine_compile_features lang) message(CHECK_PASS "done") - elseif(lang STREQUAL CUDA AND COMMAND cmake_record_cuda_compile_features) + elseif("x${lang}" STREQUAL "xCUDA" AND COMMAND cmake_record_cuda_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_CUDA03_COMPILE_FEATURES) diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake index 2780399..6430793 100644 --- a/Modules/CMakeDetermineCompiler.cmake +++ b/Modules/CMakeDetermineCompiler.cmake @@ -68,6 +68,16 @@ macro(_cmake_find_compiler lang) ) endif() find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler") + if(_CMAKE_${lang}_COMPILER_PATHS) + # As a last fall-back, search in language-specific paths + find_program(CMAKE_${lang}_COMPILER + NAMES ${CMAKE_${lang}_COMPILER_LIST} + NAMES_PER_DIR + PATHS ${_CMAKE_${lang}_COMPILER_PATHS} + DOC "${lang} compiler" + NO_DEFAULT_PATH + ) + endif() if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER) set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${CMAKE_${lang}_COMPILER_INIT}") endif() diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index ad9503c..448f071 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -166,6 +166,25 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endif() endif() + # The Fujitsu compiler does not always convey version information through + # preprocessor symbols so we extract through command line info + if (CMAKE_${lang}_COMPILER_ID STREQUAL "Fujitsu") + if(NOT CMAKE_${lang}_COMPILER_VERSION) + execute_process( + COMMAND "${CMAKE_${lang}_COMPILER}" -V + OUTPUT_VARIABLE output + ERROR_VARIABLE output + RESULT_VARIABLE result + TIMEOUT 10 + ) + if (result EQUAL 0) + if (output MATCHES [[Fujitsu [^ ]* Compiler ([0-9]+\.[0-9]+\.[0-9]+)]]) + set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + endif() + endif() + # if the format is unknown after all files have been checked, put "Unknown" in the cache if(NOT CMAKE_EXECUTABLE_FORMAT) set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format") @@ -204,6 +223,8 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) else() set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU") endif() + elseif("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xFujitsuClang") + set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU") else() set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "") endif() @@ -299,7 +320,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(id_cl "$(CLToolExe)") elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*") set(id_cl clang.exe) - # Executable names have choosen according documentation + # Executable names have been chosen according documentation # URL: (https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-dpcpp-compiler/top.html#top_GUID-A9B4C91D-97AC-450D-9742-9D895BC8AEE1) elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "Intel") if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "DPC\\+\\+ Compiler") @@ -453,9 +474,19 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(id_ItemDefinitionGroup_entry "<CudaCompile>${cuda_target}<AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions><CodeGeneration>${cuda_codegen}</CodeGeneration></CudaCompile>") set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]]) if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR) - set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>") - string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />") - string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />") + # check for legacy cuda custom toolkit folder structure + if(EXISTS ${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc) + set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>") + else() + set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}</CudaToolkitCustomDir>") + endif() + if(EXISTS ${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}CUDAVisualStudioIntegration) + string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />") + string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />") + else() + string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />") + string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />") + endif() else() string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]]) string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]]) @@ -821,8 +852,10 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}") endif() if("${info}" MATCHES "INFO:compiler_version_internal\\[([^]\"]*)\\]") - string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION_INTERNAL "${CMAKE_MATCH_1}") - string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION_INTERNAL "${COMPILER_VERSION_INTERNAL}") + set(COMPILER_VERSION_INTERNAL "${CMAKE_MATCH_1}") + string(REGEX REPLACE "^0+([0-9]+)" "\\1" COMPILER_VERSION_INTERNAL "${COMPILER_VERSION_INTERNAL}") + string(REGEX REPLACE "\\.0+([0-9]+)" ".\\1" COMPILER_VERSION_INTERNAL "${COMPILER_VERSION_INTERNAL}") + string(STRIP "${COMPILER_VERSION_INTERNAL}" COMPILER_VERSION_INTERNAL) endif() foreach(comp MAJOR MINOR PATCH TWEAK) foreach(digit 1 2 3 4 5 6 7 8 9) diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake index bae270d..8c7af06 100644 --- a/Modules/CMakeDetermineSystem.cmake +++ b/Modules/CMakeDetermineSystem.cmake @@ -27,6 +27,7 @@ # Tru64 Tru64 # Ultrix ULTRIX # cygwin CYGWIN_NT-5.1 +# MSYS MSYS_NT-6.1 # MacOSX Darwin @@ -43,7 +44,7 @@ if(CMAKE_HOST_UNIX) else() exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION) endif() - if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|^GNU$|Android") + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|MSYS.*|^GNU$|Android") exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR RETURN_VALUE val) elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") @@ -158,37 +159,14 @@ endif() include(Platform/${CMAKE_SYSTEM_NAME}-Determine OPTIONAL) -macro(ADJUST_CMAKE_SYSTEM_VARIABLES _PREFIX) - if(NOT ${_PREFIX}_NAME) - set(${_PREFIX}_NAME "UnknownOS") - endif() - - # fix for BSD/OS , remove the / - if(${_PREFIX}_NAME MATCHES BSD.OS) - set(${_PREFIX}_NAME BSDOS) - endif() - - # fix for GNU/kFreeBSD, remove the GNU/ - if(${_PREFIX}_NAME MATCHES kFreeBSD) - set(${_PREFIX}_NAME kFreeBSD) - endif() - - # fix for CYGWIN which has windows version in it - if(${_PREFIX}_NAME MATCHES CYGWIN) - set(${_PREFIX}_NAME CYGWIN) - endif() - - # set CMAKE_SYSTEM to the CMAKE_SYSTEM_NAME - set(${_PREFIX} ${${_PREFIX}_NAME}) - # if there is a CMAKE_SYSTEM_VERSION then add a -${CMAKE_SYSTEM_VERSION} - if(${_PREFIX}_VERSION) - set(${_PREFIX} ${${_PREFIX}}-${${_PREFIX}_VERSION}) - endif() - -endmacro() - -ADJUST_CMAKE_SYSTEM_VARIABLES(CMAKE_SYSTEM) -ADJUST_CMAKE_SYSTEM_VARIABLES(CMAKE_HOST_SYSTEM) +set(CMAKE_SYSTEM ${CMAKE_SYSTEM_NAME}) +if(CMAKE_SYSTEM_VERSION) + string(APPEND CMAKE_SYSTEM -${CMAKE_SYSTEM_VERSION}) +endif() +set(CMAKE_HOST_SYSTEM ${CMAKE_HOST_SYSTEM_NAME}) +if(CMAKE_HOST_SYSTEM_VERSION) + string(APPEND CMAKE_HOST_SYSTEM -${CMAKE_HOST_SYSTEM_VERSION}) +endif() # this file is also executed from cpack, then we don't need to generate these files # in this case there is no CMAKE_BINARY_DIR diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 7aa385e..d0e0e46 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -26,7 +26,7 @@ PRINT *, 'INFO:compiler[IntelLLVM]' ! __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and ! later. Look for 6 digit vs. 8 digit version number to decide encoding. -! VVVV is no smaller than the current year when a versio is released. +! VVVV is no smaller than the current year when a version is released. # if __INTEL_LLVM_COMPILER < 1000000 # define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100) # define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10) @@ -156,6 +156,15 @@ #define COMPILER_VERSION_MAJOR DEC(__NAG_COMPILER_RELEASE/10) #define COMPILER_VERSION_MINOR DEC(__NAG_COMPILER_RELEASE % 10) #define COMPILER_VERSION_PATCH DEC(__NAG_COMPILER_BUILD) +#elif defined(__FUJITSU) + PRINT *, 'INFO:compiler[Fujitsu]' +# if defined(__FRT_major__) +# define COMPILER_VERSION_MAJOR DEC(__FRT_major__) +# define COMPILER_VERSION_MINOR DEC(__FRT_minor__) +# define COMPILER_VERSION_PATCH DEC(__FRT_patchlevel__) +# elif defined(__FRT_version__) + PRINT *, 'INFO:compiler_version['//__FRT_version__//']' +# endif #else PRINT *, 'INFO:compiler[]' #endif diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index ad719ef..5813956 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -143,12 +143,12 @@ The ``COMPATIBILITY`` mode ``AnyNewerVersion`` means that the installed package version will be considered compatible if it is newer or exactly the same as the requested version. This mode should be used for packages which are fully backward compatible, also across major versions. -If ``SameMajorVersion`` is used instead, then the behaviour differs from +If ``SameMajorVersion`` is used instead, then the behavior differs from ``AnyNewerVersion`` in that the major version number must be the same as requested, e.g. version 2.0 will not be considered compatible if 1.0 is requested. This mode should be used for packages which guarantee backward compatibility within the same major version. -If ``SameMinorVersion`` is used, the behaviour is the same as +If ``SameMinorVersion`` is used, the behavior is the same as ``SameMajorVersion``, but both major and minor version must be the same as requested, e.g version 0.2 will not be compatible if 0.1 is requested. If ``ExactVersion`` is used, then the package is only considered compatible if diff --git a/Modules/CMakeParseImplicitIncludeInfo.cmake b/Modules/CMakeParseImplicitIncludeInfo.cmake index 7cd7548..5c0eda2 100644 --- a/Modules/CMakeParseImplicitIncludeInfo.cmake +++ b/Modules/CMakeParseImplicitIncludeInfo.cmake @@ -12,9 +12,9 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) set(log "") # Cray compiler (from cray wrapper, via PrgEnv-cray) - if("${CMAKE_${lang}_COMPILER_ID}" STREQUAL "Cray" AND - "${line}" MATCHES "^/" AND "${line}" MATCHES "/ccfe |/ftnfe " AND - "${line}" MATCHES " -isystem| -I") + if(CMAKE_${lang}_COMPILER_ID STREQUAL "Cray" AND + line MATCHES "^/" AND line MATCHES "/ccfe |/ftnfe " AND + line MATCHES " -isystem| -I") string(REGEX MATCHALL " (-I ?|-isystem )(\"[^\"]+\"|[^ \"]+)" incs "${line}") foreach(inc IN LISTS incs) string(REGEX REPLACE " (-I ?|-isystem )(\"[^\"]+\"|[^ \"]+)" "\\2" idir "${inc}") @@ -28,12 +28,12 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) endif() # PGI compiler - if("${CMAKE_${lang}_COMPILER_ID}" STREQUAL "PGI") + if(CMAKE_${lang}_COMPILER_ID STREQUAL "PGI") # pgc++ verbose output differs - if(("${lang}" STREQUAL "C" OR "${lang}" STREQUAL "Fortran") AND - "${line}" MATCHES "^/" AND - "${line}" MATCHES "/pgc |/pgf901 |/pgftnc " AND - "${line}" MATCHES " -cmdline ") + if((lang STREQUAL "C" OR lang STREQUAL "Fortran") AND + line MATCHES "^/" AND + line MATCHES "/pgc |/pgf901 |/pgftnc " AND + line MATCHES " -cmdline ") # cmdline has unparsed cmdline, remove it string(REGEX REPLACE "-cmdline .*" "" line "${line}") if("${line}" MATCHES " -nostdinc ") @@ -51,14 +51,14 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) else() string(APPEND log " warning: PGI C/F parse failed!\n") endif() - elseif("${lang}" STREQUAL "CXX" AND "${line}" MATCHES "^/" AND - "${line}" MATCHES "/pggpp1 " AND "${line}" MATCHES " -I") + elseif(lang STREQUAL "CXX" AND line MATCHES "^/" AND + line MATCHES "/pggpp1 " AND line MATCHES " -I") # oddly, -Mnostdinc does not get rid of system -I's, at least in # PGI 18.10.1 ... string(REGEX MATCHALL " (-I ?)([^ ]*)" incs "${line}") foreach(inc IN LISTS incs) string(REGEX REPLACE " (-I ?)([^ ]*)" "\\2" idir "${inc}") - if(NOT "${idir}" STREQUAL "-") # filter out "-I-" + if(NOT idir STREQUAL "-") # filter out "-I-" list(APPEND rv "${idir}") endif() endforeach() @@ -71,8 +71,8 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) endif() # SunPro compiler - if("${CMAKE_${lang}_COMPILER_ID}" STREQUAL "SunPro" AND - ("${line}" MATCHES "-D__SUNPRO_C" OR "${line}" MATCHES "-D__SUNPRO_F") ) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "SunPro" AND + (line MATCHES "-D__SUNPRO_C" OR line MATCHES "-D__SUNPRO_F")) string(REGEX MATCHALL " (-I ?)([^ ]*)" incs "${line}") foreach(inc IN LISTS incs) string(REGEX REPLACE " (-I ?)([^ ]*)" "\\2" idir "${inc}") @@ -81,7 +81,7 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) endif() endforeach() if(rv) - if ("${lang}" STREQUAL "C" OR "${lang}" STREQUAL "CXX") + if (lang STREQUAL "C" OR lang STREQUAL "CXX") # /usr/include appears to be hardwired in list(APPEND rv "/usr/include") endif() @@ -92,24 +92,24 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) endif() # XL compiler - if(("${CMAKE_${lang}_COMPILER_ID}" STREQUAL "XL" - OR "${CMAKE_${lang}_COMPILER_ID}" STREQUAL "XLClang") - AND "${line}" MATCHES "^/" - AND ( ("${lang}" STREQUAL "Fortran" AND - "${line}" MATCHES "/xl[fF]entry " AND - "${line}" MATCHES "OSVAR\\([^ ]+\\)") + if((CMAKE_${lang}_COMPILER_ID STREQUAL "XL" + OR CMAKE_${lang}_COMPILER_ID STREQUAL "XLClang") + AND line MATCHES "^/" + AND ( (lang STREQUAL "Fortran" AND + line MATCHES "/xl[fF]entry " AND + line MATCHES "OSVAR\\([^ ]+\\)") OR - ( ("${lang}" STREQUAL "C" OR "${lang}" STREQUAL "CXX") AND - "${line}" MATCHES "/xl[cC]2?entry " AND - "${line}" MATCHES " -qosvar=") + ( (lang STREQUAL "C" OR lang STREQUAL "CXX") AND + line MATCHES "/xl[cC]2?entry " AND + line MATCHES " -qosvar=") ) ) # -qnostdinc cancels other stdinc flags, even if present string(FIND "${line}" " -qnostdinc" nostd) - if(NOT ${nostd} EQUAL -1) + if(NOT nostd EQUAL -1) set(rv "") # defined but empty string(APPEND log " got implicit includes via XL parser (nostdinc)\n") else() - if("${lang}" STREQUAL "CXX") + if(lang STREQUAL "CXX") string(REGEX MATCHALL " -qcpp_stdinc=([^ ]*)" std "${line}") string(REGEX MATCHALL " -qgcc_cpp_stdinc=([^ ]*)" gcc_std "${line}") else() @@ -146,6 +146,21 @@ function(cmake_parse_implicit_include_line line lang id_var log_var state_var) endif() endif() + # Fujitsu compiler + if(CMAKE_${lang}_COMPILER_ID STREQUAL "Fujitsu" AND + line MATCHES "/ccpcom") + string(REGEX MATCHALL " (-I *|--sys_include=|--preinclude +)(\"[^\"]+\"|[^ \"]+)" incs "${line}") + foreach(inc IN LISTS incs) + string(REGEX REPLACE " (-I *|--sys_include=|--preinclude +)(\"[^\"]+\"|[^ \"]+)" "\\2" idir "${inc}") + list(APPEND rv "${idir}") + endforeach() + if(rv) + string(APPEND log " got implicit includes via fujitsu ccpcom parser!\n") + else() + string(APPEND log " warning: fujitsu ccpcom parse failed!\n") + endif() + endif() + if(log) set(${log_var} "${log}" PARENT_SCOPE) else() diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 1dc12c0..59195f8 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -5,6 +5,9 @@ #if defined(__linux) || defined(__linux__) || defined(linux) # define PLATFORM_ID "Linux" +#elif defined(__MSYS__) +# define PLATFORM_ID "MSYS" + #elif defined(__CYGWIN__) # define PLATFORM_ID "Cygwin" @@ -256,8 +259,12 @@ ('0' + ((n)>>4 & 0xF)), \ ('0' + ((n) & 0xF)) +/* Construct a string literal encoding the version number. */ +#ifdef COMPILER_VERSION +char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]"; + /* Construct a string literal encoding the version number components. */ -#ifdef COMPILER_VERSION_MAJOR +#elif defined(COMPILER_VERSION_MAJOR) char const info_version[] = { 'I', 'N', 'F', 'O', ':', 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', @@ -281,6 +288,8 @@ char const info_version_internal[] = { 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', 'i','n','t','e','r','n','a','l','[', COMPILER_VERSION_INTERNAL,']','\0'}; +#elif defined(COMPILER_VERSION_INTERNAL_STR) +char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]"; #endif /* Construct a string literal encoding the version number components. */ diff --git a/Modules/CMakePrintHelpers.cmake b/Modules/CMakePrintHelpers.cmake index d652ffa..8c25a73 100644 --- a/Modules/CMakePrintHelpers.cmake +++ b/Modules/CMakePrintHelpers.cmake @@ -101,7 +101,10 @@ function(cmake_print_properties) if(CPP_CACHE_ENTRIES) set(items ${CPP_CACHE_ENTRIES}) set(mode ${mode} CACHE_ENTRIES) - set(keyword CACHE) + # This is a workaround for the fact that passing `CACHE` as an argument to + # set() causes a cache variable to be set. + set(keyword "") + string(APPEND keyword CACHE) endif() if(NOT mode) diff --git a/Modules/CMakeSystemSpecificInformation.cmake b/Modules/CMakeSystemSpecificInformation.cmake index ea3a445..0ded568 100644 --- a/Modules/CMakeSystemSpecificInformation.cmake +++ b/Modules/CMakeSystemSpecificInformation.cmake @@ -14,6 +14,7 @@ set(APPLE ) set(UNIX ) set(CYGWIN ) +set(MSYS ) set(WIN32 ) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index ef5a7d5..373a707 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -291,18 +291,27 @@ installers. The most commonly-used variables are: Some compression methods used by CPack generators such as Debian or Archive may take advantage of multiple CPU cores to speed up compression. - ``CPACK_THREADS`` can be set to positive integer to specify how many threads - will be used for compression. If it is set to 0, CPack will set it so that - all available CPU cores are used. + ``CPACK_THREADS`` can be set to specify how many threads will be + used for compression. + + A positive integer can be used to specify an exact desired thread count. + + When given a negative integer CPack will use the absolute value + as the upper limit but may choose a lower value based on + the available hardware concurrency. + + Given 0 CPack will try to use all available CPU cores. + By default ``CPACK_THREADS`` is set to ``1``. - Currently only ``xz`` compression *may* take advantage of multiple cores. Other - compression methods ignore this value and use only one thread. + Currently only ``xz`` compression *may* take advantage of multiple cores. + Other compression methods ignore this value and use only one thread. - .. note:: + .. versionadded:: 3.21 - Official CMake binaries available on ``cmake.org`` ship with a ``liblzma`` - that does not support parallel compression. + Official CMake binaries available on ``cmake.org`` now ship + with a ``liblzma`` that supports parallel compression. + Older versions did not. Variables for Source Package Generators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index d57cf18..2087a51 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -125,6 +125,11 @@ The module defines the following commands: list of dependency component or component group identifiers in QtIFW style. + .. versionadded:: 3.21 + + Component or group names listed as dependencies may contain hyphens. + This requires QtIFW 3.1 or later. + ``AUTO_DEPEND_ON`` .. versionadded:: 3.8 @@ -260,6 +265,11 @@ The module defines the following commands: list of dependency component or component group identifiers in QtIFW style. + .. versionadded:: 3.21 + + Component or group names listed as dependencies may contain hyphens. + This requires QtIFW 3.1 or later. + ``AUTO_DEPEND_ON`` .. versionadded:: 3.8 diff --git a/Modules/Compiler/ARMClang.cmake b/Modules/Compiler/ARMClang.cmake index da7a43c..354c11d 100644 --- a/Modules/Compiler/ARMClang.cmake +++ b/Modules/Compiler/ARMClang.cmake @@ -3,6 +3,9 @@ if(_ARMClang_CMAKE_LOADED) endif() set(_ARMClang_CMAKE_LOADED TRUE) +# Save the CMP0123 setting in a variable used both below and by try_compile. +cmake_policy(GET CMP0123 CMAKE_ARMClang_CMP0123) + cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # if IN_LIST @@ -82,36 +85,53 @@ macro(__compiler_armclang lang) if(NOT CMAKE_${lang}_COMPILER_ARCH_LIST) __armclang_set_arch_list(${lang} CMAKE_${lang}_COMPILER_ARCH_LIST) endif() - if(NOT CMAKE_SYSTEM_PROCESSOR AND NOT CMAKE_SYSTEM_ARCH) - message(FATAL_ERROR " CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n" - " Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n" - " Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}") - else() - __armclang_check_processor("${CMAKE_SYSTEM_ARCH}" "${CMAKE_${lang}_COMPILER_ARCH_LIST}" _CMAKE_${lang}_CHECK_ARCH_RESULT) - if( _CMAKE_${lang}_CHECK_ARCH_RESULT) - string(APPEND CMAKE_${lang}_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}") - set(__march_flag_set TRUE) + + # CMAKE_SYSTEM_PROCESSOR and CMAKE_SYSTEM_ARCH are not sufficient because they provide no + # information of additional CPU features needed in `-mcpu=<name>[+[no]<feature>+...]`. + # The automatic setting of compile and link options is deprecated and projects should specify their own. + cmake_policy(GET CMP0123 policy_CMP0123) + if(NOT "x${CMAKE_ARMClang_CMP0123}x" STREQUAL "xNEWx") + if(NOT "x${CMAKE_ARMClang_CMP0123}x" STREQUAL "xOLDx") + cmake_policy(GET_WARNING CMP0123 _cmp0123_warning) + message(AUTHOR_WARNING + "${_cmp0123_warning}\n" + "For compatibility, CMake will automatically add cpu/arch flags based " + "on the CMAKE_SYSTEM_PROCESSOR and/or CMAKE_SYSTEM_ARCH variables." + ) endif() - __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}" _CMAKE_${lang}_CHECK_PROCESSOR_RESULT) - if(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT) - string(APPEND CMAKE_${lang}_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}") - set(__mcpu_flag_set TRUE) + + if(NOT CMAKE_SYSTEM_PROCESSOR AND NOT CMAKE_SYSTEM_ARCH) + message(FATAL_ERROR " CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n" + " Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n" + " Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}") + else() + __armclang_check_processor("${CMAKE_SYSTEM_ARCH}" "${CMAKE_${lang}_COMPILER_ARCH_LIST}" _CMAKE_${lang}_CHECK_ARCH_RESULT) + if( _CMAKE_${lang}_CHECK_ARCH_RESULT) + string(APPEND CMAKE_${lang}_FLAGS_INIT " -march=${CMAKE_SYSTEM_ARCH}") + set(__march_flag_set TRUE) + endif() + __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}" _CMAKE_${lang}_CHECK_PROCESSOR_RESULT) + if(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT) + string(APPEND CMAKE_${lang}_FLAGS_INIT " -mcpu=${CMAKE_SYSTEM_PROCESSOR}") + set(__mcpu_flag_set TRUE) + endif() + if(NOT __march_flag_set AND NOT __mcpu_flag_set) + message(FATAL_ERROR "At least one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n" + "Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n" + " Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}") + endif() + unset(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT) + unset(_CMAKE_${lang}_CHECK_ARCH_RESULT) endif() - if(NOT __march_flag_set AND NOT __mcpu_flag_set) - message(FATAL_ERROR "At least one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n" - "Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n" - " Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}") + + #check if CMAKE_SYSTEM_PROCESSOR belongs to supported cpu list for armlink + __armlink_set_cpu_list( ${lang} CMAKE_LINKER_CPU_LIST) + list(TRANSFORM CMAKE_LINKER_CPU_LIST TOLOWER) + __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_LINKER_CPU_LIST}" _CMAKE_CHECK_LINK_CPU_RESULT) + if(_CMAKE_CHECK_LINK_CPU_RESULT) + string(APPEND CMAKE_${lang}_LINK_FLAGS " --cpu=${CMAKE_SYSTEM_PROCESSOR}") endif() - unset(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT) - unset(_CMAKE_${lang}_CHECK_ARCH_RESULT) - endif() - #check if CMAKE_SYSTEM_PROCESSOR belongs to supported cpu list for armlink - __armlink_set_cpu_list( ${lang} CMAKE_LINKER_CPU_LIST) - list(TRANSFORM CMAKE_LINKER_CPU_LIST TOLOWER) - __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_LINKER_CPU_LIST}" _CMAKE_CHECK_LINK_CPU_RESULT) - if(_CMAKE_CHECK_LINK_CPU_RESULT) - string(APPEND CMAKE_${lang}_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}") endif() if(__CMAKE_ARMClang_USING_armlink) diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake index cd897c5..29e6730 100644 --- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake +++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake @@ -64,6 +64,12 @@ endmacro() # Define to allow compile features to be automatically determined macro(cmake_record_c_compile_features) set(_result 0) + if(_result EQUAL 0 AND DEFINED CMAKE_C23_STANDARD_COMPILE_OPTION) + _has_compiler_features_c(23) + endif() + if(_result EQUAL 0 AND DEFINED CMAKE_C17_STANDARD_COMPILE_OPTION) + _has_compiler_features_c(17) + endif() if(_result EQUAL 0 AND DEFINED CMAKE_C11_STANDARD_COMPILE_OPTION) if(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT) _has_compiler_features_c(11) diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index 5609abf..cf493d7 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -25,37 +25,60 @@ elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") endif() endif() -if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) - if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") +if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 2.1) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") - set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") - set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) + endif() + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.1) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") - set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON) - else() - # clang-cl doesn't have any of these - set(CMAKE_C90_STANDARD_COMPILE_OPTION "") - set(CMAKE_C90_EXTENSION_COMPILE_OPTION "") - set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) + elseif(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.0) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c1x") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x") + endif() + + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17") + endif() + + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0) + set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std=c2x") + set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std=gnu2x") + endif() +else() + set(CMAKE_C90_STANDARD_COMPILE_OPTION "") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "") - set(CMAKE_C99_STANDARD_COMPILE_OPTION "") - set(CMAKE_C99_EXTENSION_COMPILE_OPTION "") - set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "/std:c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "/std:c11") + set(CMAKE_C17_STANDARD_COMPILE_OPTION "/std:c17") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "/std:c17") + else() set(CMAKE_C11_STANDARD_COMPILE_OPTION "") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "") - set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_C17_STANDARD_COMPILE_OPTION "") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "") endif() endif() -if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") - __compiler_check_default_language_standard(C 3.4 99 3.6 11) -else() - set(CMAKE_C_STANDARD_DEFAULT "") +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 2.1) + set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) + set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) endif() + +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.0) + set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON) +endif() + +__compiler_check_default_language_standard(C 2.1 99 3.5.2 11 11.0 17) diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake index cafc7dd..0223081 100644 --- a/Modules/Compiler/Clang-CUDA.cmake +++ b/Modules/Compiler/Clang-CUDA.cmake @@ -22,8 +22,8 @@ set(_CMAKE_CUDA_PTX_FLAG "--cuda-device-only -S") set(_CMAKE_CUDA_DEVICE_CODE "-fgpu-rdc -c") # RulePlaceholderExpander expands crosscompile variables like sysroot and target only for CMAKE_<LANG>_COMPILER. Override the default. -set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}") -set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}") +set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") +set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") diff --git a/Modules/Compiler/Fujitsu-C.cmake b/Modules/Compiler/Fujitsu-C.cmake new file mode 100644 index 0000000..dd31e43 --- /dev/null +++ b/Modules/Compiler/Fujitsu-C.cmake @@ -0,0 +1,20 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. +include(Compiler/Fujitsu) +__compiler_fujitsu(C) + +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4) + set(CMAKE_C90_STANDARD_COMPILE_OPTION -std=c89) + set(CMAKE_C90_EXTENSION_COMPILE_OPTION -std=gnu89) + set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_C99_STANDARD_COMPILE_OPTION -std=c99) + set(CMAKE_C99_EXTENSION_COMPILE_OPTION -std=gnu99) + set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_C11_STANDARD_COMPILE_OPTION -std=c11) + set(CMAKE_C11_EXTENSION_COMPILE_OPTION -std=gnu11) + set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON) +endif() + +__compiler_check_default_language_standard(C 4 11) diff --git a/Modules/Compiler/Fujitsu-CXX.cmake b/Modules/Compiler/Fujitsu-CXX.cmake new file mode 100644 index 0000000..0f42196 --- /dev/null +++ b/Modules/Compiler/Fujitsu-CXX.cmake @@ -0,0 +1,47 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. +include(Compiler/Fujitsu) +__compiler_fujitsu(CXX) + +#set(CMAKE_PCH_EXTENSION .pch) +#set(CMAKE_PCH_EPILOGUE "#pragma hdrstop") +#set(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH --no_pch_messages -include <PCH_HEADER> --use_pch <PCH_FILE>) +#set(CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH --no_pch_messages -include <PCH_HEADER> --create_pch <PCH_FILE>) + +# The Fujitsu compiler offers both a 98 and 03 mode. These two are +# essentially interchangeable as 03 simply provides clarity to some 98 +# ambiguyity. +# +# Re: Stroustrup's C++ FAQ: +# What is the difference between C++98 and C++03? +# From a programmer's view there is none. The C++03 revision of the +# standard was a bug fix release for implementers to ensure greater +# consistency and portability. In particular, tutorial and reference +# material describing C++98 and C++03 can be used interchangeably by all +# except compiler writers and standards gurus. +# +# Since CMake doesn't actually have an 03 mode and they're effectively +# interchangeable then we're just going to explicitly use 03 mode in the +# compiler when 98 is requested. + +# The version matching is messy here. The std support seems to be related to +# the compiler tweak version derived from the patch id in the version string. + +if(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 4) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION -std=c++03) + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION -std=gnu++03) + set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION -std=c++11) + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION -std=gnu++11) + set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION -std=c++14) + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION -std=gnu++14) + set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON) + + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION -std=c++17) + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION -std=gnu++17) +endif() + +__compiler_check_default_language_standard(CXX 4 14) diff --git a/Modules/Compiler/Fujitsu-DetermineCompiler.cmake b/Modules/Compiler/Fujitsu-DetermineCompiler.cmake index 73ee38c..8534916 100644 --- a/Modules/Compiler/Fujitsu-DetermineCompiler.cmake +++ b/Modules/Compiler/Fujitsu-DetermineCompiler.cmake @@ -1,2 +1,17 @@ -set(_compiler_id_pp_test "defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version)") +set(_compiler_id_pp_test "defined(__FUJITSU)") + +set(_compiler_id_version_compute " +# if defined(__FCC_version__) +# define @PREFIX@COMPILER_VERSION __FCC_version__ +# elif defined(__FCC_major__) +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__FCC_major__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__FCC_minor__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__FCC_patchlevel__) +# endif +# if defined(__fcc_version) +# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__fcc_version) +# elif defined(__FCC_VERSION) +# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__FCC_VERSION) +# endif +") diff --git a/Modules/Compiler/Fujitsu-Fortran.cmake b/Modules/Compiler/Fujitsu-Fortran.cmake new file mode 100644 index 0000000..face2d6 --- /dev/null +++ b/Modules/Compiler/Fujitsu-Fortran.cmake @@ -0,0 +1,16 @@ +include(Compiler/Fujitsu) +__compiler_fujitsu(Fortran) + +set(CMAKE_Fortran_SUBMODULE_SEP ".") +set(CMAKE_Fortran_SUBMODULE_EXT ".smod") + +set(CMAKE_Fortran_PREPROCESS_SOURCE + "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -Cpp -P <SOURCE> -o <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-Cpp") + +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Fixed") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Free") + +string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT "") + +set(CMAKE_Fortran_MODDIR_FLAG "-M ") diff --git a/Modules/Compiler/Fujitsu.cmake b/Modules/Compiler/Fujitsu.cmake new file mode 100644 index 0000000..13bc57c --- /dev/null +++ b/Modules/Compiler/Fujitsu.cmake @@ -0,0 +1,33 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This module is shared by multiple languages; use include blocker. +if(__COMPILER_FUJITSU) + return() +endif() +set(__COMPILER_FUJITSU 1) + +include(Compiler/CMakeCommonCompilerMacros) + +macro(__compiler_fujitsu lang) + set(CMAKE_${lang}_VERBOSE_FLAG "-###") + + # Initial configuration flags + string(APPEND CMAKE_${lang}_FLAGS_INIT " ") + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g -O0") + string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") + + # PIC flags + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + + # Passing link options to the compiler + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",") + + # How to actually call the compiler + set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE + "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E $<$<COMPILE_LANGUAGE:Fortran>:-Cpp> <SOURCE> > <PREPROCESSED_SOURCE>") + set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") +endmacro() diff --git a/Modules/Compiler/FujitsuClang-C.cmake b/Modules/Compiler/FujitsuClang-C.cmake new file mode 100644 index 0000000..f700d2d --- /dev/null +++ b/Modules/Compiler/FujitsuClang-C.cmake @@ -0,0 +1,6 @@ +include(Compiler/FujitsuClang) + +set(_fjclang_ver "${CMAKE_C_COMPILER_VERSION_INTERNAL}") +set(CMAKE_C_COMPILER_VERSION "${CMAKE_C_COMPILER_VERSION_INTERNAL}") +include(Compiler/Clang-C) +set(CMAKE_C_COMPILER_VERSION "${_fjclang_ver}") diff --git a/Modules/Compiler/FujitsuClang-CXX.cmake b/Modules/Compiler/FujitsuClang-CXX.cmake new file mode 100644 index 0000000..c8790cd --- /dev/null +++ b/Modules/Compiler/FujitsuClang-CXX.cmake @@ -0,0 +1,6 @@ +include(Compiler/FujitsuClang) + +set(_fjclang_ver "${CMAKE_CXX_COMPILER_VERSION_INTERNAL}") +set(CMAKE_CXX_COMPILER_VERSION "${CMAKE_CXX_COMPILER_VERSION_INTERNAL}") +include(Compiler/Clang-CXX) +set(CMAKE_CXX_COMPILER_VERSION "${_fjclang_ver}") diff --git a/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake b/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake new file mode 100644 index 0000000..f6719b1 --- /dev/null +++ b/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake @@ -0,0 +1,9 @@ + +set(_compiler_id_pp_test "defined(__CLANG_FUJITSU)") + +set(_compiler_id_version_compute " +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__FCC_major__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__FCC_minor__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__FCC_patchlevel__) +# define @PREFIX@COMPILER_VERSION_INTERNAL_STR __clang_version__ +") diff --git a/Modules/Compiler/FujitsuClang.cmake b/Modules/Compiler/FujitsuClang.cmake new file mode 100644 index 0000000..a848248 --- /dev/null +++ b/Modules/Compiler/FujitsuClang.cmake @@ -0,0 +1,11 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This module is shared by multiple languages; use include blocker. +if(__COMPILER_FUJITSUCLANG) + return() +endif() +set(__COMPILER_FUJITSUCLANG 1) + +include(Compiler/Clang) diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake index 86b4d83..39e9c72 100644 --- a/Modules/Compiler/GNU-C.cmake +++ b/Modules/Compiler/GNU-C.cmake @@ -36,4 +36,14 @@ elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x") endif() -__compiler_check_default_language_standard(C 3.4 90 5.0 11) +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.1) + set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17") +endif() + +if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9.1) + set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std=c23") + set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std=gnu23") +endif() + +__compiler_check_default_language_standard(C 3.4 90 5.0 11 8.1 17) diff --git a/Modules/Compiler/IntelLLVM-C.cmake b/Modules/Compiler/IntelLLVM-C.cmake index fce2971..beb7132 100644 --- a/Modules/Compiler/IntelLLVM-C.cmake +++ b/Modules/Compiler/IntelLLVM-C.cmake @@ -37,6 +37,9 @@ if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") + + set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17") else() # clang-cl doesn't have any of these set(CMAKE_C90_STANDARD_COMPILE_OPTION "") @@ -47,12 +50,13 @@ else() set(CMAKE_C11_STANDARD_COMPILE_OPTION "") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_C17_STANDARD_COMPILE_OPTION "") + set(CMAKE_C17_EXTENSION_COMPILE_OPTION "") endif() if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") - # FIXME: The compiler actually defaults to C17, but - # CMake does not yet model or detect that standard. - __compiler_check_default_language_standard(C 2020 11) + __compiler_check_default_language_standard(C 2020 17) else() set(CMAKE_C_STANDARD_DEFAULT "") endif() diff --git a/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake b/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake index 124dafe..917a364 100644 --- a/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake +++ b/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake @@ -4,7 +4,7 @@ set(_compiler_id_pp_test "(defined(__clang__) && defined(__INTEL_CLANG_COMPILER) set(_compiler_id_version_compute " /* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and * later. Look for 6 digit vs. 8 digit version number to decide encoding. - * VVVV is no smaller than the current year when a versio is released. + * VVVV is no smaller than the current year when a version is released. */ #if __INTEL_LLVM_COMPILER < 1000000L # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__INTEL_LLVM_COMPILER/100) diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index a0f7c05..c2fe42d 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -24,21 +24,17 @@ else() set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") endif() +if(CMAKE_CUDA_HOST_COMPILER AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") + string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>") +endif() + if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) # The -MD flag was only added to nvcc in 10.2 so # before that we had to invoke the compiler twice # to get header dependency information set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <DEP_TARGET> -MF <DEP_FILE>") else() - if(CMAKE_CUDA_HOST_COMPILER AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") - # FIXME: Move the main -ccbin= flag from CMakeCUDAInformation to - # a block above, remove this copy, and update the VS generator too. - set(_CMAKE_CUDA_EXTRA_FLAGS_LOCAL " -ccbin=<CMAKE_CUDA_HOST_COMPILER>") - else() - set(_CMAKE_CUDA_EXTRA_FLAGS_LOCAL "") - endif() - set(CMAKE_CUDA_DEPENDS_EXTRA_COMMANDS "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS}${_CMAKE_CUDA_EXTRA_FLAGS_LOCAL} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M <SOURCE> -MT <OBJECT> -o <DEP_FILE>") - unset(_CMAKE_CUDA_EXTRA_FLAGS_LOCAL) + set(CMAKE_CUDA_DEPENDS_EXTRA_COMMANDS "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M <SOURCE> -MT <OBJECT> -o <DEP_FILE>") endif() set(CMAKE_CUDA_DEPFILE_FORMAT gcc) if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index d6fbae9..189374b 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -941,14 +941,15 @@ function(_ExternalData_link_or_copy src dst) file(RELATIVE_PATH tgt "${dst_dir}" "${src}") endif() endif() - execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${tgt}" "${tmp}" RESULT_VARIABLE result) + # Create link (falling back to copying if there's a problem). + file(CREATE_LINK "${tgt}" "${tmp}" RESULT result COPY_ON_ERROR SYMBOLIC) else() # Create a copy. - execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${src}" "${tmp}" RESULT_VARIABLE result) + file(COPY_FILE "${src}" "${tmp}" RESULT result) endif() if(result) file(REMOVE "${tmp}") - message(FATAL_ERROR "Failed to create\n ${tmp}\nfrom\n ${obj}") + message(FATAL_ERROR "Failed to create:\n \"${tmp}\"\nfrom:\n \"${obj}\"\nwith error:\n ${result}") endif() # Atomically create/replace the real destination. @@ -1101,7 +1102,14 @@ function(_ExternalData_download_object name hash algo var_obj var_success var_er set(success 1) if(found) - file(RENAME "${tmp}" "${obj}") + # Atomically create the object. If we lose a race with another process, + # do not replace it. Content-addressing ensures it has what we expect. + file(RENAME "${tmp}" "${obj}" NO_REPLACE RESULT result) + if (result STREQUAL "NO_REPLACE") + file(REMOVE "${tmp}") + elseif (result) + message(FATAL_ERROR "Failed to rename:\n \"${tmp}\"\nto:\n \"${obj}\"\nwith error:\n ${result}") + endif() message(STATUS "Downloaded object: \"${obj}\"") elseif(EXISTS "${staged}") set(obj "${staged}") diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 90ed1ee..9e25bee 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -212,7 +212,7 @@ External Project Definition ``TLS_VERIFY <bool>`` Specifies whether certificate verification should be performed for https URLs. If this option is not provided, the default behavior is - determined by the ``CMAKE_TLS_VERIFY`` variable (see + determined by the :variable:`CMAKE_TLS_VERIFY` variable (see :command:`file(DOWNLOAD)`). If that is also not set, certificate verification will not be performed. In situations where ``URL_HASH`` cannot be provided, this option can be an alternative verification @@ -456,9 +456,16 @@ External Project Definition overridden if required. ``CONFIGURE_COMMAND <cmd>...`` - The default configure command runs CMake with options based on the main - project. For non-CMake external projects, the ``CONFIGURE_COMMAND`` - option must be used to override this behavior + The default configure command runs CMake with a few options based on + the main project. The options added are typically only those needed to + use the same generator as the main project, but the ``CMAKE_GENERATOR`` + option can be given to override this. The project is responsible for + adding any toolchain details, flags or other settings it wants to + re-use from the main project or otherwise specify (see ``CMAKE_ARGS``, + ``CMAKE_CACHE_ARGS`` and ``CMAKE_CACHE_DEFAULT_ARGS`` below). + + For non-CMake external projects, the ``CONFIGURE_COMMAND`` option must + be used to override the default configure command (:manual:`generator expressions <cmake-generator-expressions(7)>` are supported). For projects that require no configure step, specify this option with an empty string as the command to execute. @@ -564,6 +571,16 @@ External Project Definition default build step. This can be overridden with custom build commands if required. + If both the main project and the external project use make as their build + tool, the build step of the external project is invoked as a recursive + make using ``$(MAKE)``. This will communicate some build tool settings + from the main project to the external project. If either the main project + or external project is not using make, no build tool settings will be + passed to the external project other than those established by the + configure step (i.e. running ``ninja -v`` in the main project will not + pass ``-v`` to the external project's build step, even if it also uses + ``ninja`` as its build tool). + ``BUILD_COMMAND <cmd>...`` Overrides the default build command (:manual:`generator expressions <cmake-generator-expressions(7)>` are diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 8adef47..bd82a90 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -34,7 +34,7 @@ The following shows a typical example of declaring content details: FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.8.0 + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0 ) For most typical cases, populating the content can then be done with a single @@ -126,13 +126,13 @@ Declaring Content Details FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.8.0 + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0 ) FetchContent_Declare( myCompanyIcons URL https://intranet.mycompany.com/assets/iconset_1.12.tar.gz - URL_HASH 5588a7b18261c20068beabfb4f530b87 + URL_HASH MD5=5588a7b18261c20068beabfb4f530b87 ) FetchContent_Declare( @@ -141,6 +141,11 @@ Declaring Content Details SVN_REVISION -r12345 ) + Where contents are being fetched from a remote location and you do not + control that server, it is advisable to use a hash for ``GIT_TAG`` rather + than a branch or tag name. A commit hash is more secure and helps to + confirm that the downloaded contents are what you expected. + Populating The Content """""""""""""""""""""" @@ -291,7 +296,7 @@ is simpler and provides additional features over the pattern above. The ``FetchContent_Populate()`` command also supports a syntax allowing the content details to be specified directly rather than using any saved details. This is more low-level and use of this form is generally to be - avoided in favour of using saved content details as outlined above. + avoided in favor of using saved content details as outlined above. Nevertheless, in certain situations it can be useful to invoke the content population as an isolated operation (typically as part of implementing some other higher level feature or when using CMake in script mode): @@ -456,12 +461,12 @@ frameworks are available to the main build: FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.8.0 + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0 ) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v2.5.0 + GIT_TAG de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad # v2.13.4 ) # After the following call, the CMake targets defined by googletest and @@ -480,7 +485,7 @@ it into the main build: FetchContent_Declare( protobuf GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git - GIT_TAG v3.12.0 + GIT_TAG ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0 SOURCE_SUBDIR cmake ) set(protobuf_BUILD_TESTS OFF) @@ -517,7 +522,7 @@ that all five projects are available on a company git server. The FetchContent_Declare( projE GIT_REPOSITORY git@mycompany.com:git/projE.git - GIT_TAG origin/release/2.3-rc1 + GIT_TAG v2.3-rc1 ) # Order is important, see notes in the discussion further below @@ -1048,7 +1053,7 @@ function(FetchContent_Populate contentName) # Don't set global properties, or record that we did this population, since # this was a direct call outside of the normal declared details form. # We only want to save values in the global properties for content that - # honours the hierarchical details mechanism so that projects are not + # honors the hierarchical details mechanism so that projects are not # robbed of the ability to override details set in nested projects. return() endif() @@ -1177,11 +1182,11 @@ endfunction() # calls will be available to the caller. macro(FetchContent_MakeAvailable) - foreach(contentName IN ITEMS ${ARGV}) - string(TOLOWER ${contentName} contentNameLower) - FetchContent_GetProperties(${contentName}) - if(NOT ${contentNameLower}_POPULATED) - FetchContent_Populate(${contentName}) + foreach(__cmake_contentName IN ITEMS ${ARGV}) + string(TOLOWER ${__cmake_contentName} __cmake_contentNameLower) + FetchContent_GetProperties(${__cmake_contentName}) + if(NOT ${__cmake_contentNameLower}_POPULATED) + FetchContent_Populate(${__cmake_contentName}) # Only try to call add_subdirectory() if the populated content # can be treated that way. Protecting the call with the check @@ -1192,22 +1197,28 @@ macro(FetchContent_MakeAvailable) # for ExternalProject. It won't matter if it was passed through # to the ExternalProject sub-build, since it would have been # ignored there. - set(__fc_srcdir "${${contentNameLower}_SOURCE_DIR}") - __FetchContent_getSavedDetails(${contentName} contentDetails) - if("${contentDetails}" STREQUAL "") - message(FATAL_ERROR "No details have been set for content: ${contentName}") + set(__cmake_srcdir "${${__cmake_contentNameLower}_SOURCE_DIR}") + __FetchContent_getSavedDetails(${__cmake_contentName} __cmake_contentDetails) + if("${__cmake_contentDetails}" STREQUAL "") + message(FATAL_ERROR "No details have been set for content: ${__cmake_contentName}") endif() - cmake_parse_arguments(__fc_arg "" "SOURCE_SUBDIR" "" ${contentDetails}) - if(NOT "${__fc_arg_SOURCE_SUBDIR}" STREQUAL "") - string(APPEND __fc_srcdir "/${__fc_arg_SOURCE_SUBDIR}") + cmake_parse_arguments(__cmake_arg "" "SOURCE_SUBDIR" "" ${__cmake_contentDetails}) + if(NOT "${__cmake_arg_SOURCE_SUBDIR}" STREQUAL "") + string(APPEND __cmake_srcdir "/${__cmake_arg_SOURCE_SUBDIR}") endif() - if(EXISTS ${__fc_srcdir}/CMakeLists.txt) - add_subdirectory(${__fc_srcdir} ${${contentNameLower}_BINARY_DIR}) + if(EXISTS ${__cmake_srcdir}/CMakeLists.txt) + add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR}) endif() - unset(__fc_srcdir) + unset(__cmake_srcdir) endif() endforeach() + # clear local variables to prevent leaking into the caller's scope + unset(__cmake_contentName) + unset(__cmake_contentNameLower) + unset(__cmake_contentDetails) + unset(__cmake_arg_SOURCE_SUBDIR) + endmacro() diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index b4650b2..0f8360a 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -55,6 +55,9 @@ The following variables may be set to influence this module's behavior: * ``Arm_ilp64_mp`` * ``EML`` * ``EML_mt`` + * ``Fujitsu_SSL2`` (Fujitsu serial blas / lapack) + * ``Fujitsu_SSL2BLAMP`` (Fujitsu parallel blas / lapack) + * ``NVHPC`` * ``Generic`` .. versionadded:: 3.6 @@ -78,6 +81,10 @@ The following variables may be set to influence this module's behavior: .. versionadded:: 3.20 Elbrus Math Library support (``EML``, ``EML_mt``). + Fujitsu SSL2 Library support (``Fujitsu_SSL2``, ``Fujitsu_SSL2BLAMP``) + + .. versionadded:: 3.21 + NVHPC support ``BLA_F95`` if ``ON`` tries to find the BLAS95 interfaces @@ -153,13 +160,18 @@ if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_CO endif() function(_add_blas_target) - if(NOT TARGET BLAS::BLAS) + if(BLAS_FOUND AND NOT TARGET BLAS::BLAS) add_library(BLAS::BLAS INTERFACE IMPORTED) if(BLAS_LIBRARIES) set_target_properties(BLAS::BLAS PROPERTIES INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}" ) endif() + if(BLAS_LINKER_FLAGS) + set_target_properties(BLAS::BLAS PROPERTIES + INTERFACE_LINK_OPTIONS "${BLAS_LINKER_FLAGS}" + ) + endif() endif() endfunction() @@ -168,10 +180,7 @@ if(CMAKE_Fortran_COMPILER_LOADED) else() include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake) endif() -include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -cmake_push_check_state() -set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) if(BLA_PREFER_PKGCONFIG) find_package(PkgConfig) @@ -184,40 +193,33 @@ if(BLA_PREFER_PKGCONFIG) endif() endif() -set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) -if(BLA_STATIC) - if(WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -else() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif() -endif() - # TODO: move this stuff to a separate module -macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - # _addlibdir is a list of additional search paths. _subdirs is a list of path - # suffixes to be used by find_library(). +function(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs) + # This function checks for the existence of the combination of libraries + # given by _list. If the combination is found, this checks whether can link + # against that library combination using the name of a routine given by _name + # using the linker flags given by _flags. If the combination of libraries is + # found and passes the link test, ${LIBRARIES} is set to the list of complete + # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE. set(_libraries_work TRUE) - set(${LIBRARIES}) + set(_libraries) set(_combined_name) + if(BLA_STATIC) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + else() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif() + endif() + set(_extaddlibdir "${_addlibdir}") if(WIN32) list(APPEND _extaddlibdir ENV LIB) @@ -229,33 +231,37 @@ macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _add list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - if(_library MATCHES "^-Wl,--(start|end)-group$") - # Respect linker flags like --start/end-group (required by MKL) - set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + if(_library MATCHES "^-") + # Respect linker flags as-is (required by MKL) + list(APPEND _libraries "${_library}") else() - set(_combined_name ${_combined_name}_${_library}) - if(NOT "${_threadlibs}" STREQUAL "") - set(_combined_name ${_combined_name}_threadlibs) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}") + set(_combined_name ${_combined_name}_${_lib_var}) + if(NOT "${_deps}" STREQUAL "") + set(_combined_name ${_combined_name}_deps) endif() if(_libraries_work) - find_library(${_prefix}_${_library}_LIBRARY + find_library(${_prefix}_${_lib_var}_LIBRARY NAMES ${_library} NAMES_PER_DIR PATHS ${_extaddlibdir} PATH_SUFFIXES ${_subdirs} ) - #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY) + list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY}) endif() endif() endforeach() + foreach(_flag ${_flags}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}") + set(_combined_name ${_combined_name}_${_flag_var}) + endforeach() if(_libraries_work) # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threadlibs}) - #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_deps}) + set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) if(CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) else() @@ -267,19 +273,20 @@ macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _add if(_libraries_work) if("${_list}" STREQUAL "") - set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") else() - set(${LIBRARIES} ${${LIBRARIES}} ${_threadlibs}) + list(APPEND _libraries ${_deps}) endif() else() - set(${LIBRARIES} FALSE) + set(_libraries FALSE) endif() - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") -endmacro() + set(${LIBRARIES} "${_libraries}" PARENT_SCOPE) +endfunction() set(BLAS_LINKER_FLAGS) set(BLAS_LIBRARIES) set(BLAS95_LIBRARIES) +set(_blas_fphsa_req_var BLAS_LIBRARIES) if(NOT $ENV{BLA_VENDOR} STREQUAL "") set(BLA_VENDOR $ENV{BLA_VENDOR}) else() @@ -302,6 +309,9 @@ if(BLA_VENDOR STREQUAL "All") "" ) endif() + if(BLAS_WORKS) + set(_blas_fphsa_req_var BLAS_WORKS) + endif() endif() # BLAS in the Intel MKL 10+ library? @@ -327,12 +337,21 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE) set(BLAS_mkl_INTFACE "gf") set(BLAS_mkl_THREADING "gnu") - set(BLAS_mkl_OMP "gomp") else() set(BLAS_mkl_INTFACE "intel") set(BLAS_mkl_THREADING "intel") - set(BLAS_mkl_OMP "iomp5") endif() + + foreach(lang IN ITEMS C CXX Fortran) + if(CMAKE_${lang}_COMPILER_LOADED) + find_package(OpenMP COMPONENTS ${lang}) + if(${OpenMP_${lang}_FOUND}) + set(BLAS_mkl_OMP ${OpenMP_${lang}_LIBRARIES}) + break() + endif() + endif() + endforeach() + set(BLAS_mkl_LM "-lm") set(BLAS_mkl_LDL "-ldl") endif() @@ -397,7 +416,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -406,7 +425,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS @@ -462,7 +481,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -471,7 +490,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS @@ -534,7 +553,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") ${BLAS_mkl_SEARCH_SYMBOL} "" "${SEARCH_LIBS}" - "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" + "${BLAS_mkl_OMP};${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" "${BLAS_mkl_MKLROOT}" "${BLAS_mkl_LIB_PATH_SUFFIXES}" ) @@ -619,8 +638,6 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") endif() set(_threadlibs "${CMAKE_THREAD_LIBS_INIT}") if(BLA_STATIC) - set(_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") - set(CMAKE_FIND_LIBRARY_SUFFIXES "${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}") if (CMAKE_C_COMPILER_LOADED) find_package(OpenMP COMPONENTS C) list(PREPEND _threadlibs "${OpenMP_C_LIBRARIES}") @@ -628,8 +645,6 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") find_package(OpenMP COMPONENTS CXX) list(PREPEND _threadlibs "${OpenMP_CXX_LIBRARIES}") endif() - set(CMAKE_FIND_LIBRARY_SUFFIXES "${_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES}") - unset(_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES) endif() check_blas_libraries( BLAS_LIBRARIES @@ -1025,8 +1040,35 @@ if(BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All") endif() +# Fujitsu SSL2 Library? +if(NOT BLAS_LIBRARIES AND + BLA_VENDOR MATCHES "Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR STREQUAL "Fujitsu_SSL2BLAMP") + set(_ssl2_suffix BLAMP) + else() + set(_ssl2_suffix) + endif() + check_blas_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "-SSL2${_ssl2_suffix}" + "" + "" + "" + "" + ) + if(BLAS_LIBRARIES) + set(BLAS_LINKER_FLAGS "-SSL2${_ssl2_suffix}") + set(_blas_fphsa_req_var BLAS_LINKER_FLAGS) + endif() + unset(_ssl2_suffix) +endif() + # Generic BLAS library? -if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") +if(BLA_VENDOR STREQUAL "Generic" OR + BLA_VENDOR STREQUAL "NVHPC" OR + BLA_VENDOR STREQUAL "All") if(NOT BLAS_LIBRARIES) check_blas_libraries( BLAS_LIBRARIES @@ -1041,17 +1083,14 @@ if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") endif() endif() -if(NOT BLA_F95) - find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES) -endif() - - -# On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines) -# we used a placeholder for empty BLAS_LIBRARIES to get through our logic above. +# On compilers that implicitly link BLAS (i.e. CrayPrgEnv) we used a +# placeholder for empty BLAS_LIBRARIES to get through our logic above. if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") set(BLAS_LIBRARIES "") endif() +if(NOT BLA_F95) + find_package_handle_standard_args(BLAS REQUIRED_VARS ${_blas_fphsa_req_var}) +endif() + _add_blas_target() -cmake_pop_check_state() -set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index d31f925..324ae27 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -189,7 +189,7 @@ This module defines the following :prop_tgt:`IMPORTED` targets: (adds ``-DBOOST_ALL_NO_LIB``). ``Boost::dynamic_linking`` - Interface target to enable dynamic linking linking with MSVC + Interface target to enable dynamic linking with MSVC (adds ``-DBOOST_ALL_DYN_LINK``). Implicit dependencies such as ``Boost::filesystem`` requiring diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake index 5e25deb..bfa1d6f 100644 --- a/Modules/FindCurses.cmake +++ b/Modules/FindCurses.cmake @@ -76,7 +76,7 @@ endif() # cygwin ncurses stopped providing curses.h symlinks see above # message. Cygwin is an ncurses package, so force ncurses on # cygwin if the curses.h is missing -if(CYGWIN) +if(CURSES_NCURSES_LIBRARY AND CYGWIN) if (CURSES_NEED_WIDE) if(NOT EXISTS /usr/include/ncursesw/curses.h) set(CURSES_USE_NCURSES TRUE) diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake index 9984943..c8e5e31 100644 --- a/Modules/FindDevIL.cmake +++ b/Modules/FindDevIL.cmake @@ -10,26 +10,57 @@ FindDevIL This module locates the developer's image library. http://openil.sourceforge.net/ +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.21 + +This module defines the :prop_tgt:`IMPORTED` targets: + +``DevIL::IL`` + Defined if the system has DevIL. + +``DevIL::ILU`` + Defined if the system has DevIL Utilities. + +``DevIL::ILUT`` + Defined if the system has DevIL Utility Toolkit. + +Result Variables +^^^^^^^^^^^^^^^^ + This module sets: -:: - - IL_LIBRARIES - the name of the IL library. These include the full path to - the core DevIL library. This one has to be linked into the - application. - ILU_LIBRARIES - the name of the ILU library. Again, the full path. This - library is for filters and effects, not actual loading. It - doesn't have to be linked if the functionality it provides - is not used. - ILUT_LIBRARIES - the name of the ILUT library. Full path. This part of the - library interfaces with OpenGL. It is not strictly needed - in applications. - IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files. - DevIL_FOUND - this is set to TRUE if all the above variables were set. - This will be set to false if ILU or ILUT are not found, - even if they are not needed. In most systems, if one - library is found all the others are as well. That's the - way the DevIL developers release it. +``IL_LIBRARIES`` + The name of the IL library. These include the full path to + the core DevIL library. This one has to be linked into the + application. + +``ILU_LIBRARIES`` + The name of the ILU library. Again, the full path. This + library is for filters and effects, not actual loading. It + doesn't have to be linked if the functionality it provides + is not used. + +``ILUT_LIBRARIES`` + The name of the ILUT library. Full path. This part of the + library interfaces with OpenGL. It is not strictly needed + in applications. + +``IL_INCLUDE_DIR`` + where to find the il.h, ilu.h and ilut.h files. + +``DevIL_FOUND`` + This is set to TRUE if all the above variables were set. + This will be set to false if ILU or ILUT are not found, + even if they are not needed. In most systems, if one + library is found all the others are as well. That's the + way the DevIL developers release it. + +``DevIL_ILUT_FOUND`` + .. versionadded:: 3.21 + + This is set to TRUE if the ILUT library is found. #]=======================================================================] # TODO: Add version support. @@ -73,3 +104,36 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(DevIL DEFAULT_MSG IL_INCLUDE_DIR) # provide legacy variable for compatibility set(IL_FOUND ${DevIL_FOUND}) + +# create imported targets ONLY if we found DevIL. +if(DevIL_FOUND) + # Report the ILUT found if ILUT_LIBRARIES contains valid path. + if (ILUT_LIBRARIES) + set(DevIL_ILUT_FOUND TRUE) + else() + set(DevIL_ILUT_FOUND FALSE) + endif() + + if(NOT TARGET DevIL::IL) + add_library(DevIL::IL UNKNOWN IMPORTED) + set_target_properties(DevIL::IL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${IL_INCLUDE_DIR}" + IMPORTED_LOCATION "${IL_LIBRARIES}") + endif() + + # DevIL Utilities target + if(NOT TARGET DevIL::ILU) + add_library(DevIL::ILU UNKNOWN IMPORTED) + set_target_properties(DevIL::ILU PROPERTIES + IMPORTED_LOCATION "${ILU_LIBRARIES}") + target_link_libraries(DevIL::ILU INTERFACE DevIL::IL) + endif() + + # ILUT (if found) + if(NOT TARGET DevIL::ILUT AND DevIL_ILUT_FOUND) + add_library(DevIL::ILUT UNKNOWN IMPORTED) + set_target_properties(DevIL::ILUT PROPERTIES + IMPORTED_LOCATION "${ILUT_LIBRARIES}") + target_link_libraries(DevIL::ILUT INTERFACE DevIL::ILU) + endif() +endif() diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index bbf941e..4a16e31 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -223,7 +223,8 @@ them to be separated by whitespace. CMake variables hold lists as a string with items separated by semi-colons, so a conversion needs to be performed. The ``doxygen_add_docs()`` command specifically checks the following Doxygen config options and will convert their associated CMake variable's contents into the -required form if set. +required form if set. CMake variables are named ``DOXYGEN_<name>`` for the +Doxygen settings specified here. :: @@ -395,6 +396,7 @@ Deprecated Hint Variables #]=======================================================================] cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # quoted if arguments cmake_policy(SET CMP0057 NEW) # if IN_LIST # For backwards compatibility support diff --git a/Modules/FindFLTK.cmake b/Modules/FindFLTK.cmake index e1e239a..bab7256 100644 --- a/Modules/FindFLTK.cmake +++ b/Modules/FindFLTK.cmake @@ -108,7 +108,7 @@ if(APPLE) set( FLTK_PLATFORM_DEPENDENT_LIBS "-framework Carbon -framework Cocoa -framework ApplicationServices -lz") endif() -# If FLTK_INCLUDE_DIR is already defined we assigne its value to FLTK_DIR +# If FLTK_INCLUDE_DIR is already defined we assign its value to FLTK_DIR. if(FLTK_INCLUDE_DIR) set(FLTK_DIR ${FLTK_INCLUDE_DIR}) endif() diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index 252f2ae..99e2887 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -39,7 +39,7 @@ LANGUAGES <lang1> <lang2> ... ) If INSTALL_DESTINATION is given then automatically install rules will be created, the language subdirectory will be taken into account (by default use share/locale/). - If ALL is specified, the pot file is processed when building the all traget. + If ALL is specified, the pot file is processed when building the all target. It creates a custom target "potfile". GETTEXT_PROCESS_PO_FILES( <lang> [ALL] [INSTALL_DESTINATION <dir>] @@ -51,7 +51,7 @@ PO_FILES <po1> <po2> ... ) If INSTALL_DESTINATION is given then automatically install rules will be created, the language subdirectory will be taken into account (by default use share/locale/). - If ALL is specified, the po files are processed when building the all traget. + If ALL is specified, the po files are processed when building the all target. It creates a custom target "pofiles". .. versionadded:: 3.2 diff --git a/Modules/FindGnuplot.cmake b/Modules/FindGnuplot.cmake index ca2467d..b4ea6ab 100644 --- a/Modules/FindGnuplot.cmake +++ b/Modules/FindGnuplot.cmake @@ -23,6 +23,7 @@ GNUPLOT_VERSION_STRING will not work for old versions like 3.7.1. #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindMsys.cmake) find_program(GNUPLOT_EXECUTABLE NAMES @@ -31,6 +32,7 @@ find_program(GNUPLOT_EXECUTABLE wgnupl32 PATHS ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) if (GNUPLOT_EXECUTABLE) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index ec5ebdd..e335355 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -811,25 +811,8 @@ if( NOT HDF5_FOUND ) endif() foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - # find the HDF5 include directories - if("${_lang}" STREQUAL "Fortran") - set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod) - elseif("${_lang}" STREQUAL "CXX") - set(HDF5_INCLUDE_FILENAME H5Cpp.h) - else() - set(HDF5_INCLUDE_FILENAME hdf5.h) - endif() - - find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} - HINTS ${HDF5_ROOT} - PATHS $ENV{HOME}/.local/include - PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR) - # set the _DIRS variable as this is what the user will normally use - set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) + # The "main" library. + set(_hdf5_main_library "") # find the HDF5 libraries foreach(LIB IN LISTS HDF5_${_lang}_LIBRARY_NAMES) @@ -861,6 +844,15 @@ if( NOT HDF5_FOUND ) ${_HDF5_SEARCH_OPTS} ) + # Set the "main" library if not already set. + if (NOT _hdf5_main_library) + if (HDF5_${LIB}_LIBRARY_RELEASE) + set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_RELEASE}") + elseif (HDF5_${LIB}_LIBRARY_DEBUG) + set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_DEBUG}") + endif () + endif () + select_library_configurations( HDF5_${LIB} ) list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) endforeach() @@ -872,6 +864,43 @@ if( NOT HDF5_FOUND ) # required libraries. list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES}) + # find the HDF5 include directories + set(_hdf5_inc_extra_paths) + set(_hdf5_inc_extra_suffixes) + if("${_lang}" STREQUAL "Fortran") + set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod) + + # Add library-based search paths for Fortran modules. + if (NOT _hdf5_main_library STREQUAL "") + # gfortran module directory + if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + get_filename_component(_hdf5_library_dir "${_hdf5_main_library}" DIRECTORY) + list(APPEND _hdf5_inc_extra_paths "${_hdf5_library_dir}") + unset(_hdf5_library_dir) + list(APPEND _hdf5_inc_extra_suffixes gfortran/modules) + endif () + endif () + elseif("${_lang}" STREQUAL "CXX") + set(HDF5_INCLUDE_FILENAME H5Cpp.h) + else() + set(HDF5_INCLUDE_FILENAME hdf5.h) + endif() + + unset(_hdf5_main_library) + + find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} + HINTS ${HDF5_ROOT} + PATHS $ENV{HOME}/.local/include ${_hdf5_inc_extra_paths} + PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes} ${_hdf5_inc_extra_suffixes} + ${_HDF5_SEARCH_OPTS} + ) + mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR) + unset(_hdf5_inc_extra_paths) + unset(_hdf5_inc_extra_suffixes) + # set the _DIRS variable as this is what the user will normally use + set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) + list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) + if(HDF5_FIND_HL) foreach(LIB IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES) if(HDF5_USE_STATIC_LIBRARIES) diff --git a/Modules/FindIconv.cmake b/Modules/FindIconv.cmake index 41b7550..566330f 100644 --- a/Modules/FindIconv.cmake +++ b/Modules/FindIconv.cmake @@ -25,6 +25,24 @@ The following variables are provided to indicate iconv support: The iconv libraries to be linked. +.. variable:: Iconv_VERSION + + .. versionadded:: 3.21 + + The version of iconv found (x.y) + +.. variable:: Iconv_VERSION_MAJOR + + .. versionadded:: 3.21 + + The major version of iconv + +.. variable:: Iconv_VERSION_MINOR + + .. versionadded:: 3.21 + + The minor version of iconv + .. variable:: Iconv_IS_BUILT_IN A variable indicating whether iconv support is stemming from the @@ -51,6 +69,10 @@ The following cache variables may also be set: On POSIX platforms, iconv might be part of the C library and the cache variables ``Iconv_INCLUDE_DIR`` and ``Iconv_LIBRARY`` might be empty. +.. note:: + Some libiconv implementations don't embed the version number in their header files. + In this case the variables ``Iconv_VERSION*`` will be empty. + #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) @@ -100,37 +122,61 @@ if(NOT DEFINED Iconv_IS_BUILT_IN) endif() endif() -if(NOT Iconv_IS_BUILT_IN) +set(_Iconv_REQUIRED_VARS) +if(Iconv_IS_BUILT_IN) + set(_Iconv_REQUIRED_VARS _Iconv_IS_BUILT_IN_MSG) + set(_Iconv_IS_BUILT_IN_MSG "built in to C library") +else() + set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR) + find_path(Iconv_INCLUDE_DIR NAMES "iconv.h" DOC "iconv include directory") set(Iconv_LIBRARY_NAMES "iconv" "libiconv") -else() - set(Iconv_INCLUDE_DIR "" CACHE FILEPATH "iconv include directory") - set(Iconv_LIBRARY_NAMES "c") + mark_as_advanced(Iconv_INCLUDE_DIR) + + find_library(Iconv_LIBRARY + NAMES iconv libiconv + NAMES_PER_DIR + DOC "iconv library (if not in the C library)") + mark_as_advanced(Iconv_LIBRARY) endif() -find_library(Iconv_LIBRARY - NAMES ${Iconv_LIBRARY_NAMES} - NAMES_PER_DIR - DOC "iconv library (potentially the C library)") +# NOTE: glibc's iconv.h does not define _LIBICONV_VERSION +if(Iconv_INCLUDE_DIR AND EXISTS "${Iconv_INCLUDE_DIR}/iconv.h") + file(STRINGS ${Iconv_INCLUDE_DIR}/iconv.h Iconv_VERSION_DEFINE REGEX "_LIBICONV_VERSION (.*)") -mark_as_advanced(Iconv_INCLUDE_DIR) -mark_as_advanced(Iconv_LIBRARY) + if(Iconv_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)") + set(Iconv_VERSION_NUMBER "${CMAKE_MATCH_1}") + # encoding -> version number: (major<<8) + minor + math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_NUMBER} >> 8" OUTPUT_FORMAT HEXADECIMAL) + math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_NUMBER} - (${Iconv_VERSION_MAJOR} << 8)" OUTPUT_FORMAT HEXADECIMAL) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -if(NOT Iconv_IS_BUILT_IN) - find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR) -else() - find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY) + math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL) + math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL) + set(Iconv_VERSION "${Iconv_VERSION_MAJOR}.${Iconv_VERSION_MINOR}") + endif() + + unset(Iconv_VERSION_DEFINE) + unset(Iconv_VERSION_NUMBER) endif() +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(Iconv + REQUIRED_VARS ${_Iconv_REQUIRED_VARS} + VERSION_VAR Iconv_VERSION) + if(Iconv_FOUND) - set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}") - set(Iconv_LIBRARIES "${Iconv_LIBRARY}") + if(Iconv_IS_BUILT_IN) + set(Iconv_INCLUDE_DIRS "") + set(Iconv_LIBRARIES "") + else() + set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}") + set(Iconv_LIBRARIES "${Iconv_LIBRARY}") + endif() if(NOT TARGET Iconv::Iconv) add_library(Iconv::Iconv INTERFACE IMPORTED) + set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}") + set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}") endif() - set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}") - set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}") endif() diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake index 43398c1..95eeabd 100644 --- a/Modules/FindIntl.cmake +++ b/Modules/FindIntl.cmake @@ -24,6 +24,30 @@ installation in several variables. The intl libraries to be linked. +.. variable:: Intl_VERSION + + .. versionadded:: 3.21 + + The version of intl found (x.y.z) + +.. variable:: Intl_VERSION_MAJOR + + .. versionadded:: 3.21 + + The major version of intl + +.. variable:: Intl_VERSION_MINOR + + .. versionadded:: 3.21 + + The minor version of intl + +.. variable:: Intl_VERSION_PATCH + + .. versionadded:: 3.21 + + The patch version of intl + .. versionadded:: 3.20 This module defines :prop_tgt:`IMPORTED` target ``Intl::Intl``. @@ -50,6 +74,10 @@ The following cache variables may also be set: case. .. note:: + Some libintl implementations don't embed the version number in their header files. + In this case the variables ``Intl_VERSION*`` will be empty. + +.. note:: If you wish to use the Gettext tools (``msgmerge``, ``msgfmt``, etc.), use :module:`FindGettext`. #]=======================================================================] @@ -101,15 +129,39 @@ else() DOC "libintl include directory") mark_as_advanced(Intl_INCLUDE_DIR) - find_library(Intl_LIBRARY "intl" "libintl" NAMES_PER_DIR + find_library(Intl_LIBRARY + NAMES "intl" "libintl" + NAMES_PER_DIR DOC "libintl libraries (if not in the C library)") mark_as_advanced(Intl_LIBRARY) endif() +# NOTE: glibc's libintl.h does not define LIBINTL_VERSION +if(Intl_INCLUDE_DIR AND EXISTS "${Intl_INCLUDE_DIR}/libintl.h") + file(STRINGS ${Intl_INCLUDE_DIR}/libintl.h Intl_VERSION_DEFINE REGEX "LIBINTL_VERSION (.*)") + + if(Intl_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)") + set(Intl_VERSION_NUMBER "${CMAKE_MATCH_1}") + # encoding -> version number: (major<<16) + (minor<<8) + patch + math(EXPR Intl_VERSION_MAJOR "${Intl_VERSION_NUMBER} >> 16" OUTPUT_FORMAT HEXADECIMAL) + math(EXPR Intl_VERSION_MINOR "(${Intl_VERSION_NUMBER} - (${Intl_VERSION_MAJOR} << 16)) >> 8" OUTPUT_FORMAT HEXADECIMAL) + math(EXPR Intl_VERSION_PATCH "${Intl_VERSION_NUMBER} - ((${Intl_VERSION_MAJOR} << 16) + (${Intl_VERSION_MINOR} << 8))" OUTPUT_FORMAT HEXADECIMAL) + + math(EXPR Intl_VERSION_MAJOR "${Intl_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL) + math(EXPR Intl_VERSION_MINOR "${Intl_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL) + math(EXPR Intl_VERSION_PATCH "${Intl_VERSION_PATCH}" OUTPUT_FORMAT DECIMAL) + set(Intl_VERSION "${Intl_VERSION_MAJOR}.${Intl_VERSION_MINOR}.${Intl_VERSION_PATCH}") + endif() + + unset(Intl_VERSION_DEFINE) + unset(Intl_VERSION_NUMBER) +endif() + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl FOUND_VAR Intl_FOUND REQUIRED_VARS ${_Intl_REQUIRED_VARS} + VERSION_VAR Intl_VERSION FAIL_MESSAGE "Failed to find Gettext libintl") unset(_Intl_REQUIRED_VARS) unset(_Intl_IS_BUILT_IN_MSG) diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index 5aa2d60..e4f60b3 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -80,7 +80,7 @@ macro(java_append_library_directories _var) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") set(_java_libarch "ppc" "ppc64") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^sparc") - # Both flavours can run on the same processor + # Both flavors can run on the same processor set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "sparc" "sparcv9") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)") set(_java_libarch "parisc" "parisc64") diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 45e4be7..fa2300d 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -45,6 +45,9 @@ The following variables may be set to influence this module's behavior: * ``Arm_ilp64_mp`` * ``EML`` * ``EML_mt`` + * ``Fujitsu_SSL2`` (Fujitsu serial blas / lapack) + * ``Fujitsu_SSL2BLAMP`` (Fujitsu parallel blas / lapack) + * ``NVHPC`` * ``Generic`` .. versionadded:: 3.6 @@ -68,6 +71,10 @@ The following variables may be set to influence this module's behavior: .. versionadded:: 3.20 Elbrus Math Library support (``EML``, ``EML_mt``). + Fujitsu SSL2 Library support (``Fujitsu_SSL2``, ``Fujitsu_SSL2BLAMP``) + + .. versionadded:: 3.21 + NVHPC support ``BLA_F95`` if ``ON`` tries to find the BLAS95/LAPACK95 interfaces @@ -124,34 +131,55 @@ if(CMAKE_Fortran_COMPILER_LOADED) else() include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake) endif() -include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) function(_add_lapack_target) if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK) add_library(LAPACK::LAPACK INTERFACE IMPORTED) + + # Filter out redundant BLAS info and replace with the BLAS target set(_lapack_libs "${LAPACK_LIBRARIES}") - if(_lapack_libs AND TARGET BLAS::BLAS) - # remove the ${BLAS_LIBRARIES} from the interface and replace it - # with the BLAS::BLAS target - list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}") + set(_lapack_flags "${LAPACK_LINKER_FLAGS}") + if(TARGET BLAS::BLAS) + if(_lapack_libs AND BLAS_LIBRARIES) + foreach(_blas_lib IN LISTS BLAS_LIBRARIES) + list(REMOVE_ITEM _lapack_libs "${_blas_lib}") + endforeach() + endif() + if(_lapack_flags AND BLAS_LINKER_FLAGS) + foreach(_blas_flag IN LISTS BLAS_LINKER_FLAGS) + list(REMOVE_ITEM _lapack_flags "${_blas_flag}") + endforeach() + endif() list(APPEND _lapack_libs BLAS::BLAS) endif() - if(_lapack_libs) set_target_properties(LAPACK::LAPACK PROPERTIES INTERFACE_LINK_LIBRARIES "${_lapack_libs}" ) endif() - unset(_lapack_libs) + if(_lapack_flags) + set_target_properties(LAPACK::LAPACK PROPERTIES + INTERFACE_LINK_OPTIONS "${_lapack_flags}" + ) + endif() endif() endfunction() -macro(_lapack_find_library_setup) - cmake_push_check_state() - set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) +# TODO: move this stuff to a separate module + +function(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs _blas) + # This function checks for the existence of the combination of libraries + # given by _list. If the combination is found, this checks whether can link + # against that library combination using the name of a routine given by _name + # using the linker flags given by _flags. If the combination of libraries is + # found and passes the link test, ${LIBRARIES} is set to the list of complete + # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE. + + set(_libraries_work TRUE) + set(_libraries) + set(_combined_name) - set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) if(BLA_STATIC) if(WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) @@ -164,33 +192,6 @@ macro(_lapack_find_library_setup) set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) endif() endif() -endmacro() - -macro(_lapack_find_library_teardown) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) - unset(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) - cmake_pop_check_state() -endmacro() - -# TODO: move this stuff to a separate module - -macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs _blas) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - # _addlibdir is a list of additional search paths. _subdirs is a list of path - # suffixes to be used by find_library(). - - set(_libraries_work TRUE) - set(${LIBRARIES}) - set(_combined_name) set(_extaddlibdir "${_addlibdir}") if(WIN32) @@ -203,31 +204,37 @@ macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _a list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - if(_library MATCHES "^-Wl,--(start|end)-group$") - # Respect linker flags like --start/end-group (required by MKL) - set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + if(_library MATCHES "^-") + # Respect linker flags as-is (required by MKL) + list(APPEND _libraries "${_library}") else() - set(_combined_name ${_combined_name}_${_library}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}") + set(_combined_name ${_combined_name}_${_lib_var}) + if(NOT "${_deps}" STREQUAL "") + set(_combined_name ${_combined_name}_deps) + endif() if(_libraries_work) - find_library(${_prefix}_${_library}_LIBRARY + find_library(${_prefix}_${_lib_var}_LIBRARY NAMES ${_library} NAMES_PER_DIR PATHS ${_extaddlibdir} PATH_SUFFIXES ${_subdirs} ) - #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY) + list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY}) endif() endif() endforeach() - unset(_library) + foreach(_flag ${_flags}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}") + set(_combined_name ${_combined_name}_${_flag_var}) + endforeach() if(_libraries_work) # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs}) - #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_blas} ${_deps}) + set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) if(CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) else() @@ -239,19 +246,15 @@ macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _a if(_libraries_work) if("${_list}${_blas}" STREQUAL "") - set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") else() - set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threadlibs}) + list(APPEND _libraries ${_blas} ${_deps}) endif() else() - set(${LIBRARIES} FALSE) + set(_libraries FALSE) endif() - - unset(_extaddlibdir) - unset(_libraries_work) - unset(_combined_name) - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") -endmacro() + set(${LIBRARIES} "${_libraries}" PARENT_SCOPE) +endfunction() macro(_lapack_find_dependency dep) set(_lapack_quiet_arg) @@ -274,11 +277,10 @@ macro(_lapack_find_dependency dep) set(_lapack_quiet_arg) endmacro() -_lapack_find_library_setup() - set(LAPACK_LINKER_FLAGS) set(LAPACK_LIBRARIES) set(LAPACK95_LIBRARIES) +set(_lapack_fphsa_req_var LAPACK_LIBRARIES) # Check the language being used if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED)) @@ -585,22 +587,78 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE) ) endif() + # Fujitsu SSL2 Library? + if(NOT LAPACK_LIBRARIES + AND BLA_VENDOR MATCHES "Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR STREQUAL "Fujitsu_SSL2BLAMP") + set(_ssl2_suffix BLAMP) + else() + set(_ssl2_suffix) + endif() + set(_ssl2_blas) + if(BLAS_LIBRARIES STREQUAL "") + set(_ssl2_blas "${BLAS_LINKER_FLAGS}") + else() + set(_ssl2_blas "${BLAS_LIBRARIES} ${BLAS_LINKER_FLAGS}") + endif() + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "-SSL2${_ssl2_suffix}" + "" + "" + "" + "" + "${_ssl2_blas}" + ) + if(LAPACK_LIBRARIES) + set(LAPACK_LINKER_FLAGS "-SSL2${_ssl2_suffix}") + set(_lapack_fphsa_req_var LAPACK_LINKER_FLAGS) + endif() + unset(_ssl2_suffix) + endif() + + # NVHPC Library? + if(NOT LAPACK_LIBRARIES + AND BLA_VENDOR MATCHES "NVHPC" OR BLA_VENDOR STREQUAL "All") + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "lapack" + "-fortranlibs" + "" + "" + "${BLAS_LIBRARIES}" + ) + endif() + # Generic LAPACK library? if(NOT LAPACK_LIBRARIES AND (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")) + if(BLA_STATIC) + # We do not know for sure how the LAPACK reference implementation + # is built on this host. Guess typical dependencies. + set(_lapack_generic_deps "-lgfortran;-lm") + else() + set(_lapack_generic_deps "") + endif() check_lapack_libraries( LAPACK_LIBRARIES LAPACK cheev "" "lapack" - "" + "${_lapack_generic_deps}" "" "" "${BLAS_LIBRARIES}" ) + unset(_lapack_generic_deps) endif() endif() @@ -612,7 +670,7 @@ if(LAPACK_NOT_FOUND_MESSAGE) set(LAPACK_NOT_FOUND_MESSAGE REASON_FAILURE_MESSAGE ${LAPACK_NOT_FOUND_MESSAGE}) endif() -find_package_handle_standard_args(LAPACK REQUIRED_VARS LAPACK_LIBRARIES +find_package_handle_standard_args(LAPACK REQUIRED_VARS ${_lapack_fphsa_req_var} ${LAPACK_NOT_FOUND_MESSAGE}) unset(LAPACK_NOT_FOUND_MESSAGE) @@ -627,5 +685,3 @@ if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") endif() _add_lapack_target() - -_lapack_find_library_teardown() diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index de38ac2..c48decb 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -277,6 +277,11 @@ set(_MPI_Fortran_GENERIC_COMPILER_NAMES mpif95 mpif95_r mpf95 mpf95_r mpif77 mpif77_r mpf77 mpf77_r mpifc) +#Fujitsu cross/own compiler names +set(_MPI_Fujitsu_C_COMPILER_NAMES mpifccpx mpifcc) +set(_MPI_Fujitsu_CXX_COMPILER_NAMES mpiFCCpx mpiFCC) +set(_MPI_Fujitsu_Fortran_COMPILER_NAMES mpifrtpx mpifrt) + # GNU compiler names set(_MPI_GNU_C_COMPILER_NAMES mpigcc mpgcc mpigcc_r mpgcc_r) set(_MPI_GNU_CXX_COMPILER_NAMES mpig++ mpg++ mpig++_r mpg++_r mpigxx) @@ -337,7 +342,7 @@ set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95 # pick up the right settings for it. foreach (LANG IN ITEMS C CXX Fortran) set(_MPI_${LANG}_COMPILER_NAMES "") - foreach (id IN ITEMS GNU Intel IntelLLVM MSVC PGI XL) + foreach (id IN ITEMS Fujitsu FujitsuClang GNU Intel IntelLLVM MSVC PGI XL) if (NOT CMAKE_${LANG}_COMPILER_ID OR CMAKE_${LANG}_COMPILER_ID STREQUAL id) foreach(_COMPILER_NAME IN LISTS _MPI_${id}_${LANG}_COMPILER_NAMES) list(APPEND _MPI_${LANG}_COMPILER_NAMES ${_COMPILER_NAME}${MPI_EXECUTABLE_SUFFIX}) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 2f56d15..c8df670 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -52,7 +52,7 @@ The module supports the following components: between the release name and the version. The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give -the path of the desired Matlab version. Otherwise, the behaviour is platform +the path of the desired Matlab version. Otherwise, the behavior is platform specific: * Windows: The installed versions of Matlab/MCR are retrieved from the @@ -83,7 +83,7 @@ Module Input Variables ^^^^^^^^^^^^^^^^^^^^^^ Users or projects may set the following variables to configure the module -behaviour: +behavior: :variable:`Matlab_ROOT_DIR` the root of the Matlab installation. @@ -184,7 +184,7 @@ Known issues **Symbol clash in a MEX target** By default, every symbols inside a MEX file defined with the command :command:`matlab_add_mex` have hidden - visibility, except for the entry point. This is the default behaviour of + visibility, except for the entry point. This is the default behavior of the MEX compiler, which lowers the risk of symbol collision between the libraries shipped with Matlab, and the libraries to which the MEX file is linking to. This is also the default on Windows platforms. @@ -223,7 +223,7 @@ Reference .. variable:: MATLAB_ADDITIONAL_VERSIONS If set, specifies additional versions of Matlab that may be looked for. - The variable should be a list of strings, organised by pairs of release + The variable should be a list of strings, organized by pairs of release name and versions, such as follows:: set(MATLAB_ADDITIONAL_VERSIONS @@ -856,7 +856,7 @@ endfunction() where ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension. ``UNITTEST_PRECOMMAND`` Matlab script command to be ran before the file - containing the test (eg. GPU device initialisation based on CMake + containing the test (eg. GPU device initialization based on CMake variables). ``TIMEOUT`` the test timeout in seconds. Defaults to 180 seconds as the @@ -1240,7 +1240,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve endif() endif() - # UNKNOWN is the default behaviour in case we + # UNKNOWN is the default behavior in case we # - have an erroneous matlab_root # - have an initial 'UNKNOWN' if(matlab_or_mcr STREQUAL "MATLAB" OR matlab_or_mcr STREQUAL "UNKNOWN") @@ -1375,7 +1375,7 @@ function(_Matlab_find_instances_osx matlab_roots) set(_matlab_possible_roots) # on mac, we look for the /Application paths - # this corresponds to the behaviour on Windows. On Linux, we do not have + # this corresponds to the behavior on Windows. On Linux, we do not have # any other guess. matlab_get_supported_releases(_matlab_releases) if(MATLAB_FIND_DEBUG) @@ -1416,7 +1416,7 @@ function(_Matlab_find_instances_from_path matlab_roots) set(_matlab_possible_roots) # At this point, we have no other choice than trying to find it from PATH. - # If set by the user, this wont change + # If set by the user, this won't change. find_program( _matlab_main_tmp NAMES matlab) @@ -1552,7 +1552,7 @@ if(_numbers_of_matlab_roots GREATER 0) # adding a warning in case of ambiguity if(_numbers_of_matlab_roots GREATER 3 AND MATLAB_FIND_DEBUG) message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})." - " If this is not the desired behaviour, use the EXACT keyword or provide the -DMatlab_ROOT_DIR=... on the command line") + " If this is not the desired behavior, use the EXACT keyword or provide the -DMatlab_ROOT_DIR=... on the command line") endif() endif() endif() diff --git a/Modules/FindMsys.cmake b/Modules/FindMsys.cmake new file mode 100644 index 0000000..b4796d2 --- /dev/null +++ b/Modules/FindMsys.cmake @@ -0,0 +1,31 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindMsys +-------- + +.. versionadded:: 3.21 + +Find MSYS, a POSIX-compatible environment that runs natively +on Microsoft Windows +#]=======================================================================] + +if (WIN32) + if(MSYS_INSTALL_PATH) + set(MSYS_CMD "${MSYS_INSTALL_PATH}/msys2_shell.cmd") + endif() + + find_program(MSYS_CMD + NAMES msys2_shell.cmd + PATHS + "C:/msys64" + "C:/msys32" + "C:/MSYS" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MSYS\\setup;rootdir]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\MSYS\\mounts v2\\/;native]" + ) + get_filename_component(MSYS_INSTALL_PATH "${MSYS_CMD}" DIRECTORY) + mark_as_advanced(MSYS_CMD) + +endif () diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 52330a4..e982e2d 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -130,6 +130,8 @@ function(_OPENMP_FLAG_CANDIDATES LANG) set(OMP_FLAG_XL "-qsmp=omp") # Cray compiler activate OpenMP with -h omp, which is enabled by default. set(OMP_FLAG_Cray " " "-h omp") + set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP") + set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp") # If we know the correct flags, use those if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake index c14e059..26962df 100644 --- a/Modules/FindPerl.cmake +++ b/Modules/FindPerl.cmake @@ -17,9 +17,11 @@ this module looks for Perl #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindMsys.cmake) set(PERL_POSSIBLE_BIN_PATHS ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) if(WIN32) diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 4b1e336..c73a2d8 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -140,7 +140,7 @@ Example: function(protobuf_generate) set(_options APPEND_PATH DESCRIPTORS) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -171,6 +171,10 @@ function(protobuf_generate) set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") endif() + if(protobuf_generate_PLUGIN) + set(_plugin "--plugin=${protobuf_generate_PLUGIN}") + endif() + if(NOT protobuf_generate_GENERATE_EXTENSIONS) if(protobuf_generate_LANGUAGE STREQUAL cpp) set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc) @@ -245,7 +249,7 @@ function(protobuf_generate) add_custom_command( OUTPUT ${_generated_srcs} COMMAND protobuf::protoc - ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} + ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" VERBATIM ) diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index ee07f83..759f57c 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -435,7 +435,7 @@ endif() # Determine the list of possible names for the ruby library -set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION}) +set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby${_Ruby_NODOT_VERSION} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION}) if(WIN32) set(_Ruby_POSSIBLE_MSVC_RUNTIMES "msvcrt;vcruntime140;vcruntime140_1") diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake index 4c7ad89..7c610d9 100644 --- a/Modules/FindSWIG.cmake +++ b/Modules/FindSWIG.cmake @@ -87,56 +87,68 @@ if (NOT _SWIG_NAMES) endif() find_program(SWIG_EXECUTABLE NAMES ${_SWIG_NAMES} swig) +unset(_SWIG_NAMES) -if(SWIG_EXECUTABLE) - execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib - OUTPUT_VARIABLE SWIG_swiglib_output - ERROR_VARIABLE SWIG_swiglib_error - RESULT_VARIABLE SWIG_swiglib_result) +if(SWIG_EXECUTABLE AND NOT SWIG_DIR) + # Find default value for SWIG library directory + execute_process(COMMAND "${SWIG_EXECUTABLE}" -swiglib + OUTPUT_VARIABLE _swig_output + ERROR_VARIABLE _swig_error + RESULT_VARIABLE _swig_result) - if(SWIG_swiglib_result) + if(_swig_result) + set(_msg "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${_swig_error}") if(SWIG_FIND_REQUIRED) - message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}") + message(SEND_ERROR "${_msg}") else() - message(STATUS "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}") + message(STATUS "${_msg}") endif() + unset(_msg) else() - string(REGEX REPLACE "[\n\r]+" ";" SWIG_swiglib_output ${SWIG_swiglib_output}) - find_path(SWIG_DIR swig.swg PATHS ${SWIG_swiglib_output} NO_CMAKE_FIND_ROOT_PATH) - if(SWIG_DIR) - set(SWIG_USE_FILE ${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake) - execute_process(COMMAND ${SWIG_EXECUTABLE} -version - OUTPUT_VARIABLE SWIG_version_output - ERROR_VARIABLE SWIG_version_output - RESULT_VARIABLE SWIG_version_result) - if(SWIG_version_result) - message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -version\" failed with output:\n${SWIG_version_output}") - else() - string(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1" - SWIG_version_output "${SWIG_version_output}") - set(SWIG_VERSION ${SWIG_version_output} CACHE STRING "Swig version" FORCE) - endif() - endif() + string(REGEX REPLACE "[\n\r]+" ";" _SWIG_LIB ${_swig_output}) endif() - if(SWIG_FIND_COMPONENTS) - execute_process(COMMAND ${SWIG_EXECUTABLE} -help - OUTPUT_VARIABLE SWIG_swighelp_output - ERROR_VARIABLE SWIG_swighelp_error - RESULT_VARIABLE SWIG_swighelp_result) - if(SWIG_swighelp_result) - message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${SWIG_swiglib_error}") - else() - string(REPLACE "\n" ";" SWIG_swighelp_output "${SWIG_swighelp_output}") - foreach(SWIG_line IN LISTS SWIG_swighelp_output) - if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers") - set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE) - endif() - endforeach() - endif() + # Find SWIG library directory + find_path(SWIG_DIR swig.swg PATHS ${_SWIG_LIB} NO_CMAKE_FIND_ROOT_PATH) + unset(_SWIG_LIB) +endif() + +if(SWIG_EXECUTABLE AND SWIG_DIR AND NOT SWIG_VERSION) + # Determine SWIG version + execute_process(COMMAND "${SWIG_EXECUTABLE}" -version + OUTPUT_VARIABLE _swig_output + ERROR_VARIABLE _swig_output + RESULT_VARIABLE _swig_result) + if(_swig_result) + message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -version\" failed with output:\n${_swig_output}") + else() + string(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1" + _swig_output "${_swig_output}") + set(SWIG_VERSION ${_swig_output} CACHE STRING "Swig version" FORCE) + endif() +endif() + +if(SWIG_EXECUTABLE AND SWIG_FIND_COMPONENTS) + execute_process(COMMAND "${SWIG_EXECUTABLE}" -help + OUTPUT_VARIABLE _swig_output + ERROR_VARIABLE _swig_error + RESULT_VARIABLE _swig_result) + if(_swig_result) + message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${_swig_error}") + else() + string(REPLACE "\n" ";" _swig_output "${_swig_output}") + foreach(SWIG_line IN LISTS _swig_output) + if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers") + set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE) + endif() + endforeach() endif() endif() +unset(_swig_output) +unset(_swig_error) +unset(_swig_result) + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args( SWIG HANDLE_COMPONENTS @@ -144,4 +156,8 @@ find_package_handle_standard_args( VERSION_VAR SWIG_VERSION HANDLE_VERSION_RANGE) +if(SWIG_FOUND) + set(SWIG_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake") +endif() + mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE) diff --git a/Modules/FindSelfPackers.cmake b/Modules/FindSelfPackers.cmake index 1abbcbd..a6eb6e5 100644 --- a/Modules/FindSelfPackers.cmake +++ b/Modules/FindSelfPackers.cmake @@ -17,15 +17,18 @@ executables or shared libs. Examples: #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindMsys.cmake) find_program(SELF_PACKER_FOR_EXECUTABLE upx ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) find_program(SELF_PACKER_FOR_SHARED_LIB upx ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index 87e88bc..c6a3451 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -119,7 +119,10 @@ macro(_check_pthreads_flag) ${CMAKE_BINARY_DIR} ${_threads_src} CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread - OUTPUT_VARIABLE OUTPUT) + OUTPUT_VARIABLE _cmake_check_pthreads_output) + + string(APPEND _cmake_find_threads_output "${_cmake_check_pthreads_output}") + unset(_cmake_check_pthreads_output) unset(_threads_src) if(THREADS_HAVE_PTHREAD_ARG) @@ -127,9 +130,6 @@ macro(_check_pthreads_flag) message(CHECK_PASS "yes") else() message(CHECK_FAIL "no") - file(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n") endif() endif() @@ -225,7 +225,7 @@ if(CMAKE_USE_PTHREADS_INIT) set(CMAKE_THREAD_LIBS_INIT ) endif() - if(CMAKE_SYSTEM MATCHES "CYGWIN_NT") + if(CMAKE_SYSTEM MATCHES "CYGWIN_NT" OR CMAKE_SYSTEM MATCHES "MSYS_NT") set(CMAKE_USE_PTHREADS_INIT 1) set(Threads_FOUND TRUE) set(CMAKE_THREAD_LIBS_INIT ) @@ -249,4 +249,10 @@ if(THREADS_FOUND AND NOT TARGET Threads::Threads) if(CMAKE_THREAD_LIBS_INIT) set_property(TARGET Threads::Threads PROPERTY INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") endif() +elseif(NOT THREADS_FOUND AND _cmake_find_threads_output) + file(APPEND + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if compiler accepts -pthread failed with the following output:\n${_cmake_find_threads_output}\n\n") endif() + +unset(_cmake_find_threads_output) diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake index 2513f5c..97739fa 100644 --- a/Modules/FindUnixCommands.cmake +++ b/Modules/FindUnixCommands.cmake @@ -13,10 +13,12 @@ This module looks for the Unix commands ``bash``, ``cp``, ``gzip``, #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindMsys.cmake) find_program(BASH bash ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( BASH @@ -25,6 +27,7 @@ mark_as_advanced( find_program(CP cp ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( CP @@ -33,6 +36,7 @@ mark_as_advanced( find_program(GZIP gzip ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( GZIP @@ -41,6 +45,7 @@ mark_as_advanced( find_program(MV mv ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( MV @@ -49,6 +54,7 @@ mark_as_advanced( find_program(RM rm ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( RM @@ -60,6 +66,7 @@ find_program(TAR gtar PATH ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) mark_as_advanced( TAR diff --git a/Modules/FindWget.cmake b/Modules/FindWget.cmake index bd01ec2..d0b6fdf 100644 --- a/Modules/FindWget.cmake +++ b/Modules/FindWget.cmake @@ -16,10 +16,12 @@ This module looks for wget. This module defines the following values: #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindMsys.cmake) find_program(WGET_EXECUTABLE wget ${CYGWIN_INSTALL_PATH}/bin + ${MSYS_INSTALL_PATH}/usr/bin ) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake index 998faf1..9e5726b 100644 --- a/Modules/FortranCInterface/Detect.cmake +++ b/Modules/FortranCInterface/Detect.cmake @@ -6,14 +6,17 @@ configure_file(${FortranCInterface_SOURCE_DIR}/Input.cmake.in # Detect the Fortran/C interface on the first run or when the # configuration changes. -if(${FortranCInterface_BINARY_DIR}/Input.cmake - IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake - OR ${FortranCInterface_SOURCE_DIR}/Output.cmake.in - IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake - OR ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt - IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake - OR ${CMAKE_CURRENT_LIST_FILE} - IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake +if(NOT EXISTS ${FortranCInterface_BINARY_DIR}/Output.cmake + OR NOT EXISTS ${FortranCInterface_BINARY_DIR}/Input.cmake + OR NOT EXISTS ${FortranCInterface_BINARY_DIR}/Output.cmake.in + OR NOT ${FortranCInterface_BINARY_DIR}/Output.cmake + IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Input.cmake + OR NOT ${FortranCInterface_SOURCE_DIR}/Output.cmake + IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake.in + OR NOT ${FortranCInterface_BINARY_DIR}/Output.cmake + IS_NEWER_THAN ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt + OR NOT ${FortranCInterface_BINARY_DIR}/Output.cmake + IS_NEWER_THAN ${CMAKE_CURRENT_LIST_FILE} ) message(CHECK_START "Detecting Fortran/C Interface") else() diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake index e149f4c..f7d8c36 100644 --- a/Modules/GNUInstallDirs.cmake +++ b/Modules/GNUInstallDirs.cmake @@ -352,7 +352,7 @@ macro(GNUInstallDirs_get_absolute_install_dir absvar var) if(GGAID_extra_arg_count GREATER 0) list(GET GGAID_extra_args 0 GGAID_dir) else() - # Historical behaviour: use ${dir} from caller's scope + # Historical behavior: use ${dir} from caller's scope set(GGAID_dir "${dir}") message(AUTHOR_WARNING "GNUInstallDirs_get_absolute_install_dir called without third argument. " diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index ed5c38b..e90a9b5 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -83,7 +83,7 @@ to 1 all prerequisites will be found recursively, if set to 0 only direct prerequisites are listed. <exclude_system> must be 0 or 1 indicating whether to include or exclude "system" prerequisites. With <verbose> set to 0 only the full path names of the prerequisites are -printed, set to 1 extra informatin will be displayed. +printed, set to 1 extra information will be displayed. :: diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index 2ea9e74..80d8e23 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -504,7 +504,8 @@ function(gtest_discover_tests TARGET) string(CONCAT ctest_include_content "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n" - " if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n" + " if(NOT EXISTS \"${ctest_tests_file}\" OR" "\n" + " NOT \"${ctest_tests_file}\" IS_NEWER_THAN \"$<TARGET_FILE:${TARGET}>\")" "\n" " include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")" "\n" " gtest_discover_tests_impl(" "\n" " TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n" diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake index 08bbc68..bece2dd 100644 --- a/Modules/Internal/CPack/CPackRPM.cmake +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -6,6 +6,56 @@ cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # if IN_LIST +function(set_spec_script_if_enabled TYPE PACKAGE_NAME VAR) + if(NOT "${VAR}" STREQUAL "" AND NOT "${VAR}" STREQUAL "\n") + if(PACKAGE_NAME) + set(PACKAGE_NAME " -n ${PACKAGE_NAME}") + endif() + set(${TYPE}_ + "%${TYPE}${PACKAGE_NAME}\n" + "${VAR}\n" PARENT_SCOPE) + else() + set(${TYPE} "" PARENT_SCOPE) + endif() +endfunction() + +macro(set_spec_scripts PACKAGE_NAME) + # we should only set scripts that were provided + # as script announcement without content inside + # spec file will generate unneeded dependency + # on shell + + set_spec_script_if_enabled( + "post" + "${PACKAGE_NAME}" + "${RPM_SYMLINK_POSTINSTALL}\n${CPACK_RPM_SPEC_POSTINSTALL}") + + set_spec_script_if_enabled( + "posttrans" + "${PACKAGE_NAME}" + "${CPACK_RPM_SPEC_POSTTRANS}") + + set_spec_script_if_enabled( + "postun" + "${PACKAGE_NAME}" + "${CPACK_RPM_SPEC_POSTUNINSTALL}") + + set_spec_script_if_enabled( + "pre" + "${PACKAGE_NAME}" + "${CPACK_RPM_SPEC_PREINSTALL}") + + set_spec_script_if_enabled( + "pretrans" + "${PACKAGE_NAME}" + "${CPACK_RPM_SPEC_PRETRANS}") + + set_spec_script_if_enabled( + "preun" + "${PACKAGE_NAME}" + "${CPACK_RPM_SPEC_PREUNINSTALL}") +endmacro() + function(get_file_permissions FILE RETURN_VAR) execute_process(COMMAND ls -l ${FILE} OUTPUT_VARIABLE permissions_ @@ -1349,15 +1399,21 @@ function(cpack_rpm_generate_package) continue() endif() - file(GLOB_RECURSE files_for_move_ LIST_DIRECTORIES false RELATIVE + file(GLOB_RECURSE files_for_move_ LIST_DIRECTORIES true RELATIVE "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}" "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/*") foreach(f_ IN LISTS files_for_move_) - get_filename_component(dir_path_ "${f_}" DIRECTORY) set(src_file_ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/${f_}") + if(IS_DIRECTORY "${src_file_}") + file(MAKE_DIRECTORY "${WDIR}/${f_}") + continue() + endif() + + get_filename_component(dir_path_ "${f_}" DIRECTORY) + # check that we are not overriding an existing file that doesn't # match the file that we want to copy if(EXISTS "${src_file_}" AND EXISTS "${WDIR}/${f_}") @@ -1607,6 +1663,9 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ ) elseif(GENERATE_SPEC_PARTS) # binary rpm with single debuginfo package + + set_spec_scripts("${CPACK_RPM_PACKAGE_NAME}") + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in "# -*- rpm-spec -*- %package -n \@CPACK_RPM_PACKAGE_NAME\@ @@ -1637,6 +1696,13 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ %description -n \@CPACK_RPM_PACKAGE_NAME\@ \@CPACK_RPM_PACKAGE_DESCRIPTION\@ +\@post_\@ +\@posttrans_\@ +\@postun_\@ +\@pre_\@ +\@pretrans_\@ +\@preun_\@ + %files -n \@CPACK_RPM_PACKAGE_NAME\@ %defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@) \@CPACK_RPM_INSTALL_FILES\@ @@ -1662,6 +1728,8 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ set(RPMBUILD_FLAGS "-bb") if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) + set_spec_scripts("") + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in "# Restore old style debuginfo creation for rpm >= 4.14. %undefine _debugsource_packages @@ -1725,24 +1793,12 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT %clean -%post -\@RPM_SYMLINK_POSTINSTALL\@ -\@CPACK_RPM_SPEC_POSTINSTALL\@ - -%posttrans -\@CPACK_RPM_SPEC_POSTTRANS\@ - -%postun -\@CPACK_RPM_SPEC_POSTUNINSTALL\@ - -%pre -\@CPACK_RPM_SPEC_PREINSTALL\@ - -%pretrans -\@CPACK_RPM_SPEC_PRETRANS\@ - -%preun -\@CPACK_RPM_SPEC_PREUNINSTALL\@ +\@post_\@ +\@posttrans_\@ +\@postun_\@ +\@pre_\@ +\@pretrans_\@ +\@preun_\@ %files %defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@) diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in index e6439ad..0a9c487 100644 --- a/Modules/Internal/CPack/NSIS.template.in +++ b/Modules/Internal/CPack/NSIS.template.in @@ -919,8 +919,8 @@ Function .onInit ;Run the uninstaller uninst: ClearErrors - StrLen $2 "\Uninstall.exe" - StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path + StrLen $2 "\@CPACK_NSIS_UNINSTALL_NAME@.exe" + StrCpy $3 $0 -$2 # remove "\@CPACK_NSIS_UNINSTALL_NAME@.exe" from UninstallString to get path ExecWait '"$0" /S _?=$3' ;Do not copy the uninstaller to a temp file IfErrors uninst_failed inst diff --git a/Modules/Platform/ARTOS-GNU-C.cmake b/Modules/Platform/ARTOS-GNU-C.cmake index fe8d782..bce4613 100644 --- a/Modules/Platform/ARTOS-GNU-C.cmake +++ b/Modules/Platform/ARTOS-GNU-C.cmake @@ -1,4 +1,4 @@ -# Define ARTOS to select proper behaviour and tell preprocessor to accept C++ style comments. +# Define ARTOS to select proper behavior and tell preprocessor to accept C++ style comments. string(APPEND CMAKE_C_FLAGS_INIT " -DARTOS -Xp -+") # ac doesn't support -g properly and doesn't support the normal gcc optimization options. Just use the defaults set by ac. string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " ") diff --git a/Modules/Platform/Apple-NVIDIA-CUDA.cmake b/Modules/Platform/Apple-NVIDIA-CUDA.cmake index bec3948..35e759a 100644 --- a/Modules/Platform/Apple-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Apple-NVIDIA-CUDA.cmake @@ -1,19 +1,19 @@ include(Platform/Darwin) -set(__IMPLICT_LINKS ) +set(__IMPLICIT_LINKS) foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) - string(APPEND __IMPLICT_LINKS " -L\"${dir}\"") + string(APPEND __IMPLICIT_LINKS " -L\"${dir}\"") endforeach() foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) if(${lib} MATCHES "/") - string(APPEND __IMPLICT_LINKS " \"${lib}\"") + string(APPEND __IMPLICIT_LINKS " \"${lib}\"") else() - string(APPEND __IMPLICT_LINKS " -l${lib}") + string(APPEND __IMPLICIT_LINKS " -l${lib}") endif() endforeach() set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS "-shared -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_CUDA_FLAGS "-shared -Wl,-headerpad_max_install_names") -set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}") -set(CMAKE_CUDA_CREATE_SHARED_MODULE "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}") +set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") +set(CMAKE_CUDA_CREATE_SHARED_MODULE "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index 4fa14ce..b81bd4d 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -10,7 +10,6 @@ set(__CYGWIN_COMPILER_GNU 1) # TODO: Is -Wl,--enable-auto-import now always default? string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -Wl,--enable-auto-import") -set(CMAKE_CREATE_WIN32_EXE "-mwindows") set(CMAKE_GNULD_IMAGE_VERSION "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>") @@ -23,6 +22,7 @@ macro(__cygwin_compiler_gnu lang) "<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>") set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") + set(CMAKE_${lang}_CREATE_WIN32_EXE "-mwindows") # No -fPIC on cygwin set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "") diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake index 9b897bd..fc4ea2e 100644 --- a/Modules/Platform/CYGWIN.cmake +++ b/Modules/Platform/CYGWIN.cmake @@ -1,7 +1,7 @@ -if("${CMAKE_MINIMUM_REQUIRED_VERSION}" VERSION_LESS "2.8.3.20101214") +if("${CMAKE_MINIMUM_REQUIRED_VERSION}" VERSION_LESS "2.8.3.20101214" AND NOT MSYS) set(__USE_CMAKE_LEGACY_CYGWIN_WIN32 1) endif() -if(NOT DEFINED WIN32) +if(NOT DEFINED WIN32 AND NOT MSYS) set(WIN32 0) if(DEFINED __USE_CMAKE_LEGACY_CYGWIN_WIN32) if(NOT DEFINED CMAKE_LEGACY_CYGWIN_WIN32 diff --git a/Modules/Platform/Linux-Fujitsu-C.cmake b/Modules/Platform/Linux-Fujitsu-C.cmake new file mode 100644 index 0000000..e37573d --- /dev/null +++ b/Modules/Platform/Linux-Fujitsu-C.cmake @@ -0,0 +1 @@ +include(Platform/Linux-Clang-C) diff --git a/Modules/Platform/Linux-Fujitsu-CXX.cmake b/Modules/Platform/Linux-Fujitsu-CXX.cmake new file mode 100644 index 0000000..5257f13 --- /dev/null +++ b/Modules/Platform/Linux-Fujitsu-CXX.cmake @@ -0,0 +1 @@ +include(Platform/Linux-Clang-CXX) diff --git a/Modules/Platform/Linux-Fujitsu.cmake b/Modules/Platform/Linux-Fujitsu.cmake new file mode 100644 index 0000000..be11b0a --- /dev/null +++ b/Modules/Platform/Linux-Fujitsu.cmake @@ -0,0 +1,17 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This module is shared by multiple languages; use include blocker. +if(__LINUX_COMPILER_FUJITSU) + return() +endif() +set(__LINUX_COMPILER_FUJITSU 1) + +macro(__linux_compiler_fujitsu lang) + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") +endmacro() diff --git a/Modules/Platform/MSYS-Clang-C.cmake b/Modules/Platform/MSYS-Clang-C.cmake new file mode 100644 index 0000000..f025b33 --- /dev/null +++ b/Modules/Platform/MSYS-Clang-C.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-Clang-C) diff --git a/Modules/Platform/MSYS-Clang-CXX.cmake b/Modules/Platform/MSYS-Clang-CXX.cmake new file mode 100644 index 0000000..e509eaa --- /dev/null +++ b/Modules/Platform/MSYS-Clang-CXX.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-Clang-CXX) diff --git a/Modules/Platform/MSYS-Determine-CXX.cmake b/Modules/Platform/MSYS-Determine-CXX.cmake new file mode 100644 index 0000000..dec17f0 --- /dev/null +++ b/Modules/Platform/MSYS-Determine-CXX.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-Determine-CXX) diff --git a/Modules/Platform/MSYS-GNU-C.cmake b/Modules/Platform/MSYS-GNU-C.cmake new file mode 100644 index 0000000..e8343a4 --- /dev/null +++ b/Modules/Platform/MSYS-GNU-C.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-GNU-C) diff --git a/Modules/Platform/MSYS-GNU-CXX.cmake b/Modules/Platform/MSYS-GNU-CXX.cmake new file mode 100644 index 0000000..67775de --- /dev/null +++ b/Modules/Platform/MSYS-GNU-CXX.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-GNU-CXX) diff --git a/Modules/Platform/MSYS-GNU-Fortran.cmake b/Modules/Platform/MSYS-GNU-Fortran.cmake new file mode 100644 index 0000000..b0b7d8e --- /dev/null +++ b/Modules/Platform/MSYS-GNU-Fortran.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-GNU-Fortran) diff --git a/Modules/Platform/MSYS-GNU.cmake b/Modules/Platform/MSYS-GNU.cmake new file mode 100644 index 0000000..012c112 --- /dev/null +++ b/Modules/Platform/MSYS-GNU.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-GNU) diff --git a/Modules/Platform/MSYS-windres.cmake b/Modules/Platform/MSYS-windres.cmake new file mode 100644 index 0000000..faaccc2 --- /dev/null +++ b/Modules/Platform/MSYS-windres.cmake @@ -0,0 +1 @@ +include(Platform/CYGWIN-windres) diff --git a/Modules/Platform/MSYS.cmake b/Modules/Platform/MSYS.cmake new file mode 100644 index 0000000..96fa36f --- /dev/null +++ b/Modules/Platform/MSYS.cmake @@ -0,0 +1,4 @@ +set(MSYS 1) +include(Platform/CYGWIN) +set(CMAKE_SHARED_LIBRARY_PREFIX "msys-") +set(CMAKE_SHARED_MODULE_PREFIX "msys-") diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index c508ac1..373be76 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -57,8 +57,8 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto") set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>") - set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "<CMAKE_RANLIB> <TARGET>") # Create archiving rules to support large object file lists for static libraries. @@ -71,8 +71,8 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") - set(CMAKE_CREATE_WIN32_EXE "-Xlinker /subsystem:windows") - set(CMAKE_CREATE_CONSOLE_EXE "-Xlinker /subsystem:console") + set(CMAKE_${lang}_CREATE_WIN32_EXE "-Xlinker /subsystem:windows") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "-Xlinker /subsystem:console") if(NOT "${lang}" STREQUAL "ASM") set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt) diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake index 8f1d024..4ecc2c2 100644 --- a/Modules/Platform/Windows-Embarcadero.cmake +++ b/Modules/Platform/Windows-Embarcadero.cmake @@ -51,11 +51,6 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES "-bcc.lib" ".lib") # Borland cannot handle + in the file name, so mangle object file name set (CMAKE_MANGLE_OBJECT_FILE_NAMES "ON") -# extra flags for a win32 exe -set(CMAKE_CREATE_WIN32_EXE "${_tW}" ) -# extra flags for a console app -set(CMAKE_CREATE_CONSOLE_EXE "${_tC}" ) - set (CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.") @@ -124,6 +119,9 @@ macro(__embarcadero_language lang) "tlib ${CMAKE_START_TEMP_FILE}/p512 <LINK_FLAGS> /a <TARGET_QUOTED> <OBJECTS>${CMAKE_END_TEMP_FILE}" ) + set(CMAKE_${lang}_CREATE_WIN32_EXE "${_tW}") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${_tC}") + # Precompile Headers if (EMBARCADERO) set(CMAKE_PCH_EXTENSION .pch) diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index a2e3811..d000380 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -35,7 +35,6 @@ set(CMAKE_LIBRARY_PATH_FLAG "-L") set(CMAKE_LINK_LIBRARY_FLAG "-l") set(CMAKE_LINK_DEF_FILE_FLAG "") # Empty string: passing the file is enough set(CMAKE_LINK_LIBRARY_SUFFIX "") -set(CMAKE_CREATE_WIN32_EXE "-mwindows") set(CMAKE_GNULD_IMAGE_VERSION "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>") @@ -105,6 +104,7 @@ macro(__windows_compiler_gnu lang) "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>") set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") + set(CMAKE_${lang}_CREATE_WIN32_EXE "-mwindows") list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI") @@ -121,7 +121,7 @@ macro(__windows_compiler_gnu lang) CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}") set(CMAKE_${lang}_${rule} "<CMAKE_COMMAND> -E rm -f <OBJECT_DIR>/objects.a" - "<CMAKE_AR> cr <OBJECT_DIR>/objects.a <OBJECTS>" + "<CMAKE_AR> qc <OBJECT_DIR>/objects.a <OBJECTS>" "${CMAKE_${lang}_${rule}}" ) endforeach() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index e384af4..4223bde 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -27,12 +27,8 @@ else() endif() if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE") - set(CMAKE_CREATE_WIN32_EXE "/entry:WinMainCRTStartup") - set(CMAKE_CREATE_CONSOLE_EXE "/entry:mainACRTStartup") set(_PLATFORM_LINK_FLAGS " /subsystem:windowsce") else() - set(CMAKE_CREATE_WIN32_EXE "/subsystem:windows") - set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:console") set(_PLATFORM_LINK_FLAGS "") endif() @@ -351,6 +347,14 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_LINK_EXECUTABLE "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") + if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE") + set(CMAKE_${lang}_CREATE_WIN32_EXE "/entry:WinMainCRTStartup") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "/entry:mainACRTStartup") + else() + set(CMAKE_${lang}_CREATE_WIN32_EXE "/subsystem:windows") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "/subsystem:console") + endif() + set(CMAKE_PCH_EXTENSION .pch) set(CMAKE_LINK_PCH ON) if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang") diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index a88f4bc..b83932e 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -7,49 +7,49 @@ set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") -set(__IMPLICT_LINKS ) +set(__IMPLICIT_LINKS) foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) - string(APPEND __IMPLICT_LINKS " -LIBPATH:\"${dir}\"") + string(APPEND __IMPLICIT_LINKS " -LIBPATH:\"${dir}\"") endforeach() foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) - string(APPEND __IMPLICT_LINKS " \"${lib}\"") + string(APPEND __IMPLICIT_LINKS " \"${lib}\"") endforeach() set(CMAKE_CUDA_LINK_EXECUTABLE - "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_LIBRARIES>${__IMPLICT_LINKS}") + "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_LIBRARIES>${__IMPLICIT_LINKS}") set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ") set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ") set(CMAKE_CUDA_CREATE_SHARED_LIBRARY - "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}") + "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICIT_LINKS} ${CMAKE_END_TEMP_FILE}") set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY}) set(CMAKE_CUDA_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ") set(CMAKE_CUDA_LINKER_SUPPORTS_PDB ON) set(CMAKE_CUDA_LINK_EXECUTABLE - "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}") -unset(_CMAKE_VS_LINK_EXE) + "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICIT_LINKS} ${CMAKE_END_TEMP_FILE}") +unset(_CMAKE_VS_LINK_DLL) unset(_CMAKE_VS_LINK_EXE) # Add implicit host link directories that contain device libraries # to the device link line. -set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) -if(__IMPLICT_DLINK_DIRS) - list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) +set(__IMPLICIT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +if(__IMPLICIT_DLINK_DIRS) + list(REMOVE_ITEM __IMPLICIT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) endif() -set(__IMPLICT_DLINK_FLAGS ) -foreach(dir ${__IMPLICT_DLINK_DIRS}) +set(__IMPLICIT_DLINK_FLAGS) +foreach(dir ${__IMPLICIT_DLINK_DIRS}) if(EXISTS "${dir}/curand_static.lib") - string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") + string(APPEND __IMPLICIT_DLINK_FLAGS " -L\"${dir}\"") endif() endforeach() -unset(__IMPLICT_DLINK_DIRS) +unset(__IMPLICIT_DLINK_DIRS) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICIT_DLINK_FLAGS}") set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") -unset(__IMPLICT_DLINK_FLAGS) + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICIT_DLINK_FLAGS}") +unset(__IMPLICIT_DLINK_FLAGS) string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}") @@ -69,14 +69,6 @@ else() endif() unset(_cmp0092) -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") - -if(UNIX) - list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") -endif() - string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"") string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG") diff --git a/Modules/Platform/Windows-OpenWatcom-C.cmake b/Modules/Platform/Windows-OpenWatcom-C.cmake index ce9bc45..b82a4cb 100644 --- a/Modules/Platform/Windows-OpenWatcom-C.cmake +++ b/Modules/Platform/Windows-OpenWatcom-C.cmake @@ -1 +1,2 @@ include(Platform/Windows-OpenWatcom) +__windows_open_watcom(C) diff --git a/Modules/Platform/Windows-OpenWatcom-CXX.cmake b/Modules/Platform/Windows-OpenWatcom-CXX.cmake index ce9bc45..ac90d28 100644 --- a/Modules/Platform/Windows-OpenWatcom-CXX.cmake +++ b/Modules/Platform/Windows-OpenWatcom-CXX.cmake @@ -1 +1,2 @@ include(Platform/Windows-OpenWatcom) +__windows_open_watcom(CXX) diff --git a/Modules/Platform/Windows-OpenWatcom.cmake b/Modules/Platform/Windows-OpenWatcom.cmake index 70055da..19bcb97 100644 --- a/Modules/Platform/Windows-OpenWatcom.cmake +++ b/Modules/Platform/Windows-OpenWatcom.cmake @@ -6,8 +6,6 @@ include_guard() set(CMAKE_BUILD_TYPE_INIT Debug) -set(CMAKE_CREATE_WIN32_EXE "system nt_win" ) -set(CMAKE_CREATE_CONSOLE_EXE "system nt" ) string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system nt_dll") string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system nt_dll") @@ -30,3 +28,8 @@ if(CMAKE_CROSSCOMPILING) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt) endif() endif() + +macro(__windows_open_watcom lang) + set(CMAKE_${lang}_CREATE_WIN32_EXE "system nt_win") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "system nt") +endmacro() diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake index 8b824bc..c823423 100644 --- a/Modules/Platform/Windows-df.cmake +++ b/Modules/Platform/Windows-df.cmake @@ -27,8 +27,8 @@ set(CMAKE_Fortran_COMPILE_OBJECT set(CMAKE_Fortran_LINK_EXECUTABLE "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") -set(CMAKE_CREATE_WIN32_EXE /winapp) -set(CMAKE_CREATE_CONSOLE_EXE ) +set(CMAKE_Fortran_CREATE_WIN32_EXE /winapp) +set(CMAKE_Fortran_CREATE_CONSOLE_EXE ) # does the compiler support pdbtype and is it the newer compiler diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 120a54c..baed7ef 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -18,6 +18,7 @@ Creating And Installing JARs add_jar(<target_name> [SOURCES] <source1> [<source2>...] [<resource1>...] + [RESOURCES NAMESPACE <ns1> <resource1>... [NAMESPACE <nsX> <resourceX>...]... ] [INCLUDE_JARS <jar1> [<jar2>...]] [ENTRY_POINT <entry>] [VERSION <version>] @@ -31,7 +32,31 @@ This command creates a ``<target_name>.jar``. It compiles the given ``<source>`` files and adds the given ``<resource>`` files to the jar file. Source files can be java files or listing files (prefixed by ``@``). If only resource files are given then just a jar file -is created. The list of ``INCLUDE_JARS`` are added to the classpath when +is created. + +The ``RESOURCES`` parameter adds the named ``<resource>`` files to the jar +by stripping the source file path and placing the file beneath ``<ns>`` +within the jar. For example:: + + RESOURCES NAMESPACE "/com/my/namespace" "a/path/to/resource.txt" + +results in a resource accessible via ``/com/my/namespace/resource.txt`` +within the jar. + +Resources may be added without adjusting the namespace by adding them to +the list of ``SOURCES`` (original behavior), in this case, resource +paths must be relative to ``CMAKE_CURRENT_SOURCE_DIR``. Adding resources +without using the ``RESOURCES`` parameter in out of source builds will +almost certainly result in confusion. + +.. note:: SOURCES + Adding resources via the ``SOURCES`` parameter relies upon a hard-coded + list of file extensions which are tested to determine whether they compile + (e.g. File.java). ``SOURCES`` files which match the extensions are compiled. + Files which do not match are treated as resources. To include uncompiled + resources matching those file extensions use the ``RESOURCES`` parameter. + +The list of ``INCLUDE_JARS`` are added to the classpath when compiling the java sources and also to the dependencies of the target. ``INCLUDE_JARS`` also accepts other target names created by ``add_jar()``. For backwards compatibility, jar files listed as sources are ignored (as @@ -449,6 +474,58 @@ function(__java_export_jar VAR TARGET PATH) set(${VAR} "${${VAR}}" PARENT_SCOPE) endfunction() +function(__java_copy_resource_namespaces VAR DEST JAVA_RESOURCE_FILES JAVA_RESOURCE_FILES_RELATIVE) + + set(_ns_ID "") + set(_ns_VAL "") + + foreach(_item IN LISTS VAR) + if(NOT _ns_ID) + if(NOT _item STREQUAL "NAMESPACE") + message(FATAL_ERROR "UseJava: Expecting \"NAMESPACE\", got\t\"${_item}\"") + return() + endif() + endif() + + if(_item STREQUAL "NAMESPACE") + set(_ns_VAL "") # Prepare for next namespace + set(_ns_ID "${_item}") + continue() + endif() + + if( NOT _ns_VAL) + # we're expecting the next token to be a namespace value + # whatever it is, we're treating it like a namespace + set(_ns_VAL "${_item}") + continue() + endif() + + if(_ns_ID AND _ns_VAL) + # We're expecting a file name, check to see if we got one + cmake_path(ABSOLUTE_PATH _item OUTPUT_VARIABLE _test_file_name) + if (NOT EXISTS "${_test_file_name}") + message(FATAL_ERROR "UseJava: File does not exist:\t${_item}") + return() + endif() + endif() + + cmake_path(ABSOLUTE_PATH _item OUTPUT_VARIABLE _abs_file_name) + cmake_path(GET _item FILENAME _resource_file_name) + set(_dest_resource_file_name "${_ns_VAL}/${_resource_file_name}" ) + + __java_copy_file( ${_abs_file_name} + ${DEST}/${_dest_resource_file_name} + "Copying ${_item} to the build directory") + + list(APPEND RESOURCE_FILES_LIST ${DEST}/${_dest_resource_file_name}) + list(APPEND RELATIVE_RESOURCE_FILES_LIST ${_dest_resource_file_name}) + + endforeach() + + set(${JAVA_RESOURCE_FILES} "${RESOURCE_FILES_LIST}" PARENT_SCOPE) + set(${JAVA_RESOURCE_FILES_RELATIVE} "${RELATIVE_RESOURCE_FILES_LIST}" PARENT_SCOPE) +endfunction() + # define helper scripts set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJava/javaTargets.cmake.in) set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJava/Symlinks.cmake) @@ -461,12 +538,14 @@ endif() function(add_jar _TARGET_NAME) - cmake_parse_arguments(_add_jar - "" - "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST" - "SOURCES;INCLUDE_JARS;GENERATE_NATIVE_HEADERS" - ${ARGN} - ) + set(options) # currently there are no zero value args (aka: options) + set(oneValueArgs "ENTRY_POINT;MANIFEST;OUTPUT_DIR;;OUTPUT_NAME;VERSION" ) + set(multiValueArgs "GENERATE_NATIVE_HEADERS;INCLUDE_JARS;RESOURCES;SOURCES" ) + + cmake_parse_arguments(PARSE_ARGV 1 _add_jar + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" ) # In CMake < 2.8.12, add_jar used variables which were set prior to calling # add_jar for customizing the behavior of add_jar. In order to be backwards @@ -490,6 +569,9 @@ function(add_jar _TARGET_NAME) set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}") endif() + # This *should* still work if <resources1>... are included without a + # named RESOURCES argument. In that case, the old behavior of potentially + # misplacing the within the Jar will behave as previously (incorrectly) set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS}) if (NOT DEFINED _add_jar_OUTPUT_DIR) @@ -639,6 +721,13 @@ function(add_jar _TARGET_NAME) endif () endforeach() + if(_add_jar_RESOURCES) # Process RESOURCES if it exists + __java_copy_resource_namespaces("${_add_jar_RESOURCES}" + ${CMAKE_JAVA_CLASS_OUTPUT_PATH} + _JAVA_RESOURCE_FILES + _JAVA_RESOURCE_FILES_RELATIVE) + endif() + foreach(_JAVA_INCLUDE_JAR IN LISTS _add_jar_INCLUDE_JARS) if (TARGET ${_JAVA_INCLUDE_JAR}) get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE) diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 6073125..5c8f152 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -38,7 +38,13 @@ Defines the following command for use with ``SWIG``: .. versionchanged:: 3.15 Alternate library name (set with the :prop_tgt:`OUTPUT_NAME` property, - for example) will be passed on to Python and CSharp wrapper libraries. + for example) will be passed on to ``Python`` and ``CSharp`` wrapper + libraries. + + .. versionchanged:: 3.21 + Generated library use standard naming conventions for ``CSharp`` language + when policy :policy:`CMP0122` is set to ``NEW``. Otherwise, the legacy + behavior is applied. .. note:: @@ -185,8 +191,12 @@ ensure generated files will receive the required settings. If set to ``TRUE``, implicit dependencies are generated by the ``swig`` tool itself. This property is only meaningful for - :ref:`Makefile <Makefile Generators>` and - :ref:`Ninja <Ninja Generators>` generators. Default value is ``FALSE``. + :ref:`Makefile <Makefile Generators>`, + :ref:`Ninja <Ninja Generators>` and :generator:`Xcode` generators. Default + value is ``FALSE``. + + .. versionadded:: 3.21 + Added the support of :generator:`Xcode` generator. ``SWIG_MODULE_NAME`` Specify the actual import name of the module in the target language. @@ -330,12 +340,17 @@ as well as ``SWIG``: .. versionadded:: 3.20 If set to ``TRUE``, implicit dependencies are generated by the ``swig`` tool - itself. This property is only meaningful for - :ref:`Makefile <Makefile Generators>` and - :ref:`Ninja <Ninja Generators>` generators. Default value is ``FALSE``. + itself. This variable is only meaningful for + :ref:`Makefile <Makefile Generators>`, + :ref:`Ninja <Ninja Generators>` and :generator:`Xcode` generators. Default + value is ``FALSE``. Source file property ``USE_SWIG_DEPENDENCIES``, if not defined, will be initialized with the value of this variable. + + .. versionadded:: 3.21 + Added the support of :generator:`Xcode` generator. + #]=======================================================================] cmake_policy(PUSH) @@ -500,7 +515,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) endif() set (use_swig_dependencies ${SWIG_USE_SWIG_DEPENDENCIES}) - if (CMAKE_GENERATOR MATCHES "Make|Ninja") + if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode") get_property(use_swig_dependencies_set SOURCE "${infile}" PROPERTY USE_SWIG_DEPENDENCIES SET) if (use_swig_dependencies_set) get_property(use_swig_dependencies SOURCE "${infile}" PROPERTY USE_SWIG_DEPENDENCIES) @@ -515,7 +530,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) endif() set (property "$<TARGET_PROPERTY:${target_name},SWIG_INCLUDE_DIRECTORIES>") list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:$<TARGET_GENEX_EVAL:${target_name},${property}>,$<SEMICOLON>-I>>") - set (property "$<TARGET_PROPERTY:${target_name},INCLUDE_DIRECTORIES>") + set (property "$<REMOVE_DUPLICATES:$<TARGET_PROPERTY:${target_name},INCLUDE_DIRECTORIES>>") get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES) if (use_target_include_dirs) list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") @@ -825,7 +840,7 @@ function(SWIG_ADD_LIBRARY name) set(SWIG_SOURCE_FILE_EXTENSIONS ".i") endif() - if (CMAKE_GENERATOR MATCHES "Make|Ninja") + if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode") # For Makefiles and Ninja generators, use SWIG generated dependencies if (NOT DEFINED SWIG_USE_SWIG_DEPENDENCIES) set (SWIG_USE_SWIG_DEPENDENCIES OFF) @@ -952,6 +967,17 @@ function(SWIG_ADD_LIBRARY name) endif () elseif (swig_lowercase_language STREQUAL "fortran") # Do *not* override the target's library prefix + elseif (swig_lowercase_language STREQUAL "csharp") + cmake_policy(GET CMP0122 csharp_naming_policy) + if (csharp_naming_policy STREQUAL "NEW") + # Do *not* override the target's library prefix + else() + if (NOT csharp_naming_policy) + cmake_policy(GET_WARNING CMP0122 _cmp0122_warning) + message(AUTHOR_WARNING "${_cmp0122_warning}\n") + endif() + set_target_properties (${target_name} PROPERTIES PREFIX "") + endif() else() # assume empty prefix because we expect the module to be dynamically loaded set_target_properties (${target_name} PROPERTIES PREFIX "") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 6adc9cf..bd9e4c2 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -44,7 +44,7 @@ endif() if(NOT CMake_DEFAULT_RECURSION_LIMIT) if(DEFINED ENV{DASHBOARD_TEST_FROM_CTEST}) set(CMake_DEFAULT_RECURSION_LIMIT 100) - elseif(MINGW) + elseif(MINGW OR MSYS) set(CMake_DEFAULT_RECURSION_LIMIT 400) elseif(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM") set(CMake_DEFAULT_RECURSION_LIMIT 600) @@ -198,6 +198,8 @@ set(SRCS cmCMakePath.cxx cmCMakePresetsFile.cxx cmCMakePresetsFile.h + cmCMakePresetsFileInternal.h + cmCMakePresetsFileReadJSON.cxx cmCommandArgumentParserHelper.cxx cmCommonTargetGenerator.cxx cmCommonTargetGenerator.h @@ -636,6 +638,7 @@ set(SRCS cmMathCommand.h cmMessageCommand.cxx cmMessageCommand.h + cmMessageMetadata.h cmOptionCommand.cxx cmOptionCommand.h cmOutputRequiredFilesCommand.cxx @@ -785,8 +788,6 @@ if (WIN32) cmVisualStudioGeneratorOptions.cxx cmVisualStudio10TargetGenerator.h cmVisualStudio10TargetGenerator.cxx - cmVisualStudio10ToolsetOptions.h - cmVisualStudio10ToolsetOptions.cxx cmLocalVisualStudio10Generator.cxx cmLocalVisualStudio10Generator.h cmGlobalVisualStudio10Generator.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9057828..b80af47 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 20) -set(CMake_VERSION_PATCH 2) +set(CMake_VERSION_PATCH 20210524) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index c4bd7f1..1429c46 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -7,6 +7,8 @@ #include <sstream> #include <utility> +#include <cm/string_view> + #include "cmCPackComponentGroup.h" #include "cmCPackIFWCommon.h" #include "cmCPackIFWGenerator.h" @@ -30,44 +32,67 @@ cmCPackIFWPackage::DependenceStruct::DependenceStruct() = default; cmCPackIFWPackage::DependenceStruct::DependenceStruct( const std::string& dependence) { - // Search compare section - size_t pos = std::string::npos; - if ((pos = dependence.find("<=")) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual; - this->Compare.Value = dependence.substr(pos + 2); - } else if ((pos = dependence.find(">=")) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual; - this->Compare.Value = dependence.substr(pos + 2); - } else if ((pos = dependence.find('<')) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareLess; - this->Compare.Value = dependence.substr(pos + 1); - } else if ((pos = dependence.find('=')) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareEqual; - this->Compare.Value = dependence.substr(pos + 1); - } else if ((pos = dependence.find('>')) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareGreater; - this->Compare.Value = dependence.substr(pos + 1); - } else if ((pos = dependence.find('-')) != std::string::npos) { - this->Compare.Type = cmCPackIFWPackage::CompareNone; - this->Compare.Value = dependence.substr(pos + 1); - } - size_t dashPos = dependence.find('-'); - if (dashPos != std::string::npos) { - pos = dashPos; - } - this->Name = dependence.substr(0, pos); + // Preferred format is name and version are separated by a colon (:), but + // note that this is only supported with QtIFW 3.1 or later. Backward + // compatibility allows a hyphen (-) as a separator instead, but names then + // cannot contain a hyphen. + size_t pos; + if ((pos = dependence.find(':')) == std::string::npos) { + pos = dependence.find('-'); + } + + if (pos != std::string::npos) { + this->Name = dependence.substr(0, pos); + ++pos; + if (pos == dependence.size()) { + // Nothing after the separator. Treat this as no version constraint. + return; + } + + const auto versionPart = + cm::string_view(dependence.data() + pos, dependence.size() - pos); + + if (cmHasLiteralPrefix(versionPart, "<=")) { + this->Compare.Type = cmCPackIFWPackage::CompareLessOrEqual; + this->Compare.Value = std::string(versionPart.substr(2)); + } else if (cmHasLiteralPrefix(versionPart, ">=")) { + this->Compare.Type = cmCPackIFWPackage::CompareGreaterOrEqual; + this->Compare.Value = std::string(versionPart.substr(2)); + } else if (cmHasPrefix(versionPart, '<')) { + this->Compare.Type = cmCPackIFWPackage::CompareLess; + this->Compare.Value = std::string(versionPart.substr(1)); + } else if (cmHasPrefix(versionPart, '=')) { + this->Compare.Type = cmCPackIFWPackage::CompareEqual; + this->Compare.Value = std::string(versionPart.substr(1)); + } else if (cmHasPrefix(versionPart, '>')) { + this->Compare.Type = cmCPackIFWPackage::CompareGreater; + this->Compare.Value = std::string(versionPart.substr(1)); + } else { + // We found no operator but a version specification is still expected to + // follow. The default behavior is to treat this the same as =. We + // explicitly record that as our type (it simplifies our logic a little + // and is also clearer). + this->Compare.Type = cmCPackIFWPackage::CompareEqual; + this->Compare.Value = std::string(versionPart); + } + } else { + this->Name = dependence; + } } std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const { - if (this->Compare.Type == cmCPackIFWPackage::CompareNone) { - return this->Name; - } - std::string result = this->Name; - - if (this->Compare.Type != cmCPackIFWPackage::CompareNone || - !this->Compare.Value.empty()) { + if (this->Name.find('-') != std::string::npos) { + // When a name contains a hyphen, we must use a colon after the name to + // prevent the hyphen from being parsed by QtIFW as the separator between + // the name and the version. Note that a colon is only supported with + // QtIFW 3.1 or later. + result += ":"; + } else if (this->Compare.Type != cmCPackIFWPackage::CompareNone || + !this->Compare.Value.empty()) { + // No hyphen in the name and we know a version part will follow. Use a + // hyphen as a separator since this works for all QtIFW versions. result += "-"; } @@ -609,6 +634,9 @@ void cmCPackIFWPackage::GeneratePackageFile() } // Dependencies + const bool hyphensInNamesUnsupported = this->Generator && + !this->Generator->FrameworkVersion.empty() && this->IsVersionLess("3.1"); + bool warnUnsupportedNames = false; std::set<DependenceStruct> compDepSet; for (DependenceStruct* ad : this->AlienDependencies) { compDepSet.insert(*ad); @@ -620,9 +648,13 @@ void cmCPackIFWPackage::GeneratePackageFile() if (!compDepSet.empty()) { std::ostringstream dependencies; auto it = compDepSet.begin(); + warnUnsupportedNames |= + hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos; dependencies << it->NameWithCompare(); ++it; while (it != compDepSet.end()) { + warnUnsupportedNames |= + hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos; dependencies << "," << it->NameWithCompare(); ++it; } @@ -638,15 +670,28 @@ void cmCPackIFWPackage::GeneratePackageFile() if (!compAutoDepSet.empty()) { std::ostringstream dependencies; auto it = compAutoDepSet.begin(); + warnUnsupportedNames |= + hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos; dependencies << it->NameWithCompare(); ++it; while (it != compAutoDepSet.end()) { + warnUnsupportedNames |= + hyphensInNamesUnsupported && it->Name.find('-') != std::string::npos; dependencies << "," << it->NameWithCompare(); ++it; } xout.Element("AutoDependOn", dependencies.str()); } + if (warnUnsupportedNames) { + cmCPackIFWLogger( + WARNING, + "The dependencies for component \"" + << this->Name << "\" specify names that contain hyphens. " + << "This requires QtIFW 3.1 or later, but you are using version " + << this->Generator->FrameworkVersion << std::endl); + } + // Licenses (copy to meta dir) std::vector<std::string> licenses = this->Licenses; for (size_t i = 1; i < licenses.size(); i += 2) { diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 7fd12dd..d9234e6 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -2,14 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackArchiveGenerator.h" +#include <cstdlib> #include <cstring> #include <map> #include <ostream> #include <utility> #include <vector> -#include <cm3p/archive.h> - #include "cmCPackComponentGroup.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" @@ -154,15 +153,9 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( << (filename) << ">." << std::endl); \ return 0; \ } \ - cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat); \ + cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0, \ + this->GetThreadCount()); \ do { \ - if (!this->SetArchiveOptions(&archive)) { \ - cmCPackLogger(cmCPackLog::LOG_ERROR, \ - "Problem to set archive options <" \ - << (filename) << ">, ERROR = " << (archive).GetError() \ - << std::endl); \ - return 0; \ - } \ if (!archive.Open()) { \ cmCPackLogger(cmCPackLog::LOG_ERROR, \ "Problem to open archive <" \ @@ -346,26 +339,16 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const return this->IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL"); } -bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive) +int cmCPackArchiveGenerator::GetThreadCount() const { -#if ARCHIVE_VERSION_NUMBER >= 3004000 - // Upstream fixed an issue with their integer parsing in 3.4.0 which would - // cause spurious errors to be raised from `strtoull`. - if (this->Compress == cmArchiveWrite::CompressXZ) { - const char* threads = "1"; - - // CPACK_ARCHIVE_THREADS overrides CPACK_THREADS - if (this->IsSet("CPACK_ARCHIVE_THREADS")) { - threads = this->GetOption("CPACK_ARCHIVE_THREADS"); - } else if (this->IsSet("CPACK_THREADS")) { - threads = this->GetOption("CPACK_THREADS"); - } + int threads = 1; - if (!archive->SetFilterOption("xz", "threads", threads)) { - return false; - } + // CPACK_ARCHIVE_THREADS overrides CPACK_THREADS + if (this->IsSet("CPACK_ARCHIVE_THREADS")) { + threads = std::atoi(this->GetOption("CPACK_ARCHIVE_THREADS")); + } else if (this->IsSet("CPACK_THREADS")) { + threads = std::atoi(this->GetOption("CPACK_THREADS")); } -#endif - return true; + return threads; } diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 5b40013..8a9bbc6 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -85,7 +85,7 @@ private: return this->OutputExtension.c_str(); } - bool SetArchiveOptions(cmArchiveWrite* archive); + int GetThreadCount() const; private: cmArchiveWrite::Compress Compress; diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index e7bcfac..006d66d 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -130,11 +130,6 @@ DebGenerator::DebGenerator( "Unrecognized number of threads: " << numThreads << std::endl); } - - if (this->NumThreads < 0) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "Number of threads cannot be negative" << std::endl); - } } bool DebGenerator::generate() const @@ -172,7 +167,6 @@ void DebGenerator::generateControlFile() const unsigned long totalSize = 0; { - std::string dirName = cmStrCat(this->TemporaryDir, '/'); for (std::string const& file : this->PackageFiles) { totalSize += cmSystemTools::FileLength(file); } diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index cefb906..b71c969 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -273,6 +273,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, ? this->GetOption("CPACK_DMG_FORMAT") : "UDZO"; + const std::string cpack_dmg_filesystem = + this->GetOption("CPACK_DMG_FILESYSTEM") + ? this->GetOption("CPACK_DMG_FILESYSTEM") + : "HFS+"; + // Get optional arguments ... std::string cpack_license_file = this->GetOption("CPACK_RESOURCE_FILE_LICENSE") @@ -319,7 +324,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, staging << src_dir; // Add a symlink to /Applications so users can drag-and-drop the bundle - // into it unless this behaviour was disabled + // into it unless this behavior was disabled if (!cpack_dmg_disable_applications_symlink) { std::ostringstream application_link; application_link << staging.str() << "/Applications"; @@ -418,7 +423,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, temp_image_command << " -ov"; temp_image_command << " -srcfolder \"" << staging.str() << "\""; temp_image_command << " -volname \"" << cpack_dmg_volume_name << "\""; - temp_image_command << " -fs HFS+"; + temp_image_command << " -fs \"" << cpack_dmg_filesystem << "\""; temp_image_command << " -format " << temp_image_format; temp_image_command << " \"" << temp_image << "\""; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 3db4162..cd2adaa 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -384,7 +384,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( for (std::string const& gf : this->files) { bool skip = false; std::string inFile = gf; - if (cmSystemTools::FileIsDirectory(gf)) { + if (cmSystemTools::FileIsDirectory(gf) && + !cmSystemTools::FileIsSymlink(gf)) { inFile += '/'; } for (cmsys::RegularExpression& reg : ignoreFilesRegex) { @@ -693,7 +694,7 @@ int cmCPackGenerator::RunPreinstallTarget( // Does this generator require pre-install? if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) { std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand( - preinstall, buildConfig, "", false); + preinstall, buildConfig, "", "", false); cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Install command: " << buildCommand << std::endl); cmCPackLogger(cmCPackLog::LOG_OUTPUT, diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index f1cc677..6bd0d1b 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -437,7 +437,9 @@ int cmCPackNSISGenerator::InitializeInternal() } #endif - nsisPath = cmSystemTools::FindProgram("makensis", path, false); + this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLE", "makensis"); + nsisPath = cmSystemTools::FindProgram( + this->GetOption("CPACK_NSIS_EXECUTABLE"), path, false); if (nsisPath.empty()) { cmCPackLogger( diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index 3e36e8c..ad0a3e2 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -51,15 +51,16 @@ int cmCPackSTGZGenerator::PackageFiles() * so we must iterate over generated packages. */ for (std::string const& pfn : this->packageFileNames) { - retval &= cmSystemTools::SetPermissions(pfn.c_str(), + retval &= static_cast<bool>( + cmSystemTools::SetPermissions(pfn.c_str(), #if defined(_MSC_VER) || defined(__MINGW32__) - S_IREAD | S_IWRITE | S_IEXEC + S_IREAD | S_IWRITE | S_IEXEC #else - S_IRUSR | S_IWUSR | S_IXUSR | - S_IRGRP | S_IWGRP | S_IXGRP | - S_IROTH | S_IWOTH | S_IXOTH + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | + S_IXOTH #endif - ); + )); } return retval; } diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 85c13ad..a778939 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -341,7 +341,7 @@ int main(int argc, char const* const* argv) cmMakefile* mf = &globalMF; cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Specified generator: " << gen << std::endl); - if (parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME")) { + if (!mf->GetDefinition("CPACK_PACKAGE_NAME")) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "CPack project name not specified" << std::endl); parsed = 0; diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index a18cbb4..adfc8ef 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -19,6 +19,8 @@ #include "cmWorkingDirectory.h" #include "cmake.h" +struct cmMessageMetadata; + cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() { this->BuildTwoConfig = false; @@ -125,7 +127,7 @@ public: : CM(cm) { cmSystemTools::SetMessageCallback( - [&s](const std::string& msg, const char* /*unused*/) { + [&s](const std::string& msg, const cmMessageMetadata& /* unused */) { s += msg; s += "\n"; }); diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 88e2871..483c316 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -27,6 +27,7 @@ void cmCTestBuildCommand::BindArguments() this->Bind("CONFIGURATION"_s, this->Configuration); this->Bind("FLAGS"_s, this->Flags); this->Bind("PROJECT_NAME"_s, this->ProjectName); + this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel); } cmCTestBuildCommand::~cmCTestBuildCommand() = default; @@ -98,8 +99,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory"); std::string buildCommand = this->GlobalGenerator->GenerateCMakeBuildCommand( - cmakeBuildTarget, cmakeBuildConfiguration, cmakeBuildAdditionalFlags, - this->Makefile->IgnoreErrorsCMP0061()); + cmakeBuildTarget, cmakeBuildConfiguration, this->ParallelLevel, + cmakeBuildAdditionalFlags, this->Makefile->IgnoreErrorsCMP0061()); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "SetMakeCommand:" << buildCommand << "\n", this->Quiet); diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index 00dbcc4..1254dad 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -60,4 +60,5 @@ protected: std::string Configuration; std::string Flags; std::string ProjectName; + std::string ParallelLevel; }; diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 103dc1e..03caa63 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -3,7 +3,6 @@ #include "cmCTestBuildHandler.h" #include <cstdlib> -#include <cstring> #include <set> #include <utility> @@ -657,14 +656,14 @@ bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname) { // error-{hash}.xml return (cmHasLiteralPrefix(fname, "error-") && - strcmp(fname + strlen(fname) - 4, ".xml") == 0); + cmHasLiteralSuffix(fname, ".xml")); } bool cmCTestBuildHandler::IsLaunchedWarningFile(const char* fname) { // warning-{hash}.xml return (cmHasLiteralPrefix(fname, "warning-") && - strcmp(fname + strlen(fname) - 4, ".xml") == 0); + cmHasLiteralSuffix(fname, ".xml")); } //###################################################################### diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx index 051c117..af495bb 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx @@ -16,7 +16,7 @@ bool cmCTestEmptyBinaryDirectoryCommand::InitialPass( return false; } - if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0].c_str())) { + if (!cmCTestScriptHandler::EmptyBinaryDirectory(args[0])) { std::ostringstream ostr; ostr << "problem removing the binary directory: " << args[0]; this->SetError(ostr.str()); diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 91818bb..cc756d7 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -21,32 +21,47 @@ cmCTestGenericHandler::cmCTestGenericHandler() cmCTestGenericHandler::~cmCTestGenericHandler() = default; -void cmCTestGenericHandler::SetOption(const std::string& op, const char* value) +/* Modify the given `map`, setting key `op` to `value` if `value` + * is non-null, otherwise removing key `op` (if it exists). + */ +static void SetMapValue(cmCTestGenericHandler::t_StringToString& map, + const std::string& op, const char* value) { if (!value) { - auto remit = this->Options.find(op); - if (remit != this->Options.end()) { - this->Options.erase(remit); - } + map.erase(op); return; } - this->Options[op] = value; + map[op] = value; +} + +void cmCTestGenericHandler::SetOption(const std::string& op, const char* value) +{ + SetMapValue(this->Options, op, value); } void cmCTestGenericHandler::SetPersistentOption(const std::string& op, const char* value) { this->SetOption(op, value); - if (!value) { - auto remit = this->PersistentOptions.find(op); - if (remit != this->PersistentOptions.end()) { - this->PersistentOptions.erase(remit); - } - return; + SetMapValue(this->PersistentOptions, op, value); +} + +void cmCTestGenericHandler::AddMultiOption(const std::string& op, + const std::string& value) +{ + if (!value.empty()) { + this->MultiOptions[op].emplace_back(value); } +} - this->PersistentOptions[op] = value; +void cmCTestGenericHandler::AddPersistentMultiOption(const std::string& op, + const std::string& value) +{ + if (!value.empty()) { + this->MultiOptions[op].emplace_back(value); + this->PersistentMultiOptions[op].emplace_back(value); + } } void cmCTestGenericHandler::Initialize() @@ -68,6 +83,17 @@ const char* cmCTestGenericHandler::GetOption(const std::string& op) return remit->second.c_str(); } +std::vector<std::string> cmCTestGenericHandler::GetMultiOption( + const std::string& optionName) const +{ + // Avoid inserting a key, which MultiOptions[op] would do. + auto remit = this->MultiOptions.find(optionName); + if (remit == this->MultiOptions.end()) { + return {}; + } + return remit->second; +} + bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part, const char* name, cmGeneratedFileStream& xofs) diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index 89d7596..e846fd9 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -13,7 +13,6 @@ #include "cmCTest.h" #include "cmSystemTools.h" -class cmCTestCommand; class cmGeneratedFileStream; class cmMakefile; @@ -72,12 +71,40 @@ public: virtual ~cmCTestGenericHandler(); using t_StringToString = std::map<std::string, std::string>; + using t_StringToMultiString = + std::map<std::string, std::vector<std::string>>; + /** + * Options collect a single value from flags; passing the + * flag multiple times on the command-line *overwrites* values, + * and only the last one specified counts. Set an option to + * nullptr to "unset" it. + * + * The value is stored as a string. The values set for single + * and multi-options (see below) live in different spaces, + * so calling a single-getter for a key that has only been set + * as a multi-value will return nullptr. + */ void SetPersistentOption(const std::string& op, const char* value); void SetOption(const std::string& op, const char* value); const char* GetOption(const std::string& op); - void SetCommand(cmCTestCommand* command) { this->Command = command; } + /** + * Multi-Options collect one or more values from flags; passing + * the flag multiple times on the command-line *adds* values, + * rather than overwriting the previous values. + * + * Adding an empty value does nothing. + * + * The value is stored as a vector of strings. The values set for single + * (see above) and multi-options live in different spaces, + * so calling a multi-getter for a key that has only been set + * as a single-value will return an empty vector. + */ + void AddPersistentMultiOption(const std::string& optionName, + const std::string& value); + void AddMultiOption(const std::string& optionName, const std::string& value); + std::vector<std::string> GetMultiOption(const std::string& op) const; void SetSubmitIndex(int idx) { this->SubmitIndex = idx; } int GetSubmitIndex() { return this->SubmitIndex; } @@ -100,8 +127,9 @@ protected: cmCTest* CTest; t_StringToString Options; t_StringToString PersistentOptions; + t_StringToMultiString MultiOptions; + t_StringToMultiString PersistentMultiOptions; t_StringToString LogFileNames; - cmCTestCommand* Command; int SubmitIndex; }; diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index d0e2974..37b3628 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -14,7 +14,7 @@ void cmCTestMemCheckCommand::BindArguments() this->Bind("DEFECT_COUNT"_s, this->DefectCount); } -cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() +cmCTestTestHandler* cmCTestMemCheckCommand::InitializeActualHandler() { cmCTestMemCheckHandler* handler = this->CTest->GetMemCheckHandler(); handler->Initialize(); diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index 6544f16..ee39e49 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -13,6 +13,7 @@ #include "cmCommand.h" class cmCTestGenericHandler; +class cmCTestTestHandler; /** \class cmCTestMemCheck * \brief Run a ctest script @@ -36,7 +37,7 @@ public: protected: void BindArguments() override; - cmCTestGenericHandler* InitializeActualHandler() override; + cmCTestTestHandler* InitializeActualHandler() override; void ProcessAdditionalValues(cmCTestGenericHandler* handler) override; diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 852f9d9..86a8e00 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -587,24 +587,24 @@ void cmCTestMultiProcessHandler::StartNextTests() onlyRunSerialTestsLeft = false; } } - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, "); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "***** WAITING, "); if (this->SerialTestRunning) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Waiting for RUN_SERIAL test to finish."); } else if (onlyRunSerialTestsLeft) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Only RUN_SERIAL tests remain, awaiting available slot."); } else { /* clang-format off */ - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "System Load: " << systemLoad << ", " "Max Allowed Load: " << this->TestLoad << ", " "Smallest test " << testWithMinProcessors << " requires " << minProcessorsRequired); /* clang-format on */ } - cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "*****" << std::endl); // Wait between 1 and 5 seconds before trying again. unsigned int milliseconds = (cmSystemTools::RandomSeed() % 5 + 1) * 1000; diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index f59ca57..7661d4d 100644 --- a/Source/CTest/cmCTestRunScriptCommand.cxx +++ b/Source/CTest/cmCTestRunScriptCommand.cxx @@ -37,8 +37,8 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, ++i; } else { int ret; - cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, - args[i].c_str(), !np, &ret); + cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i], + !np, &ret); this->Makefile->AddDefinition(returnVariable, std::to_string(ret)); } } diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 4808c36..d2cad39 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -4,7 +4,6 @@ #include <cstdio> #include <cstdlib> -#include <cstring> #include <map> #include <ratio> #include <sstream> @@ -91,7 +90,7 @@ void cmCTestScriptHandler::Initialize() cmCTestScriptHandler::~cmCTestScriptHandler() = default; // just adds an argument to the vector -void cmCTestScriptHandler::AddConfigurationScript(const char* script, +void cmCTestScriptHandler::AddConfigurationScript(const std::string& script, bool pscope) { this->ConfigurationScripts.emplace_back(script); @@ -676,7 +675,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() // clear the binary directory? if (this->EmptyBinDir) { - if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir.c_str())) { + if (!cmCTestScriptHandler::EmptyBinaryDirectory(this->BinaryDir)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem removing the binary directory" << std::endl); } @@ -724,8 +723,8 @@ int cmCTestScriptHandler::RunConfigurationDashboard() // put the initial cache into the bin dir if (!this->InitialCache.empty()) { - if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir.c_str(), - this->InitialCache.c_str())) { + if (!cmCTestScriptHandler::WriteInitialCache(this->BinaryDir, + this->InitialCache)) { this->RestoreBackupDirectories(); return 9; } @@ -812,8 +811,8 @@ int cmCTestScriptHandler::RunConfigurationDashboard() return 0; } -bool cmCTestScriptHandler::WriteInitialCache(const char* directory, - const char* text) +bool cmCTestScriptHandler::WriteInitialCache(const std::string& directory, + const std::string& text) { std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt"); cmGeneratedFileStream fout(cacheFile); @@ -821,9 +820,7 @@ bool cmCTestScriptHandler::WriteInitialCache(const char* directory, return false; } - if (text != nullptr) { - fout.write(text, strlen(text)); - } + fout.write(text.data(), text.size()); // Make sure the operating system has finished writing the file // before closing it. This will ensure the file is finished before @@ -852,7 +849,7 @@ void cmCTestScriptHandler::RestoreBackupDirectories() } bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf, - const char* sname, bool InProcess, + const std::string& sname, bool InProcess, int* returnValue) { auto sh = cm::make_unique<cmCTestScriptHandler>(); @@ -866,10 +863,10 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf, return true; } -bool cmCTestScriptHandler::EmptyBinaryDirectory(const char* sname) +bool cmCTestScriptHandler::EmptyBinaryDirectory(const std::string& sname) { // try to avoid deleting root - if (!sname || strlen(sname) < 2) { + if (sname.size() < 2) { return false; } @@ -924,7 +921,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( } } - return cmSystemTools::RemoveADirectory(directoryPath); + return static_cast<bool>(cmSystemTools::RemoveADirectory(directoryPath)); } cmDuration cmCTestScriptHandler::GetRemainingTimeAllowed() diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index 8eb9658..b7764b2 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -62,7 +62,7 @@ public: /** * Add a script to run, and if is should run in the current process */ - void AddConfigurationScript(const char*, bool pscope); + void AddConfigurationScript(const std::string&, bool pscope); /** * Run a dashboard using a specified confiuration script @@ -72,19 +72,21 @@ public: /* * Run a script */ - static bool RunScript(cmCTest* ctest, cmMakefile* mf, const char* script, - bool InProcess, int* returnValue); + static bool RunScript(cmCTest* ctest, cmMakefile* mf, + const std::string& script, bool InProcess, + int* returnValue); int RunCurrentScript(); /* * Empty Binary Directory */ - static bool EmptyBinaryDirectory(const char* dir); + static bool EmptyBinaryDirectory(const std::string& dir); /* * Write an initial CMakeCache.txt from the given contents. */ - static bool WriteInitialCache(const char* directory, const char* text); + static bool WriteInitialCache(const std::string& directory, + const std::string& text); /* * Some elapsed time handling functions diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 4403733..67f4986 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -9,7 +9,6 @@ #include <cmext/string_view> #include "cmCTest.h" -#include "cmCTestGenericHandler.h" #include "cmCTestTestHandler.h" #include "cmDuration.h" #include "cmMakefile.h" @@ -36,6 +35,7 @@ void cmCTestTestCommand::BindArguments() this->Bind("TEST_LOAD"_s, this->TestLoad); this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile); this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure); + this->Bind("OUTPUT_JUNIT"_s, this->OutputJUnit); } cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() @@ -60,7 +60,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() this->ResourceSpecFile = *resourceSpecFile; } - cmCTestGenericHandler* handler = this->InitializeActualHandler(); + cmCTestTestHandler* handler = this->InitializeActualHandler(); if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) { handler->SetOption( "TestsToRunInformation", @@ -73,11 +73,11 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() handler->SetOption("IncludeRegularExpression", this->Include.c_str()); } if (!this->ExcludeLabel.empty()) { - handler->SetOption("ExcludeLabelRegularExpression", - this->ExcludeLabel.c_str()); + handler->AddMultiOption("ExcludeLabelRegularExpression", + this->ExcludeLabel); } if (!this->IncludeLabel.empty()) { - handler->SetOption("LabelRegularExpression", this->IncludeLabel.c_str()); + handler->AddMultiOption("LabelRegularExpression", this->IncludeLabel); } if (!this->ExcludeFixture.empty()) { handler->SetOption("ExcludeFixtureRegularExpression", @@ -140,11 +140,15 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() *labelsForSubprojects, this->Quiet); } + if (!this->OutputJUnit.empty()) { + handler->SetJUnitXMLFileName(this->OutputJUnit); + } + handler->SetQuiet(this->Quiet); return handler; } -cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler() +cmCTestTestHandler* cmCTestTestCommand::InitializeActualHandler() { cmCTestTestHandler* handler = this->CTest->GetTestHandler(); handler->Initialize(); diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 624cd91..24e74e2 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -13,6 +13,7 @@ #include "cmCommand.h" class cmCTestGenericHandler; +class cmCTestTestHandler; /** \class cmCTestTest * \brief Run a ctest script @@ -40,7 +41,7 @@ public: protected: void BindArguments() override; - virtual cmCTestGenericHandler* InitializeActualHandler(); + virtual cmCTestTestHandler* InitializeActualHandler(); cmCTestGenericHandler* InitializeHandler() override; std::string Start; @@ -59,5 +60,6 @@ protected: std::string StopTime; std::string TestLoad; std::string ResourceSpecFile; + std::string OutputJUnit; bool StopOnFailure = false; }; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 1cb5d00..1596d4a 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -42,6 +42,7 @@ #include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmTimestamp.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -287,8 +288,6 @@ cmCTestTestHandler::cmCTestTestHandler() { this->UseUnion = false; - this->UseIncludeLabelRegExpFlag = false; - this->UseExcludeLabelRegExpFlag = false; this->UseIncludeRegExpFlag = false; this->UseExcludeRegExpFlag = false; this->UseExcludeRegExpFirst = false; @@ -301,6 +300,9 @@ cmCTestTestHandler::cmCTestTestHandler() this->LogFile = nullptr; + // Support for JUnit XML output. + this->JUnitXMLFileName = ""; + // regex to detect <DartMeasurement>...</DartMeasurement> this->DartStuff.compile("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)"); // regex to detect each individual <DartMeasurement>...</DartMeasurement> @@ -327,13 +329,11 @@ void cmCTestTestHandler::Initialize() this->TestsToRun.clear(); - this->UseIncludeLabelRegExpFlag = false; - this->UseExcludeLabelRegExpFlag = false; this->UseIncludeRegExpFlag = false; this->UseExcludeRegExpFlag = false; this->UseExcludeRegExpFirst = false; - this->IncludeLabelRegularExpression = ""; - this->ExcludeLabelRegularExpression = ""; + this->IncludeLabelRegularExpressions.clear(); + this->ExcludeLabelRegularExpressions.clear(); this->IncludeRegExp.clear(); this->ExcludeRegExp.clear(); this->ExcludeFixtureRegExp.clear(); @@ -460,6 +460,10 @@ int cmCTestTestHandler::ProcessHandler() return 1; } + if (!this->WriteJUnitXML()) { + return 1; + } + if (!this->PostProcessHandler()) { this->LogFile = nullptr; return -1; @@ -479,6 +483,22 @@ int cmCTestTestHandler::ProcessHandler() return 0; } +/* Given a multi-option value `parts`, compile those parts into + * regular expressions in `expressions`. Skip empty values. + * Returns true if there were any expressions. + */ +static bool BuildLabelRE(const std::vector<std::string>& parts, + std::vector<cmsys::RegularExpression>& expressions) +{ + expressions.clear(); + for (const auto& p : parts) { + if (!p.empty()) { + expressions.emplace_back(p); + } + } + return !expressions.empty(); +} + bool cmCTestTestHandler::ProcessOptions() { // Update internal data structure from generic one @@ -519,18 +539,11 @@ bool cmCTestTestHandler::ProcessOptions() this->CTest->SetStopOnFailure(true); } - const char* val; - val = this->GetOption("LabelRegularExpression"); - if (val) { - this->UseIncludeLabelRegExpFlag = true; - this->IncludeLabelRegExp = val; - } - val = this->GetOption("ExcludeLabelRegularExpression"); - if (val) { - this->UseExcludeLabelRegExpFlag = true; - this->ExcludeLabelRegExp = val; - } - val = this->GetOption("IncludeRegularExpression"); + BuildLabelRE(this->GetMultiOption("LabelRegularExpression"), + this->IncludeLabelRegularExpressions); + BuildLabelRE(this->GetMultiOption("ExcludeLabelRegularExpression"), + this->ExcludeLabelRegularExpressions); + const char* val = this->GetOption("IncludeRegularExpression"); if (val) { this->UseIncludeRegExp(); this->SetIncludeRegExp(val); @@ -763,10 +776,40 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet); } +/** + * Check if the labels (from a test) match all the expressions. + * + * Each of the RE's must match at least one label + * (e.g. all of the REs must match **some** label, + * in order for the filter to apply to the test). + */ +static bool MatchLabelsAgainstFilterRE( + const std::vector<std::string>& labels, + const std::vector<cmsys::RegularExpression>& expressions) +{ + for (const auto& re : expressions) { + // check to see if the label regular expression matches + bool found = false; // assume it does not match + cmsys::RegularExpressionMatch match; + // loop over all labels and look for match + for (std::string const& l : labels) { + if (re.find(l.c_str(), match)) { + found = true; + break; + } + } + // if no match was found, exclude the test + if (!found) { + return false; + } + } + return true; +} + void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it) { // if not using Labels to filter then return - if (!this->UseIncludeLabelRegExpFlag) { + if (this->IncludeLabelRegularExpressions.empty()) { return; } // if there are no labels and we are filtering by labels @@ -775,16 +818,9 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it) it.IsInBasedOnREOptions = false; return; } - // check to see if the label regular expression matches - bool found = false; // assume it does not match - // loop over all labels and look for match - for (std::string const& l : it.Labels) { - if (this->IncludeLabelRegularExpression.find(l)) { - found = true; - } - } // if no match was found, exclude the test - if (!found) { + if (!MatchLabelsAgainstFilterRE(it.Labels, + this->IncludeLabelRegularExpressions)) { it.IsInBasedOnREOptions = false; } } @@ -792,7 +828,7 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it) void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it) { // if not using Labels to filter then return - if (!this->UseExcludeLabelRegExpFlag) { + if (this->ExcludeLabelRegularExpressions.empty()) { return; } // if there are no labels and we are excluding by labels @@ -800,16 +836,9 @@ void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it) if (it.Labels.empty()) { return; } - // check to see if the label regular expression matches - bool found = false; // assume it does not match - // loop over all labels and look for match - for (std::string const& l : it.Labels) { - if (this->ExcludeLabelRegularExpression.find(l)) { - found = true; - } - } // if match was found, exclude the test - if (found) { + if (MatchLabelsAgainstFilterRE(it.Labels, + this->ExcludeLabelRegularExpressions)) { it.IsInBasedOnREOptions = false; } } @@ -1704,19 +1733,11 @@ bool cmCTestTestHandler::ParseResourceGroupsProperty( bool cmCTestTestHandler::GetListOfTests() { - if (!this->IncludeLabelRegExp.empty()) { - this->IncludeLabelRegularExpression.compile( - this->IncludeLabelRegExp.c_str()); - } - if (!this->ExcludeLabelRegExp.empty()) { - this->ExcludeLabelRegularExpression.compile( - this->ExcludeLabelRegExp.c_str()); - } if (!this->IncludeRegExp.empty()) { - this->IncludeTestsRegularExpression.compile(this->IncludeRegExp.c_str()); + this->IncludeTestsRegularExpression.compile(this->IncludeRegExp); } if (!this->ExcludeRegExp.empty()) { - this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str()); + this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp); } cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Constructing a list of tests" << std::endl, this->Quiet); @@ -1868,7 +1889,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed() std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary"; cmsys::Directory directory; - if (directory.Load(dirName) == 0) { + if (!directory.Load(dirName)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to read the contents of " << dirName << std::endl); return; @@ -2444,3 +2465,125 @@ bool cmCTestTestHandler::cmCTestTestResourceRequirement::operator!=( { return !(*this == other); } + +void cmCTestTestHandler::SetJUnitXMLFileName(const std::string& filename) +{ + this->JUnitXMLFileName = filename; +} + +bool cmCTestTestHandler::WriteJUnitXML() +{ + if (this->JUnitXMLFileName.empty()) { + return true; + } + + // Open new XML file for writing. + cmGeneratedFileStream xmlfile; + xmlfile.SetTempExt("tmp"); + xmlfile.Open(this->JUnitXMLFileName); + if (!xmlfile) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Problem opening file: " << this->JUnitXMLFileName + << std::endl); + return false; + } + cmXMLWriter xml(xmlfile); + + // Iterate over the test results to get the number of tests that + // passed, failed, etc. + auto num_tests = 0; + auto num_passed = 0; + auto num_failed = 0; + auto num_notrun = 0; + auto num_disabled = 0; + SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end()); + for (cmCTestTestResult const& result : resultsSet) { + num_tests++; + if (result.Status == cmCTestTestHandler::COMPLETED) { + num_passed++; + } else if (result.Status == cmCTestTestHandler::NOT_RUN) { + if (result.CompletionStatus == "Disabled") { + num_disabled++; + } else { + num_notrun++; + } + } else { + num_failed++; + } + } + + // Write <testsuite> element. + xml.StartDocument(); + xml.StartElement("testsuite"); + + xml.Attribute("name", + cmCTest::SafeBuildIdField( + this->CTest->GetCTestConfiguration("BuildName"))); + xml.BreakAttributes(); + + xml.Attribute("tests", num_tests); + xml.Attribute("failures", num_failed); + + // CTest disabled => JUnit disabled + xml.Attribute("disabled", num_disabled); + + // Otherwise, CTest notrun => JUnit skipped. + // The distinction between JUnit disabled vs. skipped is that + // skipped tests can have a message associated with them + // (why the test was skipped). + xml.Attribute("skipped", num_notrun); + + xml.Attribute("hostname", this->CTest->GetCTestConfiguration("Site")); + xml.Attribute( + "time", + std::chrono::duration_cast<std::chrono::seconds>(this->ElapsedTestingTime) + .count()); + const std::time_t start_test_time_t = + std::chrono::system_clock::to_time_t(this->StartTestTime); + cmTimestamp cmts; + xml.Attribute("timestamp", + cmts.CreateTimestampFromTimeT(start_test_time_t, + "%Y-%m-%dT%H:%M:%S", false)); + + // Write <testcase> elements. + for (cmCTestTestResult const& result : resultsSet) { + xml.StartElement("testcase"); + xml.Attribute("name", result.Name); + xml.Attribute("classname", result.Name); + xml.Attribute("time", result.ExecutionTime.count()); + + std::string status; + if (result.Status == cmCTestTestHandler::COMPLETED) { + status = "run"; + } else if (result.Status == cmCTestTestHandler::NOT_RUN) { + if (result.CompletionStatus == "Disabled") { + status = "disabled"; + } else { + status = "notrun"; + } + } else { + status = "fail"; + } + xml.Attribute("status", status); + + if (status == "notrun") { + xml.StartElement("skipped"); + xml.Attribute("message", result.CompletionStatus); + xml.EndElement(); // </skipped> + } else if (status == "fail") { + xml.StartElement("failure"); + xml.Attribute("message", result.Reason); + xml.EndElement(); // </failure> + } + + // Note: compressed test output is unconditionally disabled when + // --output-junit is specified. + xml.Element("system-out", result.Output); + xml.EndElement(); // </testcase> + } + + xml.EndElement(); // </testsuite> + xml.EndDocument(); + + return true; +} diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index aa29eeb..6841624 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -209,6 +209,9 @@ public: using ListOfTests = std::vector<cmCTestTestProperties>; + // Support for writing test results in JUnit XML format. + void SetJUnitXMLFileName(const std::string& id); + protected: using SetOfTests = std::set<cmCTestTestHandler::cmCTestTestResult, cmCTestTestResultLess>; @@ -274,6 +277,11 @@ private: */ virtual void GenerateDartOutput(cmXMLWriter& xml); + /** + * Write test results in JUnit XML format + */ + bool WriteJUnitXML(); + void PrintLabelOrSubprojectSummary(bool isSubProject); /** @@ -320,20 +328,16 @@ private: std::vector<int> TestsToRun; - bool UseIncludeLabelRegExpFlag; - bool UseExcludeLabelRegExpFlag; bool UseIncludeRegExpFlag; bool UseExcludeRegExpFlag; bool UseExcludeRegExpFirst; - std::string IncludeLabelRegExp; - std::string ExcludeLabelRegExp; std::string IncludeRegExp; std::string ExcludeRegExp; std::string ExcludeFixtureRegExp; std::string ExcludeFixtureSetupRegExp; std::string ExcludeFixtureCleanupRegExp; - cmsys::RegularExpression IncludeLabelRegularExpression; - cmsys::RegularExpression ExcludeLabelRegularExpression; + std::vector<cmsys::RegularExpression> IncludeLabelRegularExpressions; + std::vector<cmsys::RegularExpression> ExcludeLabelRegularExpressions; cmsys::RegularExpression IncludeTestsRegularExpression; cmsys::RegularExpression ExcludeTestsRegularExpression; @@ -358,4 +362,6 @@ private: cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never; int RepeatCount = 1; bool RerunFailed; + + std::string JUnitXMLFileName; }; diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 0ba2c41..797cb01 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -75,7 +75,6 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() cmCTestUpdateHandler* handler = this->CTest->GetUpdateHandler(); handler->Initialize(); - handler->SetCommand(this); if (source_dir.empty()) { this->SetError("source directory not specified. Please use SOURCE tag"); return nullptr; diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake index 7917d41..f20572e 100644 --- a/Source/Checks/cm_cxx_features.cmake +++ b/Source/Checks/cm_cxx_features.cmake @@ -80,7 +80,9 @@ if(CMake_HAVE_CXX_MAKE_UNIQUE) set(CMake_HAVE_CXX_UNIQUE_PTR 1) endif() cm_check_cxx_feature(unique_ptr) -if (NOT CMAKE_CXX_STANDARD LESS "17") +if (NOT CMAKE_CXX_STANDARD LESS "17" + AND NOT MSYS # FIXME: RunCMake.cmake_path cases crash with MSYS std::filesystem + ) if (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR) cm_check_cxx_feature(filesystem TRY_RUN) else() diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 85e256b..1ba45e5 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -19,6 +19,7 @@ #include "cmCursesStandardIncludes.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" // IWYU pragma: keep +#include "cmMessageMetadata.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -181,8 +182,8 @@ int main(int argc, char const* const* argv) return msg; }; cmSystemTools::SetMessageCallback( - [&](const std::string& message, const char* title) { - myform->AddError(cleanMessage(message), title); + [&](const std::string& message, const cmMessageMetadata& md) { + myform->AddError(cleanMessage(message), md.title); }); cmSystemTools::SetStderrCallback([&](const std::string& message) { myform->AddError(cleanMessage(message), ""); diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt index 8f26b9a..9202bc1 100644 --- a/Source/CursesDialog/form/CMakeLists.txt +++ b/Source/CursesDialog/form/CMakeLists.txt @@ -5,7 +5,7 @@ project(CMAKE_FORM) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx index b8bc82c..5727992 100644 --- a/Source/LexerParser/cmCommandArgumentParser.cxx +++ b/Source/LexerParser/cmCommandArgumentParser.cxx @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30705 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.7.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -228,6 +228,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -325,9 +337,9 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ @@ -635,7 +647,7 @@ static const yytype_int8 yypgoto[] = /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 11, 12, 13, 14, 15, 19, 20, 21, 22 + 0, 11, 12, 13, 14, 15, 19, 20, 21, 22 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -761,8 +773,8 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (yyscanner); + YY_USE (yyoutput); + YY_USE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT @@ -770,7 +782,7 @@ yy_symbol_value_print (FILE *yyo, YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1151,14 +1163,14 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner) { - YYUSE (yyvaluep); - YYUSE (yyscanner); + YY_USE (yyvaluep); + YY_USE (yyscanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1433,7 +1445,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetResult((yyvsp[0].str)); } -#line 1437 "cmCommandArgumentParser.cxx" +#line 1449 "cmCommandArgumentParser.cxx" break; case 3: /* GoalWithOptionalBackSlash: Goal */ @@ -1441,7 +1453,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1445 "cmCommandArgumentParser.cxx" +#line 1457 "cmCommandArgumentParser.cxx" break; case 4: /* GoalWithOptionalBackSlash: Goal "\\" */ @@ -1449,7 +1461,7 @@ yyreduce: { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1453 "cmCommandArgumentParser.cxx" +#line 1465 "cmCommandArgumentParser.cxx" break; case 5: /* Goal: %empty */ @@ -1457,7 +1469,7 @@ yyreduce: { (yyval.str) = 0; } -#line 1461 "cmCommandArgumentParser.cxx" +#line 1473 "cmCommandArgumentParser.cxx" break; case 6: /* Goal: String Goal */ @@ -1465,7 +1477,7 @@ yyreduce: { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1469 "cmCommandArgumentParser.cxx" +#line 1481 "cmCommandArgumentParser.cxx" break; case 7: /* String: OuterText */ @@ -1473,7 +1485,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1477 "cmCommandArgumentParser.cxx" +#line 1489 "cmCommandArgumentParser.cxx" break; case 8: /* String: Variable */ @@ -1481,7 +1493,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1485 "cmCommandArgumentParser.cxx" +#line 1497 "cmCommandArgumentParser.cxx" break; case 9: /* OuterText: cal_NAME */ @@ -1489,7 +1501,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1493 "cmCommandArgumentParser.cxx" +#line 1505 "cmCommandArgumentParser.cxx" break; case 10: /* OuterText: "@" */ @@ -1497,7 +1509,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1501 "cmCommandArgumentParser.cxx" +#line 1513 "cmCommandArgumentParser.cxx" break; case 11: /* OuterText: "$" */ @@ -1505,7 +1517,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1509 "cmCommandArgumentParser.cxx" +#line 1521 "cmCommandArgumentParser.cxx" break; case 12: /* OuterText: "{" */ @@ -1513,7 +1525,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1517 "cmCommandArgumentParser.cxx" +#line 1529 "cmCommandArgumentParser.cxx" break; case 13: /* OuterText: "}" */ @@ -1521,7 +1533,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1525 "cmCommandArgumentParser.cxx" +#line 1537 "cmCommandArgumentParser.cxx" break; case 14: /* OuterText: cal_SYMBOL */ @@ -1529,7 +1541,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1533 "cmCommandArgumentParser.cxx" +#line 1545 "cmCommandArgumentParser.cxx" break; case 15: /* Variable: cal_ENVCURLY EnvVarName "}" */ @@ -1537,7 +1549,7 @@ yyreduce: { (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str)); } -#line 1541 "cmCommandArgumentParser.cxx" +#line 1553 "cmCommandArgumentParser.cxx" break; case 16: /* Variable: cal_NCURLY MultipleIds "}" */ @@ -1545,7 +1557,7 @@ yyreduce: { (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str)); } -#line 1549 "cmCommandArgumentParser.cxx" +#line 1561 "cmCommandArgumentParser.cxx" break; case 17: /* Variable: cal_DCURLY MultipleIds "}" */ @@ -1553,7 +1565,7 @@ yyreduce: { (yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str)); } -#line 1557 "cmCommandArgumentParser.cxx" +#line 1569 "cmCommandArgumentParser.cxx" break; case 18: /* Variable: cal_ATNAME */ @@ -1561,7 +1573,7 @@ yyreduce: { (yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str)); } -#line 1565 "cmCommandArgumentParser.cxx" +#line 1577 "cmCommandArgumentParser.cxx" break; case 19: /* EnvVarName: MultipleIds */ @@ -1569,7 +1581,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1573 "cmCommandArgumentParser.cxx" +#line 1585 "cmCommandArgumentParser.cxx" break; case 20: /* EnvVarName: cal_SYMBOL EnvVarName */ @@ -1577,7 +1589,7 @@ yyreduce: { (yyval.str) = (yyvsp[-1].str); } -#line 1581 "cmCommandArgumentParser.cxx" +#line 1593 "cmCommandArgumentParser.cxx" break; case 21: /* MultipleIds: %empty */ @@ -1585,7 +1597,7 @@ yyreduce: { (yyval.str) = 0; } -#line 1589 "cmCommandArgumentParser.cxx" +#line 1601 "cmCommandArgumentParser.cxx" break; case 22: /* MultipleIds: ID MultipleIds */ @@ -1593,7 +1605,7 @@ yyreduce: { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1597 "cmCommandArgumentParser.cxx" +#line 1609 "cmCommandArgumentParser.cxx" break; case 23: /* ID: cal_NAME */ @@ -1601,7 +1613,7 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1605 "cmCommandArgumentParser.cxx" +#line 1617 "cmCommandArgumentParser.cxx" break; case 24: /* ID: Variable */ @@ -1609,11 +1621,11 @@ yyreduce: { (yyval.str) = (yyvsp[0].str); } -#line 1613 "cmCommandArgumentParser.cxx" +#line 1625 "cmCommandArgumentParser.cxx" break; -#line 1617 "cmCommandArgumentParser.cxx" +#line 1629 "cmCommandArgumentParser.cxx" default: break; } diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h index 578f793..414c6dd 100644 --- a/Source/LexerParser/cmCommandArgumentParserTokens.h +++ b/Source/LexerParser/cmCommandArgumentParserTokens.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx index 27cc177..e6b3a7e 100644 --- a/Source/LexerParser/cmDependsJavaParser.cxx +++ b/Source/LexerParser/cmDependsJavaParser.cxx @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30705 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.7.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -456,6 +456,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -553,9 +565,9 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ @@ -1108,7 +1120,7 @@ static const yytype_int16 yypgoto[] = /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 2, 156, 157, 158, 229, 112, 113, 75, 78, + 0, 2, 156, 157, 158, 229, 112, 113, 75, 78, 230, 231, 19, 20, 21, 22, 3, 4, 24, 30, 5, 31, 32, 33, 51, 52, 53, 54, 163, 164, 65, 66, 79, 67, 80, 96, 97, 98, 208, 209, @@ -1803,8 +1815,8 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (yyscanner); + YY_USE (yyoutput); + YY_USE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT @@ -1812,7 +1824,7 @@ yy_symbol_value_print (FILE *yyo, YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -2193,14 +2205,14 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner) { - YYUSE (yyvaluep); - YYUSE (yyscanner); + YY_USE (yyvaluep); + YY_USE (yyscanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -2477,7 +2489,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2481 "cmDependsJavaParser.cxx" +#line 2493 "cmDependsJavaParser.cxx" break; case 3: /* Literal: IntegerLiteral */ @@ -2488,7 +2500,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2492 "cmDependsJavaParser.cxx" +#line 2504 "cmDependsJavaParser.cxx" break; case 4: /* Literal: jp_FLOATINGPOINTLITERAL */ @@ -2499,7 +2511,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2503 "cmDependsJavaParser.cxx" +#line 2515 "cmDependsJavaParser.cxx" break; case 5: /* Literal: jp_BOOLEANLITERAL */ @@ -2510,7 +2522,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2514 "cmDependsJavaParser.cxx" +#line 2526 "cmDependsJavaParser.cxx" break; case 6: /* Literal: jp_CHARACTERLITERAL */ @@ -2521,7 +2533,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2525 "cmDependsJavaParser.cxx" +#line 2537 "cmDependsJavaParser.cxx" break; case 7: /* Literal: jp_STRINGLITERAL */ @@ -2532,7 +2544,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2536 "cmDependsJavaParser.cxx" +#line 2548 "cmDependsJavaParser.cxx" break; case 8: /* Literal: jp_NULLLITERAL */ @@ -2543,7 +2555,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2547 "cmDependsJavaParser.cxx" +#line 2559 "cmDependsJavaParser.cxx" break; case 9: /* IntegerLiteral: jp_DECIMALINTEGERLITERAL */ @@ -2554,7 +2566,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2558 "cmDependsJavaParser.cxx" +#line 2570 "cmDependsJavaParser.cxx" break; case 10: /* IntegerLiteral: jp_HEXINTEGERLITERAL */ @@ -2565,7 +2577,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2569 "cmDependsJavaParser.cxx" +#line 2581 "cmDependsJavaParser.cxx" break; case 11: /* Type: PrimitiveType */ @@ -2576,7 +2588,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2580 "cmDependsJavaParser.cxx" +#line 2592 "cmDependsJavaParser.cxx" break; case 12: /* Type: ReferenceType */ @@ -2587,7 +2599,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2591 "cmDependsJavaParser.cxx" +#line 2603 "cmDependsJavaParser.cxx" break; case 13: /* PrimitiveType: jp_BYTE_TYPE */ @@ -2595,7 +2607,7 @@ yyreduce: { jpElementStart(0); } -#line 2599 "cmDependsJavaParser.cxx" +#line 2611 "cmDependsJavaParser.cxx" break; case 14: /* PrimitiveType: jp_SHORT_TYPE */ @@ -2603,7 +2615,7 @@ yyreduce: { jpElementStart(0); } -#line 2607 "cmDependsJavaParser.cxx" +#line 2619 "cmDependsJavaParser.cxx" break; case 15: /* PrimitiveType: jp_INT_TYPE */ @@ -2611,7 +2623,7 @@ yyreduce: { jpElementStart(0); } -#line 2615 "cmDependsJavaParser.cxx" +#line 2627 "cmDependsJavaParser.cxx" break; case 16: /* PrimitiveType: jp_LONG_TYPE */ @@ -2619,7 +2631,7 @@ yyreduce: { jpElementStart(0); } -#line 2623 "cmDependsJavaParser.cxx" +#line 2635 "cmDependsJavaParser.cxx" break; case 17: /* PrimitiveType: jp_CHAR_TYPE */ @@ -2627,7 +2639,7 @@ yyreduce: { jpElementStart(0); } -#line 2631 "cmDependsJavaParser.cxx" +#line 2643 "cmDependsJavaParser.cxx" break; case 18: /* PrimitiveType: jp_FLOAT_TYPE */ @@ -2635,7 +2647,7 @@ yyreduce: { jpElementStart(0); } -#line 2639 "cmDependsJavaParser.cxx" +#line 2651 "cmDependsJavaParser.cxx" break; case 19: /* PrimitiveType: jp_DOUBLE_TYPE */ @@ -2643,7 +2655,7 @@ yyreduce: { jpElementStart(0); } -#line 2647 "cmDependsJavaParser.cxx" +#line 2659 "cmDependsJavaParser.cxx" break; case 20: /* PrimitiveType: jp_BOOLEAN_TYPE */ @@ -2651,7 +2663,7 @@ yyreduce: { jpElementStart(0); } -#line 2655 "cmDependsJavaParser.cxx" +#line 2667 "cmDependsJavaParser.cxx" break; case 21: /* ReferenceType: ClassOrInterfaceType */ @@ -2662,7 +2674,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2666 "cmDependsJavaParser.cxx" +#line 2678 "cmDependsJavaParser.cxx" break; case 22: /* ReferenceType: ArrayType */ @@ -2673,7 +2685,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2677 "cmDependsJavaParser.cxx" +#line 2689 "cmDependsJavaParser.cxx" break; case 23: /* ClassOrInterfaceType: Name */ @@ -2685,7 +2697,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2689 "cmDependsJavaParser.cxx" +#line 2701 "cmDependsJavaParser.cxx" break; case 24: /* ClassType: ClassOrInterfaceType */ @@ -2696,7 +2708,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2700 "cmDependsJavaParser.cxx" +#line 2712 "cmDependsJavaParser.cxx" break; case 25: /* InterfaceType: ClassOrInterfaceType */ @@ -2707,7 +2719,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2711 "cmDependsJavaParser.cxx" +#line 2723 "cmDependsJavaParser.cxx" break; case 26: /* ArrayType: PrimitiveType Dims */ @@ -2718,7 +2730,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2722 "cmDependsJavaParser.cxx" +#line 2734 "cmDependsJavaParser.cxx" break; case 27: /* ArrayType: Name Dims */ @@ -2730,7 +2742,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2734 "cmDependsJavaParser.cxx" +#line 2746 "cmDependsJavaParser.cxx" break; case 28: /* Name: SimpleName */ @@ -2739,7 +2751,7 @@ yyreduce: jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2743 "cmDependsJavaParser.cxx" +#line 2755 "cmDependsJavaParser.cxx" break; case 29: /* Name: QualifiedName */ @@ -2748,7 +2760,7 @@ yyreduce: jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2752 "cmDependsJavaParser.cxx" +#line 2764 "cmDependsJavaParser.cxx" break; case 30: /* SimpleName: Identifier */ @@ -2757,7 +2769,7 @@ yyreduce: jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2761 "cmDependsJavaParser.cxx" +#line 2773 "cmDependsJavaParser.cxx" break; case 31: /* Identifier: jp_NAME */ @@ -2766,7 +2778,7 @@ yyreduce: jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2770 "cmDependsJavaParser.cxx" +#line 2782 "cmDependsJavaParser.cxx" break; case 32: /* Identifier: jp_DOLLAR jp_NAME */ @@ -2775,7 +2787,7 @@ yyreduce: jpElementStart(2); (yyval.str) = (yyvsp[0].str); } -#line 2779 "cmDependsJavaParser.cxx" +#line 2791 "cmDependsJavaParser.cxx" break; case 33: /* QualifiedName: Name jp_DOT Identifier */ @@ -2787,7 +2799,7 @@ yyreduce: yyGetParser->DeallocateParserType(&((yyvsp[-2].str))); (yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine()); } -#line 2791 "cmDependsJavaParser.cxx" +#line 2803 "cmDependsJavaParser.cxx" break; case 34: /* QualifiedName: Name jp_DOT jp_CLASS */ @@ -2800,7 +2812,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2804 "cmDependsJavaParser.cxx" +#line 2816 "cmDependsJavaParser.cxx" break; case 35: /* QualifiedName: Name jp_DOT jp_THIS */ @@ -2813,7 +2825,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2817 "cmDependsJavaParser.cxx" +#line 2829 "cmDependsJavaParser.cxx" break; case 36: /* QualifiedName: SimpleType jp_DOT jp_CLASS */ @@ -2824,7 +2836,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2828 "cmDependsJavaParser.cxx" +#line 2840 "cmDependsJavaParser.cxx" break; case 37: /* SimpleType: PrimitiveType */ @@ -2835,7 +2847,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2839 "cmDependsJavaParser.cxx" +#line 2851 "cmDependsJavaParser.cxx" break; case 38: /* SimpleType: jp_VOID */ @@ -2846,7 +2858,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2850 "cmDependsJavaParser.cxx" +#line 2862 "cmDependsJavaParser.cxx" break; case 39: /* CompilationUnit: PackageDeclarationopt ImportDeclarations TypeDeclarations */ @@ -2857,7 +2869,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2861 "cmDependsJavaParser.cxx" +#line 2873 "cmDependsJavaParser.cxx" break; case 40: /* PackageDeclarationopt: %empty */ @@ -2867,7 +2879,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2871 "cmDependsJavaParser.cxx" +#line 2883 "cmDependsJavaParser.cxx" break; case 41: /* PackageDeclarationopt: PackageDeclaration */ @@ -2878,7 +2890,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2882 "cmDependsJavaParser.cxx" +#line 2894 "cmDependsJavaParser.cxx" break; case 42: /* ImportDeclarations: %empty */ @@ -2888,7 +2900,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2892 "cmDependsJavaParser.cxx" +#line 2904 "cmDependsJavaParser.cxx" break; case 43: /* ImportDeclarations: ImportDeclarations ImportDeclaration */ @@ -2899,7 +2911,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2903 "cmDependsJavaParser.cxx" +#line 2915 "cmDependsJavaParser.cxx" break; case 44: /* TypeDeclarations: %empty */ @@ -2909,7 +2921,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2913 "cmDependsJavaParser.cxx" +#line 2925 "cmDependsJavaParser.cxx" break; case 45: /* TypeDeclarations: TypeDeclarations TypeDeclaration */ @@ -2920,7 +2932,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2924 "cmDependsJavaParser.cxx" +#line 2936 "cmDependsJavaParser.cxx" break; case 46: /* PackageDeclaration: jp_PACKAGE Name jp_SEMICOL */ @@ -2934,7 +2946,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2938 "cmDependsJavaParser.cxx" +#line 2950 "cmDependsJavaParser.cxx" break; case 47: /* ImportDeclaration: SingleTypeImportDeclaration */ @@ -2945,7 +2957,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2949 "cmDependsJavaParser.cxx" +#line 2961 "cmDependsJavaParser.cxx" break; case 48: /* ImportDeclaration: TypeImportOnDemandDeclaration */ @@ -2956,7 +2968,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2960 "cmDependsJavaParser.cxx" +#line 2972 "cmDependsJavaParser.cxx" break; case 49: /* SingleTypeImportDeclaration: jp_IMPORT Name jp_SEMICOL */ @@ -2970,7 +2982,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2974 "cmDependsJavaParser.cxx" +#line 2986 "cmDependsJavaParser.cxx" break; case 50: /* TypeImportOnDemandDeclaration: jp_IMPORT Name jp_DOT jp_TIMES jp_SEMICOL */ @@ -2985,7 +2997,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2989 "cmDependsJavaParser.cxx" +#line 3001 "cmDependsJavaParser.cxx" break; case 51: /* TypeDeclaration: ClassDeclaration */ @@ -2996,7 +3008,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3000 "cmDependsJavaParser.cxx" +#line 3012 "cmDependsJavaParser.cxx" break; case 52: /* TypeDeclaration: InterfaceDeclaration */ @@ -3007,7 +3019,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3011 "cmDependsJavaParser.cxx" +#line 3023 "cmDependsJavaParser.cxx" break; case 53: /* TypeDeclaration: jp_SEMICOL */ @@ -3018,7 +3030,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3022 "cmDependsJavaParser.cxx" +#line 3034 "cmDependsJavaParser.cxx" break; case 54: /* Modifiers: Modifier */ @@ -3029,7 +3041,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3033 "cmDependsJavaParser.cxx" +#line 3045 "cmDependsJavaParser.cxx" break; case 55: /* Modifiers: Modifiers Modifier */ @@ -3040,7 +3052,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3044 "cmDependsJavaParser.cxx" +#line 3056 "cmDependsJavaParser.cxx" break; case 67: /* ClassHeader: Modifiersopt jp_CLASS Identifier */ @@ -3051,7 +3063,7 @@ yyreduce: yyGetParser->DeallocateParserType(&((yyvsp[0].str))); jpCheckEmpty(3); } -#line 3055 "cmDependsJavaParser.cxx" +#line 3067 "cmDependsJavaParser.cxx" break; case 68: /* ClassDeclaration: ClassHeader ClassBody */ @@ -3063,7 +3075,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3067 "cmDependsJavaParser.cxx" +#line 3079 "cmDependsJavaParser.cxx" break; case 69: /* ClassDeclaration: ClassHeader Interfaces ClassBody */ @@ -3075,7 +3087,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3079 "cmDependsJavaParser.cxx" +#line 3091 "cmDependsJavaParser.cxx" break; case 70: /* ClassDeclaration: ClassHeader Super ClassBody */ @@ -3087,7 +3099,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3091 "cmDependsJavaParser.cxx" +#line 3103 "cmDependsJavaParser.cxx" break; case 71: /* ClassDeclaration: ClassHeader Super Interfaces ClassBody */ @@ -3099,7 +3111,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3103 "cmDependsJavaParser.cxx" +#line 3115 "cmDependsJavaParser.cxx" break; case 72: /* Modifiersopt: %empty */ @@ -3109,7 +3121,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3113 "cmDependsJavaParser.cxx" +#line 3125 "cmDependsJavaParser.cxx" break; case 73: /* Modifiersopt: Modifiers */ @@ -3120,7 +3132,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3124 "cmDependsJavaParser.cxx" +#line 3136 "cmDependsJavaParser.cxx" break; case 74: /* Super: jp_EXTENDS ClassType */ @@ -3131,7 +3143,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3135 "cmDependsJavaParser.cxx" +#line 3147 "cmDependsJavaParser.cxx" break; case 75: /* Interfaces: jp_IMPLEMENTS InterfaceTypeList */ @@ -3142,7 +3154,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3146 "cmDependsJavaParser.cxx" +#line 3158 "cmDependsJavaParser.cxx" break; case 76: /* InterfaceTypeList: InterfaceType */ @@ -3153,7 +3165,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3157 "cmDependsJavaParser.cxx" +#line 3169 "cmDependsJavaParser.cxx" break; case 77: /* InterfaceTypeList: InterfaceTypeList jp_COMMA InterfaceType */ @@ -3164,7 +3176,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3168 "cmDependsJavaParser.cxx" +#line 3180 "cmDependsJavaParser.cxx" break; case 78: /* ClassBody: jp_CURLYSTART ClassBodyDeclarations jp_CURLYEND */ @@ -3175,7 +3187,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3179 "cmDependsJavaParser.cxx" +#line 3191 "cmDependsJavaParser.cxx" break; case 79: /* ClassBodyDeclarations: %empty */ @@ -3185,7 +3197,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3189 "cmDependsJavaParser.cxx" +#line 3201 "cmDependsJavaParser.cxx" break; case 80: /* ClassBodyDeclarations: ClassBodyDeclarations ClassBodyDeclaration */ @@ -3196,7 +3208,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3200 "cmDependsJavaParser.cxx" +#line 3212 "cmDependsJavaParser.cxx" break; case 81: /* ClassBodyDeclaration: ClassMemberDeclaration */ @@ -3207,7 +3219,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3211 "cmDependsJavaParser.cxx" +#line 3223 "cmDependsJavaParser.cxx" break; case 82: /* ClassBodyDeclaration: StaticInitializer */ @@ -3218,7 +3230,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3222 "cmDependsJavaParser.cxx" +#line 3234 "cmDependsJavaParser.cxx" break; case 83: /* ClassBodyDeclaration: ConstructorDeclaration */ @@ -3229,7 +3241,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3233 "cmDependsJavaParser.cxx" +#line 3245 "cmDependsJavaParser.cxx" break; case 84: /* ClassBodyDeclaration: TypeDeclaration */ @@ -3240,7 +3252,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3244 "cmDependsJavaParser.cxx" +#line 3256 "cmDependsJavaParser.cxx" break; case 85: /* ClassMemberDeclaration: FieldDeclaration */ @@ -3251,7 +3263,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3255 "cmDependsJavaParser.cxx" +#line 3267 "cmDependsJavaParser.cxx" break; case 86: /* ClassMemberDeclaration: MethodDeclaration */ @@ -3262,7 +3274,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3266 "cmDependsJavaParser.cxx" +#line 3278 "cmDependsJavaParser.cxx" break; case 87: /* FieldDeclaration: Modifiersopt Type VariableDeclarators jp_SEMICOL */ @@ -3270,7 +3282,7 @@ yyreduce: { jpElementStart(4); } -#line 3274 "cmDependsJavaParser.cxx" +#line 3286 "cmDependsJavaParser.cxx" break; case 88: /* VariableDeclarators: VariableDeclarator */ @@ -3281,7 +3293,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3285 "cmDependsJavaParser.cxx" +#line 3297 "cmDependsJavaParser.cxx" break; case 89: /* VariableDeclarators: VariableDeclarators jp_COMMA VariableDeclarator */ @@ -3292,7 +3304,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3296 "cmDependsJavaParser.cxx" +#line 3308 "cmDependsJavaParser.cxx" break; case 90: /* VariableDeclarator: VariableDeclaratorId */ @@ -3303,7 +3315,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3307 "cmDependsJavaParser.cxx" +#line 3319 "cmDependsJavaParser.cxx" break; case 91: /* VariableDeclarator: VariableDeclaratorId jp_EQUALS VariableInitializer */ @@ -3314,7 +3326,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3318 "cmDependsJavaParser.cxx" +#line 3330 "cmDependsJavaParser.cxx" break; case 92: /* VariableDeclaratorId: Identifier */ @@ -3326,7 +3338,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3330 "cmDependsJavaParser.cxx" +#line 3342 "cmDependsJavaParser.cxx" break; case 93: /* VariableDeclaratorId: VariableDeclaratorId jp_BRACKETSTART jp_BRACKETEND */ @@ -3337,7 +3349,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3341 "cmDependsJavaParser.cxx" +#line 3353 "cmDependsJavaParser.cxx" break; case 94: /* VariableInitializer: Expression */ @@ -3348,7 +3360,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3352 "cmDependsJavaParser.cxx" +#line 3364 "cmDependsJavaParser.cxx" break; case 95: /* VariableInitializer: ArrayInitializer */ @@ -3359,7 +3371,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3363 "cmDependsJavaParser.cxx" +#line 3375 "cmDependsJavaParser.cxx" break; case 96: /* MethodDeclaration: MethodHeader jp_SEMICOL */ @@ -3370,7 +3382,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3374 "cmDependsJavaParser.cxx" +#line 3386 "cmDependsJavaParser.cxx" break; case 97: /* MethodDeclaration: MethodHeader MethodBody */ @@ -3381,7 +3393,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3385 "cmDependsJavaParser.cxx" +#line 3397 "cmDependsJavaParser.cxx" break; case 98: /* MethodDeclaration: MethodHeader MethodBody jp_SEMICOL */ @@ -3392,7 +3404,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3396 "cmDependsJavaParser.cxx" +#line 3408 "cmDependsJavaParser.cxx" break; case 99: /* MethodHeader: Modifiersopt Type MethodDeclarator Throwsopt */ @@ -3404,7 +3416,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3408 "cmDependsJavaParser.cxx" +#line 3420 "cmDependsJavaParser.cxx" break; case 100: /* MethodHeader: Modifiersopt jp_VOID MethodDeclarator Throwsopt */ @@ -3416,7 +3428,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3420 "cmDependsJavaParser.cxx" +#line 3432 "cmDependsJavaParser.cxx" break; case 101: /* Throwsopt: %empty */ @@ -3427,7 +3439,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3431 "cmDependsJavaParser.cxx" +#line 3443 "cmDependsJavaParser.cxx" break; case 102: /* Throwsopt: Throws */ @@ -3439,7 +3451,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3443 "cmDependsJavaParser.cxx" +#line 3455 "cmDependsJavaParser.cxx" break; case 103: /* MethodDeclarator: Identifier jp_PARESTART FormalParameterListopt jp_PAREEND */ @@ -3452,7 +3464,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3456 "cmDependsJavaParser.cxx" +#line 3468 "cmDependsJavaParser.cxx" break; case 104: /* MethodDeclarator: MethodDeclarator jp_BRACKETSTART jp_BRACKETEND */ @@ -3461,7 +3473,7 @@ yyreduce: jpElementStart(3); } -#line 3465 "cmDependsJavaParser.cxx" +#line 3477 "cmDependsJavaParser.cxx" break; case 105: /* FormalParameterListopt: %empty */ @@ -3472,7 +3484,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3476 "cmDependsJavaParser.cxx" +#line 3488 "cmDependsJavaParser.cxx" break; case 107: /* FormalParameterList: FormalParameter */ @@ -3481,7 +3493,7 @@ yyreduce: jpElementStart(1); } -#line 3485 "cmDependsJavaParser.cxx" +#line 3497 "cmDependsJavaParser.cxx" break; case 108: /* FormalParameterList: FormalParameterList jp_COMMA FormalParameter */ @@ -3493,7 +3505,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3497 "cmDependsJavaParser.cxx" +#line 3509 "cmDependsJavaParser.cxx" break; case 109: /* FormalParameter: Modifiersopt Type VariableDeclaratorId */ @@ -3505,7 +3517,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3509 "cmDependsJavaParser.cxx" +#line 3521 "cmDependsJavaParser.cxx" break; case 110: /* Throws: jp_THROWS ClassTypeList */ @@ -3517,7 +3529,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3521 "cmDependsJavaParser.cxx" +#line 3533 "cmDependsJavaParser.cxx" break; case 111: /* ClassTypeList: ClassType */ @@ -3526,7 +3538,7 @@ yyreduce: jpElementStart(1); } -#line 3530 "cmDependsJavaParser.cxx" +#line 3542 "cmDependsJavaParser.cxx" break; case 112: /* ClassTypeList: ClassTypeList jp_COMMA ClassType */ @@ -3538,7 +3550,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3542 "cmDependsJavaParser.cxx" +#line 3554 "cmDependsJavaParser.cxx" break; case 113: /* MethodBody: Block */ @@ -3550,7 +3562,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3554 "cmDependsJavaParser.cxx" +#line 3566 "cmDependsJavaParser.cxx" break; case 114: /* StaticInitializer: jp_STATIC Block */ @@ -3562,7 +3574,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3566 "cmDependsJavaParser.cxx" +#line 3578 "cmDependsJavaParser.cxx" break; case 115: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody */ @@ -3574,7 +3586,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3578 "cmDependsJavaParser.cxx" +#line 3590 "cmDependsJavaParser.cxx" break; case 116: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody jp_SEMICOL */ @@ -3586,7 +3598,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3590 "cmDependsJavaParser.cxx" +#line 3602 "cmDependsJavaParser.cxx" break; case 117: /* ConstructorDeclarator: SimpleName jp_PARESTART FormalParameterListopt jp_PAREEND */ @@ -3599,7 +3611,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3603 "cmDependsJavaParser.cxx" +#line 3615 "cmDependsJavaParser.cxx" break; case 118: /* ConstructorBody: jp_CURLYSTART ExplicitConstructorInvocationopt BlockStatementsopt jp_CURLYEND */ @@ -3611,7 +3623,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3615 "cmDependsJavaParser.cxx" +#line 3627 "cmDependsJavaParser.cxx" break; case 119: /* ExplicitConstructorInvocationopt: %empty */ @@ -3622,7 +3634,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3626 "cmDependsJavaParser.cxx" +#line 3638 "cmDependsJavaParser.cxx" break; case 120: /* ExplicitConstructorInvocationopt: ExplicitConstructorInvocationopt ExplicitConstructorInvocation */ @@ -3634,7 +3646,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3638 "cmDependsJavaParser.cxx" +#line 3650 "cmDependsJavaParser.cxx" break; case 121: /* ExplicitConstructorInvocation: jp_THIS jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */ @@ -3646,7 +3658,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3650 "cmDependsJavaParser.cxx" +#line 3662 "cmDependsJavaParser.cxx" break; case 122: /* ExplicitConstructorInvocation: jp_SUPER jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */ @@ -3658,7 +3670,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3662 "cmDependsJavaParser.cxx" +#line 3674 "cmDependsJavaParser.cxx" break; case 123: /* InterfaceHeader: Modifiersopt jp_INTERFACE Identifier */ @@ -3669,7 +3681,7 @@ yyreduce: yyGetParser->DeallocateParserType(&((yyvsp[0].str))); jpCheckEmpty(3); } -#line 3673 "cmDependsJavaParser.cxx" +#line 3685 "cmDependsJavaParser.cxx" break; case 124: /* InterfaceDeclaration: InterfaceHeader ExtendsInterfacesopt InterfaceBody */ @@ -3681,7 +3693,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3685 "cmDependsJavaParser.cxx" +#line 3697 "cmDependsJavaParser.cxx" break; case 125: /* ExtendsInterfacesopt: %empty */ @@ -3691,7 +3703,7 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3695 "cmDependsJavaParser.cxx" +#line 3707 "cmDependsJavaParser.cxx" break; case 126: /* ExtendsInterfacesopt: ExtendsInterfaces */ @@ -3703,7 +3715,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3707 "cmDependsJavaParser.cxx" +#line 3719 "cmDependsJavaParser.cxx" break; case 127: /* ExtendsInterfaces: jp_EXTENDS InterfaceType */ @@ -3715,7 +3727,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3719 "cmDependsJavaParser.cxx" +#line 3731 "cmDependsJavaParser.cxx" break; case 128: /* ExtendsInterfaces: ExtendsInterfaces jp_COMMA InterfaceType */ @@ -3727,7 +3739,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3731 "cmDependsJavaParser.cxx" +#line 3743 "cmDependsJavaParser.cxx" break; case 129: /* InterfaceBody: jp_CURLYSTART InterfaceMemberDeclarations jp_CURLYEND */ @@ -3739,7 +3751,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3743 "cmDependsJavaParser.cxx" +#line 3755 "cmDependsJavaParser.cxx" break; case 130: /* InterfaceMemberDeclarations: %empty */ @@ -3750,7 +3762,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3754 "cmDependsJavaParser.cxx" +#line 3766 "cmDependsJavaParser.cxx" break; case 131: /* InterfaceMemberDeclarations: InterfaceMemberDeclarations InterfaceMemberDeclaration */ @@ -3761,7 +3773,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3765 "cmDependsJavaParser.cxx" +#line 3777 "cmDependsJavaParser.cxx" break; case 132: /* InterfaceMemberDeclaration: ConstantDeclaration */ @@ -3773,7 +3785,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3777 "cmDependsJavaParser.cxx" +#line 3789 "cmDependsJavaParser.cxx" break; case 133: /* InterfaceMemberDeclaration: AbstractMethodDeclaration */ @@ -3785,7 +3797,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3789 "cmDependsJavaParser.cxx" +#line 3801 "cmDependsJavaParser.cxx" break; case 134: /* InterfaceMemberDeclaration: ClassDeclaration */ @@ -3797,7 +3809,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3801 "cmDependsJavaParser.cxx" +#line 3813 "cmDependsJavaParser.cxx" break; case 135: /* InterfaceMemberDeclaration: ClassDeclaration jp_SEMICOL */ @@ -3808,7 +3820,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3812 "cmDependsJavaParser.cxx" +#line 3824 "cmDependsJavaParser.cxx" break; case 136: /* InterfaceMemberDeclaration: InterfaceDeclaration */ @@ -3820,7 +3832,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3824 "cmDependsJavaParser.cxx" +#line 3836 "cmDependsJavaParser.cxx" break; case 137: /* InterfaceMemberDeclaration: InterfaceDeclaration jp_SEMICOL */ @@ -3831,7 +3843,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3835 "cmDependsJavaParser.cxx" +#line 3847 "cmDependsJavaParser.cxx" break; case 138: /* ConstantDeclaration: FieldDeclaration */ @@ -3843,7 +3855,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3847 "cmDependsJavaParser.cxx" +#line 3859 "cmDependsJavaParser.cxx" break; case 139: /* AbstractMethodDeclaration: MethodHeader Semicols */ @@ -3855,7 +3867,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3859 "cmDependsJavaParser.cxx" +#line 3871 "cmDependsJavaParser.cxx" break; case 140: /* Semicols: jp_SEMICOL */ @@ -3867,7 +3879,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3871 "cmDependsJavaParser.cxx" +#line 3883 "cmDependsJavaParser.cxx" break; case 141: /* Semicols: Semicols jp_SEMICOL */ @@ -3879,7 +3891,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3883 "cmDependsJavaParser.cxx" +#line 3895 "cmDependsJavaParser.cxx" break; case 142: /* ArrayInitializer: jp_CURLYSTART VariableInitializersOptional jp_CURLYEND */ @@ -3891,7 +3903,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3895 "cmDependsJavaParser.cxx" +#line 3907 "cmDependsJavaParser.cxx" break; case 143: /* VariableInitializersOptional: %empty */ @@ -3902,7 +3914,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3906 "cmDependsJavaParser.cxx" +#line 3918 "cmDependsJavaParser.cxx" break; case 144: /* VariableInitializersOptional: VariableInitializers */ @@ -3914,7 +3926,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3918 "cmDependsJavaParser.cxx" +#line 3930 "cmDependsJavaParser.cxx" break; case 145: /* VariableInitializersOptional: VariableInitializers jp_COMMA */ @@ -3926,7 +3938,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3930 "cmDependsJavaParser.cxx" +#line 3942 "cmDependsJavaParser.cxx" break; case 146: /* VariableInitializers: VariableInitializer */ @@ -3938,7 +3950,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3942 "cmDependsJavaParser.cxx" +#line 3954 "cmDependsJavaParser.cxx" break; case 147: /* VariableInitializers: VariableInitializers jp_COMMA VariableInitializer */ @@ -3950,7 +3962,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3954 "cmDependsJavaParser.cxx" +#line 3966 "cmDependsJavaParser.cxx" break; case 148: /* Block: jp_CURLYSTART BlockStatementsopt jp_CURLYEND */ @@ -3961,7 +3973,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3965 "cmDependsJavaParser.cxx" +#line 3977 "cmDependsJavaParser.cxx" break; case 149: /* BlockStatementsopt: %empty */ @@ -3972,7 +3984,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3976 "cmDependsJavaParser.cxx" +#line 3988 "cmDependsJavaParser.cxx" break; case 150: /* BlockStatementsopt: BlockStatements */ @@ -3984,7 +3996,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3988 "cmDependsJavaParser.cxx" +#line 4000 "cmDependsJavaParser.cxx" break; case 151: /* BlockStatements: BlockStatement */ @@ -3996,7 +4008,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4000 "cmDependsJavaParser.cxx" +#line 4012 "cmDependsJavaParser.cxx" break; case 152: /* BlockStatements: BlockStatements BlockStatement */ @@ -4008,7 +4020,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4012 "cmDependsJavaParser.cxx" +#line 4024 "cmDependsJavaParser.cxx" break; case 153: /* BlockStatement: LocalVariableDeclarationStatement */ @@ -4020,7 +4032,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4024 "cmDependsJavaParser.cxx" +#line 4036 "cmDependsJavaParser.cxx" break; case 154: /* BlockStatement: Statement */ @@ -4032,7 +4044,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4036 "cmDependsJavaParser.cxx" +#line 4048 "cmDependsJavaParser.cxx" break; case 155: /* BlockStatement: ClassDeclaration */ @@ -4044,7 +4056,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4048 "cmDependsJavaParser.cxx" +#line 4060 "cmDependsJavaParser.cxx" break; case 156: /* LocalVariableDeclarationStatement: LocalVariableDeclaration jp_SEMICOL */ @@ -4056,7 +4068,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4060 "cmDependsJavaParser.cxx" +#line 4072 "cmDependsJavaParser.cxx" break; case 157: /* LocalVariableDeclaration: Modifiers Type VariableDeclarators */ @@ -4068,7 +4080,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4072 "cmDependsJavaParser.cxx" +#line 4084 "cmDependsJavaParser.cxx" break; case 158: /* LocalVariableDeclaration: Type VariableDeclarators */ @@ -4080,7 +4092,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4084 "cmDependsJavaParser.cxx" +#line 4096 "cmDependsJavaParser.cxx" break; case 159: /* Statement: StatementWithoutTrailingSubstatement */ @@ -4092,7 +4104,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4096 "cmDependsJavaParser.cxx" +#line 4108 "cmDependsJavaParser.cxx" break; case 160: /* Statement: LabeledStatement */ @@ -4104,7 +4116,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4108 "cmDependsJavaParser.cxx" +#line 4120 "cmDependsJavaParser.cxx" break; case 161: /* Statement: IfThenStatement */ @@ -4116,7 +4128,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4120 "cmDependsJavaParser.cxx" +#line 4132 "cmDependsJavaParser.cxx" break; case 162: /* Statement: IfThenElseStatement */ @@ -4128,7 +4140,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4132 "cmDependsJavaParser.cxx" +#line 4144 "cmDependsJavaParser.cxx" break; case 163: /* Statement: WhileStatement */ @@ -4140,7 +4152,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4144 "cmDependsJavaParser.cxx" +#line 4156 "cmDependsJavaParser.cxx" break; case 164: /* Statement: ForStatement */ @@ -4152,7 +4164,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4156 "cmDependsJavaParser.cxx" +#line 4168 "cmDependsJavaParser.cxx" break; case 165: /* StatementNoShortIf: StatementWithoutTrailingSubstatement */ @@ -4164,7 +4176,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4168 "cmDependsJavaParser.cxx" +#line 4180 "cmDependsJavaParser.cxx" break; case 166: /* StatementNoShortIf: LabeledStatementNoShortIf */ @@ -4176,7 +4188,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4180 "cmDependsJavaParser.cxx" +#line 4192 "cmDependsJavaParser.cxx" break; case 167: /* StatementNoShortIf: IfThenElseStatementNoShortIf */ @@ -4188,7 +4200,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4192 "cmDependsJavaParser.cxx" +#line 4204 "cmDependsJavaParser.cxx" break; case 168: /* StatementNoShortIf: WhileStatementNoShortIf */ @@ -4200,7 +4212,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4204 "cmDependsJavaParser.cxx" +#line 4216 "cmDependsJavaParser.cxx" break; case 169: /* StatementNoShortIf: ForStatementNoShortIf */ @@ -4212,7 +4224,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4216 "cmDependsJavaParser.cxx" +#line 4228 "cmDependsJavaParser.cxx" break; case 170: /* StatementWithoutTrailingSubstatement: Block */ @@ -4224,7 +4236,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4228 "cmDependsJavaParser.cxx" +#line 4240 "cmDependsJavaParser.cxx" break; case 171: /* StatementWithoutTrailingSubstatement: EmptyStatement */ @@ -4236,7 +4248,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4240 "cmDependsJavaParser.cxx" +#line 4252 "cmDependsJavaParser.cxx" break; case 172: /* StatementWithoutTrailingSubstatement: ExpressionStatement */ @@ -4248,7 +4260,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4252 "cmDependsJavaParser.cxx" +#line 4264 "cmDependsJavaParser.cxx" break; case 173: /* StatementWithoutTrailingSubstatement: SwitchStatement */ @@ -4260,7 +4272,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4264 "cmDependsJavaParser.cxx" +#line 4276 "cmDependsJavaParser.cxx" break; case 174: /* StatementWithoutTrailingSubstatement: DoStatement */ @@ -4272,7 +4284,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4276 "cmDependsJavaParser.cxx" +#line 4288 "cmDependsJavaParser.cxx" break; case 175: /* StatementWithoutTrailingSubstatement: BreakStatement */ @@ -4284,7 +4296,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4288 "cmDependsJavaParser.cxx" +#line 4300 "cmDependsJavaParser.cxx" break; case 176: /* StatementWithoutTrailingSubstatement: ContinueStatement */ @@ -4296,7 +4308,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4300 "cmDependsJavaParser.cxx" +#line 4312 "cmDependsJavaParser.cxx" break; case 177: /* StatementWithoutTrailingSubstatement: ReturnStatement */ @@ -4308,7 +4320,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4312 "cmDependsJavaParser.cxx" +#line 4324 "cmDependsJavaParser.cxx" break; case 178: /* StatementWithoutTrailingSubstatement: SynchronizedStatement */ @@ -4320,7 +4332,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4324 "cmDependsJavaParser.cxx" +#line 4336 "cmDependsJavaParser.cxx" break; case 179: /* StatementWithoutTrailingSubstatement: ThrowStatement */ @@ -4332,7 +4344,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4336 "cmDependsJavaParser.cxx" +#line 4348 "cmDependsJavaParser.cxx" break; case 180: /* StatementWithoutTrailingSubstatement: TryStatement */ @@ -4344,7 +4356,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4348 "cmDependsJavaParser.cxx" +#line 4360 "cmDependsJavaParser.cxx" break; case 181: /* StatementWithoutTrailingSubstatement: AssertStatement */ @@ -4356,7 +4368,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4360 "cmDependsJavaParser.cxx" +#line 4372 "cmDependsJavaParser.cxx" break; case 182: /* EmptyStatement: jp_SEMICOL */ @@ -4368,7 +4380,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4372 "cmDependsJavaParser.cxx" +#line 4384 "cmDependsJavaParser.cxx" break; case 183: /* LabeledStatement: Identifier jp_COLON Statement */ @@ -4381,7 +4393,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4385 "cmDependsJavaParser.cxx" +#line 4397 "cmDependsJavaParser.cxx" break; case 184: /* LabeledStatementNoShortIf: Identifier jp_COLON StatementNoShortIf */ @@ -4393,7 +4405,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4397 "cmDependsJavaParser.cxx" +#line 4409 "cmDependsJavaParser.cxx" break; case 185: /* ExpressionStatement: StatementExpression jp_SEMICOL */ @@ -4405,7 +4417,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4409 "cmDependsJavaParser.cxx" +#line 4421 "cmDependsJavaParser.cxx" break; case 186: /* StatementExpression: Assignment */ @@ -4417,7 +4429,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4421 "cmDependsJavaParser.cxx" +#line 4433 "cmDependsJavaParser.cxx" break; case 187: /* StatementExpression: PreIncrementExpression */ @@ -4429,7 +4441,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4433 "cmDependsJavaParser.cxx" +#line 4445 "cmDependsJavaParser.cxx" break; case 188: /* StatementExpression: PreDecrementExpression */ @@ -4441,7 +4453,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4445 "cmDependsJavaParser.cxx" +#line 4457 "cmDependsJavaParser.cxx" break; case 189: /* StatementExpression: PostIncrementExpression */ @@ -4453,7 +4465,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4457 "cmDependsJavaParser.cxx" +#line 4469 "cmDependsJavaParser.cxx" break; case 190: /* StatementExpression: PostDecrementExpression */ @@ -4465,7 +4477,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4469 "cmDependsJavaParser.cxx" +#line 4481 "cmDependsJavaParser.cxx" break; case 191: /* StatementExpression: MethodInvocation */ @@ -4477,7 +4489,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4481 "cmDependsJavaParser.cxx" +#line 4493 "cmDependsJavaParser.cxx" break; case 192: /* StatementExpression: ClassInstanceCreationExpression */ @@ -4489,7 +4501,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4493 "cmDependsJavaParser.cxx" +#line 4505 "cmDependsJavaParser.cxx" break; case 193: /* IfThenStatement: jp_IF jp_PARESTART Expression jp_PAREEND Statement */ @@ -4501,7 +4513,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4505 "cmDependsJavaParser.cxx" +#line 4517 "cmDependsJavaParser.cxx" break; case 194: /* IfThenElseStatement: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE Statement */ @@ -4513,7 +4525,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4517 "cmDependsJavaParser.cxx" +#line 4529 "cmDependsJavaParser.cxx" break; case 195: /* IfThenElseStatementNoShortIf: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE StatementNoShortIf */ @@ -4525,7 +4537,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4529 "cmDependsJavaParser.cxx" +#line 4541 "cmDependsJavaParser.cxx" break; case 196: /* SwitchStatement: jp_SWITCH jp_PARESTART Expression jp_PAREEND SwitchBlock */ @@ -4534,7 +4546,7 @@ yyreduce: jpElementStart(5); } -#line 4538 "cmDependsJavaParser.cxx" +#line 4550 "cmDependsJavaParser.cxx" break; case 197: /* SwitchBlock: jp_CURLYSTART SwitchBlockStatementGroups SwitchLabelsopt jp_CURLYEND */ @@ -4543,7 +4555,7 @@ yyreduce: jpElementStart(4); } -#line 4547 "cmDependsJavaParser.cxx" +#line 4559 "cmDependsJavaParser.cxx" break; case 198: /* SwitchLabelsopt: %empty */ @@ -4554,7 +4566,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4558 "cmDependsJavaParser.cxx" +#line 4570 "cmDependsJavaParser.cxx" break; case 199: /* SwitchLabelsopt: SwitchLabels */ @@ -4566,7 +4578,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4570 "cmDependsJavaParser.cxx" +#line 4582 "cmDependsJavaParser.cxx" break; case 200: /* SwitchBlockStatementGroups: %empty */ @@ -4577,7 +4589,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4581 "cmDependsJavaParser.cxx" +#line 4593 "cmDependsJavaParser.cxx" break; case 201: /* SwitchBlockStatementGroups: SwitchBlockStatementGroups SwitchBlockStatementGroup */ @@ -4589,7 +4601,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4593 "cmDependsJavaParser.cxx" +#line 4605 "cmDependsJavaParser.cxx" break; case 202: /* SwitchBlockStatementGroup: SwitchLabels BlockStatements */ @@ -4601,7 +4613,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4605 "cmDependsJavaParser.cxx" +#line 4617 "cmDependsJavaParser.cxx" break; case 203: /* SwitchLabels: SwitchLabel */ @@ -4613,7 +4625,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4617 "cmDependsJavaParser.cxx" +#line 4629 "cmDependsJavaParser.cxx" break; case 204: /* SwitchLabels: SwitchLabels SwitchLabel */ @@ -4625,7 +4637,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4629 "cmDependsJavaParser.cxx" +#line 4641 "cmDependsJavaParser.cxx" break; case 205: /* SwitchLabel: jp_CASE ConstantExpression jp_COLON */ @@ -4637,7 +4649,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4641 "cmDependsJavaParser.cxx" +#line 4653 "cmDependsJavaParser.cxx" break; case 206: /* SwitchLabel: jp_DEFAULT jp_COLON */ @@ -4649,7 +4661,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4653 "cmDependsJavaParser.cxx" +#line 4665 "cmDependsJavaParser.cxx" break; case 207: /* WhileStatement: jp_WHILE jp_PARESTART Expression jp_PAREEND Statement */ @@ -4658,7 +4670,7 @@ yyreduce: jpElementStart(5); } -#line 4662 "cmDependsJavaParser.cxx" +#line 4674 "cmDependsJavaParser.cxx" break; case 208: /* WhileStatementNoShortIf: jp_WHILE jp_PARESTART Expression jp_PAREEND StatementNoShortIf */ @@ -4667,7 +4679,7 @@ yyreduce: jpElementStart(5); } -#line 4671 "cmDependsJavaParser.cxx" +#line 4683 "cmDependsJavaParser.cxx" break; case 209: /* DoStatement: jp_DO Statement jp_WHILE jp_PARESTART Expression jp_PAREEND jp_SEMICOL */ @@ -4676,7 +4688,7 @@ yyreduce: jpElementStart(7); } -#line 4680 "cmDependsJavaParser.cxx" +#line 4692 "cmDependsJavaParser.cxx" break; case 210: /* ForStatement: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND Statement */ @@ -4685,7 +4697,7 @@ yyreduce: jpElementStart(9); } -#line 4689 "cmDependsJavaParser.cxx" +#line 4701 "cmDependsJavaParser.cxx" break; case 211: /* ForUpdateopt: %empty */ @@ -4696,7 +4708,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4700 "cmDependsJavaParser.cxx" +#line 4712 "cmDependsJavaParser.cxx" break; case 212: /* ForUpdateopt: ForUpdate */ @@ -4708,7 +4720,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4712 "cmDependsJavaParser.cxx" +#line 4724 "cmDependsJavaParser.cxx" break; case 213: /* ForInitopt: %empty */ @@ -4719,7 +4731,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4723 "cmDependsJavaParser.cxx" +#line 4735 "cmDependsJavaParser.cxx" break; case 214: /* ForInitopt: ForInit */ @@ -4731,7 +4743,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4735 "cmDependsJavaParser.cxx" +#line 4747 "cmDependsJavaParser.cxx" break; case 215: /* ForStatementNoShortIf: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND StatementNoShortIf */ @@ -4742,7 +4754,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4746 "cmDependsJavaParser.cxx" +#line 4758 "cmDependsJavaParser.cxx" break; case 216: /* Expressionopt: %empty */ @@ -4753,7 +4765,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4757 "cmDependsJavaParser.cxx" +#line 4769 "cmDependsJavaParser.cxx" break; case 217: /* Expressionopt: Expression */ @@ -4765,7 +4777,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4769 "cmDependsJavaParser.cxx" +#line 4781 "cmDependsJavaParser.cxx" break; case 218: /* ForInit: StatementExpressionList */ @@ -4777,7 +4789,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4781 "cmDependsJavaParser.cxx" +#line 4793 "cmDependsJavaParser.cxx" break; case 219: /* ForInit: LocalVariableDeclaration */ @@ -4789,7 +4801,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4793 "cmDependsJavaParser.cxx" +#line 4805 "cmDependsJavaParser.cxx" break; case 220: /* ForUpdate: StatementExpressionList */ @@ -4801,7 +4813,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4805 "cmDependsJavaParser.cxx" +#line 4817 "cmDependsJavaParser.cxx" break; case 221: /* StatementExpressionList: StatementExpression */ @@ -4813,7 +4825,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4817 "cmDependsJavaParser.cxx" +#line 4829 "cmDependsJavaParser.cxx" break; case 222: /* StatementExpressionList: StatementExpressionList jp_COMMA StatementExpression */ @@ -4825,7 +4837,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4829 "cmDependsJavaParser.cxx" +#line 4841 "cmDependsJavaParser.cxx" break; case 223: /* AssertStatement: jp_ASSERT Expression jp_SEMICOL */ @@ -4837,7 +4849,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4841 "cmDependsJavaParser.cxx" +#line 4853 "cmDependsJavaParser.cxx" break; case 224: /* AssertStatement: jp_ASSERT Expression jp_COLON Expression jp_SEMICOL */ @@ -4849,7 +4861,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4853 "cmDependsJavaParser.cxx" +#line 4865 "cmDependsJavaParser.cxx" break; case 225: /* BreakStatement: jp_BREAK Identifieropt jp_SEMICOL */ @@ -4862,7 +4874,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4866 "cmDependsJavaParser.cxx" +#line 4878 "cmDependsJavaParser.cxx" break; case 226: /* Identifieropt: %empty */ @@ -4873,7 +4885,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4877 "cmDependsJavaParser.cxx" +#line 4889 "cmDependsJavaParser.cxx" break; case 227: /* Identifieropt: Identifier */ @@ -4882,7 +4894,7 @@ yyreduce: jpElementStart(1); } -#line 4886 "cmDependsJavaParser.cxx" +#line 4898 "cmDependsJavaParser.cxx" break; case 228: /* ContinueStatement: jp_CONTINUE Identifieropt jp_SEMICOL */ @@ -4895,7 +4907,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4899 "cmDependsJavaParser.cxx" +#line 4911 "cmDependsJavaParser.cxx" break; case 229: /* ReturnStatement: jp_RETURN Expressionopt jp_SEMICOL */ @@ -4907,7 +4919,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4911 "cmDependsJavaParser.cxx" +#line 4923 "cmDependsJavaParser.cxx" break; case 230: /* ThrowStatement: jp_THROW Expression jp_SEMICOL */ @@ -4919,7 +4931,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4923 "cmDependsJavaParser.cxx" +#line 4935 "cmDependsJavaParser.cxx" break; case 231: /* SynchronizedStatement: jp_SYNCHRONIZED jp_PARESTART Expression jp_PAREEND Block */ @@ -4931,7 +4943,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4935 "cmDependsJavaParser.cxx" +#line 4947 "cmDependsJavaParser.cxx" break; case 232: /* TryStatement: jp_TRY Block Catches */ @@ -4943,7 +4955,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4947 "cmDependsJavaParser.cxx" +#line 4959 "cmDependsJavaParser.cxx" break; case 233: /* TryStatement: jp_TRY Block Catchesopt Finally */ @@ -4955,7 +4967,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4959 "cmDependsJavaParser.cxx" +#line 4971 "cmDependsJavaParser.cxx" break; case 234: /* Catchesopt: %empty */ @@ -4966,7 +4978,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4970 "cmDependsJavaParser.cxx" +#line 4982 "cmDependsJavaParser.cxx" break; case 235: /* Catchesopt: Catches */ @@ -4978,7 +4990,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4982 "cmDependsJavaParser.cxx" +#line 4994 "cmDependsJavaParser.cxx" break; case 236: /* Catches: CatchClause */ @@ -4990,7 +5002,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4994 "cmDependsJavaParser.cxx" +#line 5006 "cmDependsJavaParser.cxx" break; case 237: /* Catches: Catches CatchClause */ @@ -5002,7 +5014,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5006 "cmDependsJavaParser.cxx" +#line 5018 "cmDependsJavaParser.cxx" break; case 238: /* CatchClause: jp_CATCH jp_PARESTART FormalParameter jp_PAREEND Block */ @@ -5011,7 +5023,7 @@ yyreduce: jpElementStart(5); } -#line 5015 "cmDependsJavaParser.cxx" +#line 5027 "cmDependsJavaParser.cxx" break; case 239: /* Finally: jp_FINALLY Block */ @@ -5023,7 +5035,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5027 "cmDependsJavaParser.cxx" +#line 5039 "cmDependsJavaParser.cxx" break; case 240: /* Primary: PrimaryNoNewArray */ @@ -5035,7 +5047,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5039 "cmDependsJavaParser.cxx" +#line 5051 "cmDependsJavaParser.cxx" break; case 241: /* Primary: ArrayCreationExpression */ @@ -5047,7 +5059,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5051 "cmDependsJavaParser.cxx" +#line 5063 "cmDependsJavaParser.cxx" break; case 242: /* PrimaryNoNewArray: Literal */ @@ -5059,7 +5071,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5063 "cmDependsJavaParser.cxx" +#line 5075 "cmDependsJavaParser.cxx" break; case 243: /* PrimaryNoNewArray: jp_THIS */ @@ -5068,7 +5080,7 @@ yyreduce: jpElementStart(1); } -#line 5072 "cmDependsJavaParser.cxx" +#line 5084 "cmDependsJavaParser.cxx" break; case 244: /* PrimaryNoNewArray: jp_PARESTART Expression jp_PAREEND */ @@ -5080,7 +5092,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5084 "cmDependsJavaParser.cxx" +#line 5096 "cmDependsJavaParser.cxx" break; case 245: /* PrimaryNoNewArray: ClassInstanceCreationExpression */ @@ -5092,7 +5104,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5096 "cmDependsJavaParser.cxx" +#line 5108 "cmDependsJavaParser.cxx" break; case 246: /* PrimaryNoNewArray: FieldAccess */ @@ -5104,7 +5116,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5108 "cmDependsJavaParser.cxx" +#line 5120 "cmDependsJavaParser.cxx" break; case 247: /* PrimaryNoNewArray: MethodInvocation */ @@ -5116,7 +5128,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5120 "cmDependsJavaParser.cxx" +#line 5132 "cmDependsJavaParser.cxx" break; case 248: /* PrimaryNoNewArray: ArrayAccess */ @@ -5128,7 +5140,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5132 "cmDependsJavaParser.cxx" +#line 5144 "cmDependsJavaParser.cxx" break; case 249: /* ClassInstanceCreationExpression: New ClassType jp_PARESTART ArgumentListopt jp_PAREEND ClassBodyOpt */ @@ -5140,7 +5152,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5144 "cmDependsJavaParser.cxx" +#line 5156 "cmDependsJavaParser.cxx" break; case 250: /* ClassBodyOpt: %empty */ @@ -5151,7 +5163,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5155 "cmDependsJavaParser.cxx" +#line 5167 "cmDependsJavaParser.cxx" break; case 251: /* ClassBodyOpt: ClassBody */ @@ -5163,7 +5175,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5167 "cmDependsJavaParser.cxx" +#line 5179 "cmDependsJavaParser.cxx" break; case 252: /* ArgumentListopt: %empty */ @@ -5174,7 +5186,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5178 "cmDependsJavaParser.cxx" +#line 5190 "cmDependsJavaParser.cxx" break; case 253: /* ArgumentListopt: ArgumentList */ @@ -5186,7 +5198,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5190 "cmDependsJavaParser.cxx" +#line 5202 "cmDependsJavaParser.cxx" break; case 254: /* ArgumentList: Expression */ @@ -5198,7 +5210,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5202 "cmDependsJavaParser.cxx" +#line 5214 "cmDependsJavaParser.cxx" break; case 255: /* ArgumentList: ArgumentList jp_COMMA Expression */ @@ -5210,7 +5222,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5214 "cmDependsJavaParser.cxx" +#line 5226 "cmDependsJavaParser.cxx" break; case 256: /* ArrayCreationExpression: New PrimitiveType DimExprs Dimsopt */ @@ -5222,7 +5234,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5226 "cmDependsJavaParser.cxx" +#line 5238 "cmDependsJavaParser.cxx" break; case 257: /* ArrayCreationExpression: New ClassOrInterfaceType DimExprs Dimsopt */ @@ -5234,7 +5246,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5238 "cmDependsJavaParser.cxx" +#line 5250 "cmDependsJavaParser.cxx" break; case 258: /* ArrayCreationExpression: New PrimitiveType Dims ArrayInitializer */ @@ -5246,7 +5258,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5250 "cmDependsJavaParser.cxx" +#line 5262 "cmDependsJavaParser.cxx" break; case 259: /* ArrayCreationExpression: New ClassOrInterfaceType Dims ArrayInitializer */ @@ -5258,7 +5270,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5262 "cmDependsJavaParser.cxx" +#line 5274 "cmDependsJavaParser.cxx" break; case 260: /* Dimsopt: %empty */ @@ -5269,7 +5281,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5273 "cmDependsJavaParser.cxx" +#line 5285 "cmDependsJavaParser.cxx" break; case 261: /* Dimsopt: Dims */ @@ -5281,7 +5293,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5285 "cmDependsJavaParser.cxx" +#line 5297 "cmDependsJavaParser.cxx" break; case 262: /* DimExprs: DimExpr */ @@ -5293,7 +5305,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5297 "cmDependsJavaParser.cxx" +#line 5309 "cmDependsJavaParser.cxx" break; case 263: /* DimExprs: DimExprs DimExpr */ @@ -5305,7 +5317,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5309 "cmDependsJavaParser.cxx" +#line 5321 "cmDependsJavaParser.cxx" break; case 264: /* DimExpr: jp_BRACKETSTART Expression jp_BRACKETEND */ @@ -5317,7 +5329,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5321 "cmDependsJavaParser.cxx" +#line 5333 "cmDependsJavaParser.cxx" break; case 265: /* Dims: jp_BRACKETSTART jp_BRACKETEND */ @@ -5326,7 +5338,7 @@ yyreduce: jpElementStart(2); } -#line 5330 "cmDependsJavaParser.cxx" +#line 5342 "cmDependsJavaParser.cxx" break; case 266: /* Dims: Dims jp_BRACKETSTART jp_BRACKETEND */ @@ -5335,7 +5347,7 @@ yyreduce: jpElementStart(3); } -#line 5339 "cmDependsJavaParser.cxx" +#line 5351 "cmDependsJavaParser.cxx" break; case 267: /* FieldAccess: Primary jp_DOT Identifier */ @@ -5348,7 +5360,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5352 "cmDependsJavaParser.cxx" +#line 5364 "cmDependsJavaParser.cxx" break; case 268: /* FieldAccess: jp_SUPER jp_DOT Identifier */ @@ -5361,7 +5373,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5365 "cmDependsJavaParser.cxx" +#line 5377 "cmDependsJavaParser.cxx" break; case 269: /* FieldAccess: jp_THIS jp_DOT Identifier */ @@ -5374,7 +5386,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5378 "cmDependsJavaParser.cxx" +#line 5390 "cmDependsJavaParser.cxx" break; case 270: /* FieldAccess: Primary jp_DOT jp_THIS */ @@ -5387,7 +5399,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5391 "cmDependsJavaParser.cxx" +#line 5403 "cmDependsJavaParser.cxx" break; case 271: /* MethodInvocation: Name jp_PARESTART ArgumentListopt jp_PAREEND */ @@ -5400,7 +5412,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5404 "cmDependsJavaParser.cxx" +#line 5416 "cmDependsJavaParser.cxx" break; case 272: /* MethodInvocation: Primary jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */ @@ -5414,7 +5426,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5418 "cmDependsJavaParser.cxx" +#line 5430 "cmDependsJavaParser.cxx" break; case 273: /* MethodInvocation: jp_SUPER jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */ @@ -5427,7 +5439,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5431 "cmDependsJavaParser.cxx" +#line 5443 "cmDependsJavaParser.cxx" break; case 274: /* MethodInvocation: jp_THIS jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */ @@ -5440,7 +5452,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5444 "cmDependsJavaParser.cxx" +#line 5456 "cmDependsJavaParser.cxx" break; case 275: /* ArrayAccess: Name jp_BRACKETSTART Expression jp_BRACKETEND */ @@ -5453,7 +5465,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5457 "cmDependsJavaParser.cxx" +#line 5469 "cmDependsJavaParser.cxx" break; case 276: /* ArrayAccess: PrimaryNoNewArray jp_BRACKETSTART Expression jp_BRACKETEND */ @@ -5465,7 +5477,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5469 "cmDependsJavaParser.cxx" +#line 5481 "cmDependsJavaParser.cxx" break; case 277: /* PostfixExpression: Primary */ @@ -5477,7 +5489,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5481 "cmDependsJavaParser.cxx" +#line 5493 "cmDependsJavaParser.cxx" break; case 278: /* PostfixExpression: Name */ @@ -5489,7 +5501,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5493 "cmDependsJavaParser.cxx" +#line 5505 "cmDependsJavaParser.cxx" break; case 279: /* PostfixExpression: ArrayType jp_DOT jp_CLASS */ @@ -5501,7 +5513,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5505 "cmDependsJavaParser.cxx" +#line 5517 "cmDependsJavaParser.cxx" break; case 280: /* PostfixExpression: PostIncrementExpression */ @@ -5513,7 +5525,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5517 "cmDependsJavaParser.cxx" +#line 5529 "cmDependsJavaParser.cxx" break; case 281: /* PostfixExpression: PostDecrementExpression */ @@ -5525,7 +5537,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5529 "cmDependsJavaParser.cxx" +#line 5541 "cmDependsJavaParser.cxx" break; case 282: /* PostIncrementExpression: PostfixExpression jp_PLUSPLUS */ @@ -5537,7 +5549,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5541 "cmDependsJavaParser.cxx" +#line 5553 "cmDependsJavaParser.cxx" break; case 283: /* PostDecrementExpression: PostfixExpression jp_MINUSMINUS */ @@ -5549,7 +5561,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5553 "cmDependsJavaParser.cxx" +#line 5565 "cmDependsJavaParser.cxx" break; case 284: /* UnaryExpression: PreIncrementExpression */ @@ -5561,7 +5573,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5565 "cmDependsJavaParser.cxx" +#line 5577 "cmDependsJavaParser.cxx" break; case 285: /* UnaryExpression: PreDecrementExpression */ @@ -5573,7 +5585,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5577 "cmDependsJavaParser.cxx" +#line 5589 "cmDependsJavaParser.cxx" break; case 286: /* UnaryExpression: jp_PLUS UnaryExpression */ @@ -5585,7 +5597,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5589 "cmDependsJavaParser.cxx" +#line 5601 "cmDependsJavaParser.cxx" break; case 287: /* UnaryExpression: jp_MINUS UnaryExpression */ @@ -5597,7 +5609,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5601 "cmDependsJavaParser.cxx" +#line 5613 "cmDependsJavaParser.cxx" break; case 288: /* UnaryExpression: UnaryExpressionNotPlusMinus */ @@ -5609,7 +5621,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5613 "cmDependsJavaParser.cxx" +#line 5625 "cmDependsJavaParser.cxx" break; case 289: /* PreIncrementExpression: jp_PLUSPLUS UnaryExpression */ @@ -5621,7 +5633,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5625 "cmDependsJavaParser.cxx" +#line 5637 "cmDependsJavaParser.cxx" break; case 290: /* PreDecrementExpression: jp_MINUSMINUS UnaryExpression */ @@ -5633,7 +5645,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5637 "cmDependsJavaParser.cxx" +#line 5649 "cmDependsJavaParser.cxx" break; case 291: /* UnaryExpressionNotPlusMinus: PostfixExpression */ @@ -5645,7 +5657,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5649 "cmDependsJavaParser.cxx" +#line 5661 "cmDependsJavaParser.cxx" break; case 292: /* UnaryExpressionNotPlusMinus: jp_TILDE UnaryExpression */ @@ -5657,7 +5669,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5661 "cmDependsJavaParser.cxx" +#line 5673 "cmDependsJavaParser.cxx" break; case 293: /* UnaryExpressionNotPlusMinus: jp_EXCLAMATION UnaryExpression */ @@ -5669,7 +5681,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5673 "cmDependsJavaParser.cxx" +#line 5685 "cmDependsJavaParser.cxx" break; case 294: /* UnaryExpressionNotPlusMinus: CastExpression */ @@ -5681,7 +5693,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5685 "cmDependsJavaParser.cxx" +#line 5697 "cmDependsJavaParser.cxx" break; case 295: /* CastExpression: jp_PARESTART PrimitiveType Dimsopt jp_PAREEND UnaryExpression */ @@ -5693,7 +5705,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5697 "cmDependsJavaParser.cxx" +#line 5709 "cmDependsJavaParser.cxx" break; case 296: /* CastExpression: jp_PARESTART Expression jp_PAREEND UnaryExpressionNotPlusMinus */ @@ -5705,7 +5717,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5709 "cmDependsJavaParser.cxx" +#line 5721 "cmDependsJavaParser.cxx" break; case 297: /* CastExpression: jp_PARESTART Name Dims jp_PAREEND UnaryExpressionNotPlusMinus */ @@ -5714,7 +5726,7 @@ yyreduce: jpElementStart(5); } -#line 5718 "cmDependsJavaParser.cxx" +#line 5730 "cmDependsJavaParser.cxx" break; case 298: /* MultiplicativeExpression: UnaryExpression */ @@ -5726,7 +5738,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5730 "cmDependsJavaParser.cxx" +#line 5742 "cmDependsJavaParser.cxx" break; case 299: /* MultiplicativeExpression: MultiplicativeExpression jp_TIMES UnaryExpression */ @@ -5738,7 +5750,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5742 "cmDependsJavaParser.cxx" +#line 5754 "cmDependsJavaParser.cxx" break; case 300: /* MultiplicativeExpression: MultiplicativeExpression jp_DIVIDE UnaryExpression */ @@ -5750,7 +5762,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5754 "cmDependsJavaParser.cxx" +#line 5766 "cmDependsJavaParser.cxx" break; case 301: /* MultiplicativeExpression: MultiplicativeExpression jp_PERCENT UnaryExpression */ @@ -5762,7 +5774,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5766 "cmDependsJavaParser.cxx" +#line 5778 "cmDependsJavaParser.cxx" break; case 302: /* AdditiveExpression: MultiplicativeExpression */ @@ -5774,7 +5786,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5778 "cmDependsJavaParser.cxx" +#line 5790 "cmDependsJavaParser.cxx" break; case 303: /* AdditiveExpression: AdditiveExpression jp_PLUS MultiplicativeExpression */ @@ -5786,7 +5798,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5790 "cmDependsJavaParser.cxx" +#line 5802 "cmDependsJavaParser.cxx" break; case 304: /* AdditiveExpression: AdditiveExpression jp_MINUS MultiplicativeExpression */ @@ -5798,7 +5810,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5802 "cmDependsJavaParser.cxx" +#line 5814 "cmDependsJavaParser.cxx" break; case 305: /* ShiftExpression: AdditiveExpression */ @@ -5810,7 +5822,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5814 "cmDependsJavaParser.cxx" +#line 5826 "cmDependsJavaParser.cxx" break; case 306: /* ShiftExpression: ShiftExpression jp_LTLT AdditiveExpression */ @@ -5822,7 +5834,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5826 "cmDependsJavaParser.cxx" +#line 5838 "cmDependsJavaParser.cxx" break; case 307: /* ShiftExpression: ShiftExpression jp_GTGT AdditiveExpression */ @@ -5834,7 +5846,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5838 "cmDependsJavaParser.cxx" +#line 5850 "cmDependsJavaParser.cxx" break; case 308: /* ShiftExpression: ShiftExpression jp_GTGTGT AdditiveExpression */ @@ -5846,7 +5858,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5850 "cmDependsJavaParser.cxx" +#line 5862 "cmDependsJavaParser.cxx" break; case 309: /* RelationalExpression: ShiftExpression */ @@ -5858,7 +5870,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5862 "cmDependsJavaParser.cxx" +#line 5874 "cmDependsJavaParser.cxx" break; case 310: /* RelationalExpression: RelationalExpression jp_LESSTHAN ShiftExpression */ @@ -5870,7 +5882,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5874 "cmDependsJavaParser.cxx" +#line 5886 "cmDependsJavaParser.cxx" break; case 311: /* RelationalExpression: RelationalExpression jp_GREATER ShiftExpression */ @@ -5882,7 +5894,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5886 "cmDependsJavaParser.cxx" +#line 5898 "cmDependsJavaParser.cxx" break; case 312: /* RelationalExpression: RelationalExpression jp_LTEQUALS ShiftExpression */ @@ -5894,7 +5906,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5898 "cmDependsJavaParser.cxx" +#line 5910 "cmDependsJavaParser.cxx" break; case 313: /* RelationalExpression: RelationalExpression jp_GTEQUALS ShiftExpression */ @@ -5906,7 +5918,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5910 "cmDependsJavaParser.cxx" +#line 5922 "cmDependsJavaParser.cxx" break; case 314: /* RelationalExpression: RelationalExpression jp_INSTANCEOF ReferenceType */ @@ -5918,7 +5930,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5922 "cmDependsJavaParser.cxx" +#line 5934 "cmDependsJavaParser.cxx" break; case 315: /* EqualityExpression: RelationalExpression */ @@ -5930,7 +5942,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5934 "cmDependsJavaParser.cxx" +#line 5946 "cmDependsJavaParser.cxx" break; case 316: /* EqualityExpression: EqualityExpression jp_EQUALSEQUALS RelationalExpression */ @@ -5942,7 +5954,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5946 "cmDependsJavaParser.cxx" +#line 5958 "cmDependsJavaParser.cxx" break; case 317: /* EqualityExpression: EqualityExpression jp_EXCLAMATIONEQUALS RelationalExpression */ @@ -5954,7 +5966,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5958 "cmDependsJavaParser.cxx" +#line 5970 "cmDependsJavaParser.cxx" break; case 318: /* AndExpression: EqualityExpression */ @@ -5966,7 +5978,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5970 "cmDependsJavaParser.cxx" +#line 5982 "cmDependsJavaParser.cxx" break; case 319: /* AndExpression: AndExpression jp_AND EqualityExpression */ @@ -5978,7 +5990,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5982 "cmDependsJavaParser.cxx" +#line 5994 "cmDependsJavaParser.cxx" break; case 320: /* ExclusiveOrExpression: AndExpression */ @@ -5990,7 +6002,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5994 "cmDependsJavaParser.cxx" +#line 6006 "cmDependsJavaParser.cxx" break; case 321: /* ExclusiveOrExpression: ExclusiveOrExpression jp_CARROT AndExpression */ @@ -6002,7 +6014,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6006 "cmDependsJavaParser.cxx" +#line 6018 "cmDependsJavaParser.cxx" break; case 322: /* InclusiveOrExpression: ExclusiveOrExpression */ @@ -6014,7 +6026,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6018 "cmDependsJavaParser.cxx" +#line 6030 "cmDependsJavaParser.cxx" break; case 323: /* InclusiveOrExpression: InclusiveOrExpression jp_PIPE ExclusiveOrExpression */ @@ -6026,7 +6038,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6030 "cmDependsJavaParser.cxx" +#line 6042 "cmDependsJavaParser.cxx" break; case 324: /* ConditionalAndExpression: InclusiveOrExpression */ @@ -6038,7 +6050,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6042 "cmDependsJavaParser.cxx" +#line 6054 "cmDependsJavaParser.cxx" break; case 325: /* ConditionalAndExpression: ConditionalAndExpression jp_ANDAND InclusiveOrExpression */ @@ -6050,7 +6062,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6054 "cmDependsJavaParser.cxx" +#line 6066 "cmDependsJavaParser.cxx" break; case 326: /* ConditionalOrExpression: ConditionalAndExpression */ @@ -6062,7 +6074,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6066 "cmDependsJavaParser.cxx" +#line 6078 "cmDependsJavaParser.cxx" break; case 327: /* ConditionalOrExpression: ConditionalOrExpression jp_PIPEPIPE ConditionalAndExpression */ @@ -6074,7 +6086,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6078 "cmDependsJavaParser.cxx" +#line 6090 "cmDependsJavaParser.cxx" break; case 328: /* ConditionalExpression: ConditionalOrExpression */ @@ -6086,7 +6098,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6090 "cmDependsJavaParser.cxx" +#line 6102 "cmDependsJavaParser.cxx" break; case 329: /* ConditionalExpression: ConditionalOrExpression jp_QUESTION Expression jp_COLON ConditionalExpression */ @@ -6098,7 +6110,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6102 "cmDependsJavaParser.cxx" +#line 6114 "cmDependsJavaParser.cxx" break; case 330: /* AssignmentExpression: ConditionalExpression */ @@ -6110,7 +6122,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6114 "cmDependsJavaParser.cxx" +#line 6126 "cmDependsJavaParser.cxx" break; case 331: /* AssignmentExpression: Assignment */ @@ -6122,7 +6134,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6126 "cmDependsJavaParser.cxx" +#line 6138 "cmDependsJavaParser.cxx" break; case 332: /* Assignment: LeftHandSide AssignmentOperator AssignmentExpression */ @@ -6134,7 +6146,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6138 "cmDependsJavaParser.cxx" +#line 6150 "cmDependsJavaParser.cxx" break; case 333: /* LeftHandSide: Name */ @@ -6147,7 +6159,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6151 "cmDependsJavaParser.cxx" +#line 6163 "cmDependsJavaParser.cxx" break; case 334: /* LeftHandSide: FieldAccess */ @@ -6159,7 +6171,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6163 "cmDependsJavaParser.cxx" +#line 6175 "cmDependsJavaParser.cxx" break; case 335: /* LeftHandSide: ArrayAccess */ @@ -6171,7 +6183,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6175 "cmDependsJavaParser.cxx" +#line 6187 "cmDependsJavaParser.cxx" break; case 336: /* AssignmentOperator: jp_EQUALS */ @@ -6183,7 +6195,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6187 "cmDependsJavaParser.cxx" +#line 6199 "cmDependsJavaParser.cxx" break; case 337: /* AssignmentOperator: jp_TIMESEQUALS */ @@ -6195,7 +6207,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6199 "cmDependsJavaParser.cxx" +#line 6211 "cmDependsJavaParser.cxx" break; case 338: /* AssignmentOperator: jp_DIVIDEEQUALS */ @@ -6207,7 +6219,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6211 "cmDependsJavaParser.cxx" +#line 6223 "cmDependsJavaParser.cxx" break; case 339: /* AssignmentOperator: jp_PERCENTEQUALS */ @@ -6219,7 +6231,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6223 "cmDependsJavaParser.cxx" +#line 6235 "cmDependsJavaParser.cxx" break; case 340: /* AssignmentOperator: jp_PLUSEQUALS */ @@ -6231,7 +6243,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6235 "cmDependsJavaParser.cxx" +#line 6247 "cmDependsJavaParser.cxx" break; case 341: /* AssignmentOperator: jp_MINUSEQUALS */ @@ -6243,7 +6255,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6247 "cmDependsJavaParser.cxx" +#line 6259 "cmDependsJavaParser.cxx" break; case 342: /* AssignmentOperator: jp_LESLESEQUALS */ @@ -6255,7 +6267,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6259 "cmDependsJavaParser.cxx" +#line 6271 "cmDependsJavaParser.cxx" break; case 343: /* AssignmentOperator: jp_GTGTEQUALS */ @@ -6267,7 +6279,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6271 "cmDependsJavaParser.cxx" +#line 6283 "cmDependsJavaParser.cxx" break; case 344: /* AssignmentOperator: jp_GTGTGTEQUALS */ @@ -6279,7 +6291,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6283 "cmDependsJavaParser.cxx" +#line 6295 "cmDependsJavaParser.cxx" break; case 345: /* AssignmentOperator: jp_ANDEQUALS */ @@ -6291,7 +6303,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6295 "cmDependsJavaParser.cxx" +#line 6307 "cmDependsJavaParser.cxx" break; case 346: /* AssignmentOperator: jp_CARROTEQUALS */ @@ -6303,7 +6315,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6307 "cmDependsJavaParser.cxx" +#line 6319 "cmDependsJavaParser.cxx" break; case 347: /* AssignmentOperator: jp_PIPEEQUALS */ @@ -6315,7 +6327,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6319 "cmDependsJavaParser.cxx" +#line 6331 "cmDependsJavaParser.cxx" break; case 348: /* Expression: AssignmentExpression */ @@ -6327,7 +6339,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6331 "cmDependsJavaParser.cxx" +#line 6343 "cmDependsJavaParser.cxx" break; case 349: /* ConstantExpression: Expression */ @@ -6339,7 +6351,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6343 "cmDependsJavaParser.cxx" +#line 6355 "cmDependsJavaParser.cxx" break; case 350: /* New: jp_NEW */ @@ -6351,7 +6363,7 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6355 "cmDependsJavaParser.cxx" +#line 6367 "cmDependsJavaParser.cxx" break; case 351: /* New: Name jp_DOT jp_NEW */ @@ -6364,11 +6376,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6368 "cmDependsJavaParser.cxx" +#line 6380 "cmDependsJavaParser.cxx" break; -#line 6372 "cmDependsJavaParser.cxx" +#line 6384 "cmDependsJavaParser.cxx" default: break; } diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h index 4ae55fa..885cc66 100644 --- a/Source/LexerParser/cmDependsJavaParserTokens.h +++ b/Source/LexerParser/cmDependsJavaParserTokens.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx index b747d8b..d9b0ae3 100644 --- a/Source/LexerParser/cmExprParser.cxx +++ b/Source/LexerParser/cmExprParser.cxx @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30705 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.7.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -120,7 +120,11 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message); # endif #endif -#line 124 "cmExprParser.cxx" +#if defined(__NVCOMPILER) +# pragma diag_suppress 550 /* variable set but never used */ +#endif + +#line 128 "cmExprParser.cxx" # ifndef YY_CAST # ifdef __cplusplus @@ -218,6 +222,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -315,9 +331,9 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ @@ -544,9 +560,9 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 81, 81, 86, 89, 94, 97, 102, 105, 110, - 113, 116, 121, 124, 127, 132, 135, 138, 144, 149, - 152, 155, 158, 163, 166 + 0, 85, 85, 90, 93, 98, 101, 106, 109, 114, + 117, 120, 125, 128, 131, 136, 139, 142, 148, 153, + 156, 159, 162, 167, 170 }; #endif @@ -629,7 +645,7 @@ static const yytype_int8 yypgoto[] = /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 6, 7, 8, 9, 10, 11, 12, 13, 14 + 0, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -754,8 +770,8 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (yyscanner); + YY_USE (yyoutput); + YY_USE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT @@ -763,7 +779,7 @@ yy_symbol_value_print (FILE *yyo, YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1144,14 +1160,14 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner) { - YYUSE (yyvaluep); - YYUSE (yyscanner); + YY_USE (yyvaluep); + YY_USE (yyscanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1421,194 +1437,194 @@ yyreduce: switch (yyn) { case 2: /* start: exp */ -#line 81 "cmExprParser.y" +#line 85 "cmExprParser.y" { cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number)); } -#line 1429 "cmExprParser.cxx" +#line 1445 "cmExprParser.cxx" break; case 3: /* exp: bitwiseor */ -#line 86 "cmExprParser.y" +#line 90 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1437 "cmExprParser.cxx" +#line 1453 "cmExprParser.cxx" break; case 4: /* exp: exp exp_OR bitwiseor */ -#line 89 "cmExprParser.y" +#line 93 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number); } -#line 1445 "cmExprParser.cxx" +#line 1461 "cmExprParser.cxx" break; case 5: /* bitwiseor: bitwisexor */ -#line 94 "cmExprParser.y" +#line 98 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1453 "cmExprParser.cxx" +#line 1469 "cmExprParser.cxx" break; case 6: /* bitwiseor: bitwiseor exp_XOR bitwisexor */ -#line 97 "cmExprParser.y" +#line 101 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number); } -#line 1461 "cmExprParser.cxx" +#line 1477 "cmExprParser.cxx" break; case 7: /* bitwisexor: bitwiseand */ -#line 102 "cmExprParser.y" +#line 106 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1469 "cmExprParser.cxx" +#line 1485 "cmExprParser.cxx" break; case 8: /* bitwisexor: bitwisexor exp_AND bitwiseand */ -#line 105 "cmExprParser.y" +#line 109 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number); } -#line 1477 "cmExprParser.cxx" +#line 1493 "cmExprParser.cxx" break; case 9: /* bitwiseand: shift */ -#line 110 "cmExprParser.y" +#line 114 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1485 "cmExprParser.cxx" +#line 1501 "cmExprParser.cxx" break; case 10: /* bitwiseand: bitwiseand exp_SHIFTLEFT shift */ -#line 113 "cmExprParser.y" +#line 117 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number); } -#line 1493 "cmExprParser.cxx" +#line 1509 "cmExprParser.cxx" break; case 11: /* bitwiseand: bitwiseand exp_SHIFTRIGHT shift */ -#line 116 "cmExprParser.y" +#line 120 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number); } -#line 1501 "cmExprParser.cxx" +#line 1517 "cmExprParser.cxx" break; case 12: /* shift: term */ -#line 121 "cmExprParser.y" +#line 125 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1509 "cmExprParser.cxx" +#line 1525 "cmExprParser.cxx" break; case 13: /* shift: shift exp_PLUS term */ -#line 124 "cmExprParser.y" +#line 128 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number); } -#line 1517 "cmExprParser.cxx" +#line 1533 "cmExprParser.cxx" break; case 14: /* shift: shift exp_MINUS term */ -#line 127 "cmExprParser.y" +#line 131 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number); } -#line 1525 "cmExprParser.cxx" +#line 1541 "cmExprParser.cxx" break; case 15: /* term: unary */ -#line 132 "cmExprParser.y" +#line 136 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1533 "cmExprParser.cxx" +#line 1549 "cmExprParser.cxx" break; case 16: /* term: term exp_TIMES unary */ -#line 135 "cmExprParser.y" +#line 139 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number); } -#line 1541 "cmExprParser.cxx" +#line 1557 "cmExprParser.cxx" break; case 17: /* term: term exp_DIVIDE unary */ -#line 138 "cmExprParser.y" +#line 142 "cmExprParser.y" { if (yyvsp[0].Number == 0) { throw std::overflow_error("divide by zero"); } (yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number); } -#line 1552 "cmExprParser.cxx" +#line 1568 "cmExprParser.cxx" break; case 18: /* term: term exp_MOD unary */ -#line 144 "cmExprParser.y" +#line 148 "cmExprParser.y" { (yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number); } -#line 1560 "cmExprParser.cxx" +#line 1576 "cmExprParser.cxx" break; case 19: /* unary: factor */ -#line 149 "cmExprParser.y" +#line 153 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1568 "cmExprParser.cxx" +#line 1584 "cmExprParser.cxx" break; case 20: /* unary: exp_PLUS unary */ -#line 152 "cmExprParser.y" +#line 156 "cmExprParser.y" { (yyval.Number) = + (yyvsp[0].Number); } -#line 1576 "cmExprParser.cxx" +#line 1592 "cmExprParser.cxx" break; case 21: /* unary: exp_MINUS unary */ -#line 155 "cmExprParser.y" +#line 159 "cmExprParser.y" { (yyval.Number) = - (yyvsp[0].Number); } -#line 1584 "cmExprParser.cxx" +#line 1600 "cmExprParser.cxx" break; case 22: /* unary: exp_NOT unary */ -#line 158 "cmExprParser.y" +#line 162 "cmExprParser.y" { (yyval.Number) = ~ (yyvsp[0].Number); } -#line 1592 "cmExprParser.cxx" +#line 1608 "cmExprParser.cxx" break; case 23: /* factor: exp_NUMBER */ -#line 163 "cmExprParser.y" +#line 167 "cmExprParser.y" { (yyval.Number) = (yyvsp[0].Number); } -#line 1600 "cmExprParser.cxx" +#line 1616 "cmExprParser.cxx" break; case 24: /* factor: exp_OPENPARENT exp exp_CLOSEPARENT */ -#line 166 "cmExprParser.y" +#line 170 "cmExprParser.y" { (yyval.Number) = (yyvsp[-1].Number); } -#line 1608 "cmExprParser.cxx" +#line 1624 "cmExprParser.cxx" break; -#line 1612 "cmExprParser.cxx" +#line 1628 "cmExprParser.cxx" default: break; } @@ -1833,7 +1849,7 @@ yyreturn: return yyresult; } -#line 171 "cmExprParser.y" +#line 175 "cmExprParser.y" /* End of grammar */ diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y index b49f482..fda2395 100644 --- a/Source/LexerParser/cmExprParser.y +++ b/Source/LexerParser/cmExprParser.y @@ -44,6 +44,10 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message); # pragma clang diagnostic ignored "-Wused-but-marked-unused" # endif #endif + +#if defined(__NVCOMPILER) +# pragma diag_suppress 550 /* variable set but never used */ +#endif %} /* Generate a reentrant parser object. */ diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h index 2eb1fe9..67b03de 100644 --- a/Source/LexerParser/cmExprParserTokens.h +++ b/Source/LexerParser/cmExprParserTokens.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx index dba2cac..0ea3d97 100644 --- a/Source/LexerParser/cmFortranParser.cxx +++ b/Source/LexerParser/cmFortranParser.cxx @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30705 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.7.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -259,6 +259,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -356,9 +368,9 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ @@ -701,7 +713,7 @@ static const yytype_int8 yypgoto[] = /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 32, 33, 34, 35, 36, 37, 38, 39, + 0, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 44, 82 }; @@ -955,8 +967,8 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (yyscanner); + YY_USE (yyoutput); + YY_USE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT @@ -964,7 +976,7 @@ yy_symbol_value_print (FILE *yyo, YYPRINT (yyo, yytoknum[yykind], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1345,14 +1357,14 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, yyscan_t yyscanner) { - YYUSE (yyvaluep); - YYUSE (yyscanner); + YY_USE (yyvaluep); + YY_USE (yyscanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1627,7 +1639,7 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_SetInInterface(parser, true); } -#line 1631 "cmFortranParser.cxx" +#line 1643 "cmFortranParser.cxx" break; case 5: /* stmt: USE WORD other EOSTMT */ @@ -1637,7 +1649,7 @@ yyreduce: cmFortranParser_RuleUse(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1641 "cmFortranParser.cxx" +#line 1653 "cmFortranParser.cxx" break; case 6: /* stmt: MODULE WORD other EOSTMT */ @@ -1651,7 +1663,7 @@ yyreduce: } free((yyvsp[-2].string)); } -#line 1655 "cmFortranParser.cxx" +#line 1667 "cmFortranParser.cxx" break; case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT */ @@ -1662,7 +1674,7 @@ yyreduce: free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1666 "cmFortranParser.cxx" +#line 1678 "cmFortranParser.cxx" break; case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT */ @@ -1674,7 +1686,7 @@ yyreduce: free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1678 "cmFortranParser.cxx" +#line 1690 "cmFortranParser.cxx" break; case 9: /* stmt: INTERFACE WORD other EOSTMT */ @@ -1684,7 +1696,7 @@ yyreduce: cmFortranParser_SetInInterface(parser, true); free((yyvsp[-2].string)); } -#line 1688 "cmFortranParser.cxx" +#line 1700 "cmFortranParser.cxx" break; case 10: /* stmt: END INTERFACE other EOSTMT */ @@ -1693,7 +1705,7 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_SetInInterface(parser, false); } -#line 1697 "cmFortranParser.cxx" +#line 1709 "cmFortranParser.cxx" break; case 11: /* stmt: USE DCOLON WORD other EOSTMT */ @@ -1703,7 +1715,7 @@ yyreduce: cmFortranParser_RuleUse(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1707 "cmFortranParser.cxx" +#line 1719 "cmFortranParser.cxx" break; case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT */ @@ -1716,7 +1728,7 @@ yyreduce: free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1720 "cmFortranParser.cxx" +#line 1732 "cmFortranParser.cxx" break; case 13: /* stmt: INCLUDE STRING other EOSTMT */ @@ -1726,7 +1738,7 @@ yyreduce: cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1730 "cmFortranParser.cxx" +#line 1742 "cmFortranParser.cxx" break; case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */ @@ -1736,7 +1748,7 @@ yyreduce: cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1740 "cmFortranParser.cxx" +#line 1752 "cmFortranParser.cxx" break; case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */ @@ -1746,7 +1758,7 @@ yyreduce: cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1750 "cmFortranParser.cxx" +#line 1762 "cmFortranParser.cxx" break; case 16: /* stmt: include STRING other EOSTMT */ @@ -1756,7 +1768,7 @@ yyreduce: cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1760 "cmFortranParser.cxx" +#line 1772 "cmFortranParser.cxx" break; case 17: /* stmt: define WORD other EOSTMT */ @@ -1766,7 +1778,7 @@ yyreduce: cmFortranParser_RuleDefine(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1770 "cmFortranParser.cxx" +#line 1782 "cmFortranParser.cxx" break; case 18: /* stmt: undef WORD other EOSTMT */ @@ -1776,7 +1788,7 @@ yyreduce: cmFortranParser_RuleUndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1780 "cmFortranParser.cxx" +#line 1792 "cmFortranParser.cxx" break; case 19: /* stmt: ifdef WORD other EOSTMT */ @@ -1786,7 +1798,7 @@ yyreduce: cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1790 "cmFortranParser.cxx" +#line 1802 "cmFortranParser.cxx" break; case 20: /* stmt: ifndef WORD other EOSTMT */ @@ -1796,7 +1808,7 @@ yyreduce: cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1800 "cmFortranParser.cxx" +#line 1812 "cmFortranParser.cxx" break; case 21: /* stmt: if other EOSTMT */ @@ -1805,7 +1817,7 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIf(parser); } -#line 1809 "cmFortranParser.cxx" +#line 1821 "cmFortranParser.cxx" break; case 22: /* stmt: elif other EOSTMT */ @@ -1814,7 +1826,7 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElif(parser); } -#line 1818 "cmFortranParser.cxx" +#line 1830 "cmFortranParser.cxx" break; case 23: /* stmt: else other EOSTMT */ @@ -1823,7 +1835,7 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElse(parser); } -#line 1827 "cmFortranParser.cxx" +#line 1839 "cmFortranParser.cxx" break; case 24: /* stmt: endif other EOSTMT */ @@ -1832,23 +1844,23 @@ yyreduce: cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleEndif(parser); } -#line 1836 "cmFortranParser.cxx" +#line 1848 "cmFortranParser.cxx" break; case 48: /* misc_code: WORD */ #line 229 "cmFortranParser.y" { free ((yyvsp[0].string)); } -#line 1842 "cmFortranParser.cxx" +#line 1854 "cmFortranParser.cxx" break; case 55: /* misc_code: STRING */ #line 236 "cmFortranParser.y" { free ((yyvsp[0].string)); } -#line 1848 "cmFortranParser.cxx" +#line 1860 "cmFortranParser.cxx" break; -#line 1852 "cmFortranParser.cxx" +#line 1864 "cmFortranParser.cxx" default: break; } diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h index e250110..3a19cfb 100644 --- a/Source/LexerParser/cmFortranParserTokens.h +++ b/Source/LexerParser/cmFortranParserTokens.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.7.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify diff --git a/Source/Modules/FindLibUUID.cmake b/Source/Modules/FindLibUUID.cmake index 17f11c1..ca5b61d 100644 --- a/Source/Modules/FindLibUUID.cmake +++ b/Source/Modules/FindLibUUID.cmake @@ -40,7 +40,14 @@ They may be set by end users to point at LibUUID components. #]=======================================================================] #----------------------------------------------------------------------------- -if(CYGWIN) +if(MSYS) + # Note: on current version of MSYS2, linking to libuuid.dll.a doesn't + # import the right symbols sometimes. Fix this by linking directly + # to the DLL that provides the symbols, instead. + find_library(LibUUID_LIBRARY + NAMES msys-uuid-1.dll + ) +elseif(CYGWIN) # Note: on current version of Cygwin, linking to libuuid.dll.a doesn't # import the right symbols sometimes. Fix this by linking directly # to the DLL that provides the symbols, instead. diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 5debdb8..8ffa3e7 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -112,7 +112,10 @@ int main(int argc, char** argv) cmAddPluginPath(); #endif -#if QT_VERSION >= 0x050600 +// HighDpiScaling is always enabled starting with Qt6, but will still issue a +// deprecation warning if you try to set the attribute for it +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && \ + QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif @@ -132,9 +135,9 @@ int main(int argc, char** argv) translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR)); translationsDir.cd("i18n"); QTranslator translator; - QString transfile = QString("cmake_%1").arg(QLocale::system().name()); - translator.load(transfile, translationsDir.path()); - QApplication::installTranslator(&translator); + if (translator.load(QLocale(), "cmake", "_", translationsDir.path())) { + QApplication::installTranslator(&translator); + } // app setup QApplication::setApplicationName("CMakeSetup"); diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 0313088..1785571 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -178,7 +178,11 @@ CMakeSetupDialog::CMakeSetupDialog() &CMakeSetupDialog::doOutputErrorNext); a->setShortcut(QKeySequence(Qt::Key_F8)); auto* s = new QShortcut(this); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) s->setKey(QKeySequence(Qt::CTRL + Qt::Key_Period)); +#else + s->setKey(QKeySequence(Qt::CTRL | Qt::Key_Period)); +#endif QObject::connect(s, &QShortcut::activated, this, &CMakeSetupDialog::doOutputErrorNext); // in Eclipse diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index f593f83..e6faef4 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -13,6 +13,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmGlobalGenerator.h" +#include "cmMessageMetadata.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -37,8 +38,8 @@ QCMake::QCMake(QObject* p) cmSystemTools::SetRunCommandHideConsole(true); cmSystemTools::SetMessageCallback( - [this](std::string const& msg, const char* title) { - this->messageCallback(msg, title); + [this](std::string const& msg, const cmMessageMetadata& md) { + this->messageCallback(msg, md.title); }); cmSystemTools::SetStdoutCallback( [this](std::string const& msg) { this->stdoutCallback(msg); }); @@ -160,7 +161,7 @@ void QCMake::setPreset(const QString& name, bool setBinary) auto const& expandedPreset = this->CMakePresetsFile.ConfigurePresets[presetName].Expanded; if (expandedPreset) { - if (setBinary) { + if (setBinary && !expandedPreset->BinaryDir.empty()) { QString binaryDir = QString::fromLocal8Bit(expandedPreset->BinaryDir.data()); this->setBinaryDirectory(binaryDir); @@ -334,7 +335,12 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) toremove.append(QString::fromLocal8Bit(key.c_str())); } else { prop = props[idx]; - if (prop.Value.type() == QVariant::Bool) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + const bool isBool = prop.Value.type() == QVariant::Bool; +#else + const bool isBool = prop.Value.metaType() == QMetaType::fromType<bool>(); +#endif + if (isBool) { state->SetCacheEntryValue(key, prop.Value.toBool() ? "ON" : "OFF"); } else { state->SetCacheEntryValue(key, @@ -557,7 +563,7 @@ void QCMake::loadPresets() preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data())); preset.setToolset = !p.ToolsetStrategy || p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; - preset.enabled = it.Expanded && + preset.enabled = it.Expanded && it.Expanded->ConditionResult && std::find_if(this->AvailableGenerators.begin(), this->AvailableGenerators.end(), [&p](const cmake::GeneratorInfo& g) { diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index b685b73..54b2998 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -2,11 +2,16 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmArchiveWrite.h" -#include <cstdio> +#include <cstdlib> #include <cstring> #include <ctime> #include <iostream> +#include <limits> #include <sstream> +#include <string> +#include <thread> + +#include <cm/algorithm> #include <cm3p/archive.h> #include <cm3p/archive_entry.h> @@ -144,16 +149,36 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, cm_archive_error_string(this->Archive)); return; } + { - char sNumThreads[8]; - snprintf(sNumThreads, sizeof(sNumThreads), "%d", numThreads); - sNumThreads[7] = '\0'; // for safety +#if ARCHIVE_VERSION_NUMBER >= 3004000 + // Upstream fixed an issue with their integer parsing in 3.4.0 + // which would cause spurious errors to be raised from `strtoull`. + + if (numThreads < 1) { + int upperLimit = (numThreads == 0) ? std::numeric_limits<int>::max() + : std::abs(numThreads); + + numThreads = + cm::clamp<int>(std::thread::hardware_concurrency(), 1, upperLimit); + } + +# ifdef _AIX + // FIXME: Using more than 2 threads creates an empty archive. + // Enforce this limit pending further investigation. + numThreads = std::min(numThreads, 2); +# endif + + std::string sNumThreads = std::to_string(numThreads); + if (archive_write_set_filter_option(this->Archive, "xz", "threads", - sNumThreads) != ARCHIVE_OK) { + sNumThreads.c_str()) != + ARCHIVE_OK) { this->Error = cmStrCat("archive_compressor_xz_options: ", cm_archive_error_string(this->Archive)); return; } +#endif } break; @@ -425,16 +450,3 @@ bool cmArchiveWrite::AddData(const char* file, size_t size) } return true; } - -bool cmArchiveWrite::SetFilterOption(const char* module, const char* key, - const char* value) -{ - if (archive_write_set_filter_option(this->Archive, module, key, value) != - ARCHIVE_OK) { - this->Error = "archive_write_set_filter_option: "; - this->Error += cm_archive_error_string(this->Archive); - return false; - } - - return true; -} diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 34aafe9..260bd20 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -141,9 +141,6 @@ public: this->Gname = ""; } - //! Set an option on a filter; - bool SetFilterOption(const char* module, const char* key, const char* value); - private: bool Okay() const { return this->Error.empty(); } bool AddPath(const char* path, size_t skip, const char* prefix, diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 2eaf315..56b080a 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -28,12 +28,14 @@ bool MainSignature(std::vector<std::string> const& args, std::string configuration; std::string project_name; std::string target; + std::string parallel; enum Doing { DoingNone, DoingConfiguration, DoingProjectName, - DoingTarget + DoingTarget, + DoingParallel }; Doing doing = DoingNone; for (unsigned int i = 1; i < args.size(); ++i) { @@ -43,6 +45,8 @@ bool MainSignature(std::vector<std::string> const& args, doing = DoingProjectName; } else if (args[i] == "TARGET") { doing = DoingTarget; + } else if (args[i] == "PARALLEL_LEVEL") { + doing = DoingParallel; } else if (doing == DoingConfiguration) { doing = DoingNone; configuration = args[i]; @@ -52,6 +56,9 @@ bool MainSignature(std::vector<std::string> const& args, } else if (doing == DoingTarget) { doing = DoingNone; target = args[i]; + } else if (doing == DoingParallel) { + doing = DoingNone; + parallel = args[i]; } else { status.SetError(cmStrCat("unknown argument \"", args[i], "\"")); return false; @@ -77,7 +84,7 @@ bool MainSignature(std::vector<std::string> const& args, } std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( - target, configuration, "", mf.IgnoreErrorsCMP0061()); + target, configuration, parallel, "", mf.IgnoreErrorsCMP0061()); mf.AddDefinition(variable, makecommand); @@ -104,7 +111,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args, } std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( - "", configType, "", mf.IgnoreErrorsCMP0061()); + "", configType, "", "", mf.IgnoreErrorsCMP0061()); if (cacheValue) { return true; diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx index 962fdcc..9a5fa7b 100644 --- a/Source/cmCMakePathCommand.cxx +++ b/Source/cmCMakePathCommand.cxx @@ -18,6 +18,7 @@ #include "cmCMakePath.h" #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmProperty.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSubcommandTable.h" @@ -149,8 +150,8 @@ public: bool getInputPath(const std::string& arg, cmExecutionStatus& status, std::string& path) { - const auto* def = status.GetMakefile().GetDefinition(arg); - if (def == nullptr) { + cmProp def = status.GetMakefile().GetDefinition(arg); + if (!def) { status.SetError("undefined variable for input path."); return false; } diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx index dda3661..2f9972c 100644 --- a/Source/cmCMakePresetsFile.cxx +++ b/Source/cmCMakePresetsFile.cxx @@ -9,28 +9,17 @@ #include <iterator> #include <utility> -#include <cmext/string_view> +#include <cm/string_view> -#include <cm3p/json/reader.h> -#include <cm3p/json/value.h> +#include "cmsys/RegularExpression.hxx" -#include "cmsys/FStream.hxx" - -#include "cmJSONHelpers.h" +#include "cmCMakePresetsFileInternal.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cmVersion.h" - -#define CHECK_OK(expr) \ - { \ - auto _result = expr; \ - if (_result != ReadFileResult::READ_OK) \ - return _result; \ - } -#define CHECK_EXPAND(out, field, expanders) \ +#define CHECK_EXPAND(out, field, expanders, version) \ { \ - switch (ExpandMacros(field, expanders)) { \ + switch (ExpandMacros(field, expanders, version)) { \ case ExpandMacroResult::Error: \ return false; \ case ExpandMacroResult::Ignore: \ @@ -50,673 +39,11 @@ enum class CycleStatus }; using ReadFileResult = cmCMakePresetsFile::ReadFileResult; -using CacheVariable = cmCMakePresetsFile::CacheVariable; using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; using BuildPreset = cmCMakePresetsFile::BuildPreset; using TestPreset = cmCMakePresetsFile::TestPreset; -using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy; - -constexpr int MIN_VERSION = 1; -constexpr int MAX_VERSION = 2; - -struct CMakeVersion -{ - unsigned int Major = 0; - unsigned int Minor = 0; - unsigned int Patch = 0; -}; - -struct RootPresets -{ - CMakeVersion CMakeMinimumRequired; - std::vector<cmCMakePresetsFile::ConfigurePreset> ConfigurePresets; - std::vector<cmCMakePresetsFile::BuildPreset> BuildPresets; - std::vector<cmCMakePresetsFile::TestPreset> TestPresets; -}; - -cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) -{ - return [error](std::nullptr_t& /*out*/, - const Json::Value* value) -> ReadFileResult { - if (!value) { - return ReadFileResult::READ_OK; - } - - if (!value->isObject()) { - return error; - } - - return ReadFileResult::READ_OK; - }; -} - -auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( - ReadFileResult::NO_VERSION, VersionIntHelper); - -auto const RootVersionHelper = - cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_ROOT) - .Bind("version"_s, VersionHelper, false); - -auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); - -ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) -{ - if (!value) { - out.clear(); - return ReadFileResult::READ_OK; - } - - if (value->isBool()) { - out = value->asBool() ? "TRUE" : "FALSE"; - return ReadFileResult::READ_OK; - } - - return VariableStringHelper(out, value); -} - -auto const VariableObjectHelper = - cmJSONObjectHelper<CacheVariable, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) - .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) - .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); - -ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, - const Json::Value* value) -{ - if (value->isBool()) { - out = CacheVariable{ - /*Type=*/"BOOL", - /*Value=*/value->asBool() ? "TRUE" : "FALSE", - }; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = CacheVariable{ - /*Type=*/"", - /*Value=*/value->asString(), - }; - return ReadFileResult::READ_OK; - } - if (value->isObject()) { - out.emplace(); - return VariableObjectHelper(*out, value); - } - if (value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_VARIABLE; -} - -auto const VariablesHelper = - cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); - -auto const PresetStringHelper = cmJSONStringHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, - const Json::Value* value) -{ - if (!value || value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = value->asString(); - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_PRESET; -} - -auto const EnvironmentMapHelper = - cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - EnvironmentHelper); - -auto const PresetVectorStringHelper = - cmJSONVectorHelper<std::string, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - PresetStringHelper); - -ReadFileResult PresetInheritsHelper(std::vector<std::string>& out, - const Json::Value* value) -{ - out.clear(); - if (!value) { - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.push_back(value->asString()); - return ReadFileResult::READ_OK; - } - - return PresetVectorStringHelper(out, value); -} - -auto const PresetBoolHelper = cmJSONBoolHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalBoolHelper = - cmJSONOptionalHelper<bool, ReadFileResult>(ReadFileResult::READ_OK, - PresetBoolHelper); - -auto const PresetIntHelper = cmJSONIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalIntHelper = cmJSONOptionalHelper<int, ReadFileResult>( - ReadFileResult::READ_OK, PresetIntHelper); - -auto const PresetVectorIntHelper = cmJSONVectorHelper<int, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); - -auto const PresetWarningsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::WarnDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, - PresetOptionalBoolHelper, false) - .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, - PresetOptionalBoolHelper, false) - .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, - PresetOptionalBoolHelper, false) - .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, - PresetOptionalBoolHelper, false); - -auto const PresetErrorsHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::ErrorDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, - PresetOptionalBoolHelper, false); - -auto const PresetDebugHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("output"_s, &ConfigurePreset::DebugOutput, PresetOptionalBoolHelper, - false) - .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, - PresetOptionalBoolHelper, false) - .Bind("find"_s, &ConfigurePreset::DebugFind, PresetOptionalBoolHelper, - false); - -ReadFileResult ArchToolsetStrategyHelper( - cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) -{ - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "set") { - out = ArchToolsetStrategy::Set; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "external") { - out = ArchToolsetStrategy::External; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)> -ArchToolsetHelper( - std::string ConfigurePreset::*valueField, - cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) -{ - auto const objectHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("value", valueField, PresetStringHelper, false) - .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); - return [valueField, strategyField, objectHelper]( - ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { - if (!value) { - (out.*valueField).clear(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.*valueField = value->asString(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return objectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; - }; -} - -auto const ArchitectureHelper = ArchToolsetHelper( - &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); -auto const ToolsetHelper = ArchToolsetHelper( - &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); - -auto const ConfigurePresetHelper = - cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &ConfigurePreset::Name, PresetStringHelper) - .Bind("inherits"_s, &ConfigurePreset::Inherits, PresetInheritsHelper, - false) - .Bind("hidden"_s, &ConfigurePreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &ConfigurePreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &ConfigurePreset::Description, PresetStringHelper, - false) - .Bind("generator"_s, &ConfigurePreset::Generator, PresetStringHelper, - false) - .Bind("architecture"_s, ArchitectureHelper, false) - .Bind("toolset"_s, ToolsetHelper, false) - .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper, - false) - .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false) - .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, - VariablesHelper, false) - .Bind("environment"_s, &ConfigurePreset::Environment, EnvironmentMapHelper, - false) - .Bind("warnings"_s, PresetWarningsHelper, false) - .Bind("errors"_s, PresetErrorsHelper, false) - .Bind("debug"_s, PresetDebugHelper, false); - -auto const BuildPresetHelper = - cmJSONObjectHelper<BuildPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &BuildPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &BuildPreset::Inherits, PresetInheritsHelper, false) - .Bind("hidden"_s, &BuildPreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &BuildPreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &BuildPreset::Description, PresetStringHelper, - false) - .Bind("environment"_s, &BuildPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &BuildPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("jobs"_s, &BuildPreset::Jobs, PresetOptionalIntHelper, false) - .Bind("targets"_s, &BuildPreset::Targets, PresetVectorStringHelper, false) - .Bind("configuration"_s, &BuildPreset::Configuration, PresetStringHelper, - false) - .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, PresetOptionalBoolHelper, - false) - .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false) - .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, - PresetVectorStringHelper, false); - -ReadFileResult TestPresetOutputVerbosityHelper( - TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) -{ - if (!value) { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "verbose") { - out = TestPreset::OutputOptions::VerbosityEnum::Verbose; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "extra") { - out = TestPreset::OutputOptions::VerbosityEnum::Extra; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalOutputVerbosityHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetOutputVerbosityHelper); - -auto const TestPresetOptionalOutputHelper = - cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, - PresetOptionalBoolHelper, false) - .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, - TestPresetOptionalOutputVerbosityHelper, false) - .Bind("debug"_s, &TestPreset::OutputOptions::Debug, - PresetOptionalBoolHelper, false) - .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, - PresetOptionalBoolHelper, false) - .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, - PresetOptionalBoolHelper, false) - .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, - PresetStringHelper, false) - .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, - PresetOptionalBoolHelper, false) - .Bind("subprojectSummary"_s, - &TestPreset::OutputOptions::SubprojectSummary, - PresetOptionalBoolHelper, false) - .Bind("maxPassedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxPassedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxFailedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxFailedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, - PresetOptionalIntHelper, false)); - -auto const TestPresetOptionalFilterIncludeIndexObjectHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, - PresetOptionalIntHelper, false) - .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, - PresetOptionalIntHelper, false) - .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, - PresetOptionalIntHelper, false) - .Bind("specificTests"_s, - &TestPreset::IncludeOptions::IndexOptions::SpecificTests, - PresetVectorIntHelper, false)); - -ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( - cm::optional<TestPreset::IncludeOptions::IndexOptions>& out, - const Json::Value* value) -{ - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.emplace(); - out->IndexFile = value->asString(); - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalFilterIncludeHelper = - cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::IncludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::IncludeOptions::Label, PresetStringHelper, - false) - .Bind("index"_s, &TestPreset::IncludeOptions::Index, - TestPresetOptionalFilterIncludeIndexHelper, false) - .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, - PresetOptionalBoolHelper, false)); - -auto const TestPresetOptionalFilterExcludeFixturesHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, - PresetStringHelper, false) - .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, - PresetStringHelper, false) - .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, - PresetStringHelper, false)); - -auto const TestPresetOptionalFilterExcludeHelper = - cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::ExcludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::ExcludeOptions::Label, PresetStringHelper, - false) - .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, - TestPresetOptionalFilterExcludeFixturesHelper, false)); - -ReadFileResult TestPresetExecutionShowOnlyHelper( - TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) -{ - if (!value || !value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "human") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "json-v1") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionShowOnlyHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionShowOnlyHelper); - -ReadFileResult TestPresetExecutionModeHelper( - TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, - const Json::Value* value) -{ - if (!value) { - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "until-fail") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "until-pass") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "after-timeout") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionRepeatHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions, - ReadFileResult>(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, - TestPresetExecutionModeHelper, true) - .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, - PresetIntHelper, true)); - -ReadFileResult TestPresetExecutionNoTestsActionHelper( - TestPreset::ExecutionOptions::NoTestsActionEnum& out, - const Json::Value* value) -{ - if (!value) { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "error") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "ignore") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionNoTestsActionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum, - ReadFileResult>(ReadFileResult::READ_OK, - TestPresetExecutionNoTestsActionHelper); - -auto const TestPresetExecutionHelper = - cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, - PresetOptionalBoolHelper, false) - .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, - PresetOptionalBoolHelper, false) - .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, - PresetOptionalIntHelper, false) - .Bind("resourceSpecFile"_s, - &TestPreset::ExecutionOptions::ResourceSpecFile, - PresetStringHelper, false) - .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, - PresetOptionalIntHelper, false) - .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, - TestPresetOptionalExecutionShowOnlyHelper, false) - .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, - TestPresetOptionalExecutionRepeatHelper, false) - .Bind("interactiveDebugging"_s, - &TestPreset::ExecutionOptions::InteractiveDebugging, - PresetOptionalBoolHelper, false) - .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, - PresetOptionalBoolHelper, false) - .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, - PresetOptionalIntHelper, false) - .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, - TestPresetOptionalExecutionNoTestsActionHelper, false)); - -auto const TestPresetFilterHelper = - cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>( - ReadFileResult::READ_OK, - cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("include"_s, &TestPreset::FilterOptions::Include, - TestPresetOptionalFilterIncludeHelper, false) - .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, - TestPresetOptionalFilterExcludeHelper, false)); - -auto const TestPresetHelper = - cmJSONObjectHelper<TestPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &TestPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &TestPreset::Inherits, PresetInheritsHelper, false) - .Bind("hidden"_s, &TestPreset::Hidden, PresetBoolHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &TestPreset::DisplayName, PresetStringHelper, false) - .Bind("description"_s, &TestPreset::Description, PresetStringHelper, false) - .Bind("environment"_s, &TestPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &TestPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("configuration"_s, &TestPreset::Configuration, PresetStringHelper, - false) - .Bind("overwriteConfigurationFile"_s, - &TestPreset::OverwriteConfigurationFile, PresetVectorStringHelper, - false) - .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, - false) - .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) - .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, - false); - -auto const ConfigurePresetsHelper = - cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - ConfigurePresetHelper); - -auto const BuildPresetsHelper = - cmJSONVectorHelper<BuildPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - BuildPresetHelper); - -auto const TestPresetsHelper = cmJSONVectorHelper<TestPreset, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper); - -auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const CMakeVersionHelper = - cmJSONObjectHelper<CMakeVersion, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) - .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) - .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) - .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); - -auto const RootPresetsHelper = - cmJSONObjectHelper<RootPresets, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) - .Bind<int>("version"_s, nullptr, VersionHelper) - .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, - ConfigurePresetsHelper, false) - .Bind("buildPresets"_s, &RootPresets::BuildPresets, BuildPresetsHelper, - false) - .Bind("testPresets"_s, &RootPresets::TestPresets, TestPresetsHelper, false) - .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, - CMakeVersionHelper, false) - .Bind<std::nullptr_t>("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_ROOT), false); +using ExpandMacroResult = cmCMakePresetsFileInternal::ExpandMacroResult; +using MacroExpander = cmCMakePresetsFileInternal::MacroExpander; void InheritString(std::string& child, const std::string& parent) { @@ -751,7 +78,7 @@ void InheritVector(std::vector<T>& child, const std::vector<T>& parent) template <class T> ReadFileResult VisitPreset( T& preset, std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets, - std::map<std::string, CycleStatus> cycleStatus) + std::map<std::string, CycleStatus> cycleStatus, int version) { switch (cycleStatus[preset.Name]) { case CycleStatus::InProgress: @@ -781,7 +108,7 @@ ReadFileResult VisitPreset( return ReadFileResult::USER_PRESET_INHERITANCE; } - auto result = VisitPreset(parentPreset, presets, cycleStatus); + auto result = VisitPreset(parentPreset, presets, cycleStatus, version); if (result != ReadFileResult::READ_OK) { return result; } @@ -791,9 +118,17 @@ ReadFileResult VisitPreset( for (auto const& v : parentPreset.Environment) { preset.Environment.insert(v); } + + if (!preset.ConditionEvaluator) { + preset.ConditionEvaluator = parentPreset.ConditionEvaluator; + } } - CHECK_OK(preset.VisitPresetAfterInherit()) + if (preset.ConditionEvaluator && preset.ConditionEvaluator->IsNull()) { + preset.ConditionEvaluator.reset(); + } + + CHECK_OK(preset.VisitPresetAfterInherit(version)) cycleStatus[preset.Name] = CycleStatus::Verified; return ReadFileResult::READ_OK; @@ -801,7 +136,8 @@ ReadFileResult VisitPreset( template <class T> ReadFileResult ComputePresetInheritance( - std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets) + std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets, + const cmCMakePresetsFile& file) { std::map<std::string, CycleStatus> cycleStatus; for (auto const& it : presets) { @@ -809,7 +145,9 @@ ReadFileResult ComputePresetInheritance( } for (auto& it : presets) { - auto result = VisitPreset<T>(it.second.Unexpanded, presets, cycleStatus); + auto& preset = it.second.Unexpanded; + auto result = + VisitPreset<T>(preset, presets, cycleStatus, file.GetVersion(preset)); if (result != ReadFileResult::READ_OK) { return result; } @@ -839,24 +177,17 @@ bool IsValidMacroNamespace(const std::string& str) [&str](const char* prefix) -> bool { return str == prefix; }); } -enum class ExpandMacroResult -{ - Ok, - Ignore, - Error, -}; - -using MacroExpander = std::function<ExpandMacroResult( - const std::string&, const std::string&, std::string&)>; - ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, - const std::vector<MacroExpander>& macroExpanders); + const std::vector<MacroExpander>& macroExpanders, + int version); ExpandMacroResult ExpandMacros( - std::string& out, const std::vector<MacroExpander>& macroExpanders); -ExpandMacroResult ExpandMacro( - std::string& out, const std::string& macroNamespace, - const std::string& macroName, - const std::vector<MacroExpander>& macroExpanders); + std::string& out, const std::vector<MacroExpander>& macroExpanders, + int version); +ExpandMacroResult ExpandMacro(std::string& out, + const std::string& macroNamespace, + const std::string& macroName, + const std::vector<MacroExpander>& macroExpanders, + int version); bool ExpandMacros(const cmCMakePresetsFile& file, const ConfigurePreset& preset, @@ -864,7 +195,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const std::vector<MacroExpander>& macroExpanders) { std::string binaryDir = preset.BinaryDir; - CHECK_EXPAND(out, binaryDir, macroExpanders) + CHECK_EXPAND(out, binaryDir, macroExpanders, file.GetVersion(preset)) if (!cmSystemTools::FileIsFullPath(binaryDir)) { binaryDir = cmStrCat(file.SourceDir, '/', binaryDir); @@ -872,69 +203,95 @@ bool ExpandMacros(const cmCMakePresetsFile& file, out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); cmSystemTools::ConvertToUnixSlashes(out->BinaryDir); + if (!preset.InstallDir.empty()) { + std::string installDir = preset.InstallDir; + CHECK_EXPAND(out, installDir, macroExpanders, file.GetVersion(preset)) + + if (!cmSystemTools::FileIsFullPath(installDir)) { + installDir = cmStrCat(file.SourceDir, '/', installDir); + } + out->InstallDir = cmSystemTools::CollapseFullPath(installDir); + cmSystemTools::ConvertToUnixSlashes(out->InstallDir); + } + + if (!preset.ToolchainFile.empty()) { + std::string toolchain = preset.ToolchainFile; + CHECK_EXPAND(out, toolchain, macroExpanders, file.GetVersion(preset)) + out->ToolchainFile = toolchain; + } + for (auto& variable : out->CacheVariables) { if (variable.second) { - CHECK_EXPAND(out, variable.second->Value, macroExpanders) + CHECK_EXPAND(out, variable.second->Value, macroExpanders, + file.GetVersion(preset)) } } return true; } -bool ExpandMacros(const cmCMakePresetsFile&, const BuildPreset&, +bool ExpandMacros(const cmCMakePresetsFile& file, const BuildPreset& preset, cm::optional<BuildPreset>& out, const std::vector<MacroExpander>& macroExpanders) { for (auto& target : out->Targets) { - CHECK_EXPAND(out, target, macroExpanders) + CHECK_EXPAND(out, target, macroExpanders, file.GetVersion(preset)) } for (auto& nativeToolOption : out->NativeToolOptions) { - CHECK_EXPAND(out, nativeToolOption, macroExpanders) + CHECK_EXPAND(out, nativeToolOption, macroExpanders, + file.GetVersion(preset)) } return true; } -bool ExpandMacros(const cmCMakePresetsFile&, const TestPreset&, +bool ExpandMacros(const cmCMakePresetsFile& file, const TestPreset& preset, cm::optional<TestPreset>& out, const std::vector<MacroExpander>& macroExpanders) { for (auto& overwrite : out->OverwriteConfigurationFile) { - CHECK_EXPAND(out, overwrite, macroExpanders); + CHECK_EXPAND(out, overwrite, macroExpanders, file.GetVersion(preset)); } if (out->Output) { - CHECK_EXPAND(out, out->Output->OutputLogFile, macroExpanders) + CHECK_EXPAND(out, out->Output->OutputLogFile, macroExpanders, + file.GetVersion(preset)) } if (out->Filter) { if (out->Filter->Include) { - CHECK_EXPAND(out, out->Filter->Include->Name, macroExpanders) - CHECK_EXPAND(out, out->Filter->Include->Label, macroExpanders) + CHECK_EXPAND(out, out->Filter->Include->Name, macroExpanders, + file.GetVersion(preset)) + CHECK_EXPAND(out, out->Filter->Include->Label, macroExpanders, + file.GetVersion(preset)) if (out->Filter->Include->Index) { CHECK_EXPAND(out, out->Filter->Include->Index->IndexFile, - macroExpanders); + macroExpanders, file.GetVersion(preset)); } } if (out->Filter->Exclude) { - CHECK_EXPAND(out, out->Filter->Exclude->Name, macroExpanders) - CHECK_EXPAND(out, out->Filter->Exclude->Label, macroExpanders) + CHECK_EXPAND(out, out->Filter->Exclude->Name, macroExpanders, + file.GetVersion(preset)) + CHECK_EXPAND(out, out->Filter->Exclude->Label, macroExpanders, + file.GetVersion(preset)) if (out->Filter->Exclude->Fixtures) { - CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Any, macroExpanders) + CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Any, macroExpanders, + file.GetVersion(preset)) CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Setup, - macroExpanders) + macroExpanders, file.GetVersion(preset)) CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Cleanup, - macroExpanders) + macroExpanders, file.GetVersion(preset)) } } } if (out->Execution) { - CHECK_EXPAND(out, out->Execution->ResourceSpecFile, macroExpanders) + CHECK_EXPAND(out, out->Execution->ResourceSpecFile, macroExpanders, + file.GetVersion(preset)) } return true; @@ -955,8 +312,8 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, MacroExpander defaultMacroExpander = [&file, &preset](const std::string& macroNamespace, - const std::string& macroName, - std::string& macroOut) -> ExpandMacroResult { + const std::string& macroName, std::string& macroOut, + int version) -> ExpandMacroResult { if (macroNamespace.empty()) { if (macroName == "sourceDir") { macroOut += file.SourceDir; @@ -985,6 +342,13 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, macroOut += '$'; return ExpandMacroResult::Ok; } + if (macroName == "hostSystemName") { + if (version < 3) { + return ExpandMacroResult::Error; + } + macroOut += cmSystemTools::GetSystemName(); + return ExpandMacroResult::Ok; + } } return ExpandMacroResult::Ignore; @@ -993,11 +357,12 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, MacroExpander environmentMacroExpander = [¯oExpanders, &out, &envCycles]( const std::string& macroNamespace, const std::string& macroName, - std::string& result) -> ExpandMacroResult { + std::string& result, int version) -> ExpandMacroResult { if (macroNamespace == "env" && !macroName.empty() && out) { auto v = out->Environment.find(macroName); if (v != out->Environment.end() && v->second) { - auto e = VisitEnv(*v->second, envCycles[macroName], macroExpanders); + auto e = + VisitEnv(*v->second, envCycles[macroName], macroExpanders, version); if (e != ExpandMacroResult::Ok) { return e; } @@ -1025,7 +390,8 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, for (auto& v : out->Environment) { if (v.second) { - switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders)) { + switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders, + file.GetVersion(preset))) { case ExpandMacroResult::Error: return false; case ExpandMacroResult::Ignore: @@ -1037,11 +403,25 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, } } + if (preset.ConditionEvaluator) { + cm::optional<bool> result; + if (!preset.ConditionEvaluator->Evaluate( + macroExpanders, file.GetVersion(preset), result)) { + return false; + } + if (!result) { + out.reset(); + return true; + } + out->ConditionResult = *result; + } + return ExpandMacros(file, preset, out, macroExpanders); } ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, - const std::vector<MacroExpander>& macroExpanders) + const std::vector<MacroExpander>& macroExpanders, + int version) { if (status == CycleStatus::Verified) { return ExpandMacroResult::Ok; @@ -1051,7 +431,7 @@ ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, } status = CycleStatus::InProgress; - auto e = ExpandMacros(value, macroExpanders); + auto e = ExpandMacros(value, macroExpanders, version); if (e != ExpandMacroResult::Ok) { return e; } @@ -1060,7 +440,8 @@ ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, } ExpandMacroResult ExpandMacros( - std::string& out, const std::vector<MacroExpander>& macroExpanders) + std::string& out, const std::vector<MacroExpander>& macroExpanders, + int version) { std::string result; std::string macroNamespace; @@ -1107,8 +488,8 @@ ExpandMacroResult ExpandMacros( case State::MacroName: if (c == '}') { - auto e = - ExpandMacro(result, macroNamespace, macroName, macroExpanders); + auto e = ExpandMacro(result, macroNamespace, macroName, + macroExpanders, version); if (e != ExpandMacroResult::Ok) { return e; } @@ -1140,10 +521,11 @@ ExpandMacroResult ExpandMacros( ExpandMacroResult ExpandMacro(std::string& out, const std::string& macroNamespace, const std::string& macroName, - const std::vector<MacroExpander>& macroExpanders) + const std::vector<MacroExpander>& macroExpanders, + int version) { for (auto const& macroExpander : macroExpanders) { - auto result = macroExpander(macroNamespace, macroName, out); + auto result = macroExpander(macroNamespace, macroName, out, version); if (result != ExpandMacroResult::Ignore) { return result; } @@ -1157,6 +539,98 @@ ExpandMacroResult ExpandMacro(std::string& out, } } +bool cmCMakePresetsFileInternal::EqualsCondition::Evaluate( + const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const +{ + std::string lhs = this->Lhs; + CHECK_EXPAND(out, lhs, expanders, version); + + std::string rhs = this->Rhs; + CHECK_EXPAND(out, rhs, expanders, version); + + out = (lhs == rhs); + return true; +} + +bool cmCMakePresetsFileInternal::InListCondition::Evaluate( + const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const +{ + std::string str = this->String; + CHECK_EXPAND(out, str, expanders, version); + + for (auto item : this->List) { + CHECK_EXPAND(out, item, expanders, version); + if (str == item) { + out = true; + return true; + } + } + + out = false; + return true; +} + +bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate( + const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const +{ + std::string str = this->String; + CHECK_EXPAND(out, str, expanders, version); + std::string regexStr = this->Regex; + CHECK_EXPAND(out, regexStr, expanders, version); + + cmsys::RegularExpression regex; + if (!regex.compile(regexStr)) { + return false; + } + + out = regex.find(str); + return true; +} + +bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate( + const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const +{ + for (auto const& condition : this->Conditions) { + cm::optional<bool> result; + if (!condition->Evaluate(expanders, version, result)) { + out.reset(); + return false; + } + + if (!result) { + out.reset(); + return true; + } + + if (result == this->StopValue) { + out = result; + return true; + } + } + + out = !this->StopValue; + return true; +} + +bool cmCMakePresetsFileInternal::NotCondition::Evaluate( + const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const +{ + out.reset(); + if (!this->SubCondition->Evaluate(expanders, version, out)) { + out.reset(); + return false; + } + if (out) { + *out = !*out; + } + return true; +} + cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( const cmCMakePresetsFile::Preset& parentPreset) @@ -1174,6 +648,8 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( preset.ToolsetStrategy = parent.ToolsetStrategy; } InheritString(preset.BinaryDir, parent.BinaryDir); + InheritString(preset.InstallDir, parent.InstallDir); + InheritString(preset.ToolchainFile, parent.ToolchainFile); InheritOptionalValue(preset.WarnDev, parent.WarnDev); InheritOptionalValue(preset.ErrorDev, parent.ErrorDev); InheritOptionalValue(preset.WarnDeprecated, parent.WarnDeprecated); @@ -1201,16 +677,19 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit() } cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit() +cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version) { auto& preset = *this; if (!preset.Hidden) { - if (preset.Generator.empty()) { - return ReadFileResult::INVALID_PRESET; - } - if (preset.BinaryDir.empty()) { - return ReadFileResult::INVALID_PRESET; + if (version < 3) { + if (preset.Generator.empty()) { + return ReadFileResult::INVALID_PRESET; + } + if (preset.BinaryDir.empty()) { + return ReadFileResult::INVALID_PRESET; + } } + if (preset.WarnDev == false && preset.ErrorDev == true) { return ReadFileResult::INVALID_PRESET; } @@ -1246,7 +725,7 @@ cmCMakePresetsFile::BuildPreset::VisitPresetInherit( } cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit() +cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -1356,7 +835,7 @@ cmCMakePresetsFile::TestPreset::VisitPresetInherit( } cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit() +cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -1417,9 +896,9 @@ cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles) : ReadFileResult::FILE_NOT_FOUND; } - CHECK_OK(ComputePresetInheritance(this->ConfigurePresets)) - CHECK_OK(ComputePresetInheritance(this->BuildPresets)) - CHECK_OK(ComputePresetInheritance(this->TestPresets)) + CHECK_OK(ComputePresetInheritance(this->ConfigurePresets, *this)) + CHECK_OK(ComputePresetInheritance(this->BuildPresets, *this)) + CHECK_OK(ComputePresetInheritance(this->TestPresets, *this)) for (auto& it : this->ConfigurePresets) { if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) { @@ -1510,111 +989,21 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) "support."; case ReadFileResult::INVALID_CONFIGURE_PRESET: return "Invalid \"configurePreset\" field"; + case ReadFileResult::INSTALL_PREFIX_UNSUPPORTED: + return "File version must be 3 or higher for installDir preset " + "support."; + case ReadFileResult::INVALID_CONDITION: + return "Invalid preset condition"; + case ReadFileResult::CONDITION_UNSUPPORTED: + return "File version must be 3 or higher for condition support"; + case ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED: + return "File version must be 3 or higher for toolchainFile preset " + "support."; } return "Unknown error"; } -cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( - const std::string& filename, bool user) -{ - cmsys::ifstream fin(filename.c_str()); - if (!fin) { - return ReadFileResult::FILE_NOT_FOUND; - } - // If there's a BOM, toss it. - cmsys::FStream::ReadBOM(fin); - - Json::Value root; - Json::CharReaderBuilder builder; - Json::CharReaderBuilder::strictMode(&builder.settings_); - if (!Json::parseFromStream(builder, fin, &root, nullptr)) { - return ReadFileResult::JSON_PARSE_ERROR; - } - - int v = 0; - auto result = RootVersionHelper(v, &root); - if (result != ReadFileResult::READ_OK) { - return result; - } - if (v < MIN_VERSION || v > MAX_VERSION) { - return ReadFileResult::UNRECOGNIZED_VERSION; - } - - // Support for build and test presets added in version 2. - if (v < 2 && - (root.isMember("buildPresets") || root.isMember("testPresets"))) { - return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED; - } - - RootPresets presets; - if ((result = RootPresetsHelper(presets, &root)) != - ReadFileResult::READ_OK) { - return result; - } - - unsigned int currentMajor = cmVersion::GetMajorVersion(); - unsigned int currentMinor = cmVersion::GetMinorVersion(); - unsigned int currentPatch = cmVersion::GetPatchVersion(); - auto const& required = presets.CMakeMinimumRequired; - if (required.Major > currentMajor || - (required.Major == currentMajor && - (required.Minor > currentMinor || - (required.Minor == currentMinor && - (required.Patch > currentPatch))))) { - return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; - } - - for (auto& preset : presets.ConfigurePresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<ConfigurePreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->ConfigurePresets - .emplace(std::make_pair(preset.Name, presetPair)) - .second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - this->ConfigurePresetOrder.push_back(preset.Name); - } - - for (auto& preset : presets.BuildPresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<BuildPreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->BuildPresets.emplace(preset.Name, presetPair).second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - this->BuildPresetOrder.push_back(preset.Name); - } - - for (auto& preset : presets.TestPresets) { - preset.User = user; - if (preset.Name.empty()) { - return ReadFileResult::INVALID_PRESET; - } - - PresetPair<TestPreset> presetPair; - presetPair.Unexpanded = preset; - presetPair.Expanded = cm::nullopt; - if (!this->TestPresets.emplace(preset.Name, presetPair).second) { - return ReadFileResult::DUPLICATE_PRESETS; - } - this->TestPresetOrder.push_back(preset.Name); - } - - return ReadFileResult::READ_OK; -} - void cmCMakePresetsFile::ClearPresets() { this->ConfigurePresets.clear(); @@ -1666,7 +1055,7 @@ void cmCMakePresetsFile::PrintConfigurePresetList( for (auto const& p : this->ConfigurePresetOrder) { auto const& preset = this->ConfigurePresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && - filter(preset.Unexpanded)) { + preset.Expanded->ConditionResult && filter(preset.Unexpanded)) { presets.push_back( static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); } @@ -1683,7 +1072,8 @@ void cmCMakePresetsFile::PrintBuildPresetList() const std::vector<const cmCMakePresetsFile::Preset*> presets; for (auto const& p : this->BuildPresetOrder) { auto const& preset = this->BuildPresets.at(p); - if (!preset.Unexpanded.Hidden && preset.Expanded) { + if (!preset.Unexpanded.Hidden && preset.Expanded && + preset.Expanded->ConditionResult) { presets.push_back( static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); } @@ -1700,7 +1090,8 @@ void cmCMakePresetsFile::PrintTestPresetList() const std::vector<const cmCMakePresetsFile::Preset*> presets; for (auto const& p : this->TestPresetOrder) { auto const& preset = this->TestPresets.at(p); - if (!preset.Unexpanded.Hidden && preset.Expanded) { + if (!preset.Unexpanded.Hidden && preset.Expanded && + preset.Expanded->ConditionResult) { presets.push_back( static_cast<const cmCMakePresetsFile::Preset*>(&preset.Unexpanded)); } diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsFile.h index 3067d5e..7aa9b6a 100644 --- a/Source/cmCMakePresetsFile.h +++ b/Source/cmCMakePresetsFile.h @@ -2,8 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once +#include "cmConfigure.h" // IWYU pragma: keep + #include <functional> #include <map> +#include <memory> #include <string> #include <utility> #include <vector> @@ -33,6 +36,10 @@ public: INVALID_MACRO_EXPANSION, BUILD_TEST_PRESETS_UNSUPPORTED, INVALID_CONFIGURE_PRESET, + INSTALL_PREFIX_UNSUPPORTED, + INVALID_CONDITION, + CONDITION_UNSUPPORTED, + TOOLCHAIN_FILE_UNSUPPORTED, }; enum class ArchToolsetStrategy @@ -48,6 +55,8 @@ public: std::string Value; }; + class Condition; + class Preset { public: @@ -70,6 +79,9 @@ public: std::string DisplayName; std::string Description; + std::shared_ptr<Condition> ConditionEvaluator; + bool ConditionResult = true; + std::map<std::string, cm::optional<std::string>> Environment; virtual ReadFileResult VisitPresetInherit(const Preset& parent) = 0; @@ -78,7 +90,7 @@ public: return ReadFileResult::READ_OK; } - virtual ReadFileResult VisitPresetAfterInherit() + virtual ReadFileResult VisitPresetAfterInherit(int /* version */) { return ReadFileResult::READ_OK; } @@ -102,7 +114,9 @@ public: cm::optional<ArchToolsetStrategy> ArchitectureStrategy; std::string Toolset; cm::optional<ArchToolsetStrategy> ToolsetStrategy; + std::string ToolchainFile; std::string BinaryDir; + std::string InstallDir; std::map<std::string, cm::optional<CacheVariable>> CacheVariables; @@ -120,7 +134,7 @@ public: ReadFileResult VisitPresetInherit(const Preset& parent) override; ReadFileResult VisitPresetBeforeInherit() override; - ReadFileResult VisitPresetAfterInherit() override; + ReadFileResult VisitPresetAfterInherit(int version) override; }; class BuildPreset : public Preset @@ -146,7 +160,7 @@ public: std::vector<std::string> NativeToolOptions; ReadFileResult VisitPresetInherit(const Preset& parent) override; - ReadFileResult VisitPresetAfterInherit() override; + ReadFileResult VisitPresetAfterInherit(int /* version */) override; }; class TestPreset : public Preset @@ -273,7 +287,7 @@ public: cm::optional<ExecutionOptions> Execution; ReadFileResult VisitPresetInherit(const Preset& parent) override; - ReadFileResult VisitPresetAfterInherit() override; + ReadFileResult VisitPresetAfterInherit(int /* version */) override; }; template <class T> @@ -293,6 +307,13 @@ public: std::vector<std::string> TestPresetOrder; std::string SourceDir; + int Version; + int UserVersion; + + int GetVersion(const Preset& preset) const + { + return preset.User ? this->UserVersion : this->Version; + } static std::string GetFilename(const std::string& sourceDir); static std::string GetUserFilename(const std::string& sourceDir); diff --git a/Source/cmCMakePresetsFileInternal.h b/Source/cmCMakePresetsFileInternal.h new file mode 100644 index 0000000..3269276 --- /dev/null +++ b/Source/cmCMakePresetsFileInternal.h @@ -0,0 +1,112 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <memory> + +#include "cmCMakePresetsFile.h" + +#define CHECK_OK(expr) \ + { \ + auto _result = expr; \ + if (_result != ReadFileResult::READ_OK) \ + return _result; \ + } + +namespace cmCMakePresetsFileInternal { +enum class ExpandMacroResult +{ + Ok, + Ignore, + Error, +}; + +using MacroExpander = std::function<ExpandMacroResult( + const std::string&, const std::string&, std::string&, int version)>; +} + +class cmCMakePresetsFile::Condition +{ +public: + virtual ~Condition() = default; + + virtual bool Evaluate( + const std::vector<cmCMakePresetsFileInternal::MacroExpander>& expanders, + int version, cm::optional<bool>& out) const = 0; + virtual bool IsNull() const { return false; } +}; + +namespace cmCMakePresetsFileInternal { + +class NullCondition : public cmCMakePresetsFile::Condition +{ + bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, + int /*version*/, cm::optional<bool>& out) const override + { + out = true; + return true; + } + + bool IsNull() const override { return true; } +}; + +class ConstCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& /*expanders*/, + int /*version*/, cm::optional<bool>& out) const override + { + out = this->Value; + return true; + } + + bool Value; +}; + +class EqualsCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string Lhs; + std::string Rhs; +}; + +class InListCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string String; + std::vector<std::string> List; +}; + +class MatchesCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::string String; + std::string Regex; +}; + +class AnyAllOfCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::vector<std::unique_ptr<Condition>> Conditions; + bool StopValue; +}; + +class NotCondition : public cmCMakePresetsFile::Condition +{ +public: + bool Evaluate(const std::vector<MacroExpander>& expanders, int version, + cm::optional<bool>& out) const override; + + std::unique_ptr<Condition> SubCondition; +}; +} diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsFileReadJSON.cxx new file mode 100644 index 0000000..909a78b --- /dev/null +++ b/Source/cmCMakePresetsFileReadJSON.cxx @@ -0,0 +1,1029 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include <functional> +#include <map> +#include <string> +#include <utility> +#include <vector> + +#include <cm/memory> +#include <cm/optional> +#include <cmext/string_view> + +#include <cm3p/json/reader.h> +#include <cm3p/json/value.h> + +#include "cmsys/FStream.hxx" + +#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsFileInternal.h" +#include "cmJSONHelpers.h" +#include "cmVersion.h" + +namespace { +using ReadFileResult = cmCMakePresetsFile::ReadFileResult; +using CacheVariable = cmCMakePresetsFile::CacheVariable; +using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; +using BuildPreset = cmCMakePresetsFile::BuildPreset; +using TestPreset = cmCMakePresetsFile::TestPreset; +using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy; + +constexpr int MIN_VERSION = 1; +constexpr int MAX_VERSION = 3; + +struct CMakeVersion +{ + unsigned int Major = 0; + unsigned int Minor = 0; + unsigned int Patch = 0; +}; + +struct RootPresets +{ + CMakeVersion CMakeMinimumRequired; + std::vector<cmCMakePresetsFile::ConfigurePreset> ConfigurePresets; + std::vector<cmCMakePresetsFile::BuildPreset> BuildPresets; + std::vector<cmCMakePresetsFile::TestPreset> TestPresets; +}; + +std::unique_ptr<cmCMakePresetsFileInternal::NotCondition> InvertCondition( + std::unique_ptr<cmCMakePresetsFile::Condition> condition) +{ + auto retval = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); + retval->SubCondition = std::move(condition); + return retval; +} + +auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionStringListHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, + ConditionStringHelper); + +auto const ConstConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::ConstCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("value"_s, &cmCMakePresetsFileInternal::ConstCondition::Value, + ConditionBoolHelper, true); + +auto const EqualsConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::EqualsCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("lhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Lhs, + ConditionStringHelper, true) + .Bind("rhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Rhs, + ConditionStringHelper, true); + +auto const InListConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::InListCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("string"_s, &cmCMakePresetsFileInternal::InListCondition::String, + ConditionStringHelper, true) + .Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List, + ConditionStringListHelper, true); + +auto const MatchesConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::MatchesCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("string"_s, &cmCMakePresetsFileInternal::MatchesCondition::String, + ConditionStringHelper, true) + .Bind("regex"_s, &cmCMakePresetsFileInternal::MatchesCondition::Regex, + ConditionStringHelper, true); + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value); + +auto const ListConditionVectorHelper = + cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsFile::Condition>, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, + SubConditionHelper); +auto const AnyAllOfConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::AnyAllOfCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("conditions"_s, + &cmCMakePresetsFileInternal::AnyAllOfCondition::Conditions, + ListConditionVectorHelper); + +auto const NotConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::NotCondition, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("condition"_s, + &cmCMakePresetsFileInternal::NotCondition::SubCondition, + SubConditionHelper); + +ReadFileResult ConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + if (!value) { + out.reset(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); + c->Value = value->asBool(); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (value->isNull()) { + out = cm::make_unique<cmCMakePresetsFileInternal::NullCondition>(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + if (!value->isMember("type")) { + return ReadFileResult::INVALID_CONDITION; + } + + if (!(*value)["type"].isString()) { + return ReadFileResult::INVALID_CONDITION; + } + auto type = (*value)["type"].asString(); + + if (type == "const") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); + CHECK_OK(ConstConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "equals" || type == "notEquals") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::EqualsCondition>(); + CHECK_OK(EqualsConditionHelper(*c, value)); + out = std::move(c); + if (type == "notEquals") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "inList" || type == "notInList") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::InListCondition>(); + CHECK_OK(InListConditionHelper(*c, value)); + out = std::move(c); + if (type == "notInList") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "matches" || type == "notMatches") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::MatchesCondition>(); + CHECK_OK(MatchesConditionHelper(*c, value)); + out = std::move(c); + if (type == "notMatches") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "anyOf" || type == "allOf") { + auto c = + cm::make_unique<cmCMakePresetsFileInternal::AnyAllOfCondition>(); + c->StopValue = (type == "anyOf"); + CHECK_OK(AnyAllOfConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "not") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); + CHECK_OK(NotConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + } + + return ReadFileResult::INVALID_CONDITION; +} + +ReadFileResult PresetConditionHelper( + std::shared_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsFile::Condition> ptr; + auto result = ConditionHelper(ptr, value); + out = std::move(ptr); + return result; +} + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsFile::Condition> ptr; + auto result = ConditionHelper(ptr, value); + if (ptr && ptr->IsNull()) { + return ReadFileResult::INVALID_CONDITION; + } + out = std::move(ptr); + return result; +} + +cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) +{ + return [error](std::nullptr_t& /*out*/, + const Json::Value* value) -> ReadFileResult { + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isObject()) { + return error; + } + + return ReadFileResult::READ_OK; + }; +} + +auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( + ReadFileResult::NO_VERSION, VersionIntHelper); + +auto const RootVersionHelper = + cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT) + .Bind("version"_s, VersionHelper, false); + +auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); + +ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) +{ + if (!value) { + out.clear(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + out = value->asBool() ? "TRUE" : "FALSE"; + return ReadFileResult::READ_OK; + } + + return VariableStringHelper(out, value); +} + +auto const VariableObjectHelper = + cmJSONObjectHelper<CacheVariable, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) + .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) + .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); + +ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, + const Json::Value* value) +{ + if (value->isBool()) { + out = CacheVariable{ + /*Type=*/"BOOL", + /*Value=*/value->asBool() ? "TRUE" : "FALSE", + }; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = CacheVariable{ + /*Type=*/"", + /*Value=*/value->asString(), + }; + return ReadFileResult::READ_OK; + } + if (value->isObject()) { + out.emplace(); + return VariableObjectHelper(*out, value); + } + if (value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_VARIABLE; +} + +auto const VariablesHelper = + cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); + +auto const PresetStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + +ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, + const Json::Value* value) +{ + if (!value || value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = value->asString(); + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_PRESET; +} + +auto const EnvironmentMapHelper = + cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + EnvironmentHelper); + +auto const PresetVectorStringHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + PresetStringHelper); + +ReadFileResult PresetInheritsHelper(std::vector<std::string>& out, + const Json::Value* value) +{ + out.clear(); + if (!value) { + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.push_back(value->asString()); + return ReadFileResult::READ_OK; + } + + return PresetVectorStringHelper(out, value); +} + +auto const PresetBoolHelper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + +auto const PresetOptionalBoolHelper = + cmJSONOptionalHelper<bool, ReadFileResult>(ReadFileResult::READ_OK, + PresetBoolHelper); + +auto const PresetIntHelper = cmJSONIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + +auto const PresetOptionalIntHelper = cmJSONOptionalHelper<int, ReadFileResult>( + ReadFileResult::READ_OK, PresetIntHelper); + +auto const PresetVectorIntHelper = cmJSONVectorHelper<int, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); + +auto const PresetWarningsHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::WarnDev, PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, + PresetOptionalBoolHelper, false) + .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, + PresetOptionalBoolHelper, false) + .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, + PresetOptionalBoolHelper, false) + .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, + PresetOptionalBoolHelper, false); + +auto const PresetErrorsHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::ErrorDev, PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, + PresetOptionalBoolHelper, false); + +auto const PresetDebugHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("output"_s, &ConfigurePreset::DebugOutput, PresetOptionalBoolHelper, + false) + .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, + PresetOptionalBoolHelper, false) + .Bind("find"_s, &ConfigurePreset::DebugFind, PresetOptionalBoolHelper, + false); + +ReadFileResult ArchToolsetStrategyHelper( + cm::optional<ArchToolsetStrategy>& out, const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "set") { + out = ArchToolsetStrategy::Set; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "external") { + out = ArchToolsetStrategy::External; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +std::function<ReadFileResult(ConfigurePreset&, const Json::Value*)> +ArchToolsetHelper( + std::string ConfigurePreset::*valueField, + cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField) +{ + auto const objectHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("value", valueField, PresetStringHelper, false) + .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); + return [valueField, strategyField, objectHelper]( + ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { + if (!value) { + (out.*valueField).clear(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.*valueField = value->asString(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return objectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; + }; +} + +auto const ArchitectureHelper = ArchToolsetHelper( + &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); +auto const ToolsetHelper = ArchToolsetHelper( + &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); + +auto const ConfigurePresetHelper = + cmJSONObjectHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &ConfigurePreset::Name, PresetStringHelper) + .Bind("inherits"_s, &ConfigurePreset::Inherits, PresetInheritsHelper, + false) + .Bind("hidden"_s, &ConfigurePreset::Hidden, PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_PRESET), false) + .Bind("displayName"_s, &ConfigurePreset::DisplayName, PresetStringHelper, + false) + .Bind("description"_s, &ConfigurePreset::Description, PresetStringHelper, + false) + .Bind("generator"_s, &ConfigurePreset::Generator, PresetStringHelper, + false) + .Bind("architecture"_s, ArchitectureHelper, false) + .Bind("toolset"_s, ToolsetHelper, false) + .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, + PresetStringHelper, false) + .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper, + false) + .Bind("installDir"_s, &ConfigurePreset::InstallDir, PresetStringHelper, + false) + .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false) + .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, + VariablesHelper, false) + .Bind("environment"_s, &ConfigurePreset::Environment, EnvironmentMapHelper, + false) + .Bind("warnings"_s, PresetWarningsHelper, false) + .Bind("errors"_s, PresetErrorsHelper, false) + .Bind("debug"_s, PresetDebugHelper, false) + .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, + PresetConditionHelper, false); + +auto const BuildPresetHelper = + cmJSONObjectHelper<BuildPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &BuildPreset::Name, PresetStringHelper) + .Bind("inherits"_s, &BuildPreset::Inherits, PresetInheritsHelper, false) + .Bind("hidden"_s, &BuildPreset::Hidden, PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_PRESET), false) + .Bind("displayName"_s, &BuildPreset::DisplayName, PresetStringHelper, + false) + .Bind("description"_s, &BuildPreset::Description, PresetStringHelper, + false) + .Bind("environment"_s, &BuildPreset::Environment, EnvironmentMapHelper, + false) + .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, + PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &BuildPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, + false) + .Bind("jobs"_s, &BuildPreset::Jobs, PresetOptionalIntHelper, false) + .Bind("targets"_s, &BuildPreset::Targets, PresetVectorStringHelper, false) + .Bind("configuration"_s, &BuildPreset::Configuration, PresetStringHelper, + false) + .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, PresetOptionalBoolHelper, + false) + .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false) + .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, + PresetVectorStringHelper, false) + .Bind("condition"_s, &BuildPreset::ConditionEvaluator, + PresetConditionHelper, false); + +ReadFileResult TestPresetOutputVerbosityHelper( + TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) +{ + if (!value) { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "verbose") { + out = TestPreset::OutputOptions::VerbosityEnum::Verbose; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "extra") { + out = TestPreset::OutputOptions::VerbosityEnum::Extra; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalOutputVerbosityHelper = + cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetOutputVerbosityHelper); + +auto const TestPresetOptionalOutputHelper = + cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, + PresetOptionalBoolHelper, false) + .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, + TestPresetOptionalOutputVerbosityHelper, false) + .Bind("debug"_s, &TestPreset::OutputOptions::Debug, + PresetOptionalBoolHelper, false) + .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, + PresetOptionalBoolHelper, false) + .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, + PresetOptionalBoolHelper, false) + .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, + PresetStringHelper, false) + .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, + PresetOptionalBoolHelper, false) + .Bind("subprojectSummary"_s, + &TestPreset::OutputOptions::SubprojectSummary, + PresetOptionalBoolHelper, false) + .Bind("maxPassedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxPassedTestOutputSize, + PresetOptionalIntHelper, false) + .Bind("maxFailedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxFailedTestOutputSize, + PresetOptionalIntHelper, false) + .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, + PresetOptionalIntHelper, false)); + +auto const TestPresetOptionalFilterIncludeIndexObjectHelper = + cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, + PresetOptionalIntHelper, false) + .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, + PresetOptionalIntHelper, false) + .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, + PresetOptionalIntHelper, false) + .Bind("specificTests"_s, + &TestPreset::IncludeOptions::IndexOptions::SpecificTests, + PresetVectorIntHelper, false)); + +ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( + cm::optional<TestPreset::IncludeOptions::IndexOptions>& out, + const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.emplace(); + out->IndexFile = value->asString(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalFilterIncludeHelper = + cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::IncludeOptions::Name, PresetStringHelper, + false) + .Bind("label"_s, &TestPreset::IncludeOptions::Label, PresetStringHelper, + false) + .Bind("index"_s, &TestPreset::IncludeOptions::Index, + TestPresetOptionalFilterIncludeIndexHelper, false) + .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, + PresetOptionalBoolHelper, false)); + +auto const TestPresetOptionalFilterExcludeFixturesHelper = + cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, + PresetStringHelper, false) + .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, + PresetStringHelper, false) + .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, + PresetStringHelper, false)); + +auto const TestPresetOptionalFilterExcludeHelper = + cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::ExcludeOptions::Name, PresetStringHelper, + false) + .Bind("label"_s, &TestPreset::ExcludeOptions::Label, PresetStringHelper, + false) + .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, + TestPresetOptionalFilterExcludeFixturesHelper, false)); + +ReadFileResult TestPresetExecutionShowOnlyHelper( + TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) +{ + if (!value || !value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "human") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "json-v1") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionShowOnlyHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetExecutionShowOnlyHelper); + +ReadFileResult TestPresetExecutionModeHelper( + TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, + const Json::Value* value) +{ + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "until-fail") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "until-pass") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "after-timeout") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionRepeatHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions, + ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, + TestPresetExecutionModeHelper, true) + .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, + PresetIntHelper, true)); + +ReadFileResult TestPresetExecutionNoTestsActionHelper( + TestPreset::ExecutionOptions::NoTestsActionEnum& out, + const Json::Value* value) +{ + if (!value) { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "error") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "ignore") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionNoTestsActionHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum, + ReadFileResult>(ReadFileResult::READ_OK, + TestPresetExecutionNoTestsActionHelper); + +auto const TestPresetExecutionHelper = + cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, + PresetOptionalBoolHelper, false) + .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, + PresetOptionalBoolHelper, false) + .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, + PresetOptionalIntHelper, false) + .Bind("resourceSpecFile"_s, + &TestPreset::ExecutionOptions::ResourceSpecFile, + PresetStringHelper, false) + .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, + PresetOptionalIntHelper, false) + .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, + TestPresetOptionalExecutionShowOnlyHelper, false) + .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, + TestPresetOptionalExecutionRepeatHelper, false) + .Bind("interactiveDebugging"_s, + &TestPreset::ExecutionOptions::InteractiveDebugging, + PresetOptionalBoolHelper, false) + .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, + PresetOptionalBoolHelper, false) + .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, + PresetOptionalIntHelper, false) + .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, + TestPresetOptionalExecutionNoTestsActionHelper, false)); + +auto const TestPresetFilterHelper = + cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>( + ReadFileResult::READ_OK, + cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("include"_s, &TestPreset::FilterOptions::Include, + TestPresetOptionalFilterIncludeHelper, false) + .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, + TestPresetOptionalFilterExcludeHelper, false)); + +auto const TestPresetHelper = + cmJSONObjectHelper<TestPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &TestPreset::Name, PresetStringHelper) + .Bind("inherits"_s, &TestPreset::Inherits, PresetInheritsHelper, false) + .Bind("hidden"_s, &TestPreset::Hidden, PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_PRESET), false) + .Bind("displayName"_s, &TestPreset::DisplayName, PresetStringHelper, false) + .Bind("description"_s, &TestPreset::Description, PresetStringHelper, false) + .Bind("environment"_s, &TestPreset::Environment, EnvironmentMapHelper, + false) + .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, + PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &TestPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, + false) + .Bind("configuration"_s, &TestPreset::Configuration, PresetStringHelper, + false) + .Bind("overwriteConfigurationFile"_s, + &TestPreset::OverwriteConfigurationFile, PresetVectorStringHelper, + false) + .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, + false) + .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) + .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, + false) + .Bind("condition"_s, &TestPreset::ConditionEvaluator, + PresetConditionHelper, false); + +auto const ConfigurePresetsHelper = + cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + ConfigurePresetHelper); + +auto const BuildPresetsHelper = + cmJSONVectorHelper<BuildPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + BuildPresetHelper); + +auto const TestPresetsHelper = cmJSONVectorHelper<TestPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper); + +auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const CMakeVersionHelper = + cmJSONObjectHelper<CMakeVersion, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) + .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) + .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) + .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); + +auto const RootPresetsHelper = + cmJSONObjectHelper<RootPresets, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) + .Bind<int>("version"_s, nullptr, VersionHelper) + .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, + ConfigurePresetsHelper, false) + .Bind("buildPresets"_s, &RootPresets::BuildPresets, BuildPresetsHelper, + false) + .Bind("testPresets"_s, &RootPresets::TestPresets, TestPresetsHelper, false) + .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, + CMakeVersionHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_ROOT), false); +} + +cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( + const std::string& filename, bool user) +{ + cmsys::ifstream fin(filename.c_str()); + if (!fin) { + return ReadFileResult::FILE_NOT_FOUND; + } + // If there's a BOM, toss it. + cmsys::FStream::ReadBOM(fin); + + Json::Value root; + Json::CharReaderBuilder builder; + Json::CharReaderBuilder::strictMode(&builder.settings_); + if (!Json::parseFromStream(builder, fin, &root, nullptr)) { + return ReadFileResult::JSON_PARSE_ERROR; + } + + int v = 0; + auto result = RootVersionHelper(v, &root); + if (result != ReadFileResult::READ_OK) { + return result; + } + if (v < MIN_VERSION || v > MAX_VERSION) { + return ReadFileResult::UNRECOGNIZED_VERSION; + } + if (user) { + this->UserVersion = v; + } else { + this->Version = v; + } + + // Support for build and test presets added in version 2. + if (v < 2 && + (root.isMember("buildPresets") || root.isMember("testPresets"))) { + return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED; + } + + RootPresets presets; + if ((result = RootPresetsHelper(presets, &root)) != + ReadFileResult::READ_OK) { + return result; + } + + unsigned int currentMajor = cmVersion::GetMajorVersion(); + unsigned int currentMinor = cmVersion::GetMinorVersion(); + unsigned int currentPatch = cmVersion::GetPatchVersion(); + auto const& required = presets.CMakeMinimumRequired; + if (required.Major > currentMajor || + (required.Major == currentMajor && + (required.Minor > currentMinor || + (required.Minor == currentMinor && + (required.Patch > currentPatch))))) { + return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; + } + + for (auto& preset : presets.ConfigurePresets) { + preset.User = user; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<ConfigurePreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->ConfigurePresets + .emplace(std::make_pair(preset.Name, presetPair)) + .second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for installDir presets added in version 3. + if (v < 3 && !preset.InstallDir.empty()) { + return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + // Support for toolchainFile presets added in version 3. + if (v < 3 && !preset.ToolchainFile.empty()) { + return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED; + } + + this->ConfigurePresetOrder.push_back(preset.Name); + } + + for (auto& preset : presets.BuildPresets) { + preset.User = user; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<BuildPreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->BuildPresets.emplace(preset.Name, presetPair).second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + this->BuildPresetOrder.push_back(preset.Name); + } + + for (auto& preset : presets.TestPresets) { + preset.User = user; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + + PresetPair<TestPreset> presetPair; + presetPair.Unexpanded = preset; + presetPair.Expanded = cm::nullopt; + if (!this->TestPresets.emplace(preset.Name, presetPair).second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + + this->TestPresetOrder.push_back(preset.Name); + } + + return ReadFileResult::READ_OK; +} diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 438a077..ace7382 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -734,7 +734,7 @@ void CCONV cmSourceFileSetName2(void* arg, const char* name, const char* dir, } sf->SourceName = name; std::string fname = sf->SourceName; - if (ext && strlen(ext)) { + if (cmNonempty(ext)) { fname += "."; fname += ext; } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 620ba19..7534e37 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -4,7 +4,6 @@ #include <algorithm> #include <cctype> -#include <cerrno> #include <chrono> #include <cstdio> #include <cstdlib> @@ -2070,6 +2069,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } i++; this->Impl->TestDir = std::string(args[i]); + } else if (this->CheckArgument(arg, "--output-junit"_s)) { + if (i >= args.size() - 1) { + errormsg = "'--output-junit' requires an argument"; + return false; + } + i++; + this->Impl->TestHandler.SetJUnitXMLFileName(std::string(args[i])); + // Turn test output compression off. + // This makes it easier to include test output in the resulting + // JUnit XML report. + this->Impl->CompressTestOutput = false; } cm::string_view noTestsPrefix = "--no-tests="; @@ -2108,17 +2118,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") && i < args.size() - 1) { i++; - this->GetTestHandler()->SetPersistentOption("LabelRegularExpression", - args[i].c_str()); - this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression", - args[i].c_str()); + this->GetTestHandler()->AddPersistentMultiOption("LabelRegularExpression", + args[i]); + this->GetMemCheckHandler()->AddPersistentMultiOption( + "LabelRegularExpression", args[i]); } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") && i < args.size() - 1) { i++; - this->GetTestHandler()->SetPersistentOption( - "ExcludeLabelRegularExpression", args[i].c_str()); - this->GetMemCheckHandler()->SetPersistentOption( - "ExcludeLabelRegularExpression", args[i].c_str()); + this->GetTestHandler()->AddPersistentMultiOption( + "ExcludeLabelRegularExpression", args[i]); + this->GetMemCheckHandler()->AddPersistentMultiOption( + "ExcludeLabelRegularExpression", args[i]); } else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") && @@ -2205,6 +2215,10 @@ bool cmCTest::ColoredOutputSupportedByConsole() !clicolor_force.empty() && clicolor_force != "0") { return true; } + std::string clicolor; + if (cmSystemTools::GetEnv("CLICOLOR", clicolor) && clicolor == "0") { + return false; + } return ConsoleIsNotDumb(); #endif } @@ -2221,7 +2235,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, cmCTestScriptHandler* ch = this->GetScriptHandler(); // -SR is an internal argument, -SP should be ignored when it is passed if (!SRArgumentSpecified) { - ch->AddConfigurationScript(args[i].c_str(), false); + ch->AddConfigurationScript(args[i], false); } } @@ -2231,7 +2245,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, this->Impl->RunConfigurationScript = true; i++; cmCTestScriptHandler* ch = this->GetScriptHandler(); - ch->AddConfigurationScript(args[i].c_str(), true); + ch->AddConfigurationScript(args[i], true); } if (this->CheckArgument(arg, "-S"_s, "--script") && i < args.size() - 1) { @@ -2240,7 +2254,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, cmCTestScriptHandler* ch = this->GetScriptHandler(); // -SR is an internal argument, -S should be ignored when it is passed if (!SRArgumentSpecified) { - ch->AddConfigurationScript(args[i].c_str(), true); + ch->AddConfigurationScript(args[i], true); } } } @@ -2268,6 +2282,15 @@ void cmCTest::SetPersistentOptionIfNotEmpty(const std::string& value, } } +void cmCTest::AddPersistentMultiOptionIfNotEmpty(const std::string& value, + const std::string& optionName) +{ + if (!value.empty()) { + this->GetTestHandler()->AddPersistentMultiOption(optionName, value); + this->GetMemCheckHandler()->AddPersistentMultiOption(optionName, value); + } +} + bool cmCTest::SetArgsFromPreset(const std::string& presetName, bool listPresets) { @@ -2310,6 +2333,13 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, return false; } + if (!expandedPreset->ConditionResult) { + cmSystemTools::Error(cmStrCat("Cannot use disabled test preset in ", + workingDirectory, ": \"", presetName, '"')); + settingsFile.PrintTestPresetList(); + return false; + } + auto configurePresetPair = settingsFile.ConfigurePresets.find(expandedPreset->ConfigurePreset); if (configurePresetPair == settingsFile.ConfigurePresets.end()) { @@ -2412,7 +2442,7 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Filter->Include) { this->SetPersistentOptionIfNotEmpty( expandedPreset->Filter->Include->Name, "IncludeRegularExpression"); - this->SetPersistentOptionIfNotEmpty( + this->AddPersistentMultiOptionIfNotEmpty( expandedPreset->Filter->Include->Label, "LabelRegularExpression"); if (expandedPreset->Filter->Include->Index) { @@ -2445,7 +2475,7 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Filter->Exclude) { this->SetPersistentOptionIfNotEmpty( expandedPreset->Filter->Exclude->Name, "ExcludeRegularExpression"); - this->SetPersistentOptionIfNotEmpty( + this->AddPersistentMultiOptionIfNotEmpty( expandedPreset->Filter->Exclude->Label, "ExcludeLabelRegularExpression"); @@ -2826,9 +2856,10 @@ int cmCTest::ExecuteTests() cmCTestLog(this, OUTPUT, "Internal ctest changing into directory: " << workDir << std::endl); - if (cmSystemTools::ChangeDirectory(workDir) != 0) { + cmsys::Status status = cmSystemTools::ChangeDirectory(workDir); + if (!status) { auto msg = "Failed to change working directory to \"" + workDir + - "\" : " + std::strerror(errno) + "\n"; + "\" : " + status.GetString() + "\n"; cmCTestLog(this, ERROR_MESSAGE, msg); return 1; } diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 4669a1c..392eb1c 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -463,6 +463,8 @@ public: private: void SetPersistentOptionIfNotEmpty(const std::string& value, const std::string& optionName); + void AddPersistentMultiOptionIfNotEmpty(const std::string& value, + const std::string& optionName); int GenerateNotesFile(const std::string& files); diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index ddfff32..72ab045 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h @@ -17,10 +17,25 @@ struct cmCommandLineArgument OneOrMore }; + enum class RequiresSeparator + { + Yes, + No + }; + + enum class ParseMode + { + Valid, + Invalid, + SyntaxError, + ValueError + }; + std::string InvalidSyntaxMessage; std::string InvalidValueMessage; std::string Name; Values Type; + RequiresSeparator SeparatorNeeded; std::function<FunctionSignature> StoreCall; template <typename FunctionType> @@ -29,6 +44,19 @@ struct cmCommandLineArgument , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, Values t, RequiresSeparator s, + FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } @@ -40,14 +68,39 @@ struct cmCommandLineArgument , InvalidValueMessage(std::move(failedMsg)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, std::string failedMsg, Values t, + RequiresSeparator s, FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(std::move(failedMsg)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } bool matches(std::string const& input) const { - return (this->Type == Values::Zero) ? (input == this->Name) - : cmHasPrefix(input, this->Name); + bool matched = false; + if (this->Type == Values::Zero) { + matched = (input == this->Name); + } else if (this->SeparatorNeeded == RequiresSeparator::No) { + matched = cmHasPrefix(input, this->Name); + } else if (cmHasPrefix(input, this->Name)) { + if (input.size() == this->Name.size()) { + matched = true; + } else { + matched = + (input[this->Name.size()] == '=' || input[this->Name.size()] == ' '); + } + } + return matched; } template <typename T, typename... CallState> @@ -55,13 +108,6 @@ struct cmCommandLineArgument std::vector<std::string> const& allArgs, CallState&&... state) const { - enum class ParseMode - { - Valid, - Invalid, - SyntaxError, - ValueError - }; ParseMode parseState = ParseMode::Valid; if (this->Type == Values::Zero) { @@ -95,19 +141,10 @@ struct cmCommandLineArgument index = nextValueIndex; } } else { - // parse the string to get the value - auto possible_value = cm::string_view(input).substr(this->Name.size()); - if (possible_value.empty()) { - parseState = ParseMode::ValueError; - } else if (possible_value[0] == '=') { - possible_value.remove_prefix(1); - if (possible_value.empty()) { - parseState = ParseMode::ValueError; - } - } + auto value = this->extract_single_value(input, parseState); if (parseState == ParseMode::Valid) { - parseState = this->StoreCall(std::string(possible_value), - std::forward<CallState>(state)...) + parseState = + this->StoreCall(value, std::forward<CallState>(state)...) ? ParseMode::Valid : ParseMode::Invalid; } @@ -145,7 +182,13 @@ struct cmCommandLineArgument index = (nextValueIndex - 1); } } else { - parseState = ParseMode::SyntaxError; + auto value = this->extract_single_value(input, parseState); + if (parseState == ParseMode::Valid) { + parseState = + this->StoreCall(value, std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } } } @@ -157,4 +200,24 @@ struct cmCommandLineArgument } return (parseState == ParseMode::Valid); } + +private: + std::string extract_single_value(std::string const& input, + ParseMode& parseState) const + { + // parse the string to get the value + auto possible_value = cm::string_view(input).substr(this->Name.size()); + if (possible_value.empty()) { + parseState = ParseMode::ValueError; + } else if (possible_value[0] == '=') { + possible_value.remove_prefix(1); + if (possible_value.empty()) { + parseState = ParseMode::ValueError; + } + } + if (parseState == ParseMode::Valid && possible_value[0] == ' ') { + possible_value.remove_prefix(1); + } + return std::string(possible_value); + } }; diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 228cff7..0c5a7df 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -241,8 +241,7 @@ std::string cmCommonTargetGenerator::GetManifests(const std::string& config) manifests.reserve(manifest_srcs.size()); for (cmSourceFile const* manifest_src : manifest_srcs) { manifests.push_back(this->LocalCommonGenerator->ConvertToOutputFormat( - this->LocalCommonGenerator->MaybeConvertToRelativePath( - this->LocalCommonGenerator->GetWorkingDirectory(), + this->LocalCommonGenerator->MaybeRelativeToWorkDir( manifest_src->GetFullPath()), cmOutputConverter::SHELL)); } diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 6225a4a..5473316 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -701,6 +701,10 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item, this->AddTargetItem(lib, tgt); this->AddLibraryRuntimeInfo(lib.Value, tgt); + if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY && + this->Target->IsDLLPlatform()) { + this->AddRuntimeDLL(tgt); + } } } else { // This is not a CMake target. Use the name given. @@ -728,6 +732,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item, void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item, const cmGeneratorTarget* tgt) { + // Record dependencies on DLLs. + if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY && + this->Target->IsDLLPlatform() && + this->SharedDependencyMode != SharedDepModeLink) { + this->AddRuntimeDLL(tgt); + } + // If dropping shared library dependencies, ignore them. if (this->SharedDependencyMode == SharedDepModeNone) { return; @@ -799,6 +810,14 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item, } } +void cmComputeLinkInformation::AddRuntimeDLL(cmGeneratorTarget const* tgt) +{ + if (std::find(this->RuntimeDLLs.begin(), this->RuntimeDLLs.end(), tgt) == + this->RuntimeDLLs.end()) { + this->RuntimeDLLs.emplace_back(tgt); + } +} + void cmComputeLinkInformation::ComputeLinkTypeInfo() { // Check whether archives may actually be shared libraries. diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 9fec702..4acb99f 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -64,6 +64,10 @@ public: std::string GetRPathString(bool for_install) const; std::string GetChrpathString() const; std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const; + std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const + { + return this->RuntimeDLLs; + } std::string const& GetLibLinkFileFlag() const { @@ -81,6 +85,7 @@ private: void AddItem(BT<std::string> const& item, const cmGeneratorTarget* tgt); void AddSharedDepItem(BT<std::string> const& item, cmGeneratorTarget const* tgt); + void AddRuntimeDLL(cmGeneratorTarget const* tgt); // Output information. ItemVector Items; @@ -89,6 +94,7 @@ private: std::vector<std::string> FrameworkPaths; std::vector<std::string> RuntimeSearchPath; std::set<cmGeneratorTarget const*> SharedLibrariesLinked; + std::vector<cmGeneratorTarget const*> RuntimeDLLs; // Context information. cmGeneratorTarget const* const Target; diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 62bc526..f99592c 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -654,10 +654,10 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, if (argP1 != newArgs.end() && argP2 != newArgs.end() && this->IsKeyword(keyIS_NEWER_THAN, *argP1)) { int fileIsNewer = 0; - bool success = cmSystemTools::FileTimeCompare( + cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare( arg->GetValue(), (argP2)->GetValue(), &fileIsNewer); this->HandleBinaryOp( - (!success || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg, + (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg, newArgs, argP1, argP2); } diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 6672aa6..5399fd0 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -8,6 +8,7 @@ #include <sstream> #include <utility> +#include <cm/string_view> #include <cmext/string_view> #include "cmsys/Directory.hxx" @@ -217,6 +218,7 @@ std::string const kCMAKE_POSITION_INDEPENDENT_CODE = std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT"; std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE"; std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK"; +std::string const kCMAKE_ARMClang_CMP0123 = "CMAKE_ARMClang_CMP0123"; std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES = "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES"; std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES = @@ -552,6 +554,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, fprintf(fout, "cmake_policy(SET CMP0104 OLD)\n"); } + /* Set ARMClang cpu/arch policy to match outer project. */ + if (cmProp cmp0123 = + this->Makefile->GetDefinition(kCMAKE_ARMClang_CMP0123)) { + fprintf(fout, "cmake_policy(SET CMP0123 %s)\n", + *cmp0123 == "NEW"_s ? "NEW" : "OLD"); + } + std::string projectLangs; for (std::string const& li : testLangs) { projectLangs += " " + li; @@ -1015,17 +1024,21 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir) // cannot delete them immediately. Try a few times. cmSystemTools::WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry(); - while (!cmSystemTools::RemoveFile(fullPath) && --retry.Count && - cmSystemTools::FileExists(fullPath)) { + cmsys::Status status; + while (!((status = cmSystemTools::RemoveFile(fullPath))) && + --retry.Count && cmSystemTools::FileExists(fullPath)) { cmSystemTools::Delay(retry.Delay); } if (retry.Count == 0) #else - if (!cmSystemTools::RemoveFile(fullPath)) + cmsys::Status status = cmSystemTools::RemoveFile(fullPath); + if (!status) #endif { - std::string m = "Remove failed on file: " + fullPath; - cmSystemTools::ReportLastSystemError(m.c_str()); + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("The file:\n ", fullPath, + "\ncould not be removed:\n ", status.GetString())); } } } diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx index 3001ae0..a2fac73 100644 --- a/Source/cmCreateTestSourceList.cxx +++ b/Source/cmCreateTestSourceList.cxx @@ -90,10 +90,15 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args, std::replace(func_name.begin(), func_name.end(), ' ', '_'); std::replace(func_name.begin(), func_name.end(), '/', '_'); std::replace(func_name.begin(), func_name.end(), ':', '_'); + bool already_declared = + std::find(tests_func_name.begin(), tests_func_name.end(), func_name) != + tests_func_name.end(); tests_func_name.push_back(func_name); - forwardDeclareCode += "int "; - forwardDeclareCode += func_name; - forwardDeclareCode += "(int, char*[]);\n"; + if (!already_declared) { + forwardDeclareCode += "int "; + forwardDeclareCode += func_name; + forwardDeclareCode += "(int, char*[]);\n"; + } } std::string functionMapCode; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 4329caf..1054beb 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -139,11 +139,21 @@ std::vector<std::string> EvaluateOutputs(std::vector<std::string> const& paths, } return outputs; } + +std::string EvaluateDepfile(std::string const& path, + cmGeneratorExpression const& ge, + cmLocalGenerator* lg, std::string const& config) +{ + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(path); + return cge->Evaluate(lg, config); +} } cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg, - bool transformDepfile, cm::optional<std::string> crossConfig) + bool transformDepfile, cm::optional<std::string> crossConfig, + std::function<std::string(const std::string&, const std::string&)> + computeInternalDepfile) : CC(&cc) , OutputConfig(crossConfig ? *crossConfig : config) , CommandConfig(std::move(config)) @@ -151,7 +161,15 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( , OldStyle(cc.GetEscapeOldStyle()) , MakeVars(cc.GetEscapeAllowMakeVars()) , EmulatorsWithArguments(cc.GetCommandLines().size()) + , ComputeInternalDepfile(std::move(computeInternalDepfile)) { + if (!this->ComputeInternalDepfile) { + this->ComputeInternalDepfile = + [this](const std::string& cfg, const std::string& file) -> std::string { + return this->GetInternalDepfileName(cfg, file); + }; + } + cmGeneratorExpression ge(cc.GetBacktrace()); const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines(); @@ -208,6 +226,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( case cmDepfileFormat::VsTlog: argv.emplace_back("vstlog"); break; + case cmDepfileFormat::MakeDepfile: + argv.emplace_back("makedepfile"); + break; } argv.push_back(this->LG->GetSourceDirectory()); argv.push_back(this->LG->GetCurrentSourceDirectory()); @@ -381,9 +402,20 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c, } } +std::string cmCustomCommandGenerator::GetDepfile() const +{ + const auto& depfile = this->CC->GetDepfile(); + if (depfile.empty()) { + return ""; + } + + cmGeneratorExpression ge(this->CC->GetBacktrace()); + return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig); +} + std::string cmCustomCommandGenerator::GetFullDepfile() const { - std::string depfile = this->CC->GetDepfile(); + std::string depfile = this->GetDepfile(); if (depfile.empty()) { return ""; } @@ -394,17 +426,14 @@ std::string cmCustomCommandGenerator::GetFullDepfile() const return cmSystemTools::CollapseFullPath(depfile); } -std::string cmCustomCommandGenerator::GetInternalDepfile() const +std::string cmCustomCommandGenerator::GetInternalDepfileName( + const std::string& /*config*/, const std::string& depfile) { - std::string depfile = this->GetFullDepfile(); - if (depfile.empty()) { - return ""; - } - cmCryptoHash hash(cmCryptoHash::AlgoSHA256); std::string extension; switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) { case cmDepfileFormat::GccDepfile: + case cmDepfileFormat::MakeDepfile: extension = ".d"; break; case cmDepfileFormat::VsTlog: @@ -415,6 +444,16 @@ std::string cmCustomCommandGenerator::GetInternalDepfile() const hash.HashString(depfile), extension); } +std::string cmCustomCommandGenerator::GetInternalDepfile() const +{ + std::string depfile = this->GetFullDepfile(); + if (depfile.empty()) { + return ""; + } + + return this->ComputeInternalDepfile(this->OutputConfig, depfile); +} + const char* cmCustomCommandGenerator::GetComment() const { return this->CC->GetComment(); diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 4be5b3f..e70909a 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <functional> #include <set> #include <string> #include <utility> @@ -19,6 +20,8 @@ class cmLocalGenerator; class cmCustomCommandGenerator { + std::string GetInternalDepfileName(const std::string&, const std::string&); + cmCustomCommand const* CC; std::string OutputConfig; std::string CommandConfig; @@ -32,15 +35,19 @@ class cmCustomCommandGenerator std::vector<std::string> Depends; std::string WorkingDirectory; std::set<BT<std::pair<std::string, bool>>> Utilities; + std::function<std::string(const std::string&, const std::string&)> + ComputeInternalDepfile; void FillEmulatorsWithArguments(); std::vector<std::string> GetCrossCompilingEmulator(unsigned int c) const; const char* GetArgv0Location(unsigned int c) const; public: - cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config, - cmLocalGenerator* lg, bool transformDepfile = true, - cm::optional<std::string> crossConfig = {}); + cmCustomCommandGenerator( + cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg, + bool transformDepfile = true, cm::optional<std::string> crossConfig = {}, + std::function<std::string(const std::string&, const std::string&)> + computeInternalDepfile = {}); cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete; cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default; cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) = @@ -57,6 +64,7 @@ public: std::vector<std::string> const& GetDepends() const; std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const; bool HasOnlyEmptyCommandLines() const; + std::string GetDepfile() const; std::string GetFullDepfile() const; std::string GetInternalDepfile() const; diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 566c3bf..46c7e3e 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -229,11 +229,10 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, void cmDepends::SetIncludePathFromLanguage(const std::string& lang) { // Look for the new per "TARGET_" variant first: - cmProp includePath = nullptr; std::string includePathVar = cmStrCat("CMAKE_", lang, "_TARGET_INCLUDE_PATH"); cmMakefile* mf = this->LocalGenerator->GetMakefile(); - includePath = mf->GetDefinition(includePathVar); + cmProp includePath = mf->GetDefinition(includePathVar); if (includePath) { cmExpandList(*includePath, this->IncludePath); } else { diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 60e8cbf..da37d45 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -90,13 +90,10 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, std::set<std::string> dependencies; bool haveDeps = false; - std::string binDir = this->LocalGenerator->GetBinaryDirectory(); - // Compute a path to the object file to write to the internal depend file. // Any existing content of the internal depend file has already been // loaded in ValidDeps with this path as a key. - std::string obj_i = - this->LocalGenerator->MaybeConvertToRelativePath(binDir, obj); + std::string obj_i = this->LocalGenerator->MaybeRelativeToTopBinDir(obj); if (this->ValidDeps != nullptr) { auto const tmpIt = this->ValidDeps->find(obj_i); @@ -228,7 +225,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, } for (std::string const& dep : dependencies) { std::string dependee = this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep)); + this->LocalGenerator->MaybeRelativeToTopBinDir(dep)); if (supportLongLineDepend) { makeDepends << ' ' << lineContinue << ' ' << dependee; } else { diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx index 2b48df9..800725f 100644 --- a/Source/cmDependsCompiler.cxx +++ b/Source/cmDependsCompiler.cxx @@ -190,21 +190,19 @@ void cmDependsCompiler::WriteDependencies( bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()) ->SupportsLongLineDependencies(); - const auto& binDir = this->LocalGenerator->GetBinaryDirectory(); cmDepends::DependencyMap makeDependencies(dependencies); std::unordered_set<cm::string_view> phonyTargets; // external dependencies file for (auto& node : makeDependencies) { auto target = this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first)); + this->LocalGenerator->MaybeRelativeToTopBinDir(node.first)); auto& deps = node.second; - std::transform( - deps.cbegin(), deps.cend(), deps.begin(), - [this, &binDir](const std::string& dep) { - return this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep)); - }); + std::transform(deps.cbegin(), deps.cend(), deps.begin(), + [this](const std::string& dep) { + return this->LocalGenerator->ConvertToMakefilePath( + this->LocalGenerator->MaybeRelativeToTopBinDir(dep)); + }); bool first_dep = true; if (supportLongLineDepend) { diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 1a06f31..bca26b9 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -17,8 +17,6 @@ #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmProperty.h" -#include "cmStateDirectory.h" -#include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -192,8 +190,6 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, cmGeneratedFileStream fcStream(fcName); fcStream << "# Remove fortran modules provided by this target.\n"; fcStream << "FILE(REMOVE"; - std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); for (std::string const& i : provides) { std::string mod_upper = cmStrCat(mod_dir, '/'); std::string mod_lower = cmStrCat(mod_dir, '/'); @@ -201,13 +197,13 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp"); fcStream << "\n" " \"" - << this->MaybeConvertToRelativePath(currentBinDir, mod_lower) + << this->LocalGenerator->MaybeRelativeToCurBinDir(mod_lower) << "\"\n" " \"" - << this->MaybeConvertToRelativePath(currentBinDir, mod_upper) + << this->LocalGenerator->MaybeRelativeToCurBinDir(mod_upper) << "\"\n" " \"" - << this->MaybeConvertToRelativePath(currentBinDir, stamp) + << this->LocalGenerator->MaybeRelativeToCurBinDir(stamp) << "\"\n"; } fcStream << " )\n"; @@ -317,8 +313,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::string const& src = info.Source; // Write the include dependencies to the output stream. - std::string binDir = this->LocalGenerator->GetBinaryDirectory(); - std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj); + std::string obj_i = this->LocalGenerator->MaybeRelativeToTopBinDir(obj); std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i); internalDepends << obj_i << "\n " << src << '\n'; if (!info.Includes.empty()) { @@ -333,7 +328,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, } for (std::string const& i : info.Includes) { std::string dependee = cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, i)); + this->LocalGenerator->MaybeRelativeToTopBinDir(i)); if (supportLongLineDepend) { makeDepends << ' ' << lineContinue << ' ' << dependee; } else { @@ -360,7 +355,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, if (!required->second.empty()) { // This module is known. Depend on its timestamp file. std::string stampFile = cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, required->second)); + this->LocalGenerator->MaybeRelativeToTopBinDir(required->second)); makeDepends << obj_m << ": " << stampFile << '\n'; } else { // This module is not known to CMake. Try to locate it where @@ -368,7 +363,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::string module; if (this->FindModule(i, module)) { module = cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, module)); + this->LocalGenerator->MaybeRelativeToTopBinDir(module)); makeDepends << obj_m << ": " << module << '\n'; } } @@ -387,10 +382,10 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, // try various cases for the real mod file name. std::string modFile = cmStrCat(mod_dir, '/', i); modFile = this->LocalGenerator->ConvertToOutputFormat( - this->MaybeConvertToRelativePath(binDir, modFile), + this->LocalGenerator->MaybeRelativeToTopBinDir(modFile), cmOutputConverter::SHELL); std::string stampFile = cmStrCat(stamp_dir, '/', i, ".stamp"); - stampFile = this->MaybeConvertToRelativePath(binDir, stampFile); + stampFile = this->LocalGenerator->MaybeRelativeToTopBinDir(stampFile); std::string const stampFileForShell = this->LocalGenerator->ConvertToOutputFormat(stampFile, cmOutputConverter::SHELL); @@ -425,7 +420,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, // the target finishes building. std::string driver = cmStrCat(this->TargetDirectory, "/build"); driver = cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, driver)); + this->LocalGenerator->MaybeRelativeToTopBinDir(driver)); makeDepends << driver << ": " << obj_m << ".provides.build\n"; } @@ -681,13 +676,3 @@ bool cmDependsFortran::ModulesDiffer(const std::string& modFile, // content. return cmFortranStreamsDiffer(finModFile, finStampFile); } - -std::string cmDependsFortran::MaybeConvertToRelativePath( - std::string const& base, std::string const& path) -{ - if (!this->LocalGenerator->GetStateSnapshot().GetDirectory().ContainsBoth( - base, path)) { - return path; - } - return cmSystemTools::ForceToRelativePath(base, path); -} diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h index e377a2c..0d407bc 100644 --- a/Source/cmDependsFortran.h +++ b/Source/cmDependsFortran.h @@ -85,8 +85,4 @@ protected: // Internal implementation details. std::unique_ptr<cmDependsFortranInternals> Internal; - -private: - std::string MaybeConvertToRelativePath(std::string const& base, - std::string const& path); }; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 7015a01..dd611de 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -924,13 +924,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os) // Isolate the file policy level. // Support CMake versions as far back as 2.6 but also support using NEW - // policy settings for up to CMake 3.18 (this upper limit may be reviewed + // policy settings for up to CMake 3.19 (this upper limit may be reviewed // and increased from time to time). This reduces the opportunity for CMake // warnings when an older export file is later used with newer CMake // versions. /* clang-format off */ os << "cmake_policy(PUSH)\n" - << "cmake_policy(VERSION 2.6...3.18)\n"; + << "cmake_policy(VERSION 2.6...3.19)\n"; /* clang-format on */ } @@ -1229,7 +1229,7 @@ bool cmExportFileGenerator::PopulateExportProperties( return false; } cmProp propertyValue = targetProperties.GetPropertyValue(prop); - if (propertyValue == nullptr) { + if (!propertyValue) { // Asked to export a property that isn't defined on the target. Do not // consider this an error, there's just nothing to export. continue; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index ccfd727..672089c 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -248,17 +248,17 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out, // now we have both, decide which one to use std::string valueToUse; - if (!envVarSet && cacheValue == nullptr) { + if (!envVarSet && !cacheValue) { // nothing known, do nothing valueToUse.clear(); - } else if (envVarSet && cacheValue == nullptr) { + } else if (envVarSet && !cacheValue) { // The variable is in the env, but not in the cache. Use it and put it // in the cache valueToUse = envVarValue; mf->AddCacheDefinition(cacheEntryName, valueToUse, cacheEntryName.c_str(), cmStateEnums::STRING, true); mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory()); - } else if (!envVarSet && cacheValue != nullptr) { + } else if (!envVarSet && cacheValue) { // It is already in the cache, but not in the env, so use it from the cache valueToUse = *cacheValue; } else { @@ -655,7 +655,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const xml.EndElement(); // extension } else { std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - if (systemName == "CYGWIN") { + if (systemName == "CYGWIN" || systemName == "MSYS") { xml.StartElement("extension"); xml.Attribute("id", "org.eclipse.cdt.core.Cygwin_PE"); xml.Attribute("point", "org.eclipse.cdt.core.BinaryParser"); @@ -916,8 +916,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const // and UTILITY targets for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) { const auto& targets = lgen->GetGeneratorTargets(); - std::string subdir = lgen->MaybeConvertToRelativePath( - this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory()); + std::string subdir = + lgen->MaybeRelativeToTopBinDir(lgen->GetCurrentBinaryDirectory()); if (subdir == ".") { subdir.clear(); } @@ -1097,7 +1097,7 @@ void cmExtraEclipseCDT4Generator::AppendStorageScanners( compiler = "gcc"; } - // the following right now hardcodes gcc behaviour :-/ + // the following right now hardcodes gcc behavior :-/ std::string compilerArgs = "-E -P -v -dD ${plugin_state_location}/${specs_file}"; if (!arg1.empty()) { diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 54c3114..9153119 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -130,7 +130,7 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg, if (targetName == "edit_cache") { cmProp editCommand = localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND"); - if (editCommand == nullptr || + if (!editCommand || strstr(editCommand->c_str(), "ccmake") != nullptr) { insertTarget = false; } diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index a92f6e3..52965bb 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -435,7 +435,8 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes( lg->GetIncludeDirectories(includes, target, language, config); std::string includesString = - lg->GetIncludeFlags(includes, target, language, true, false, config); + lg->GetIncludeFlags(includes, target, language, config, false, + cmLocalGenerator::IncludePathStyle::Absolute); return includesString; } diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index d2a9bec..d529f52 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -686,7 +686,7 @@ std::string cmFileAPI::NoSupportedVersion( // The "codemodel" object kind. -static unsigned int const CodeModelV2Minor = 2; +static unsigned int const CodeModelV2Minor = 3; void cmFileAPI::BuildClientRequestCodeModel( ClientRequest& r, std::vector<RequestVersion> const& versions) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 9061109..945b547 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -20,11 +20,16 @@ #include <cm3p/json/value.h> #include "cmCryptoHash.h" +#include "cmExportSet.h" #include "cmFileAPI.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmInstallDirectoryGenerator.h" +#include "cmInstallExportGenerator.h" +#include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" +#include "cmInstallScriptGenerator.h" #include "cmInstallSubdirectoryGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" @@ -42,103 +47,17 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" +#include "cmTargetExport.h" #include "cmake.h" namespace { -class Codemodel -{ - cmFileAPI& FileAPI; - unsigned long Version; - - Json::Value DumpPaths(); - Json::Value DumpConfigurations(); - Json::Value DumpConfiguration(std::string const& config); - -public: - Codemodel(cmFileAPI& fileAPI, unsigned long version); - Json::Value Dump(); -}; - -class CodemodelConfig -{ - cmFileAPI& FileAPI; - unsigned long Version; - std::string const& Config; - std::string TopSource; - std::string TopBuild; - - struct Directory - { - cmStateSnapshot Snapshot; - cmLocalGenerator const* LocalGenerator = nullptr; - Json::Value TargetIndexes = Json::arrayValue; - Json::ArrayIndex ProjectIndex; - bool HasInstallRule = false; - }; - std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder> - DirectoryMap; - std::vector<Directory> Directories; - - struct Project - { - cmStateSnapshot Snapshot; - static const Json::ArrayIndex NoParentIndex = - static_cast<Json::ArrayIndex>(-1); - Json::ArrayIndex ParentIndex = NoParentIndex; - Json::Value ChildIndexes = Json::arrayValue; - Json::Value DirectoryIndexes = Json::arrayValue; - Json::Value TargetIndexes = Json::arrayValue; - }; - std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder> - ProjectMap; - std::vector<Project> Projects; - - void ProcessDirectories(); - - Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg); - Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s); - - Json::ArrayIndex AddProject(cmStateSnapshot s); - - Json::Value DumpTargets(); - Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti); - - Json::Value DumpDirectories(); - Json::Value DumpDirectory(Directory& d); - - Json::Value DumpProjects(); - Json::Value DumpProject(Project& p); - - Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s); - -public: - CodemodelConfig(cmFileAPI& fileAPI, unsigned long version, - std::string const& config); - Json::Value Dump(); -}; +using TargetIndexMapType = + std::unordered_map<cmGeneratorTarget const*, Json::ArrayIndex>; std::string RelativeIfUnder(std::string const& top, std::string const& in) { - std::string out; - if (in == top) { - out = "."; - } else if (cmSystemTools::IsSubDirectory(in, top)) { - out = in.substr(top.size() + 1); - } else { - out = in; - } - return out; -} - -std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild) -{ - cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_256); - std::string path = RelativeIfUnder( - topBuild, gt->GetLocalGenerator()->GetCurrentBinaryDirectory()); - std::string hash = hasher.HashString(path); - hash.resize(20, '0'); - return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash; + return cmSystemTools::RelativeIfUnder(top, in); } class JBTIndex @@ -290,6 +209,91 @@ Json::Value BacktraceData::Dump() return backtraceGraph; } +class Codemodel +{ + cmFileAPI& FileAPI; + unsigned long Version; + + Json::Value DumpPaths(); + Json::Value DumpConfigurations(); + Json::Value DumpConfiguration(std::string const& config); + +public: + Codemodel(cmFileAPI& fileAPI, unsigned long version); + Json::Value Dump(); +}; + +class CodemodelConfig +{ + cmFileAPI& FileAPI; + unsigned long Version; + std::string const& Config; + std::string TopSource; + std::string TopBuild; + + struct Directory + { + cmStateSnapshot Snapshot; + cmLocalGenerator const* LocalGenerator = nullptr; + Json::Value TargetIndexes = Json::arrayValue; + Json::ArrayIndex ProjectIndex; + bool HasInstallRule = false; + }; + std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder> + DirectoryMap; + std::vector<Directory> Directories; + + struct Project + { + cmStateSnapshot Snapshot; + static const Json::ArrayIndex NoParentIndex = + static_cast<Json::ArrayIndex>(-1); + Json::ArrayIndex ParentIndex = NoParentIndex; + Json::Value ChildIndexes = Json::arrayValue; + Json::Value DirectoryIndexes = Json::arrayValue; + Json::Value TargetIndexes = Json::arrayValue; + }; + std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder> + ProjectMap; + std::vector<Project> Projects; + + TargetIndexMapType TargetIndexMap; + + void ProcessDirectories(); + + Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg); + Json::ArrayIndex GetDirectoryIndex(cmStateSnapshot s); + + Json::ArrayIndex AddProject(cmStateSnapshot s); + + Json::Value DumpTargets(); + Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti); + + Json::Value DumpDirectories(); + Json::Value DumpDirectory(Directory& d); + Json::Value DumpDirectoryObject(Directory& d); + + Json::Value DumpProjects(); + Json::Value DumpProject(Project& p); + + Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s); + +public: + CodemodelConfig(cmFileAPI& fileAPI, unsigned long version, + std::string const& config); + Json::Value Dump(); +}; + +std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild) +{ + cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_256); + std::string path = RelativeIfUnder( + topBuild, gt->GetLocalGenerator()->GetCurrentBinaryDirectory()); + std::string hash = hasher.HashString(path); + hash.resize(20, '0'); + return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash; +} + struct CompileData { struct IncludeEntry @@ -367,6 +371,31 @@ struct hash<CompileData> } // namespace std namespace { +class DirectoryObject +{ + cmLocalGenerator const* LG = nullptr; + std::string const& Config; + TargetIndexMapType& TargetIndexMap; + std::string TopSource; + std::string TopBuild; + BacktraceData Backtraces; + + void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt); + + Json::Value DumpPaths(); + Json::Value DumpInstallers(); + Json::Value DumpInstaller(cmInstallGenerator* gen); + Json::Value DumpInstallerExportTargets(cmExportSet* exp); + Json::Value DumpInstallerPath(std::string const& top, + std::string const& fromPathIn, + std::string const& toPath); + +public: + DirectoryObject(cmLocalGenerator const* lg, std::string const& config, + TargetIndexMapType& targetIndexMap); + Json::Value Dump(); +}; + class Target { cmGeneratorTarget* GT; @@ -663,6 +692,8 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt, target["projectIndex"] = pi; this->Projects[pi].TargetIndexes.append(ti); + this->TargetIndexMap[gt] = ti; + return target; } @@ -677,7 +708,7 @@ Json::Value CodemodelConfig::DumpDirectories() Json::Value CodemodelConfig::DumpDirectory(Directory& d) { - Json::Value directory = Json::objectValue; + Json::Value directory = this->DumpDirectoryObject(d); std::string sourceDir = d.Snapshot.GetDirectory().GetCurrentSource(); directory["source"] = RelativeIfUnder(this->TopSource, sourceDir); @@ -717,6 +748,31 @@ Json::Value CodemodelConfig::DumpDirectory(Directory& d) return directory; } +Json::Value CodemodelConfig::DumpDirectoryObject(Directory& d) +{ + std::string prefix = "directory"; + std::string sourceDirRel = RelativeIfUnder( + this->TopSource, d.Snapshot.GetDirectory().GetCurrentSource()); + std::string buildDirRel = RelativeIfUnder( + this->TopBuild, d.Snapshot.GetDirectory().GetCurrentBinary()); + if (!cmSystemTools::FileIsFullPath(buildDirRel)) { + prefix = cmStrCat(prefix, '-', buildDirRel); + } else if (!cmSystemTools::FileIsFullPath(sourceDirRel)) { + prefix = cmStrCat(prefix, '-', sourceDirRel); + } + for (char& c : prefix) { + if (c == '/' || c == '\\') { + c = '.'; + } + } + if (!this->Config.empty()) { + prefix += "-" + this->Config; + } + + DirectoryObject dir(d.LocalGenerator, this->Config, this->TargetIndexMap); + return this->FileAPI.MaybeJsonFile(dir.Dump(), prefix); +} + Json::Value CodemodelConfig::DumpProjects() { Json::Value projects = Json::arrayValue; @@ -760,6 +816,251 @@ Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s) return minimumCMakeVersion; } +DirectoryObject::DirectoryObject(cmLocalGenerator const* lg, + std::string const& config, + TargetIndexMapType& targetIndexMap) + : LG(lg) + , Config(config) + , TargetIndexMap(targetIndexMap) + , TopSource(lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory()) + , TopBuild( + lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeOutputDirectory()) + , Backtraces(this->TopSource) +{ +} + +Json::Value DirectoryObject::Dump() +{ + Json::Value directoryObject = Json::objectValue; + directoryObject["paths"] = this->DumpPaths(); + directoryObject["installers"] = this->DumpInstallers(); + directoryObject["backtraceGraph"] = this->Backtraces.Dump(); + return directoryObject; +} + +void DirectoryObject::AddBacktrace(Json::Value& object, + cmListFileBacktrace const& bt) +{ + if (JBTIndex backtrace = this->Backtraces.Add(bt)) { + object["backtrace"] = backtrace.Index; + } +} + +Json::Value DirectoryObject::DumpPaths() +{ + Json::Value paths = Json::objectValue; + + std::string const& sourceDir = this->LG->GetCurrentSourceDirectory(); + paths["source"] = RelativeIfUnder(this->TopSource, sourceDir); + + std::string const& buildDir = this->LG->GetCurrentBinaryDirectory(); + paths["build"] = RelativeIfUnder(this->TopBuild, buildDir); + + return paths; +} + +Json::Value DirectoryObject::DumpInstallers() +{ + Json::Value installers = Json::arrayValue; + for (const auto& gen : this->LG->GetMakefile()->GetInstallGenerators()) { + Json::Value installer = this->DumpInstaller(gen.get()); + if (!installer.empty()) { + installers.append(std::move(installer)); // NOLINT(*) + } + } + return installers; +} + +Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen) +{ + Json::Value installer = Json::objectValue; + + // Exclude subdirectory installers. They are implementation details. + if (dynamic_cast<cmInstallSubdirectoryGenerator*>(gen)) { + return installer; + } + + // Exclude installers not used in this configuration. + if (!gen->InstallsForConfig(this->Config)) { + return installer; + } + + // Add fields specific to each kind of install generator. + if (auto* installTarget = dynamic_cast<cmInstallTargetGenerator*>(gen)) { + cmInstallTargetGenerator::Files const& files = + installTarget->GetFiles(this->Config); + if (files.From.empty()) { + return installer; + } + + installer["type"] = "target"; + installer["destination"] = installTarget->GetDestination(this->Config); + installer["targetId"] = + TargetId(installTarget->GetTarget(), this->TopBuild); + installer["targetIndex"] = + this->TargetIndexMap[installTarget->GetTarget()]; + + std::string fromDir = files.FromDir; + if (!fromDir.empty()) { + fromDir.push_back('/'); + } + + std::string toDir = files.ToDir; + if (!toDir.empty()) { + toDir.push_back('/'); + } + + Json::Value paths = Json::arrayValue; + for (size_t i = 0; i < files.From.size(); ++i) { + std::string const& fromPath = cmStrCat(fromDir, files.From[i]); + std::string const& toPath = cmStrCat(toDir, files.To[i]); + paths.append(this->DumpInstallerPath(this->TopBuild, fromPath, toPath)); + } + installer["paths"] = std::move(paths); + + if (installTarget->GetOptional()) { + installer["isOptional"] = true; + } + + if (installTarget->IsImportLibrary()) { + installer["targetIsImportLibrary"] = true; + } + + switch (files.NamelinkMode) { + case cmInstallTargetGenerator::NamelinkModeNone: + break; + case cmInstallTargetGenerator::NamelinkModeOnly: + installer["targetInstallNamelink"] = "only"; + break; + case cmInstallTargetGenerator::NamelinkModeSkip: + installer["targetInstallNamelink"] = "skip"; + break; + } + + // FIXME: Parse FilePermissions to provide structured information. + // FIXME: Thread EXPORT name through from install() call. + } else if (auto* installFiles = + dynamic_cast<cmInstallFilesGenerator*>(gen)) { + std::vector<std::string> const& files = + installFiles->GetFiles(this->Config); + if (files.empty()) { + return installer; + } + + installer["type"] = "file"; + installer["destination"] = installFiles->GetDestination(this->Config); + Json::Value paths = Json::arrayValue; + std::string const& rename = installFiles->GetRename(this->Config); + if (!rename.empty() && files.size() == 1) { + paths.append(this->DumpInstallerPath(this->TopSource, files[0], rename)); + } else { + for (std::string const& file : installFiles->GetFiles(this->Config)) { + paths.append(RelativeIfUnder(this->TopSource, file)); + } + } + installer["paths"] = std::move(paths); + if (installFiles->GetOptional()) { + installer["isOptional"] = true; + } + // FIXME: Parse FilePermissions to provide structured information. + } else if (auto* installDir = + dynamic_cast<cmInstallDirectoryGenerator*>(gen)) { + std::vector<std::string> const& dirs = + installDir->GetDirectories(this->Config); + if (dirs.empty()) { + return installer; + } + + installer["type"] = "directory"; + installer["destination"] = installDir->GetDestination(this->Config); + Json::Value paths = Json::arrayValue; + for (std::string const& dir : dirs) { + if (cmHasLiteralSuffix(dir, "/")) { + paths.append(this->DumpInstallerPath( + this->TopSource, dir.substr(0, dir.size() - 1), ".")); + } else { + paths.append(this->DumpInstallerPath( + this->TopSource, dir, cmSystemTools::GetFilenameName(dir))); + } + } + installer["paths"] = std::move(paths); + if (installDir->GetOptional()) { + installer["isOptional"] = true; + } + // FIXME: Parse FilePermissions, DirPermissions, and LiteralArguments. + // to provide structured information. + } else if (auto* installExport = + dynamic_cast<cmInstallExportGenerator*>(gen)) { + installer["type"] = "export"; + installer["destination"] = installExport->GetDestination(); + cmExportSet* exportSet = installExport->GetExportSet(); + installer["exportName"] = exportSet->GetName(); + installer["exportTargets"] = this->DumpInstallerExportTargets(exportSet); + Json::Value paths = Json::arrayValue; + paths.append( + RelativeIfUnder(this->TopBuild, installExport->GetMainImportFile())); + installer["paths"] = std::move(paths); + } else if (auto* installScript = + dynamic_cast<cmInstallScriptGenerator*>(gen)) { + if (installScript->IsCode()) { + installer["type"] = "code"; + } else { + installer["type"] = "script"; + installer["scriptFile"] = RelativeIfUnder( + this->TopSource, installScript->GetScript(this->Config)); + } + } + + // Add fields common to all install generators. + installer["component"] = gen->GetComponent(); + if (gen->GetExcludeFromAll()) { + installer["isExcludeFromAll"] = true; + } + + if (gen->GetAllComponentsFlag()) { + installer["isForAllComponents"] = true; + } + + this->AddBacktrace(installer, gen->GetBacktrace()); + + return installer; +} + +Json::Value DirectoryObject::DumpInstallerExportTargets(cmExportSet* exp) +{ + Json::Value targets = Json::arrayValue; + for (auto const& targetExport : exp->GetTargetExports()) { + Json::Value target = Json::objectValue; + target["id"] = TargetId(targetExport->Target, this->TopBuild); + target["index"] = this->TargetIndexMap[targetExport->Target]; + targets.append(std::move(target)); // NOLINT(*) + } + return targets; +} + +Json::Value DirectoryObject::DumpInstallerPath(std::string const& top, + std::string const& fromPathIn, + std::string const& toPath) +{ + Json::Value installPath; + + std::string fromPath = RelativeIfUnder(top, fromPathIn); + + // If toPath is the last component of fromPath, use just fromPath. + if (toPath.find_first_of('/') == std::string::npos && + cmHasSuffix(fromPath, toPath) && + (fromPath.size() == toPath.size() || + fromPath[fromPath.size() - toPath.size() - 1] == '/')) { + installPath = fromPath; + } else { + installPath = Json::objectValue; + installPath["from"] = fromPath; + installPath["to"] = toPath; + } + + return installPath; +} + Target::Target(cmGeneratorTarget* gt, std::string const& config) : GT(gt) , Config(config) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 4a28238..1088347 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1246,9 +1246,12 @@ bool HandleRealPathCommand(std::vector<std::string> const& args, struct Arguments { std::string BaseDirectory; + bool ExpandTilde = false; }; - static auto const parser = cmArgumentParser<Arguments>{}.Bind( - "BASE_DIRECTORY"_s, &Arguments::BaseDirectory); + static auto const parser = + cmArgumentParser<Arguments>{} + .Bind("BASE_DIRECTORY"_s, &Arguments::BaseDirectory) + .Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde); std::vector<std::string> unparsedArguments; std::vector<std::string> keywordsMissingValue; @@ -1270,7 +1273,21 @@ bool HandleRealPathCommand(std::vector<std::string> const& args, arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory(); } - cmCMakePath path(args[1]); + auto input = args[1]; + if (arguments.ExpandTilde && !input.empty()) { + if (input[0] == '~' && (input.length() == 1 || input[1] == '/')) { + std::string home; + if ( +#if defined(_WIN32) && !defined(__CYGWIN__) + cmSystemTools::GetEnv("USERPROFILE", home) || +#endif + cmSystemTools::GetEnv("HOME", home)) { + input.replace(0, 1, home); + } + } + } + + cmCMakePath path(input, cmCMakePath::auto_format); path = path.Absolute(arguments.BaseDirectory).Normal(); auto realPath = cmSystemTools::GetRealPath(path.GenericString()); @@ -1313,8 +1330,9 @@ bool HandleRelativePathCommand(std::vector<std::string> const& args, bool HandleRename(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (args.size() != 3) { - status.SetError("RENAME given incorrect number of arguments."); + if (args.size() < 3) { + status.SetError("RENAME must be called with at least two additional " + "arguments"); return false; } @@ -1330,21 +1348,148 @@ bool HandleRename(std::vector<std::string> const& args, cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]); } - if (!cmSystemTools::RenameFile(oldname, newname)) { - std::string err = cmSystemTools::GetLastSystemError(); - status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, - "\nto\n ", newname, "\nbecause: ", err, "\n")); + struct Arguments + { + bool NoReplace = false; + std::string Result; + }; + + static auto const parser = cmArgumentParser<Arguments>{} + .Bind("NO_REPLACE"_s, &Arguments::NoReplace) + .Bind("RESULT"_s, &Arguments::Result); + + std::vector<std::string> unconsumedArgs; + Arguments const arguments = + parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs); + if (!unconsumedArgs.empty()) { + status.SetError("RENAME unknown argument:\n " + unconsumedArgs.front()); return false; } - return true; + + std::string err; + switch (cmSystemTools::RenameFile(oldname, newname, + arguments.NoReplace + ? cmSystemTools::Replace::No + : cmSystemTools::Replace::Yes, + &err)) { + case cmSystemTools::RenameResult::Success: + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, "0"); + } + return true; + case cmSystemTools::RenameResult::NoReplace: + if (!arguments.Result.empty()) { + err = "NO_REPLACE"; + } else { + err = "path not replaced"; + } + CM_FALLTHROUGH; + case cmSystemTools::RenameResult::Failure: + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, err); + return true; + } + break; + } + status.SetError(cmStrCat("RENAME failed to rename\n ", oldname, "\nto\n ", + newname, "\nbecause: ", err, "\n")); + return false; } -bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse, - cmExecutionStatus& status) +bool HandleCopyFile(std::vector<std::string> const& args, + cmExecutionStatus& status) { + if (args.size() < 3) { + status.SetError("COPY_FILE must be called with at least two additional " + "arguments"); + return false; + } - std::string message; + // Compute full path for old and new names. + std::string oldname = args[1]; + if (!cmsys::SystemTools::FileIsFullPath(oldname)) { + oldname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]); + } + std::string newname = args[2]; + if (!cmsys::SystemTools::FileIsFullPath(newname)) { + newname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]); + } + + struct Arguments + { + bool OnlyIfDifferent = false; + std::string Result; + }; + + static auto const parser = + cmArgumentParser<Arguments>{} + .Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent) + .Bind("RESULT"_s, &Arguments::Result); + + std::vector<std::string> unconsumedArgs; + Arguments const arguments = + parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs); + if (!unconsumedArgs.empty()) { + status.SetError("COPY_FILE unknown argument:\n " + + unconsumedArgs.front()); + return false; + } + + bool result = true; + if (cmsys::SystemTools::FileIsDirectory(oldname)) { + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, + "cannot copy a directory"); + } else { + status.SetError( + cmStrCat("COPY_FILE cannot copy a directory\n ", oldname)); + result = false; + } + return result; + } + if (cmsys::SystemTools::FileIsDirectory(newname)) { + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, + "cannot copy to a directory"); + } else { + status.SetError( + cmStrCat("COPY_FILE cannot copy to a directory\n ", newname)); + result = false; + } + return result; + } + cmSystemTools::CopyWhen when; + if (arguments.OnlyIfDifferent) { + when = cmSystemTools::CopyWhen::OnlyIfDifferent; + } else { + when = cmSystemTools::CopyWhen::Always; + } + + std::string err; + if (cmSystemTools::CopySingleFile(oldname, newname, when, &err) == + cmSystemTools::CopyResult::Success) { + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, "0"); + } + } else { + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, err); + } else { + status.SetError(cmStrCat("COPY_FILE failed to copy\n ", oldname, + "\nto\n ", newname, "\nbecause: ", err, "\n")); + result = false; + } + } + + return result; +} + +bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse, + cmExecutionStatus& status) +{ for (std::string const& arg : cmMakeRange(args).advance(1)) // Get rid of subcommand { @@ -2818,16 +2963,21 @@ bool HandleCreateLinkCommand(std::vector<std::string> const& args, // Check if the command requires a symbolic link. if (arguments.Symbolic) { - completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result); + completed = static_cast<bool>( + cmSystemTools::CreateSymlink(fileName, newFileName, &result)); } else { - completed = cmSystemTools::CreateLink(fileName, newFileName, &result); + completed = static_cast<bool>( + cmSystemTools::CreateLink(fileName, newFileName, &result)); } // Check if copy-on-error is enabled in the arguments. if (!completed && arguments.CopyOnError) { - completed = cmsys::SystemTools::CopyFileAlways(fileName, newFileName); - if (!completed) { - result = "Copy failed: " + cmSystemTools::GetLastSystemError(); + cmsys::Status copied = + cmsys::SystemTools::CopyFileAlways(fileName, newFileName); + if (copied) { + completed = true; + } else { + result = "Copy failed: " + copied.GetString(); } } @@ -3569,6 +3719,7 @@ bool cmFileCommand(std::vector<std::string> const& args, { "GLOB_RECURSE"_s, HandleGlobRecurseCommand }, { "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand }, { "RENAME"_s, HandleRename }, + { "COPY_FILE"_s, HandleCopyFile }, { "REMOVE"_s, HandleRemove }, { "REMOVE_RECURSE"_s, HandleRemoveRecurse }, { "COPY"_s, HandleCopyCommand }, diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index bf52d75..6296d06 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -9,7 +9,10 @@ #include <cmext/algorithm> +#include "cmCMakePath.h" #include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmPolicies.h" #include "cmProperty.h" #include "cmRange.h" #include "cmSearchPath.h" @@ -17,11 +20,13 @@ #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +#include "cmake.h" class cmExecutionStatus; -cmFindBase::cmFindBase(cmExecutionStatus& status) +cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status) : cmFindCommon(status) + , FindCommandName(std::move(findCommandName)) { } @@ -299,27 +304,106 @@ bool cmFindBase::CheckForVariableInCache() cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName); bool found = !cmIsNOTFOUND(*cacheValue); bool cached = cacheEntry != nullptr; + auto cacheType = cached ? state->GetCacheEntryType(this->VariableName) + : cmStateEnums::UNINITIALIZED; + + if (cached && cacheType != cmStateEnums::UNINITIALIZED) { + this->VariableType = cacheType; + if (const auto* hs = + state->GetCacheEntryProperty(this->VariableName, "HELPSTRING")) { + this->VariableDocumentation = *hs; + } + } + if (found) { // If the user specifies the entry on the command line without a // type we should add the type and docstring but keep the // original value. Tell the subclass implementations to do // this. - if (cached && - state->GetCacheEntryType(this->VariableName) == - cmStateEnums::UNINITIALIZED) { + if (cached && cacheType == cmStateEnums::UNINITIALIZED) { this->AlreadyInCacheWithoutMetaInfo = true; } return true; } - if (cached) { - cmProp hs = - state->GetCacheEntryProperty(this->VariableName, "HELPSTRING"); - this->VariableDocumentation = hs ? *hs : "(none)"; - } } return false; } +void cmFindBase::NormalizeFindResult() +{ + if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) == + cmPolicies::NEW) { + // ensure the path returned by find_* command is absolute + const auto* existingValue = + this->Makefile->GetDefinition(this->VariableName); + std::string value; + if (!existingValue->empty()) { + value = + cmCMakePath(*existingValue, cmCMakePath::auto_format) + .Absolute(cmCMakePath( + this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory())) + .Normal() + .GenericString(); + // value = cmSystemTools::CollapseFullPath(*existingValue); + if (!cmSystemTools::FileExists(value, false)) { + value = *existingValue; + } + } + + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if (value != *existingValue || this->AlreadyInCacheWithoutMetaInfo) { + this->Makefile->GetCMakeInstance()->AddCacheEntry( + this->VariableName, value.c_str(), this->VariableDocumentation.c_str(), + this->VariableType); + // if there was a definition then remove it + // This is required to ensure same behavior as + // cmMakefile::AddCacheDefinition. + // See #22038 for problems raised by this behavior. + this->Makefile->RemoveDefinition(this->VariableName); + } + } else { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if (this->AlreadyInCacheWithoutMetaInfo) { + this->Makefile->AddCacheDefinition(this->VariableName, "", + this->VariableDocumentation.c_str(), + this->VariableType); + } + } +} + +void cmFindBase::StoreFindResult(const std::string& value) +{ + bool force = + this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) == cmPolicies::NEW; + + if (!value.empty()) { + this->Makefile->AddCacheDefinition(this->VariableName, value, + this->VariableDocumentation.c_str(), + this->VariableType, force); + return; + } + + this->Makefile->AddCacheDefinition( + this->VariableName, cmStrCat(this->VariableName, "-NOTFOUND"), + this->VariableDocumentation.c_str(), this->VariableType, force); + + if (this->Required) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Could not find ", this->VariableName, " using the following ", + (this->FindCommandName == "find_file" || + this->FindCommandName == "find_path" + ? "files" + : "names"), + ": ", cmJoin(this->Names, ", "))); + cmSystemTools::SetFatalErrorOccured(); + } +} + cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName, cmFindBase const* findBase) : FindCommand(findBase) diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 57a40be..c2a9288 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -9,6 +9,7 @@ #include <vector> #include "cmFindCommon.h" +#include "cmStateTypes.h" class cmExecutionStatus; @@ -21,7 +22,7 @@ class cmExecutionStatus; class cmFindBase : public cmFindCommon { public: - cmFindBase(cmExecutionStatus& status); + cmFindBase(std::string findCommandName, cmExecutionStatus& status); virtual ~cmFindBase() = default; /** @@ -39,8 +40,15 @@ protected: // if it has documentation in the cache bool CheckForVariableInCache(); + void NormalizeFindResult(); + void StoreFindResult(const std::string& value); + + // actual find command name + std::string FindCommandName; + // use by command during find std::string VariableDocumentation; + cmStateEnums::CacheEntryType VariableType = cmStateEnums::UNINITIALIZED; std::string VariableName; std::vector<std::string> Names; bool NamesPerDir = false; diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx index 29a2bc4..a88c1b1 100644 --- a/Source/cmFindFileCommand.cxx +++ b/Source/cmFindFileCommand.cxx @@ -2,12 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFindFileCommand.h" +#include "cmStateTypes.h" + class cmExecutionStatus; cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status) - : cmFindPathCommand(status) + : cmFindPathCommand("find_file", status) { this->IncludeFileInPath = true; + this->VariableType = cmStateEnums::FILEPATH; } bool cmFindFile(std::vector<std::string> const& args, diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 49b1bd7..b1f4275 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -12,7 +12,6 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" -#include "cmMessageType.h" #include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" @@ -22,30 +21,26 @@ class cmExecutionStatus; cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status) - : cmFindBase(status) + : cmFindBase("find_library", status) { this->EnvironmentPath = "LIB"; this->NamesPerDirAllowed = true; + this->VariableDocumentation = "Path to a library."; + this->VariableType = cmStateEnums::FILEPATH; } // cmFindLibraryCommand bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) { this->DebugMode = this->ComputeIfDebugModeWanted(); - this->VariableDocumentation = "Path to a library."; this->CMakePathName = "LIBRARY"; + if (!this->ParseArguments(argsIn)) { return false; } + if (this->AlreadyInCache) { - // If the user specifies the entry on the command line without a - // type we should add the type and docstring but keep the original - // value. - if (this->AlreadyInCacheWithoutMetaInfo) { - this->Makefile->AddCacheDefinition(this->VariableName, "", - this->VariableDocumentation.c_str(), - cmStateEnums::FILEPATH); - } + this->NormalizeFindResult(); return true; } @@ -75,24 +70,7 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) } std::string const library = this->FindLibrary(); - if (!library.empty()) { - // Save the value in the cache - this->Makefile->AddCacheDefinition(this->VariableName, library, - this->VariableDocumentation.c_str(), - cmStateEnums::FILEPATH); - return true; - } - std::string notfound = this->VariableName + "-NOTFOUND"; - this->Makefile->AddCacheDefinition(this->VariableName, notfound, - this->VariableDocumentation.c_str(), - cmStateEnums::FILEPATH); - if (this->Required) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "Could not find " + this->VariableName + - " using the following names: " + cmJoin(this->Names, ", ")); - cmSystemTools::SetFatalErrorOccured(); - } + this->StoreFindResult(library); return true; } @@ -208,7 +186,8 @@ std::string cmFindLibraryCommand::FindLibrary() struct cmFindLibraryHelper { - cmFindLibraryHelper(cmMakefile* mf, cmFindBase const* findBase); + cmFindLibraryHelper(std::string debugName, cmMakefile* mf, + cmFindBase const* findBase); // Context information. cmMakefile* Makefile; @@ -280,11 +259,11 @@ struct cmFindLibraryHelper }; }; -cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf, +cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf, cmFindBase const* base) : Makefile(mf) , DebugMode(base->DebugModeEnabled()) - , DebugSearches("find_library", base) + , DebugSearches(std::move(debugName), base) { this->GG = this->Makefile->GetGlobalGenerator(); @@ -374,7 +353,7 @@ void cmFindLibraryHelper::AddName(std::string const& name) regex += "(\\.[0-9]+\\.[0-9]+)?"; } regex += "$"; - entry.Regex.compile(regex.c_str()); + entry.Regex.compile(regex); this->Names.push_back(std::move(entry)); } @@ -485,7 +464,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary() std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir() { // Search for all names in each directory. - cmFindLibraryHelper helper(this->Makefile, this); + cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this); for (std::string const& n : this->Names) { helper.AddName(n); } @@ -502,7 +481,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir() std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName() { // Search the entire path for each name. - cmFindLibraryHelper helper(this->Makefile, this); + cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this); for (std::string const& n : this->Names) { // Switch to searching for this name. helper.SetName(n); diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 3fb0826..126cc2f 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -2,70 +2,53 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFindPathCommand.h" +#include <utility> + #include "cmsys/Glob.hxx" -#include "cmMakefile.h" -#include "cmMessageType.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; -cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status) - : cmFindBase(status) +cmFindPathCommand::cmFindPathCommand(std::string findCommandName, + cmExecutionStatus& status) + : cmFindBase(std::move(findCommandName), status) { this->EnvironmentPath = "INCLUDE"; this->IncludeFileInPath = false; + this->VariableDocumentation = "Path to a file."; + this->VariableType = cmStateEnums::PATH; +} +cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status) + : cmFindPathCommand("find_path", status) +{ } // cmFindPathCommand bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn) { this->DebugMode = this->ComputeIfDebugModeWanted(); - this->VariableDocumentation = "Path to a file."; this->CMakePathName = "INCLUDE"; + if (!this->ParseArguments(argsIn)) { return false; } + if (this->AlreadyInCache) { - // If the user specifies the entry on the command line without a - // type we should add the type and docstring but keep the original - // value. - if (this->AlreadyInCacheWithoutMetaInfo) { - this->Makefile->AddCacheDefinition( - this->VariableName, "", this->VariableDocumentation.c_str(), - (this->IncludeFileInPath ? cmStateEnums::FILEPATH - : cmStateEnums::PATH)); - } + this->NormalizeFindResult(); return true; } std::string result = this->FindHeader(); - if (!result.empty()) { - this->Makefile->AddCacheDefinition( - this->VariableName, result, this->VariableDocumentation.c_str(), - (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH); - return true; - } - this->Makefile->AddCacheDefinition( - this->VariableName, this->VariableName + "-NOTFOUND", - this->VariableDocumentation.c_str(), - (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH); - if (this->Required) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "Could not find " + this->VariableName + - " using the following files: " + cmJoin(this->Names, ", ")); - cmSystemTools::SetFatalErrorOccured(); - } + this->StoreFindResult(result); return true; } std::string cmFindPathCommand::FindHeader() { - std::string debug_name = this->IncludeFileInPath ? "find_file" : "find_path"; - cmFindBaseDebugState debug(debug_name, this); + cmFindBaseDebugState debug(this->FindCommandName, this); std::string header; if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) { header = this->FindFrameworkHeader(debug); diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index 6101ea1..c7281f1 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -22,6 +22,7 @@ class cmFindPathCommand : public cmFindBase { public: cmFindPathCommand(cmExecutionStatus& status); + cmFindPathCommand(std::string findCommandName, cmExecutionStatus& status); bool InitialPass(std::vector<std::string> const& args); diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index c22462e..76fc4a4 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -4,6 +4,7 @@ #include <algorithm> #include <string> +#include <utility> #include "cmMakefile.h" #include "cmMessageType.h" @@ -20,8 +21,9 @@ class cmExecutionStatus; struct cmFindProgramHelper { - cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base) - : DebugSearches("find_program", base) + cmFindProgramHelper(std::string debugName, cmMakefile* makefile, + cmFindBase const* base) + : DebugSearches(std::move(debugName), base) , Makefile(makefile) , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109)) { @@ -145,52 +147,31 @@ struct cmFindProgramHelper }; cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status) - : cmFindBase(status) + : cmFindBase("find_program", status) { this->NamesPerDirAllowed = true; + this->VariableDocumentation = "Path to a program."; + this->VariableType = cmStateEnums::FILEPATH; } // cmFindProgramCommand bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn) { this->DebugMode = this->ComputeIfDebugModeWanted(); - this->VariableDocumentation = "Path to a program."; this->CMakePathName = "PROGRAM"; + // call cmFindBase::ParseArguments if (!this->ParseArguments(argsIn)) { return false; } + if (this->AlreadyInCache) { - // If the user specifies the entry on the command line without a - // type we should add the type and docstring but keep the original - // value. - if (this->AlreadyInCacheWithoutMetaInfo) { - this->Makefile->AddCacheDefinition(this->VariableName, "", - this->VariableDocumentation.c_str(), - cmStateEnums::FILEPATH); - } + this->NormalizeFindResult(); return true; } std::string const result = this->FindProgram(); - if (!result.empty()) { - // Save the value in the cache - this->Makefile->AddCacheDefinition(this->VariableName, result, - this->VariableDocumentation.c_str(), - cmStateEnums::FILEPATH); - - return true; - } - this->Makefile->AddCacheDefinition( - this->VariableName, this->VariableName + "-NOTFOUND", - this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH); - if (this->Required) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "Could not find " + this->VariableName + - " using the following names: " + cmJoin(this->Names, ", ")); - cmSystemTools::SetFatalErrorOccured(); - } + this->StoreFindResult(result); return true; } @@ -222,7 +203,7 @@ std::string cmFindProgramCommand::FindNormalProgram() std::string cmFindProgramCommand::FindNormalProgramNamesPerDir() { // Search for all names in each directory. - cmFindProgramHelper helper(this->Makefile, this); + cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this); for (std::string const& n : this->Names) { helper.AddName(n); } @@ -245,7 +226,7 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir() std::string cmFindProgramCommand::FindNormalProgramDirsPerName() { // Search the entire path for each name. - cmFindProgramHelper helper(this->Makefile, this); + cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this); for (std::string const& n : this->Names) { // Switch to searching for this name. helper.SetName(n); diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index bcacb15..4845a6d 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -17,6 +17,7 @@ #include <utility> #include <cm/memory> +#include <cm/optional> #include <cm/string_view> #include <cmext/string_view> @@ -25,7 +26,7 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" +#include "cmPolicies.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -113,9 +114,11 @@ bool cmForEachFunctionBlocker::ReplayItems( // At end of for each execute recorded commands // store the old value - std::string oldDef; - if (cmProp d = mf.GetDefinition(this->Args.front())) { - oldDef = *d; + cm::optional<std::string> oldDef; + if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { + oldDef = mf.GetSafeDefinition(this->Args.front()); + } else if (mf.IsNormalDefinitionSet(this->Args.front())) { + oldDef = *mf.GetDefinition(this->Args.front()); } auto restore = false; @@ -131,9 +134,14 @@ bool cmForEachFunctionBlocker::ReplayItems( } if (restore) { - // restore the variable to its prior value - mf.AddDefinition(this->Args.front(), oldDef); + if (oldDef) { + // restore the variable to its prior value + mf.AddDefinition(this->Args.front(), *oldDef); + } else { + mf.RemoveDefinition(this->Args.front()); + } } + return true; } @@ -185,10 +193,15 @@ bool cmForEachFunctionBlocker::ReplayZipLists( assert("Sanity check" && iterationVars.size() == values.size()); // Store old values for iteration variables - std::map<std::string, std::string> oldDefs; + std::map<std::string, cm::optional<std::string>> oldDefs; for (auto i = 0u; i < values.size(); ++i) { - if (cmProp d = mf.GetDefinition(iterationVars[i])) { - oldDefs.emplace(iterationVars[i], *d); + const auto& varName = iterationVars[i]; + if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { + oldDefs.emplace(varName, mf.GetSafeDefinition(varName)); + } else if (mf.IsNormalDefinitionSet(varName)) { + oldDefs.emplace(varName, *mf.GetDefinition(varName)); + } else { + oldDefs.emplace(varName, cm::nullopt); } } @@ -226,7 +239,11 @@ bool cmForEachFunctionBlocker::ReplayZipLists( // Restore the variables to its prior value if (restore) { for (auto const& p : oldDefs) { - mf.AddDefinition(p.first, p.second); + if (p.second) { + mf.AddDefinition(p.first, *p.second); + } else { + mf.RemoveDefinition(p.first); + } } } return true; diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 43f384a..06778b1 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -42,6 +42,11 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name, #else static_cast<void>(encoding); #endif + if (encoding == codecvt::UTF8_WITH_BOM) { + // Write the BOM encoding header into the file + char magic[] = { char(0xEF), char(0xBB), char(0xBF) }; + this->write(magic, 3); + } } cmGeneratedFileStream::~cmGeneratedFileStream() diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index e40316e..7125170 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -14,6 +14,7 @@ #include <utility> #include <cm/iterator> +#include <cm/optional> #include <cm/string_view> #include <cm/vector> #include <cmext/algorithm> @@ -23,6 +24,7 @@ #include "cmsys/String.h" #include "cmAlgorithms.h" +#include "cmComputeLinkInformation.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" @@ -1627,8 +1629,8 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode type != cmStateEnums::OBJECT_LIBRARY) { std::ostringstream e; e << "Objects of target \"" << tgtName - << "\" referenced but is not an allowed library types (EXECUTABLE, " - << "STATIC, SHARED, MODULE, OBJECT)."; + << "\" referenced but is not one of the allowed target types " + << "(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT)."; reportError(context, content->GetOriginalExpression(), e.str()); return std::string(); } @@ -1687,6 +1689,54 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode } } targetObjectsNode; +static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode +{ + TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default) + + std::string Evaluate( + const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + { + std::string tgtName = parameters.front(); + cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName); + if (!gt) { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but no such target exists."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + cmStateEnums::TargetType type = gt->GetType(); + if (type != cmStateEnums::EXECUTABLE && + type != cmStateEnums::SHARED_LIBRARY && + type != cmStateEnums::MODULE_LIBRARY) { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but is not one of the allowed target types " + << "(EXECUTABLE, SHARED, MODULE)."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + + if (auto* cli = gt->GetLinkInformation(context->Config)) { + std::vector<std::string> dllPaths; + auto const& dlls = cli->GetRuntimeDLLs(); + + for (auto const& dll : dlls) { + if (auto loc = dll->MaybeGetLocation(context->Config)) { + dllPaths.emplace_back(*loc); + } + } + + return cmJoin(dllPaths, ";"); + } + + return ""; + } +} targetRuntimeDllsNode; + static const struct CompileFeaturesNode : public cmGeneratorExpressionNode { CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default) @@ -2603,6 +2653,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode( { "TARGET_EXISTS", &targetExistsNode }, { "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode }, { "TARGET_GENEX_EVAL", &targetGenexEvalNode }, + { "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode }, { "GENEX_EVAL", &genexEvalNode }, { "BUILD_INTERFACE", &buildInterfaceNode }, { "INSTALL_INTERFACE", &installInterfaceNode }, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index efac06a..e2ec82a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -52,6 +52,11 @@ class cmMessenger; +namespace { +const cmsys::RegularExpression FrameworkRegularExpression( + "^(.*/)?([^/]*)\\.framework/(.*)$"); +} + template <> cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( cmGeneratorTarget const* tgt, cmMessenger* /* messenger */, @@ -970,7 +975,7 @@ cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport( std::string const& lang, const char* suffix) const { cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix)); - if (propertyValue == nullptr) { + if (!propertyValue) { // Check if we should use the value set by another language. if (lang == "OBJC") { propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix); @@ -1062,6 +1067,20 @@ const std::string& cmGeneratorTarget::GetLocation( return location; } +cm::optional<std::string> cmGeneratorTarget::MaybeGetLocation( + std::string const& config) const +{ + cm::optional<std::string> location; + if (cmGeneratorTarget::ImportInfo const* imp = this->GetImportInfo(config)) { + if (!imp->Location.empty()) { + location = imp->Location; + } + } else { + location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact); + } + return location; +} + std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands() const { @@ -2243,8 +2262,16 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const return cmSystemTools::GetFilenameName(info->Location); } // Use the soname given if any. + if (this->IsFrameworkOnApple()) { + cmsys::RegularExpressionMatch match; + if (FrameworkRegularExpression.find(info->SOName.c_str(), match)) { + auto frameworkName = match.match(2); + auto fileName = match.match(3); + return cmStrCat(frameworkName, ".framework/", fileName); + } + } if (cmHasLiteralPrefix(info->SOName, "@rpath/")) { - return info->SOName.substr(6); + return info->SOName.substr(cmStrLen("@rpath/")); } return info->SOName; } @@ -4701,21 +4728,20 @@ bool cmGeneratorTarget::ComputeCompileFeatures( cmStrCat(cmSystemTools::UpperCase(config), '-', language.first); BTs<std::string> const* standardToCopy = this->GetLanguageStandardProperty(language.second, config); - if (standardToCopy != nullptr) { + if (standardToCopy) { this->LanguageStandardMap[key] = *standardToCopy; generatorTargetLanguageStandard = &this->LanguageStandardMap[key]; } else { cmProp defaultStandard = this->Makefile->GetDefinition( cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT")); - if (defaultStandard != nullptr) { + if (defaultStandard) { this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard); generatorTargetLanguageStandard = &this->LanguageStandardMap[key]; } } // Custom updates for the CUDA standard. - if (generatorTargetLanguageStandard != nullptr && - language.first == "CUDA") { + if (generatorTargetLanguageStandard && language.first == "CUDA") { if (generatorTargetLanguageStandard->Value == "98") { this->LanguageStandardMap[key].Value = "03"; } @@ -6446,9 +6472,19 @@ std::string cmGeneratorTarget::GetDirectory( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { + auto fullPath = this->Target->ImportedGetFullPath(config, artifact); + if (this->IsFrameworkOnApple()) { + cmsys::RegularExpressionMatch match; + if (FrameworkRegularExpression.find(fullPath.c_str(), match)) { + auto path = match.match(1); + if (!path.empty()) { + path.erase(path.length() - 1); + } + return path; + } + } // Return the directory from which the target is imported. - return cmSystemTools::GetFilenamePath( - this->Target->ImportedGetFullPath(config, artifact)); + return cmSystemTools::GetFilenamePath(fullPath); } if (OutputInfo const* info = this->GetOutputInfo(config)) { // Return the directory in which the target will be built. @@ -6757,7 +6793,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( return; } iface.Exists = true; - iface.Explicit = cmp0022NEW || explicitLibraries != nullptr; + iface.Explicit = cmp0022NEW || explicitLibraries; if (explicitLibraries) { // The interface libraries have been explicitly set. diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 8fe70ab..2935e0b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,6 +14,8 @@ #include <utility> #include <vector> +#include <cm/optional> + #include "cmLinkItem.h" #include "cmListFileCache.h" #include "cmPolicies.h" @@ -50,6 +52,9 @@ public: bool CanCompileSources() const; const std::string& GetLocation(const std::string& config) const; + /** Get the full path to the target's main artifact, if known. */ + cm::optional<std::string> MaybeGetLocation(std::string const& config) const; + std::vector<cmCustomCommand> const& GetPreBuildCommands() const; std::vector<cmCustomCommand> const& GetPreLinkCommands() const; std::vector<cmCustomCommand> const& GetPostBuildCommands() const; diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index ed5bff5..32238e4 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -159,13 +159,11 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout, const std::string& config) { std::string outpath; - std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory(); if (this->TagType != GhsMultiGpj::SUBPROJECT) { // set target binary file destination outpath = this->GeneratorTarget->GetDirectory(config); - outpath = - this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath); + outpath = this->LocalGenerator->MaybeRelativeToCurBinDir(outpath); /* clang-format off */ fout << " :binDirRelative=\"" << outpath << "\"\n" " -o \"" << this->TargetNameReal << "\"\n"; @@ -369,7 +367,6 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( // if the command specified a working directory use it. std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory(); - std::string currentBinDir = dir; std::string workingDir = ccg.GetWorkingDirectory(); if (!workingDir.empty()) { dir = workingDir; @@ -427,8 +424,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( // working directory will be the start-output directory. bool had_slash = cmd.find('/') != std::string::npos; if (workingDir.empty()) { - cmd = - this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, cmd); + cmd = this->LocalGenerator->MaybeRelativeToCurBinDir(cmd); } bool has_slash = cmd.find('/') != std::string::npos; if (had_slash && !has_slash) { @@ -710,7 +706,7 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride( std::ostream& fout, const cmSourceFile* sourceFile) { cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE"); - if (nullptr != rawLangProp) { + if (rawLangProp) { std::string sourceLangProp(*rawLangProp); std::string const& extension = sourceFile->GetExtension(); if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) { diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 996fcff..b7bac9c 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -30,7 +30,7 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm) /* * Borland Make does not support long line depend rule, as we have tested * generate one source file includes 40000 header files, and generate - * depend.make in one line(use line continued tag), and error occured: + * depend.make in one line(use line continued tag), and error occurred: * ** Fatal CMakeFiles\main.dir\depend.make 1224: Rule line too long ** * we disable long line dependencies rule generation for Borland make */ diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ab76260..d7da0d3 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2077,7 +2077,7 @@ bool cmGlobalGenerator::Open(const std::string& bindir, std::string cmGlobalGenerator::GenerateCMakeBuildCommand( const std::string& target, const std::string& config, - const std::string& native, bool ignoreErrors) + const std::string& parallel, const std::string& native, bool ignoreErrors) { std::string makeCommand = cmSystemTools::GetCMakeCommand(); makeCommand = @@ -2087,6 +2087,11 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand( makeCommand += config; makeCommand += "\""; } + if (!parallel.empty()) { + makeCommand += " --parallel \""; + makeCommand += parallel; + makeCommand += "\""; + } if (!target.empty()) { makeCommand += " --target \""; makeCommand += target; @@ -2255,7 +2260,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, // Check whether the genex expansion of the property agrees in all // configurations. - if (trueCount && falseCount) { + if (trueCount > 0 && falseCount > 0) { std::ostringstream e; e << "The EXCLUDE_FROM_ALL property of target \"" << target->GetName() << "\" varies by configuration. This is not supported by the \"" @@ -3022,10 +3027,8 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, } // Shorten the output name (in expected use case). - cmStateDirectory cmDir = - this->GetMakefiles()[0]->GetStateSnapshot().GetDirectory(); - std::string fname = cmDir.ConvertToRelPathIfNotContained( - this->GetMakefiles()[0]->GetState()->GetBinaryDirectory(), outputs[0]); + std::string fname = + this->LocalGenerators[0]->MaybeRelativeToTopBinDir(outputs[0]); // Associate the hash with this output. this->RuleHashes[fname] = hash; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 590de26..fee0359 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -249,9 +249,13 @@ public: virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; - /** Generate a "cmake --build" call for a given target and config. */ + /** + * Generate a "cmake --build" call for a given target, config and parallel + * level. + */ std::string GenerateCMakeBuildCommand(const std::string& target, const std::string& config, + const std::string& parallel, const std::string& native, bool ignoreErrors); diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 172cf3f..7cf3e93 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -375,7 +375,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout, } void cmGlobalGhsMultiGenerator::WriteProjectLine( - std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root, + std::ostream& fout, cmGeneratorTarget const* target, std::string& rootBinaryDir) { cmProp projName = target->GetProperty("GENERATOR_FILE_NAME"); @@ -383,7 +383,7 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine( if (projName && projType) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); + dir = cmSystemTools::ForceToRelativePath(rootBinaryDir, dir); if (dir == ".") { dir.clear(); } else { @@ -433,7 +433,7 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) target->GetName(), "] had a cycle.\n")); } else { for (auto& tgt : build) { - this->WriteProjectLine(fbld, tgt, root, rootBinaryDir); + this->WriteProjectLine(fbld, tgt, rootBinaryDir); } } fbld.Close(); @@ -490,7 +490,7 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget( target->GetType() == cmStateEnums::SHARED_LIBRARY) { continue; } - this->WriteProjectLine(fbld, target, root, rootBinaryDir); + this->WriteProjectLine(fbld, target, rootBinaryDir); } } fbld.Close(); diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 7753b31..bd08301 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -103,7 +103,7 @@ private: void WriteSubProjects(std::ostream& fout, std::string& all_target); void WriteTargets(cmLocalGenerator* root); void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target, - cmLocalGenerator* root, std::string& rootBinaryDir); + std::string& rootBinaryDir); void WriteCustomRuleBOD(std::ostream& fout); void WriteCustomTargetBOD(std::ostream& fout); void WriteAllTarget(cmLocalGenerator* root, diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index 36f583f..f08b1da 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -2,7 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGlobalNMakeMakefileGenerator.h" +#include "cmsys/RegularExpression.hxx" + #include "cmDocumentationEntry.h" +#include "cmDuration.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmState.h" @@ -34,6 +37,42 @@ void cmGlobalNMakeMakefileGenerator::EnableLanguage( this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } +bool cmGlobalNMakeMakefileGenerator::FindMakeProgram(cmMakefile* mf) +{ + if (!this->cmGlobalGenerator::FindMakeProgram(mf)) { + return false; + } + if (cmProp nmakeCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) { + std::vector<std::string> command{ *nmakeCommand, "-?" }; + std::string out; + std::string err; + if (!cmSystemTools::RunSingleCommand(command, &out, &err, nullptr, nullptr, + cmSystemTools::OUTPUT_NONE, + cmDuration(30))) { + mf->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("Running\n '", cmJoin(command, "' '"), + "'\n" + "failed with:\n ", + err)); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + cmsys::RegularExpression regex( + "Program Maintenance Utility Version ([1-9][0-9.]+)"); + if (regex.find(err)) { + this->NMakeVersion = regex.match(1); + this->CheckNMakeFeatures(); + } + } + return true; +} + +void cmGlobalNMakeMakefileGenerator::CheckNMakeFeatures() +{ + this->NMakeSupportsUTF8 = !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NMakeVersion.c_str(), "9"); +} + void cmGlobalNMakeMakefileGenerator::GetDocumentation( cmDocumentationEntry& entry) { diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index abe64ff..402b89f 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -31,7 +31,7 @@ public: /** Get encoding used by generator for makefile files */ codecvt::Encoding GetMakefileEncoding() const override { - return codecvt::ANSI; + return this->NMakeSupportsUTF8 ? codecvt::UTF8_WITH_BOM : codecvt::ANSI; } /** Get the documentation entry for this generator. */ @@ -55,6 +55,11 @@ protected: void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; private: + bool NMakeSupportsUTF8 = false; + std::string NMakeVersion; + bool FindMakeProgram(cmMakefile* mf) override; + void CheckNMakeFeatures(); + void PrintCompilerAdvice(std::ostream& os, std::string const& lang, const char* envVar) const override; }; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c502fb8..6034434 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -9,6 +9,8 @@ #include <cm/iterator> #include <cm/memory> +#include <cm/optional> +#include <cm/string_view> #include <cmext/algorithm> #include <cmext/memory> @@ -214,22 +216,32 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, { // Write explicit outputs for (std::string const& output : build.Outputs) { - buildStr += cmStrCat(' ', this->EncodePath(output)); + buildStr = cmStrCat(buildStr, ' ', this->EncodePath(output)); if (this->ComputingUnknownDependencies) { this->CombinedBuildOutputs.insert(output); } } // Write implicit outputs - if (!build.ImplicitOuts.empty()) { - buildStr += " |"; + if (!build.ImplicitOuts.empty() || !build.WorkDirOuts.empty()) { + buildStr = cmStrCat(buildStr, " |"); for (std::string const& implicitOut : build.ImplicitOuts) { - buildStr += cmStrCat(' ', this->EncodePath(implicitOut)); + buildStr = cmStrCat(buildStr, ' ', this->EncodePath(implicitOut)); + if (this->ComputingUnknownDependencies) { + this->CombinedBuildOutputs.insert(implicitOut); + } + } + for (std::string const& workdirOut : build.WorkDirOuts) { + // Repeat some outputs, but expressed as absolute paths. + // This helps Ninja handle absolute paths found in a depfile. + // FIXME: Unfortunately this causes Ninja to stat the file twice. + // We could avoid this if Ninja Issue 1251 were fixed. + buildStr = cmStrCat(buildStr, " ${cmake_ninja_workdir}", + this->EncodePath(workdirOut)); } } - buildStr += ':'; // Write the rule. - buildStr += cmStrCat(' ', build.Rule); + buildStr = cmStrCat(buildStr, ": ", build.Rule); } std::string arguments; @@ -305,21 +317,46 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() this->AddRule(rule); } +void cmGlobalNinjaGenerator::CCOutputs::Add( + std::vector<std::string> const& paths) +{ + for (std::string const& path : paths) { + std::string out = this->GG->ConvertToNinjaPath(path); + if (this->GG->SupportsImplicitOuts() && + !cmSystemTools::FileIsFullPath(out)) { + // This output is expressed as a relative path. Repeat it, + // but expressed as an absolute path for Ninja Issue 1251. + this->WorkDirOuts.emplace_back(out); + } + this->GG->SeenCustomCommandOutput(out); + this->ExplicitOuts.emplace_back(std::move(out)); + } +} + void cmGlobalNinjaGenerator::WriteCustomCommandBuild( - const std::string& command, const std::string& description, - const std::string& comment, const std::string& depfile, - const std::string& job_pool, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const std::string& config, - const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps) + std::string const& command, std::string const& description, + std::string const& comment, std::string const& depfile, + std::string const& job_pool, bool uses_terminal, bool restat, + std::string const& config, CCOutputs outputs, cmNinjaDeps explicitDeps, + cmNinjaDeps orderOnlyDeps) { this->AddCustomCommandRule(); + if (this->ComputingUnknownDependencies) { + // we need to track every dependency that comes in, since we are trying + // to find dependencies that are side effects of build commands + for (std::string const& dep : explicitDeps) { + this->CombinedCustomCommandExplicitDependencies.insert(dep); + } + } + { cmNinjaBuild build("CUSTOM_COMMAND"); build.Comment = comment; - build.Outputs = outputs; - build.ExplicitDeps = explicitDeps; - build.OrderOnlyDeps = orderOnlyDeps; + build.Outputs = std::move(outputs.ExplicitOuts); + build.WorkDirOuts = std::move(outputs.WorkDirOuts); + build.ExplicitDeps = std::move(explicitDeps); + build.OrderOnlyDeps = std::move(orderOnlyDeps); cmNinjaVars& vars = build.Variables; { @@ -349,14 +386,6 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( this->WriteBuild(*this->GetImplFileStream(config), build); } } - - if (this->ComputingUnknownDependencies) { - // we need to track every dependency that comes in, since we are trying - // to find dependencies that are side effects of build commands - for (std::string const& dep : explicitDeps) { - this->CombinedCustomCommandExplicitDependencies.insert(dep); - } - } } void cmGlobalNinjaGenerator::AddMacOSXContentRule() @@ -503,14 +532,7 @@ std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator( codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const { -#ifdef _WIN32 - // Ninja on Windows does not support non-ANSI characters. - // https://github.com/ninja-build/ninja/issues/1195 - return codecvt::ANSI; -#else - // No encoding conversion needed on other platforms. - return codecvt::None; -#endif + return this->NinjaExpectedEncoding; } void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry) @@ -732,6 +754,61 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures() this->NinjaSupportsMetadataOnRegeneration = !cmSystemTools::VersionCompare( cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), RequiredNinjaVersionForMetadataOnRegeneration().c_str()); +#ifdef _WIN32 + this->NinjaSupportsCodePage = !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), + RequiredNinjaVersionForCodePage().c_str()); + if (this->NinjaSupportsCodePage) { + this->CheckNinjaCodePage(); + } else { + this->NinjaExpectedEncoding = codecvt::ANSI; + } +#endif +} + +void cmGlobalNinjaGenerator::CheckNinjaCodePage() +{ + std::vector<std::string> command{ this->NinjaCommand, "-t", "wincodepage" }; + std::string output; + std::string error; + int result; + if (!cmSystemTools::RunSingleCommand(command, &output, &error, &result, + nullptr, cmSystemTools::OUTPUT_NONE)) { + this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("Running\n '", + cmJoin(command, "' '"), + "'\n" + "failed with:\n ", + error)); + cmSystemTools::SetFatalErrorOccured(); + } else if (result == 0) { + std::istringstream outputStream(output); + std::string line; + bool found = false; + while (cmSystemTools::GetLineFromStream(outputStream, line)) { + if (cmHasLiteralPrefix(line, "Build file encoding: ")) { + cm::string_view lineView(line); + cm::string_view encoding = + lineView.substr(cmStrLen("Build file encoding: ")); + if (encoding == "UTF-8") { + // Ninja expects UTF-8. We use that internally. No conversion needed. + this->NinjaExpectedEncoding = codecvt::None; + } else { + this->NinjaExpectedEncoding = codecvt::ANSI; + } + found = true; + break; + } + } + if (!found) { + this->GetCMakeInstance()->IssueMessage( + MessageType::WARNING, + "Could not determine Ninja's code page, defaulting to UTF-8"); + this->NinjaExpectedEncoding = codecvt::None; + } + } else { + this->NinjaExpectedEncoding = codecvt::ANSI; + } } bool cmGlobalNinjaGenerator::CheckLanguages( @@ -1073,10 +1150,8 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( return f->second; } - const auto& ng = - cm::static_reference_cast<cmLocalNinjaGenerator>(this->LocalGenerators[0]); - std::string const& bin_dir = ng.GetState()->GetBinaryDirectory(); - std::string convPath = ng.MaybeConvertToRelativePath(bin_dir, path); + std::string convPath = + this->LocalGenerators[0]->MaybeRelativeToTopBinDir(path); convPath = this->NinjaOutputPath(convPath); #ifdef _WIN32 std::replace(convPath.begin(), convPath.end(), '/', '\\'); @@ -1150,6 +1225,8 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) const void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (auto const& asd : this->AssumedSourceDependencies) { + CCOutputs outputs(this); + outputs.ExplicitOuts.emplace_back(asd.first); cmNinjaDeps orderOnlyDeps; std::copy(asd.second.begin(), asd.second.end(), std::back_inserter(orderOnlyDeps)); @@ -1158,8 +1235,8 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() "Assume dependencies for generated source file.", /*depfile*/ "", /*job_pool*/ "", /*uses_terminal*/ false, - /*restat*/ true, cmNinjaDeps(1, asd.first), "", cmNinjaDeps(), - orderOnlyDeps); + /*restat*/ true, std::string(), outputs, cmNinjaDeps(), + std::move(orderOnlyDeps)); } } @@ -2198,14 +2275,22 @@ Compilation of source files within a target is split into the following steps: (because the latter consumes the module). */ -static std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( +namespace { + +struct cmSourceInfo +{ + cmScanDepInfo ScanDep; + std::vector<std::string> Includes; +}; + +cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( std::string const& arg_tdi, std::string const& arg_pp); +} int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, std::vector<std::string>::const_iterator argEnd) { std::string arg_tdi; - std::string arg_src; std::string arg_pp; std::string arg_dep; std::string arg_obj; @@ -2214,8 +2299,6 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, for (std::string const& arg : cmMakeRange(argBeg, argEnd)) { if (cmHasLiteralPrefix(arg, "--tdi=")) { arg_tdi = arg.substr(6); - } else if (cmHasLiteralPrefix(arg, "--src=")) { - arg_src = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--pp=")) { arg_pp = arg.substr(5); } else if (cmHasLiteralPrefix(arg, "--dep=")) { @@ -2256,11 +2339,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, cmSystemTools::Error("-E cmake_ninja_depends requires value for --lang="); return 1; } - if (arg_src.empty()) { - arg_src = cmStrCat("<", arg_obj, " input file>"); - } - std::unique_ptr<cmSourceInfo> info; + cm::optional<cmSourceInfo> info; if (arg_lang == "Fortran") { info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp); } else { @@ -2275,7 +2355,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, return 1; } - info->PrimaryOutput = arg_obj; + info->ScanDep.PrimaryOutput = arg_obj; { cmGeneratedFileStream depfile(arg_dep); @@ -2286,7 +2366,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, depfile << "\n"; } - if (!cmScanDepFormat_P1689_Write(arg_ddi, arg_src, *info)) { + if (!cmScanDepFormat_P1689_Write(arg_ddi, info->ScanDep)) { cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi)); return 1; @@ -2294,9 +2374,12 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, return 0; } -std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( +namespace { + +cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( std::string const& arg_tdi, std::string const& arg_pp) { + cm::optional<cmSourceInfo> info; cmFortranCompiler fc; std::vector<std::string> includes; { @@ -2309,7 +2392,7 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends failed to parse ", arg_tdi, reader.getFormattedErrorMessages())); - return nullptr; + return info; } } @@ -2336,19 +2419,19 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) { cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp)); - return nullptr; + return info; } if (cmFortran_yyparse(parser.Scanner) != 0) { // Failed to parse the file. - return nullptr; + return info; } - auto info = cm::make_unique<cmSourceInfo>(); + info = cmSourceInfo(); for (std::string const& provide : finfo.Provides) { cmSourceReqInfo src_info; src_info.LogicalName = provide; src_info.CompiledModulePath = provide; - info->Provides.emplace_back(src_info); + info->ScanDep.Provides.emplace_back(src_info); } for (std::string const& require : finfo.Requires) { // Require modules not provided in the same source. @@ -2358,13 +2441,14 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( cmSourceReqInfo src_info; src_info.LogicalName = require; src_info.CompiledModulePath = require; - info->Requires.emplace_back(src_info); + info->ScanDep.Requires.emplace_back(src_info); } for (std::string const& include : finfo.Includes) { info->Includes.push_back(include); } return info; } +} bool cmGlobalNinjaGenerator::WriteDyndepFile( std::string const& dir_top_src, std::string const& dir_top_bld, @@ -2379,17 +2463,17 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( cmStateSnapshot snapshot = this->GetCMakeInstance()->GetCurrentSnapshot(); snapshot.GetDirectory().SetCurrentSource(dir_cur_src); snapshot.GetDirectory().SetCurrentBinary(dir_cur_bld); - snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str()); - snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str()); auto mfd = cm::make_unique<cmMakefile>(this, snapshot); auto lgd = this->CreateLocalGenerator(mfd.get()); + lgd->SetRelativePathTopSource(dir_top_src); + lgd->SetRelativePathTopBinary(dir_top_bld); this->Makefiles.push_back(std::move(mfd)); this->LocalGenerators.push_back(std::move(lgd)); } - std::vector<cmSourceInfo> objects; + std::vector<cmScanDepInfo> objects; for (std::string const& arg_ddi : arg_ddis) { - cmSourceInfo info; + cmScanDepInfo info; if (!cmScanDepFormat_P1689_Parse(arg_ddi, &info)) { cmSystemTools::Error( cmStrCat("-E cmake_ninja_dyndep failed to parse ddi file ", arg_ddi)); @@ -2425,7 +2509,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // We do this after loading the modules provided by linked targets // in case we have one of the same name that must be preferred. Json::Value tm = Json::objectValue; - for (cmSourceInfo const& object : objects) { + for (cmScanDepInfo const& object : objects) { for (auto const& p : object.Provides) { std::string const mod = cmStrCat( module_dir, cmSystemTools::GetFilenameName(p.CompiledModulePath)); @@ -2440,7 +2524,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( { cmNinjaBuild build("dyndep"); build.Outputs.emplace_back(""); - for (cmSourceInfo const& object : objects) { + for (cmScanDepInfo const& object : objects) { build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput); build.ImplicitOuts.clear(); for (auto const& p : object.Provides) { diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 0c919ef..7a3674e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -110,13 +110,29 @@ public: void WriteBuild(std::ostream& os, cmNinjaBuild const& build, int cmdLineLimit = 0, bool* usedResponseFile = nullptr); - void WriteCustomCommandBuild( - const std::string& command, const std::string& description, - const std::string& comment, const std::string& depfile, - const std::string& pool, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const std::string& config, - const cmNinjaDeps& explicitDeps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + class CCOutputs + { + cmGlobalNinjaGenerator* GG; + + public: + CCOutputs(cmGlobalNinjaGenerator* gg) + : GG(gg) + { + } + void Add(std::vector<std::string> const& outputs); + cmNinjaDeps ExplicitOuts; + cmNinjaDeps WorkDirOuts; + }; + + void WriteCustomCommandBuild(std::string const& command, + std::string const& description, + std::string const& comment, + std::string const& depfile, + std::string const& pool, bool uses_terminal, + bool restat, std::string const& config, + CCOutputs outputs, + cmNinjaDeps explicitDeps = cmNinjaDeps(), + cmNinjaDeps orderOnlyDeps = cmNinjaDeps()); void WriteMacOSXContentBuild(std::string input, std::string output, const std::string& config); @@ -388,6 +404,7 @@ public: { return "1.10.2"; } + static std::string RequiredNinjaVersionForCodePage() { return "1.11"; } bool SupportsConsolePool() const; bool SupportsImplicitOuts() const; bool SupportsManifestRestat() const; @@ -474,6 +491,7 @@ private: std::string GetEditCacheCommand() const override; bool FindMakeProgram(cmMakefile* mf) override; void CheckNinjaFeatures(); + void CheckNinjaCodePage(); bool CheckLanguages(std::vector<std::string> const& languages, cmMakefile* mf) const override; bool CheckFortran(cmMakefile* mf) const; @@ -568,6 +586,9 @@ private: bool NinjaSupportsUnconditionalRecompactTool = false; bool NinjaSupportsMultipleOutputs = false; bool NinjaSupportsMetadataOnRegeneration = false; + bool NinjaSupportsCodePage = false; + + codecvt::Encoding NinjaExpectedEncoding = codecvt::None; bool DiagnosedCxxModuleSupport = false; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 97384cd..9c3de1e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -22,7 +22,6 @@ #include "cmOutputConverter.h" #include "cmProperty.h" #include "cmState.h" -#include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -147,7 +146,7 @@ void cmGlobalUnixMakefileGenerator3::Generate() // write each target's progress.make this loop is done twice. Basically the // Generate pass counts all the actions, the first loop below determines // how many actions have progress updates for each target and writes to - // corrrect variable values for everything except the all targets. The + // correct variable values for everything except the all targets. The // second loop actually writes out correct values for the all targets as // well. This is because the all targets require more information that is // computed in the first loop. @@ -318,16 +317,13 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() const auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>( this->LocalGenerators[0]); - const std::string& currentBinDir = lg.GetCurrentBinaryDirectory(); // Save the list to the cmake file. cmakefileStream << "# The top level Makefile was generated from the following files:\n" << "set(CMAKE_MAKEFILE_DEPENDS\n" << " \"CMakeCache.txt\"\n"; for (std::string const& f : lfiles) { - cmakefileStream << " \"" - << lg.MaybeConvertToRelativePath(currentBinDir, f) - << "\"\n"; + cmakefileStream << " \"" << lg.MaybeRelativeToCurBinDir(f) << "\"\n"; } cmakefileStream << " )\n\n"; @@ -339,17 +335,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // Set the corresponding makefile in the cmake file. cmakefileStream << "# The corresponding makefile is:\n" << "set(CMAKE_MAKEFILE_OUTPUTS\n" - << " \"" - << lg.MaybeConvertToRelativePath(currentBinDir, - makefileName) + << " \"" << lg.MaybeRelativeToCurBinDir(makefileName) << "\"\n" - << " \"" - << lg.MaybeConvertToRelativePath(currentBinDir, check) - << "\"\n"; + << " \"" << lg.MaybeRelativeToCurBinDir(check) << "\"\n"; cmakefileStream << " )\n\n"; - const std::string& binDir = lg.GetBinaryDirectory(); - // CMake must rerun if a byproduct is missing. cmakefileStream << "# Byproducts of CMake generate step:\n" << "set(CMAKE_MAKEFILE_PRODUCTS\n"; @@ -359,14 +349,12 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() for (const auto& localGen : this->LocalGenerators) { for (std::string const& outfile : localGen->GetMakefile()->GetOutputFiles()) { - cmakefileStream << " \"" - << lg.MaybeConvertToRelativePath(binDir, outfile) + cmakefileStream << " \"" << lg.MaybeRelativeToTopBinDir(outfile) << "\"\n"; } tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(), "/CMakeFiles/CMakeDirectoryInformation.cmake"); - cmakefileStream << " \"" - << localGen->MaybeConvertToRelativePath(binDir, tmpStr) + cmakefileStream << " \"" << localGen->MaybeRelativeToTopBinDir(tmpStr) << "\"\n"; } cmakefileStream << " )\n\n"; @@ -458,9 +446,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG); // Begin the directory-level rules section. { - std::string dir = - cmSystemTools::ConvertToOutputPath(lg->MaybeConvertToRelativePath( - lg->GetBinaryDirectory(), lg->GetCurrentBinaryDirectory())); + std::string dir = cmSystemTools::ConvertToOutputPath( + lg->MaybeRelativeToTopBinDir(lg->GetCurrentBinaryDirectory())); lg->WriteDivider(ruleFileStream); if (lg->IsRootMakefile()) { ruleFileStream << "# Directory level rules for the build root directory"; @@ -564,21 +551,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( bool fast, int jobs, bool verbose, std::vector<std::string> const& makeOptions) { - std::unique_ptr<cmMakefile> mfu; - cmMakefile* mf; - if (!this->Makefiles.empty()) { - mf = this->Makefiles[0].get(); - } else { - cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot(); - snapshot.GetDirectory().SetCurrentSource( - this->CMakeInstance->GetHomeDirectory()); - snapshot.GetDirectory().SetCurrentBinary( - this->CMakeInstance->GetHomeOutputDirectory()); - snapshot.SetDefaultDefinitions(); - mfu = cm::make_unique<cmMakefile>(this, snapshot); - mf = mfu.get(); - } - GeneratedMakeCommand makeCommand; // Make it possible to set verbosity also from command line @@ -609,9 +581,6 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( if (fast) { tname += "/fast"; } - tname = - mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfNotContained( - mf->GetState()->GetBinaryDirectory(), tname); cmSystemTools::ConvertToOutputSlashes(tname); makeCommand.Add(std::move(tname)); } diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index badce2e..6c52ce0 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -231,6 +231,23 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( return false; } + if (!this->CustomFlagTableDir.empty() && + !(cmSystemTools::FileIsFullPath(this->CustomFlagTableDir) && + cmSystemTools::FileIsDirectory(this->CustomFlagTableDir))) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given toolset\n" + " customFlagTableDir=" << this->CustomFlagTableDir << "\n" + "that is not an absolute path to an existing directory."; + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + if (cmHasLiteralPrefix(this->GetPlatformToolsetString(), "v140")) { // The GenerateDebugInformation link setting for the v140 toolset // in VS 2015 was originally an enum with "No" and "Debug" values, @@ -263,8 +280,8 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( bcDir = this->VCTargetsPath + "/BuildCustomizations"; } else { bcDir = this->GetPlatformToolsetCudaCustomDirString() + - "CUDAVisualStudioIntegration\\extras\\" - "visual_studio_integration\\MSBuildExtensions"; + this->GetPlatformToolsetCudaVSIntegrationSubdirString() + + "extras\\visual_studio_integration\\MSBuildExtensions"; cmSystemTools::ConvertToUnixSlashes(bcDir); } cmsys::Glob gl; @@ -470,11 +487,27 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField( if (this->GeneratorToolsetCudaCustomDir.back() != '\\') { this->GeneratorToolsetCudaCustomDir.push_back('\\'); } + /* check for legacy toolkit folder structure */ + if (cmsys::SystemTools::FileIsDirectory( + cmStrCat(this->GeneratorToolsetCudaCustomDir, "nvcc"))) { + this->GeneratorToolsetCudaNvccSubdir = "nvcc\\"; + } + if (cmsys::SystemTools::FileIsDirectory( + cmStrCat(this->GeneratorToolsetCudaCustomDir, + "CUDAVisualStudioIntegration"))) { + this->GeneratorToolsetCudaVSIntegrationSubdir = + "CUDAVisualStudioIntegration\\"; + } } else { this->GeneratorToolsetCuda = value; } return true; } + if (key == "customFlagTableDir") { + this->CustomFlagTableDir = value; + cmSystemTools::ConvertToUnixSlashes(this->CustomFlagTableDir); + return true; + } if (key == "version") { this->GeneratorToolsetVersion = value; return true; @@ -787,6 +820,18 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDirString() const return this->GeneratorToolsetCudaCustomDir; } +std::string const& +cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaNvccSubdirString() const +{ + return this->GeneratorToolsetCudaNvccSubdir; +} + +std::string const& cmGlobalVisualStudio10Generator:: + GetPlatformToolsetCudaVSIntegrationSubdirString() const +{ + return this->GeneratorToolsetCudaVSIntegrationSubdir; +} + cmGlobalVisualStudio10Generator::AuxToolset cmGlobalVisualStudio10Generator::FindAuxToolset(std::string&, std::string&) const @@ -991,6 +1036,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) cmd.push_back(this->GetMSBuildCommand()); cmd.push_back(vcxproj); cmd.push_back("/p:Configuration=Debug"); + cmd.push_back(cmStrCat("/p:Platform=", this->GetPlatformName())); cmd.push_back(std::string("/p:VisualStudioVersion=") + this->GetIDEVersion()); std::string out; @@ -1349,137 +1395,262 @@ static cmIDEFlagTable const* cmLoadFlagTableJson( return ret; } -static std::string cmGetFlagTableName(std::string const& toolsetName, - std::string const& table) +cm::optional<std::string> cmGlobalVisualStudio10Generator::FindFlagTable( + cm::string_view toolsetName, cm::string_view table) const { - return cmSystemTools::GetCMakeRoot() + "/Templates/MSBuild/FlagTables/" + - toolsetName + "_" + table + ".json"; + if (!this->CustomFlagTableDir.empty()) { + std::string customFlagTableFile = + cmStrCat(this->CustomFlagTableDir, '/', this->GetPlatformName(), '_', + toolsetName, '_', table, ".json"); + if (cmSystemTools::FileExists(customFlagTableFile)) { + return customFlagTableFile; + } + customFlagTableFile = + cmStrCat(this->CustomFlagTableDir, '/', this->GetPlatformName(), '_', + table, ".json"); + if (cmSystemTools::FileExists(customFlagTableFile)) { + return customFlagTableFile; + } + } + std::string fullPath = + cmStrCat(cmSystemTools::GetCMakeRoot(), "/Templates/MSBuild/FlagTables/", + toolsetName, '_', table, ".json"); + if (cmSystemTools::FileExists(fullPath)) { + return fullPath; + } + return {}; } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::LoadFlagTable( - std::string const& optionsName, std::string const& toolsetName, - std::string const& defaultName, std::string const& table) const + std::string const& toolSpecificName, std::string const& defaultName, + std::string const& table) const { - cmIDEFlagTable const* ret = nullptr; + cmMakefile* mf = this->GetCurrentMakefile(); std::string filename; - if (!optionsName.empty()) { - filename = cmGetFlagTableName(optionsName, table); - ret = cmLoadFlagTableJson(filename); + if (!toolSpecificName.empty()) { + if (cm::optional<std::string> found = + this->FindFlagTable(toolSpecificName, table)) { + filename = std::move(*found); + } else { + mf->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("JSON flag table for ", table, + " not found for toolset ", toolSpecificName)); + return nullptr; + } } else { - filename = cmGetFlagTableName(toolsetName, table); - if (cmSystemTools::FileExists(filename)) { - ret = cmLoadFlagTableJson(filename); + std::string const& genericName = + this->CanonicalToolsetName(this->GetPlatformToolsetString()); + cm::optional<std::string> found = this->FindFlagTable(genericName, table); + if (!found) { + found = this->FindFlagTable(defaultName, table); + } + if (found) { + filename = std::move(*found); } else { - filename = cmGetFlagTableName(defaultName, table); - ret = cmLoadFlagTableJson(filename); + mf->IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("JSON flag table for ", table, + " not found for toolset ", genericName, " ", + defaultName)); + return nullptr; } } - if (!ret) { - cmMakefile* mf = this->GetCurrentMakefile(); - - std::ostringstream e; - /* clang-format off */ - e << "JSON flag table \"" << filename << - "\" could not be loaded.\n"; - /* clang-format on */ - mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + if (cmIDEFlagTable const* ret = cmLoadFlagTableJson(filename)) { + return ret; } - return ret; + + mf->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("JSON flag table could not be loaded:\n ", filename)); + return nullptr; } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetClFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetClFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultCLFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "CL"); + return LoadFlagTable(this->GetClFlagTableName(), + this->DefaultCLFlagTableName, "CL"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCSharpFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetCSharpFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultCSharpFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "CSharp"); + return LoadFlagTable(this->GetCSharpFlagTableName(), + this->DefaultCSharpFlagTableName, "CSharp"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetRcFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetRcFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultRCFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "RC"); + return LoadFlagTable(this->GetRcFlagTableName(), + this->DefaultRCFlagTableName, "RC"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetLibFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetLibFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultLibFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "LIB"); + return LoadFlagTable(this->GetLibFlagTableName(), + this->DefaultLibFlagTableName, "LIB"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetLinkFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetLinkFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultLinkFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "Link"); + return LoadFlagTable(this->GetLinkFlagTableName(), + this->DefaultLinkFlagTableName, "Link"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaFlagTable() const { - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultCudaFlagTableName); - return LoadFlagTable("", toolsetName, defaultName, "Cuda"); + return LoadFlagTable(std::string(), this->DefaultCudaFlagTableName, "Cuda"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaHostFlagTable() const { - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultCudaHostFlagTableName); - return LoadFlagTable("", toolsetName, defaultName, "CudaHost"); + return LoadFlagTable(std::string(), this->DefaultCudaHostFlagTableName, + "CudaHost"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMasmFlagTable() const { - std::string optionsName = this->ToolsetOptions.GetMasmFlagTableName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultMasmFlagTableName); - return LoadFlagTable(optionsName, toolsetName, defaultName, "MASM"); + return LoadFlagTable(this->GetMasmFlagTableName(), + this->DefaultMasmFlagTableName, "MASM"); } cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetNasmFlagTable() const { - std::string toolsetName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->GetPlatformToolsetString()); - std::string defaultName = this->ToolsetOptions.GetToolsetName( - this->GetPlatformName(), this->DefaultNasmFlagTableName); - return LoadFlagTable("", toolsetName, defaultName, "NASM"); + return LoadFlagTable(std::string(), this->DefaultNasmFlagTableName, "NASM"); +} + +std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if (toolset == "v142") { + return "v142"; + } else if (toolset == "v141") { + return "v141"; + } else if (useToolset == "v140") { + return "v140"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::GetCSharpFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if (useToolset == "v142") { + return "v142"; + } else if (useToolset == "v141") { + return "v141"; + } else if (useToolset == "v140") { + return "v140"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::GetRcFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if ((useToolset == "v140") || (useToolset == "v141") || + (useToolset == "v142")) { + return "v14"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::GetLibFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if ((useToolset == "v140") || (useToolset == "v141") || + (useToolset == "v142")) { + return "v14"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::GetLinkFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if (useToolset == "v142") { + return "v142"; + } else if (useToolset == "v141") { + return "v141"; + } else if (useToolset == "v140") { + return "v140"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::GetMasmFlagTableName() const +{ + std::string const& toolset = this->GetPlatformToolsetString(); + std::string const useToolset = this->CanonicalToolsetName(toolset); + + if ((useToolset == "v140") || (useToolset == "v141") || + (useToolset == "v142")) { + return "v14"; + } else if (useToolset == "v120") { + return "v12"; + } else if (useToolset == "v110") { + return "v11"; + } else if (useToolset == "v100") { + return "v10"; + } else { + return ""; + } +} + +std::string cmGlobalVisualStudio10Generator::CanonicalToolsetName( + std::string const& toolset) const +{ + std::size_t length = toolset.length(); + + if (cmHasLiteralSuffix(toolset, "_xp")) { + length -= 3; + } + + return toolset.substr(0, length); } diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 8d30ef8..2596720 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -5,8 +5,10 @@ #include <memory> #include <set> +#include <cm/optional> +#include <cm/string_view> + #include "cmGlobalVisualStudio8Generator.h" -#include "cmVisualStudio10ToolsetOptions.h" /** \class cmGlobalVisualStudio10Generator * \brief Write a Unix makefiles. @@ -76,6 +78,13 @@ public: const char* GetPlatformToolsetCudaCustomDir() const; std::string const& GetPlatformToolsetCudaCustomDirString() const; + /** The nvcc subdirectory of a custom cuda install directory */ + std::string const& GetPlatformToolsetCudaNvccSubdirString() const; + + /** The visual studio integration subdirectory of a custom cuda install + * directory */ + std::string const& GetPlatformToolsetCudaVSIntegrationSubdirString() const; + /** Return whether we need to use No/Debug instead of false/true for GenerateDebugInformation. */ bool GetPlatformToolsetNeedsDebugEnum() const @@ -176,8 +185,7 @@ protected: std::string const& GetMSBuildCommand(); - cmIDEFlagTable const* LoadFlagTable(std::string const& optionsName, - std::string const& toolsetName, + cmIDEFlagTable const* LoadFlagTable(std::string const& toolSpecificName, std::string const& defaultName, std::string const& table) const; @@ -187,6 +195,8 @@ protected: std::string GeneratorToolsetCustomVCTargetsDir; std::string GeneratorToolsetCuda; std::string GeneratorToolsetCudaCustomDir; + std::string GeneratorToolsetCudaNvccSubdir; + std::string GeneratorToolsetCudaVSIntegrationSubdir; std::string DefaultPlatformToolset; std::string DefaultPlatformToolsetHostArchitecture; std::string DefaultAndroidToolset; @@ -230,7 +240,6 @@ private: std::string MSBuildCommand; bool MSBuildCommandInitialized; - cmVisualStudio10ToolsetOptions ToolsetOptions; std::set<std::string> AndroidExecutableWarnings; virtual std::string FindMSBuildCommand(); std::string FindDevEnvCommand() override; @@ -242,6 +251,19 @@ private: bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf); + std::string GetClFlagTableName() const; + std::string GetCSharpFlagTableName() const; + std::string GetRcFlagTableName() const; + std::string GetLibFlagTableName() const; + std::string GetLinkFlagTableName() const; + std::string GetMasmFlagTableName() const; + std::string CanonicalToolsetName(std::string const& toolset) const; + + cm::optional<std::string> FindFlagTable(cm::string_view toolsetName, + cm::string_view table) const; + + std::string CustomFlagTableDir; + std::string CustomVCTargetsPath; std::string VCTargetsPath; bool FindVCTargetsPath(cmMakefile* mf); diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 75cd714..0c85a044 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -367,7 +367,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( { VisualStudioFolders.clear(); - std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); for (cmGeneratorTarget const* target : projectTargets) { if (!target->IsInBuildSystem()) { continue; @@ -390,7 +389,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( if (vcprojName) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); + dir = root->MaybeRelativeToCurBinDir(dir); if (dir == ".") { dir.clear(); // msbuild cannot handle ".\" prefix } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index d6cc423..009d133 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -17,6 +17,7 @@ #include "cmsys/RegularExpression.hxx" +#include "cmCMakePath.h" #include "cmComputeLinkInformation.h" #include "cmCryptoHash.h" #include "cmCustomCommand.h" @@ -392,7 +393,7 @@ bool cmGlobalXCodeGenerator::ProcessGeneratorToolsetField( " ", this->GetName(), "\n" "toolset specification field\n" " buildsystem=", value, "\n" - "value is unkonwn. It must be '1' or '12'." + "value is unknown. It must be '1' or '12'." ); /* clang-format on */ mf->IssueMessage(MessageType::FATAL_ERROR, e); @@ -585,13 +586,7 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root) { this->CurrentProject = root->GetProjectName(); this->SetCurrentLocalGenerator(root); - cmSystemTools::SplitPath( - this->CurrentLocalGenerator->GetCurrentSourceDirectory(), - this->ProjectSourceDirectoryComponents); - cmSystemTools::SplitPath( - this->CurrentLocalGenerator->GetCurrentBinaryDirectory(), - this->ProjectOutputDirectoryComponents); - + this->CurrentRootGenerator = root; this->CurrentXCodeHackMakefile = cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeScripts"); cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile); @@ -991,7 +986,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES), *sf); } - lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true)); + lg->AppendFlags(flags, + lg->GetIncludeFlags(includes, gtgt, lang, std::string())); cmXCodeObject* buildFile = this->CreateXCodeBuildFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf); @@ -1863,9 +1859,20 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( std::set<std::string> allConfigInputs; std::set<std::string> allConfigOutputs; + cmXCodeObject* buildPhase = + this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase, + cmStrCat(gt->GetName(), ':', sf->GetFullPath())); + + auto depfilesDirectory = cmStrCat( + gt->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/CMakeFiles/d/"); + auto depfilesPrefix = cmStrCat(depfilesDirectory, buildPhase->GetId(), "."); + std::string shellScript = "set -e\n"; for (std::string const& configName : this->CurrentConfigurationTypes) { - cmCustomCommandGenerator ccg(cc, configName, this->CurrentLocalGenerator); + cmCustomCommandGenerator ccg( + cc, configName, this->CurrentLocalGenerator, true, {}, + [&depfilesPrefix](const std::string& config, const std::string&) + -> std::string { return cmStrCat(depfilesPrefix, config, ".d"); }); std::vector<std::string> realDepends; realDepends.reserve(ccg.GetDepends().size()); for (auto const& d : ccg.GetDepends()) { @@ -1885,9 +1892,22 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( "\"; then :\n", this->ConstructScript(ccg), "fi\n"); } - cmXCodeObject* buildPhase = - this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase, - cmStrCat(gt->GetName(), ':', sf->GetFullPath())); + if (!cc.GetDepfile().empty()) { + buildPhase->AddAttribute( + "dependencyFile", + this->CreateString(cmStrCat(depfilesDirectory, buildPhase->GetId(), + ".$(CONFIGURATION).d"))); + // to avoid spurious errors during first build, create empty dependency + // files + cmSystemTools::MakeDirectory(depfilesDirectory); + for (std::string const& configName : this->CurrentConfigurationTypes) { + auto file = cmStrCat(depfilesPrefix, configName, ".d"); + if (!cmSystemTools::FileExists(file)) { + cmSystemTools::Touch(file, true); + } + } + } + buildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); @@ -2187,9 +2207,33 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile( } } makefileStream << "\n\n"; + + auto depfilesDirectory = + cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/CMakeFiles/d/"); + for (auto const& command : commands) { - cmCustomCommandGenerator ccg(command, configName, - this->CurrentLocalGenerator); + cmCustomCommandGenerator ccg( + command, configName, this->CurrentLocalGenerator, true, {}, + [this, &depfilesDirectory](const std::string& config, + const std::string& file) -> std::string { + return cmStrCat( + depfilesDirectory, + this->GetObjectId(cmXCodeObject::PBXShellScriptBuildPhase, file), + ".", config, ".d"); + }); + + auto depfile = ccg.GetInternalDepfile(); + if (!depfile.empty()) { + makefileStream << "include " + << cmSystemTools::ConvertToOutputPath(depfile) << "\n\n"; + + cmSystemTools::MakeDirectory(depfilesDirectory); + if (!cmSystemTools::FileExists(depfile)) { + cmSystemTools::Touch(depfile, true); + } + } + std::vector<std::string> realDepends; realDepends.reserve(ccg.GetDepends().size()); for (auto const& d : ccg.GetDepends()) { @@ -2695,7 +2739,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, // GNU assembly files (#16449) for (auto const& language : languages) { std::string includeFlags = this->CurrentLocalGenerator->GetIncludeFlags( - includes, gtgt, language, true, false, configName); + includes, gtgt, language, configName); if (!includeFlags.empty()) { cflags[language] += " " + includeFlags; @@ -3727,7 +3771,10 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) } } -void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) +void cmGlobalXCodeGenerator::AddEmbeddedObjects( + cmXCodeObject* target, const std::string& copyFilesBuildPhaseName, + const std::string& embedPropertyName, const std::string& dstSubfolderSpec, + int actionsOnByDefault) { cmGeneratorTarget* gt = target->GetTarget(); if (!gt) { @@ -3743,7 +3790,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) if (!(isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { return; } - cmProp files = gt->GetProperty("XCODE_EMBED_FRAMEWORKS"); + cmProp files = gt->GetProperty(embedPropertyName); if (!files) { return; } @@ -3751,16 +3798,15 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) // Create an "Embedded Frameworks" build phase auto* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); - std::string copyFilesBuildPhaseName = "Embed Frameworks"; - std::string destinationFrameworks = "10"; copyFilesBuildPhase->SetComment(copyFilesBuildPhaseName); copyFilesBuildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", - this->CreateString(destinationFrameworks)); + this->CreateString(dstSubfolderSpec)); copyFilesBuildPhase->AddAttribute( "name", this->CreateString(copyFilesBuildPhaseName)); - if (cmProp fwEmbedPath = gt->GetProperty("XCODE_EMBED_FRAMEWORKS_PATH")) { + if (cmProp fwEmbedPath = + gt->GetProperty(cmStrCat(embedPropertyName, "_PATH"))) { copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString(*fwEmbedPath)); } else { @@ -3774,10 +3820,10 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) for (std::string const& relFile : relFiles) { cmXCodeObject* buildFile{ nullptr }; std::string filePath = relFile; - auto* genTarget = FindGeneratorTarget(relFile); + auto* genTarget = this->FindGeneratorTarget(relFile); if (genTarget) { // This is a target - get it's product path reference - auto* xcTarget = FindXCodeTarget(genTarget); + auto* xcTarget = this->FindXCodeTarget(genTarget); if (!xcTarget) { cmSystemTools::Error("Can not find a target for " + genTarget->GetName()); @@ -3791,18 +3837,18 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) " is missing product reference"); continue; } - auto it = FileRefToEmbedBuildFileMap.find(fileRefObject); - if (it == FileRefToEmbedBuildFileMap.end()) { + auto it = this->FileRefToEmbedBuildFileMap.find(fileRefObject); + if (it == this->FileRefToEmbedBuildFileMap.end()) { buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); buildFile->AddAttribute("fileRef", fileRefObject); - FileRefToEmbedBuildFileMap[fileRefObject] = buildFile; + this->FileRefToEmbedBuildFileMap[fileRefObject] = buildFile; } else { buildFile = it->second; } } else if (cmSystemTools::IsPathToFramework(relFile)) { // This is a regular string path - create file reference - auto it = EmbeddedLibRefs.find(relFile); - if (it == EmbeddedLibRefs.end()) { + auto it = this->EmbeddedLibRefs.find(relFile); + if (it == this->EmbeddedLibRefs.end()) { cmXCodeObject* fileRef = this->CreateXCodeFileReferenceFromPath(relFile, gt, "", nullptr); if (fileRef) { @@ -3828,16 +3874,25 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); - const auto& rmHeadersProp = - gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY"); - if (cmIsOn(rmHeadersProp)) { + + bool removeHeaders = actionsOnByDefault & RemoveHeadersOnCopyByDefault; + if (auto prop = gt->GetProperty( + cmStrCat(embedPropertyName, "_REMOVE_HEADERS_ON_COPY"))) { + removeHeaders = cmIsOn(*prop); + } + if (removeHeaders) { attrs->AddObject(this->CreateString("RemoveHeadersOnCopy")); } - const auto& codeSignProp = - gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY"); - if (cmIsOn(codeSignProp)) { + + bool codeSign = actionsOnByDefault & CodeSignOnCopyByDefault; + if (auto prop = + gt->GetProperty(cmStrCat(embedPropertyName, "_CODE_SIGN_ON_COPY"))) { + codeSign = cmIsOn(*prop); + } + if (codeSign) { attrs->AddObject(this->CreateString("CodeSignOnCopy")); } + settings->AddAttributeIfNotEmpty("ATTRIBUTES", attrs); buildFile->AddAttributeIfNotEmpty("settings", settings); if (!buildFiles->HasObject(buildFile)) { @@ -3846,11 +3901,30 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) } copyFilesBuildPhase->AddAttribute("files", buildFiles); auto* buildPhases = target->GetAttribute("buildPhases"); - // Insert embed build phase right before the post-build command + // Embed-something build phases must be inserted before the post-build + // command because that command is expected to be last buildPhases->InsertObject(buildPhases->GetObjectCount() - 1, copyFilesBuildPhase); } +void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) +{ + static const auto dstSubfolderSpec = "10"; + + this->AddEmbeddedObjects(target, "Embed Frameworks", + "XCODE_EMBED_FRAMEWORKS", dstSubfolderSpec, + NoActionOnCopyByDefault); +} + +void cmGlobalXCodeGenerator::AddEmbeddedAppExtensions(cmXCodeObject* target) +{ + static const auto dstSubfolderSpec = "13"; + + this->AddEmbeddedObjects(target, "Embed App Extensions", + "XCODE_EMBED_APP_EXTENSIONS", dstSubfolderSpec, + RemoveHeadersOnCopyByDefault); +} + bool cmGlobalXCodeGenerator::CreateGroups( std::vector<cmLocalGenerator*>& generators) { @@ -4230,6 +4304,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( for (auto t : targets) { this->AddDependAndLinkInformation(t); this->AddEmbeddedFrameworks(t); + this->AddEmbeddedAppExtensions(t); // Inherit project-wide values for any target-specific search paths. this->InheritBuildSettingAttribute(t, "HEADER_SEARCH_PATHS"); this->InheritBuildSettingAttribute(t, "SYSTEM_HEADER_SEARCH_PATHS"); @@ -4237,6 +4312,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( this->InheritBuildSettingAttribute(t, "SYSTEM_FRAMEWORK_SEARCH_PATHS"); this->InheritBuildSettingAttribute(t, "LIBRARY_SEARCH_PATHS"); this->InheritBuildSettingAttribute(t, "LD_RUNPATH_SEARCH_PATHS"); + this->InheritBuildSettingAttribute(t, "GCC_PREPROCESSOR_DEFINITIONS"); + this->InheritBuildSettingAttribute(t, "OTHER_CFLAGS"); + this->InheritBuildSettingAttribute(t, "OTHER_LDFLAGS"); } if (this->XcodeBuildSystem == BuildSystem::One) { @@ -4620,13 +4698,12 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const std::string& p) // We force conversion because Xcode breakpoints do not work unless // they are in a file named relative to the source tree. return cmSystemTools::ForceToRelativePath( - cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p); + this->CurrentRootGenerator->GetCurrentSourceDirectory(), p); } std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p) { - return this->CurrentLocalGenerator->MaybeConvertToRelativePath( - cmSystemTools::JoinPath(this->ProjectOutputDirectoryComponents), p); + return this->CurrentRootGenerator->MaybeRelativeToCurBinDir(p); } std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p) diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 1ab56e2..1e1b344 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -14,6 +14,7 @@ #include <cm/string_view> #include "cmGlobalGenerator.h" +#include "cmTransformDepfile.h" #include "cmXCodeObject.h" class cmCustomCommand; @@ -111,6 +112,17 @@ public: bool ShouldStripResourcePath(cmMakefile*) const override; + /** + * Used to determine if this generator supports DEPFILE option. + */ + bool SupportsCustomCommandDepfile() const override { return true; } + virtual cm::optional<cmDepfileFormat> DepfileFormat() const override + { + return this->XcodeBuildSystem == BuildSystem::One + ? cmDepfileFormat::MakeDepfile + : cmDepfileFormat::GccDepfile; + } + bool SetSystemName(std::string const& s, cmMakefile* mf) override; bool SetGeneratorToolset(std::string const& ts, bool build, cmMakefile* mf) override; @@ -132,6 +144,13 @@ protected: } private: + enum EmbedActionFlags + { + NoActionOnCopyByDefault = 0, + CodeSignOnCopyByDefault = 1, + RemoveHeadersOnCopyByDefault = 2, + }; + bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf); bool ProcessGeneratorToolsetField(std::string const& key, std::string const& value, cmMakefile* mf); @@ -196,7 +215,13 @@ private: const char* attribute); cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt); void AddDependAndLinkInformation(cmXCodeObject* target); + void AddEmbeddedObjects(cmXCodeObject* target, + const std::string& copyFilesBuildPhaseName, + const std::string& embedPropertyName, + const std::string& dstSubfolderSpec, + int actionsOnByDefault); void AddEmbeddedFrameworks(cmXCodeObject* target); + void AddEmbeddedAppExtensions(cmXCodeObject* target); void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target, cmXCodeObject* buildSettings, const std::string& configName); @@ -323,13 +348,12 @@ private: cmXCodeObject* FrameworkGroup; cmMakefile* CurrentMakefile; cmLocalGenerator* CurrentLocalGenerator; + cmLocalGenerator* CurrentRootGenerator = nullptr; std::vector<std::string> CurrentConfigurationTypes; std::string CurrentReRunCMakeMakefile; std::string CurrentXCodeHackMakefile; std::string CurrentProject; std::set<std::string> TargetDoneSet; - std::vector<std::string> ProjectSourceDirectoryComponents; - std::vector<std::string> ProjectOutputDirectoryComponents; std::map<std::string, cmXCodeObject*> GroupMap; std::map<std::string, cmXCodeObject*> GroupNameMap; std::map<std::string, cmXCodeObject*> TargetGroup; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 7788db3..e973764 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -161,6 +161,7 @@ bool HandleScriptMode(std::vector<std::string> const& args, bool doing_script = false; bool doing_code = false; bool exclude_from_all = false; + bool all_components = false; // Scan the args once for COMPONENT. Only allow one. // @@ -172,6 +173,8 @@ bool HandleScriptMode(std::vector<std::string> const& args, } if (args[i] == "EXCLUDE_FROM_ALL") { exclude_from_all = true; + } else if (args[i] == "ALL_COMPONENTS") { + all_components = true; } } @@ -182,6 +185,11 @@ bool HandleScriptMode(std::vector<std::string> const& args, return false; } + if (all_components && componentCount == 1) { + status.SetError("ALL_COMPONENTS and COMPONENT are mutually exclusive"); + return false; + } + // Scan the args again, this time adding install generators each time we // encounter a SCRIPT or CODE arg: // @@ -208,14 +216,14 @@ bool HandleScriptMode(std::vector<std::string> const& args, } helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - script, false, component, exclude_from_all, + script, false, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } else if (doing_code) { doing_code = false; std::string const& code = arg; helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - code, true, component, exclude_from_all, + code, true, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } } @@ -775,7 +783,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args, if (!resourceArgs.GetDestination().empty()) { resourceGenerator = CreateInstallFilesGenerator( helper.Makefile, absFiles, resourceArgs, false); - } else { + } else if (!target.IsAppBundleOnApple()) { cmSystemTools::Message( cmStrCat("INSTALL TARGETS - target ", target.GetName(), " has RESOURCE files but no RESOURCE DESTINATION."), @@ -1482,7 +1490,8 @@ bool Helper::MakeFilesFullPath(const char* modeName, } // Make sure the file is not a directory. - if (gpos == std::string::npos && cmSystemTools::FileIsDirectory(file)) { + if (gpos == std::string::npos && !cmSystemTools::FileIsSymlink(file) && + cmSystemTools::FileIsDirectory(file)) { this->SetError( cmStrCat(modeName, " given directory \"", relFile, "\" to install.")); return false; diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 4eb5f69..86362e4 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -18,7 +18,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( MessageLevel message, bool exclude_from_all, std::string literal_args, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Directories(dirs) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index fdc3f8c..ccefd92 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -26,7 +26,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( std::string filename, std::string name_space, bool exportOld, bool android, cmListFileBacktrace backtrace) : cmInstallGenerator(destination, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , ExportSet(exportSet) , FilePermissions(std::move(file_permissions)) , FileName(std::move(filename)) diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 556c938..04aaa29 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -17,7 +17,7 @@ cmInstallFilesGenerator::cmInstallFilesGenerator( MessageLevel message, bool exclude_from_all, std::string rename, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Files(files) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 98e3766..cf5f45e 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -11,12 +11,13 @@ cmInstallGenerator::cmInstallGenerator( std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, bool exclude_from_all, - cmListFileBacktrace backtrace) + bool all_components, cmListFileBacktrace backtrace) : cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations) , Destination(std::move(destination)) , Component(std::move(component)) , Message(message) , ExcludeFromAll(exclude_from_all) + , AllComponents(all_components) , Backtrace(std::move(backtrace)) { } @@ -160,15 +161,20 @@ void cmInstallGenerator::GenerateScript(std::ostream& os) Indent indent; // Begin this block of installation. - std::string component_test = - this->CreateComponentTest(this->Component, this->ExcludeFromAll); - os << indent << "if(" << component_test << ")\n"; + if (!this->AllComponents) { + std::string component_test = + this->CreateComponentTest(this->Component, this->ExcludeFromAll); + os << indent << "if(" << component_test << ")\n"; + } // Generate the script possibly with per-configuration code. - this->GenerateScriptConfigs(os, indent.Next()); + this->GenerateScriptConfigs(os, + this->AllComponents ? indent : indent.Next()); // End this block of installation. - os << indent << "endif()\n\n"; + if (!this->AllComponents) { + os << indent << "endif()\n\n"; + } } bool cmInstallGenerator::InstallsForConfig(const std::string& config) diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index 6cd9ff9..0117617 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -33,7 +33,8 @@ public: cmInstallGenerator(std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, - bool exclude_from_all, cmListFileBacktrace backtrace); + bool exclude_from_all, bool all_components, + cmListFileBacktrace backtrace); ~cmInstallGenerator() override; cmInstallGenerator(cmInstallGenerator const&) = delete; @@ -65,6 +66,7 @@ public: std::string const& GetComponent() const { return this->Component; } bool GetExcludeFromAll() const { return this->ExcludeFromAll; } + bool GetAllComponentsFlag() const { return this->AllComponents; } cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } @@ -79,5 +81,6 @@ protected: std::string const Component; MessageLevel const Message; bool const ExcludeFromAll; + bool const AllComponents; cmListFileBacktrace const Backtrace; }; diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index bb38990..bec98b6 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -14,9 +14,10 @@ cmInstallScriptGenerator::cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, cmListFileBacktrace backtrace) + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), component, - MessageDefault, exclude_from_all, std::move(backtrace)) + MessageDefault, exclude_from_all, all_components, + std::move(backtrace)) , Script(std::move(script)) , Code(code) , AllowGenex(false) diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index 6274f1c..2cf6a4b 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/Source/cmInstallScriptGenerator.h @@ -21,7 +21,7 @@ class cmInstallScriptGenerator : public cmInstallGenerator public: cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace = cmListFileBacktrace()); ~cmInstallScriptGenerator() override; diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index c333bca..794694e 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -17,7 +17,7 @@ cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( cmMakefile* makefile, std::string binaryDirectory, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault, - false, std::move(backtrace)) + false, false, std::move(backtrace)) , Makefile(makefile) , BinaryDirectory(std::move(binaryDirectory)) { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index bef785d..3e79ad8 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -46,7 +46,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( std::string const& component, MessageLevel message, bool exclude_from_all, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , TargetName(std::move(targetName)) , Target(nullptr) , FilePermissions(std::move(file_permissions)) @@ -338,6 +338,7 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles( // Add the names based on the current namelink mode. if (haveNamelink) { + files.NamelinkMode = this->NamelinkMode; // With a namelink we need to check the mode. if (this->NamelinkMode == NamelinkModeOnly) { // Install the namelink only. diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 8c5d444..84fce42 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -39,7 +39,6 @@ public: NamelinkModeSkip }; void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; } - NamelinkModeType GetNamelinkMode() const { return this->NamelinkMode; } std::string GetInstallFilename(const std::string& config) const; @@ -82,6 +81,7 @@ public: // Prefix for all files in To. std::string ToDir; + NamelinkModeType NamelinkMode = NamelinkModeNone; bool NoTweak = false; bool UseSourcePermissions = false; cmInstallType Type = cmInstallType(); diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h index a63347d..6690aef 100644 --- a/Source/cmJSONHelpers.h +++ b/Source/cmJSONHelpers.h @@ -239,7 +239,7 @@ cmJSONHelper<std::vector<T>, E> cmJSONVectorFilterHelper(E success, E fail, if (!filter(t)) { continue; } - out.push_back(t); + out.push_back(std::move(t)); } return success; }; diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 480c005..a3f2968 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -11,10 +11,8 @@ #include "cmGeneratorTarget.h" #include "cmListFileCache.h" #include "cmOutputConverter.h" -#include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" -#include "cmSystemTools.h" cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) @@ -52,13 +50,7 @@ void cmLinkLineComputer::SetRelink(bool relink) std::string cmLinkLineComputer::ConvertToLinkReference( std::string const& lib) const { - std::string relLib = lib; - - if (this->StateDir.ContainsBoth(this->StateDir.GetCurrentBinary(), lib)) { - relLib = cmSystemTools::ForceToRelativePath( - this->StateDir.GetCurrentBinary(), lib); - } - return relLib; + return this->OutputConverter->MaybeRelativeToCurBinDir(lib); } std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index fdddb45..09cd88e 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -4,9 +4,7 @@ #include <algorithm> #include <cassert> -#include <cstddef> #include <cstdio> -#include <cstdlib> // required for atoi #include <functional> #include <iterator> #include <set> @@ -36,6 +34,42 @@ namespace { +bool GetIndexArg(const std::string& arg, int* idx, cmMakefile& mf) +{ + long value; + if (!cmStrToLong(arg, &value)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0121)) { + case cmPolicies::WARN: { + // Default is to warn and use old behavior OLD behavior is to allow + // compatibility, so issue a warning and use the previous behavior. + std::string warn = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0121), + " Invalid list index \"", arg, "\"."); + mf.IssueMessage(MessageType::AUTHOR_WARNING, warn); + break; + } + case cmPolicies::OLD: + // OLD behavior is to allow compatibility, so just ignore the + // situation. + break; + case cmPolicies::NEW: + return false; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + std::string msg = + cmStrCat(cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0121), + " Invalid list index \"", arg, "\"."); + mf.IssueMessage(MessageType::FATAL_ERROR, msg); + break; + } + } + + // Truncation is happening here, but it had always been happening here. + *idx = static_cast<int>(value); + + return true; +} + bool FilterRegex(std::vector<std::string> const& args, bool includeMatches, std::string const& listName, std::vector<std::string>& varArgsExpanded, @@ -154,7 +188,11 @@ bool HandleGetCommand(std::vector<std::string> const& args, const char* sep = ""; size_t nitem = varArgsExpanded.size(); for (cc = 2; cc < args.size() - 1; cc++) { - int item = atoi(args[cc].c_str()); + int item; + if (!GetIndexArg(args[cc], &item, status.GetMakefile())) { + status.SetError(cmStrCat("index: ", args[cc], " is not a valid index")); + return false; + } value += sep; sep = ";"; if (item < 0) { @@ -362,7 +400,11 @@ bool HandleInsertCommand(std::vector<std::string> const& args, const std::string& listName = args[1]; // expand the variable - int item = atoi(args[2].c_str()); + int item; + if (!GetIndexArg(args[2], &item, status.GetMakefile())) { + status.SetError(cmStrCat("index: ", args[2], " is not a valid index")); + return false; + } std::vector<std::string> varArgsExpanded; if ((!GetList(varArgsExpanded, listName, status.GetMakefile()) || varArgsExpanded.empty()) && @@ -1282,8 +1324,16 @@ bool HandleSublistCommand(std::vector<std::string> const& args, return true; } - const int start = atoi(args[2].c_str()); - const int length = atoi(args[3].c_str()); + int start; + int length; + if (!GetIndexArg(args[2], &start, status.GetMakefile())) { + status.SetError(cmStrCat("index: ", args[2], " is not a valid index")); + return false; + } + if (!GetIndexArg(args[3], &length, status.GetMakefile())) { + status.SetError(cmStrCat("index: ", args[3], " is not a valid index")); + return false; + } using size_type = decltype(varArgsExpanded)::size_type; @@ -1338,7 +1388,11 @@ bool HandleRemoveAtCommand(std::vector<std::string> const& args, std::vector<size_t> removed; size_t nitem = varArgsExpanded.size(); for (cc = 2; cc < args.size(); ++cc) { - int item = atoi(args[cc].c_str()); + int item; + if (!GetIndexArg(args[cc], &item, status.GetMakefile())) { + status.SetError(cmStrCat("index: ", args[cc], " is not a valid index")); + return false; + } if (item < 0) { item = static_cast<int>(nitem) + item; } diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 1464a14..4f7c959 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -7,11 +7,14 @@ #include <sstream> #include <utility> +#ifdef _WIN32 +# include <cmsys/Encoding.hxx> +#endif + #include "cmListFileLexer.h" #include "cmMessageType.h" #include "cmMessenger.h" #include "cmState.h" -#include "cmStateDirectory.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -83,9 +86,15 @@ bool cmListFileParser::ParseFile(const char* filename) { this->FileName = filename; +#ifdef _WIN32 + std::string expandedFileName = cmsys::Encoding::ToNarrow( + cmSystemTools::ConvertToWindowsExtendedPath(filename)); + filename = expandedFileName.c_str(); +#endif + // Open the file. cmListFileLexer_BOM bom; - if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) { + if (!cmListFileLexer_SetFileName(this->Lexer, filename, &bom)) { this->IssueFileOpenError("cmListFileCache: error can not open file."); return false; } @@ -540,7 +549,7 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const cmListFileContext lfc = this->TopEntry->Context; cmStateSnapshot bottom = this->GetBottom(); if (!bottom.GetState()->GetIsInTryCompile()) { - lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfNotContained( + lfc.FilePath = cmSystemTools::RelativeIfUnder( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } out << (lfc.Line ? " at " : " in ") << lfc; @@ -571,7 +580,7 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const } cmListFileContext lfc = cur->Context; if (!bottom.GetState()->GetIsInTryCompile()) { - lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfNotContained( + lfc.FilePath = cmSystemTools::RelativeIfUnder( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } out << " " << lfc << "\n"; diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 2981ef8..2456db9 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -90,6 +90,9 @@ struct LoadedCommandImpl : cmLoadedCommandInfo { if (this->Destructor) { SignalHandlerGuard guard(this->Name); +#if defined(__NVCOMPILER) + static_cast<void>(guard); // convince compiler var is used +#endif this->Destructor(this); } if (this->Error != nullptr) { @@ -103,12 +106,18 @@ struct LoadedCommandImpl : cmLoadedCommandInfo int DoInitialPass(cmMakefile* mf, int argc, char* argv[]) { SignalHandlerGuard guard(this->Name); +#if defined(__NVCOMPILER) + static_cast<void>(guard); // convince compiler var is used +#endif return this->InitialPass(this, mf, argc, argv); } void DoFinalPass(cmMakefile* mf) { SignalHandlerGuard guard(this->Name); +#if defined(__NVCOMPILER) + static_cast<void>(guard); // convince compiler var is used +#endif this->FinalPass(this, mf); } }; diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 5daaeff..211525a 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -9,14 +9,17 @@ #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmProperty.h" +#include "cmState.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" #include "cmStringAlgorithms.h" class cmGlobalGenerator; cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, - cmMakefile* mf, std::string wd) + cmMakefile* mf, WorkDir wd) : cmLocalGenerator(gg, mf) - , WorkingDirectory(std::move(wd)) + , WorkingDirectory(wd) { this->ConfigNames = this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); @@ -24,6 +27,23 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, cmLocalCommonGenerator::~cmLocalCommonGenerator() = default; +std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const +{ + if (this->WorkingDirectory == WorkDir::TopBin) { + return this->GetState()->GetBinaryDirectory(); + } + return this->StateSnapshot.GetDirectory().GetCurrentBinary(); +} + +std::string cmLocalCommonGenerator::MaybeRelativeToWorkDir( + std::string const& path) const +{ + if (this->WorkingDirectory == WorkDir::TopBin) { + return this->MaybeRelativeToTopBinDir(path); + } + return this->MaybeRelativeToCurBinDir(path); +} + std::string cmLocalCommonGenerator::GetTargetFortranFlags( cmGeneratorTarget const* target, std::string const& config) { @@ -35,11 +55,10 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( // Add a module output directory flag if necessary. std::string mod_dir = - target->GetFortranModuleDirectory(this->WorkingDirectory); + target->GetFortranModuleDirectory(this->GetWorkingDirectory()); if (!mod_dir.empty()) { mod_dir = this->ConvertToOutputFormat( - this->MaybeConvertToRelativePath(this->WorkingDirectory, mod_dir), - cmOutputConverter::SHELL); + this->MaybeRelativeToWorkDir(mod_dir), cmOutputConverter::SHELL); } else { mod_dir = this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h index f1eaf61..0505c13 100644 --- a/Source/cmLocalCommonGenerator.h +++ b/Source/cmLocalCommonGenerator.h @@ -20,9 +20,15 @@ class cmSourceFile; */ class cmLocalCommonGenerator : public cmLocalGenerator { +protected: + enum class WorkDir + { + TopBin, + CurBin, + }; + public: - cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf, - std::string wd); + cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf, WorkDir wd); ~cmLocalCommonGenerator() override; std::vector<std::string> const& GetConfigNames() const @@ -30,7 +36,9 @@ public: return this->ConfigNames; } - std::string GetWorkingDirectory() const { return this->WorkingDirectory; } + std::string const& GetWorkingDirectory() const; + + std::string MaybeRelativeToWorkDir(std::string const& path) const; std::string GetTargetFortranFlags(cmGeneratorTarget const* target, std::string const& config) override; @@ -40,7 +48,7 @@ public: cmGeneratorTarget const* gt = nullptr) override; protected: - std::string WorkingDirectory; + WorkDir WorkingDirectory; std::vector<std::string> ConfigNames; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index dcf590a..0c686aa 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -88,7 +88,6 @@ static auto ruleReplaceVars = { "CMAKE_${LANG}_COMPILER", cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile) : cmOutputConverter(makefile->GetStateSnapshot()) - , StateSnapshot(makefile->GetStateSnapshot()) , DirectoryBacktrace(makefile->GetBacktrace()) { this->GlobalGenerator = gg; @@ -351,11 +350,10 @@ void cmLocalGenerator::GenerateTestFiles() } using vec_t = std::vector<cmStateSnapshot>; vec_t const& children = this->Makefile->GetStateSnapshot().GetChildren(); - std::string parentBinDir = this->GetCurrentBinaryDirectory(); for (cmStateSnapshot const& i : children) { // TODO: Use add_subdirectory instead? std::string outP = i.GetDirectory().GetCurrentBinary(); - outP = this->MaybeConvertToRelativePath(parentBinDir, outP); + outP = this->MaybeRelativeToCurBinDir(outP); outP = cmOutputConverter::EscapeForCMake(outP); fout << "subdirs(" << outP << ")\n"; } @@ -838,16 +836,16 @@ cmProp cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target, } std::string cmLocalGenerator::ConvertToIncludeReference( - std::string const& path, OutputFormat format, bool forceFullPaths) + std::string const& path, IncludePathStyle pathStyle, OutputFormat format) { - static_cast<void>(forceFullPaths); + static_cast<void>(pathStyle); return this->ConvertToOutputForExisting(path, format); } std::string cmLocalGenerator::GetIncludeFlags( - const std::vector<std::string>& includeDirs, cmGeneratorTarget* target, - const std::string& lang, bool forceFullPaths, bool forResponseFile, - const std::string& config) + std::vector<std::string> const& includeDirs, cmGeneratorTarget* target, + std::string const& lang, std::string const& config, bool forResponseFile, + IncludePathStyle pathStyle) { if (lang.empty()) { return ""; @@ -923,7 +921,7 @@ std::string cmLocalGenerator::GetIncludeFlags( flagUsed = true; } std::string includePath = - this->ConvertToIncludeReference(i, shellFormat, forceFullPaths); + this->ConvertToIncludeReference(i, pathStyle, shellFormat); if (quotePaths && !includePath.empty() && includePath.front() != '\"') { includeFlags << "\""; } @@ -1527,12 +1525,12 @@ void cmLocalGenerator::GetTargetFlags( } if (target->IsWin32Executable(config)) { - exeFlags += - this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"); + exeFlags += this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE")); exeFlags += " "; } else { - exeFlags += - this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); + exeFlags += this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE")); exeFlags += " "; } @@ -1972,7 +1970,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, } } - // Add VFS Overlay for Clang compiliers + // Add VFS Overlay for Clang compilers if (compiler == "Clang") { if (cmProp vfsOverlay = this->Makefile->GetDefinition("CMAKE_CLANG_VFS_OVERLAY")) { @@ -2307,13 +2305,6 @@ void cmLocalGenerator::AddCMP0018Flags(std::string& flags, if (this->GetShouldUseOldFlags(shared, lang)) { this->AddSharedFlags(flags, lang, shared); } else { - if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) { - this->AddPositionIndependentFlags(flags, lang, targetType); - } - return; - } - if (target->GetLinkInterfaceDependentBoolProperty( "POSITION_INDEPENDENT_CODE", config)) { this->AddPositionIndependentFlags(flags, lang, targetType); @@ -2438,7 +2429,7 @@ void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target) } cmProp ispcHeaderSuffixProp = target->GetProperty("ISPC_HEADER_SUFFIX"); - assert(ispcHeaderSuffixProp != nullptr); + assert(ispcHeaderSuffixProp); std::vector<std::string> ispcArchSuffixes = detail::ComputeISPCObjectSuffixes(target); @@ -2701,8 +2692,9 @@ void cmLocalGenerator::CopyPchCompilePdb( } file << "foreach(retry RANGE 1 30)\n"; - file << " if (EXISTS \"" << from_file << "\" AND \"" << from_file - << " \" IS_NEWER_THAN \"" << dest_file << "\")\n"; + file << " if (EXISTS \"" << from_file << "\" AND (NOT EXISTS \"" + << dest_file << "\" OR NOT \"" << dest_file << " \" IS_NEWER_THAN \"" + << from_file << "\"))\n"; file << " execute_process(COMMAND ${CMAKE_COMMAND} -E copy"; file << " \"" << from_file << "\"" << " \"" << to_dir << "\" RESULT_VARIABLE result " @@ -2785,7 +2777,7 @@ void cmLocalGenerator::IncludeFileInUnitySources( cmGeneratedFileStream& unity_file, std::string const& sf_full_path, cmProp beforeInclude, cmProp afterInclude, cmProp uniqueIdName) const { - if (uniqueIdName && !uniqueIdName->empty()) { + if (cmNonempty(uniqueIdName)) { std::string pathToHash; auto PathEqOrSubDir = [](std::string const& a, std::string const& b) { return (cmSystemTools::ComparePath(a, b) || @@ -3000,7 +2992,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, const std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_IPO"; cmProp rawFlagsList = this->Makefile->GetDefinition(name); - if (rawFlagsList == nullptr) { + if (!rawFlagsList) { return; } @@ -3239,7 +3231,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags, { cmProp optionList = this->Makefile->GetDefinition( cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature)); - if (optionList != nullptr) { + if (optionList) { std::vector<std::string> options = cmExpandedList(*optionList); for (std::string const& o : options) { this->AppendFlagEscape(flags, o); @@ -3285,10 +3277,9 @@ std::string cmLocalGenerator::ConstructComment( std::string comment; comment = "Generating "; const char* sep = ""; - std::string currentBinaryDir = this->GetCurrentBinaryDirectory(); for (std::string const& o : ccg.GetOutputs()) { comment += sep; - comment += this->MaybeConvertToRelativePath(currentBinaryDir, o); + comment += this->MaybeRelativeToCurBinDir(o); sep = ", "; } return comment; @@ -3326,7 +3317,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified pre-install script for this target. if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*preinstall, false, "", false); + cmInstallScriptGenerator g(*preinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } @@ -3379,7 +3370,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified post-install script for this target. if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*postinstall, false, "", false); + cmInstallScriptGenerator g(*postinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } } @@ -3540,6 +3531,21 @@ bool cmLocalGenerator::IsNinjaMulti() const return this->GetState()->UseNinjaMulti(); } +namespace { +std::string relativeIfUnder(std::string const& top, std::string const& cur, + std::string const& path) +{ + // Use a path relative to 'cur' if it can be expressed without + // a `../` sequence that leaves 'top'. + if (cmSystemTools::IsSubDirectory(path, cur) || + (cmSystemTools::IsSubDirectory(cur, top) && + cmSystemTools::IsSubDirectory(path, top))) { + return cmSystemTools::ForceToRelativePath(cur, path); + } + return path; +} +} + std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( const cmSourceFile& source, std::string const& dir_max, bool* hasSourceExtension, char const* customOutputExtension) @@ -3549,15 +3555,15 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( std::string const& fullPath = source.GetFullPath(); // Try referencing the source relative to the source tree. - std::string relFromSource = this->MaybeConvertToRelativePath( - this->GetCurrentSourceDirectory(), fullPath); + std::string relFromSource = relativeIfUnder( + this->GetSourceDirectory(), this->GetCurrentSourceDirectory(), fullPath); assert(!relFromSource.empty()); bool relSource = !cmSystemTools::FileIsFullPath(relFromSource); bool subSource = relSource && relFromSource[0] != '.'; // Try referencing the source relative to the binary tree. - std::string relFromBinary = this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), fullPath); + std::string relFromBinary = relativeIfUnder( + this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory(), fullPath); assert(!relFromBinary.empty()); bool relBinary = !cmSystemTools::FileIsFullPath(relFromBinary); bool subBinary = relBinary && relFromBinary[0] != '.'; @@ -3672,13 +3678,6 @@ std::string const& cmLocalGenerator::GetCurrentSourceDirectory() const return this->StateSnapshot.GetDirectory().GetCurrentSource(); } -std::string cmLocalGenerator::MaybeConvertToRelativePath( - std::string const& local_path, std::string const& remote_path) const -{ - return this->StateSnapshot.GetDirectory().ConvertToRelPathIfNotContained( - local_path, remote_path); -} - std::string cmLocalGenerator::GetTargetDirectory( const cmGeneratorTarget* /*unused*/) const { @@ -3930,7 +3929,7 @@ std::string ComputeCustomCommandRuleFileName(cmLocalGenerator& lg, // The output path contains a generator expression, but we must choose // a single source file path to which to attach the custom command. - // Use some heuristics to provie a nice-looking name when possible. + // Use some heuristics to provide a nice-looking name when possible. // If the only genex is $<CONFIG>, replace that gracefully. { @@ -4218,7 +4217,7 @@ std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target) auto pos = ispcTarget.find('-'); auto target_suffix = ispcTarget.substr(0, pos); if (target_suffix == - "avx1") { // when targetting avx1 ISPC uses the 'avx' output string + "avx1") { // when targeting avx1 ISPC uses the 'avx' output string target_suffix = "avx"; } ispcTarget = target_suffix; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index e48849a..993280a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -171,13 +171,19 @@ public: cmGeneratorTarget* target, const std::string& config, const std::string& lang); + + enum class IncludePathStyle + { + Default, + Absolute, + }; + //! Get the include flags for the current makefile and language - std::string GetIncludeFlags(const std::vector<std::string>& includes, - cmGeneratorTarget* target, - const std::string& lang, - bool forceFullPaths = false, - bool forResponseFile = false, - const std::string& config = ""); + std::string GetIncludeFlags( + std::vector<std::string> const& includes, cmGeneratorTarget* target, + std::string const& lang, std::string const& config, + bool forResponseFile = false, + IncludePathStyle pathStyle = IncludePathStyle::Default); using GeneratorTargetVector = std::vector<std::unique_ptr<cmGeneratorTarget>>; @@ -256,11 +262,6 @@ public: bool GetRealDependency(const std::string& name, const std::string& config, std::string& dep); - virtual std::string ConvertToIncludeReference( - std::string const& path, - cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL, - bool forceFullPaths = false); - /** Called from command-line hook to clear dependencies. */ virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {} @@ -462,16 +463,6 @@ public: std::string const& GetCurrentSourceDirectory() const; /** - * Convert the given remote path to a relative path with respect to - * the given local path. Both paths must use forward slashes and not - * already be escaped or quoted. - * The conversion is skipped if the paths are not both in the source - * or both in the binary tree. - */ - std::string MaybeConvertToRelativePath(std::string const& local_path, - std::string const& remote_path) const; - - /** * Generate a macOS application bundle Info.plist file. */ void GenerateAppleInfoPList(cmGeneratorTarget* target, @@ -557,6 +548,13 @@ public: cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop); protected: + // The default implementation ignores the IncludePathStyle and always + // uses absolute paths. A generator may override this to use relative + // paths in some cases. + virtual std::string ConvertToIncludeReference( + std::string const& path, IncludePathStyle pathStyle, + cmOutputConverter::OutputFormat format); + //! put all the libraries for a target on into the given stream void OutputLinkLibraries(cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer, @@ -583,7 +581,6 @@ protected: virtual bool CheckDefinition(std::string const& define) const; cmMakefile* Makefile; - cmStateSnapshot StateSnapshot; cmListFileBacktrace DirectoryBacktrace; cmGlobalGenerator* GlobalGenerator; std::map<std::string, std::string> UniqueObjectNamesMap; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 081cc41..fb6c730 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -39,7 +39,7 @@ cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmMakefile* mf) - : cmLocalCommonGenerator(gg, mf, mf->GetState()->GetBinaryDirectory()) + : cmLocalCommonGenerator(gg, mf, WorkDir::TopBin) { } @@ -60,8 +60,8 @@ void cmLocalNinjaGenerator::Generate() { // Compute the path to use when referencing the current output // directory from the top output directory. - this->HomeRelativeOutputPath = this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory()); + this->HomeRelativeOutputPath = + this->MaybeRelativeToTopBinDir(this->GetCurrentBinaryDirectory()); if (this->HomeRelativeOutputPath == ".") { this->HomeRelativeOutputPath.clear(); } @@ -97,9 +97,12 @@ void cmLocalNinjaGenerator::Generate() // contains any non-ASCII characters and dependency checking will fail. // As a workaround, leave the msvc_deps_prefix UTF-8 encoded even though // the rest of the file is ANSI encoded. - if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8) { + if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8 && + this->GetGlobalGenerator()->GetMakefileEncoding() != codecvt::None) { this->GetRulesFileStream().WriteRaw(showIncludesPrefix); } else { + // Ninja 1.11 and above uses the UTF-8 code page if it's supported, so + // in that case we can write it normally without using raw bytes. this->GetRulesFileStream() << showIncludesPrefix; } #else @@ -202,17 +205,16 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator() // Virtual protected methods. std::string cmLocalNinjaGenerator::ConvertToIncludeReference( - std::string const& path, cmOutputConverter::OutputFormat format, - bool forceFullPaths) + std::string const& path, IncludePathStyle pathStyle, + cmOutputConverter::OutputFormat format) { - if (forceFullPaths) { + if (pathStyle == IncludePathStyle::Absolute) { return this->ConvertToOutputFormat( cmSystemTools::CollapseFullPath(path, this->GetCurrentBinaryDirectory()), format); } - return this->ConvertToOutputFormat( - this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), path), - format); + return this->ConvertToOutputFormat(this->MaybeRelativeToTopBinDir(path), + format); } // Private methods. @@ -261,6 +263,7 @@ void cmLocalNinjaGenerator::WriteBuildFileTop() this->GetConfigNames().front()); } this->WriteNinjaFilesInclusionCommon(this->GetCommonFileStream()); + this->WriteNinjaWorkDir(this->GetCommonFileStream()); // For the rule file. this->WriteProjectHeader(this->GetRulesFileStream()); @@ -362,6 +365,17 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os) os << "\n"; } +void cmLocalNinjaGenerator::WriteNinjaWorkDir(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + cmGlobalNinjaGenerator::WriteComment( + os, "Logical path to working directory; prefix for absolute paths."); + cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator(); + std::string ninja_workdir = this->GetBinaryDirectory(); + ng->StripNinjaOutputPathPrefixAsSuffix(ninja_workdir); // Also appends '/'. + os << "cmake_ninja_workdir = " << ng->EncodePath(ninja_workdir) << "\n"; +} + void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); @@ -636,16 +650,11 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } } - cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()); - std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), - gg->MapToNinjaPath()); - std::transform(byproducts.begin(), byproducts.end(), - ninjaOutputs.begin() + outputs.size(), - gg->MapToNinjaPath()); + cmGlobalNinjaGenerator::CCOutputs ccOutputs(gg); + ccOutputs.Add(outputs); + ccOutputs.Add(byproducts); - for (std::string const& ninjaOutput : ninjaOutputs) { - gg->SeenCustomCommandOutput(ninjaOutput); - } + std::string mainOutput = ccOutputs.ExplicitOuts[0]; cmNinjaDeps ninjaDeps; this->AppendCustomCommandDeps(ccg, ninjaDeps, fileConfig); @@ -655,13 +664,14 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( if (cmdLines.empty()) { cmNinjaBuild build("phony"); - build.Comment = "Phony custom command for " + ninjaOutputs[0]; - build.Outputs = std::move(ninjaOutputs); + build.Comment = cmStrCat("Phony custom command for ", mainOutput); + build.Outputs = std::move(ccOutputs.ExplicitOuts); + build.WorkDirOuts = std::move(ccOutputs.WorkDirOuts); build.ExplicitDeps = std::move(ninjaDeps); build.OrderOnlyDeps = orderOnlyDeps; gg->WriteBuild(this->GetImplFileStream(fileConfig), build); } else { - std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); + std::string customStep = cmSystemTools::GetFilenameName(mainOutput); if (this->GlobalGenerator->IsMultiConfig()) { customStep += '-'; customStep += fileConfig; @@ -671,9 +681,9 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( // Hash full path to make unique. customStep += '-'; cmCryptoHash hash(cmCryptoHash::AlgoSHA256); - customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7); + customStep += hash.HashString(mainOutput).substr(0, 7); - std::string depfile = cc->GetDepfile(); + std::string depfile = ccg.GetDepfile(); if (!depfile.empty()) { switch (cc->GetCMP0116Status()) { case cmPolicies::WARN: @@ -699,13 +709,14 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } } + std::string comment = cmStrCat("Custom command for ", mainOutput); gg->WriteCustomCommandBuild( this->BuildCommandLine(cmdLines, ccg.GetOutputConfig(), fileConfig, customStep), - this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], - depfile, cc->GetJobPool(), cc->GetUsesTerminal(), - /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig, - ninjaDeps, orderOnlyDeps); + this->ConstructComment(ccg), comment, depfile, cc->GetJobPool(), + cc->GetUsesTerminal(), + /*restat*/ !symbolic || !byproducts.empty(), fileConfig, + std::move(ccOutputs), std::move(ninjaDeps), std::move(orderOnlyDeps)); } } } @@ -878,8 +889,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( if (!outputs.empty()) { output = outputs[0]; if (ccg.GetWorkingDirectory().empty()) { - output = this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), output); + output = this->MaybeRelativeToCurBinDir(output); } output = this->ConvertToOutputFormat(output, cmOutputConverter::SHELL); } diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 0734c5c..6404037 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -12,6 +12,7 @@ #include "cmListFileCache.h" #include "cmLocalCommonGenerator.h" +#include "cmLocalGenerator.h" #include "cmNinjaTypes.h" #include "cmOutputConverter.h" @@ -92,9 +93,8 @@ public: protected: std::string ConvertToIncludeReference( - std::string const& path, - cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL, - bool forceFullPaths = false) override; + std::string const& path, IncludePathStyle pathStyle, + cmOutputConverter::OutputFormat format) override; private: cmGeneratedFileStream& GetImplFileStream(const std::string& config) const; @@ -108,6 +108,7 @@ private: const std::string& config); void WriteNinjaFilesInclusionConfig(std::ostream& os); void WriteNinjaFilesInclusionCommon(std::ostream& os); + void WriteNinjaWorkDir(std::ostream& os); void WriteProcessedMakefile(std::ostream& os); void WritePools(std::ostream& os); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 464df68..3a65a80 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -38,7 +38,6 @@ #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" #include "cmState.h" -#include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" @@ -110,7 +109,7 @@ private: cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3( cmGlobalGenerator* gg, cmMakefile* mf) - : cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory()) + : cmLocalCommonGenerator(gg, mf, WorkDir::CurBin) { this->MakefileVariableSize = 0; this->ColorMakefile = false; @@ -177,8 +176,8 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath() { // Compute the path to use when referencing the current output // directory from the top output directory. - this->HomeRelativeOutputPath = this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory()); + this->HomeRelativeOutputPath = + this->MaybeRelativeToTopBinDir(this->GetCurrentBinaryDirectory()); if (this->HomeRelativeOutputPath == ".") { this->HomeRelativeOutputPath.clear(); } @@ -474,11 +473,9 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() infoFileStream << "# Relative path conversion top directories.\n" << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" - << this->StateSnapshot.GetDirectory().GetRelativePathTopSource() - << "\")\n" + << this->GetRelativePathTopSource() << "\")\n" << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" - << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary() - << "\")\n" + << this->GetRelativePathTopBinary() << "\")\n" << "\n"; /* clang-format on */ @@ -561,8 +558,8 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule( } // Construct the left hand side of the rule. - std::string tgt = this->ConvertToMakefilePath( - this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target)); + std::string tgt = + this->ConvertToMakefilePath(this->MaybeRelativeToTopBinDir(target)); const char* space = ""; if (tgt.size() == 1) { @@ -586,11 +583,9 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule( } else { // Split dependencies into multiple rule lines. This allows for // very long dependency lists even on older make implementations. - std::string binDir = this->GetBinaryDirectory(); for (std::string const& depend : depends) { os << tgt << space << ": " - << this->ConvertToMakefilePath( - this->MaybeConvertToRelativePath(binDir, depend)) + << this->ConvertToMakefilePath(this->MaybeRelativeToTopBinDir(depend)) << '\n'; } } @@ -968,7 +963,6 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( // Add each command line to the set of commands. std::vector<std::string> commands1; - std::string currentBinDir = this->GetCurrentBinaryDirectory(); for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { // Build the command line in a single string. std::string cmd = ccg.GetCommand(c); @@ -993,7 +987,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( // working directory will be the start-output directory. bool had_slash = cmd.find('/') != std::string::npos; if (workingDir.empty()) { - cmd = this->MaybeConvertToRelativePath(currentBinDir, cmd); + cmd = this->MaybeRelativeToCurBinDir(cmd); } bool has_slash = cmd.find('/') != std::string::npos; if (had_slash && !has_slash) { @@ -1017,8 +1011,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( if (!outputs.empty()) { output = outputs[0]; if (workingDir.empty()) { - output = this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), output); + output = this->MaybeRelativeToCurBinDir(output); } output = this->ConvertToOutputFormat(output, cmOutputConverter::SHELL); @@ -1097,18 +1090,16 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand( if (!files.empty()) { fout << "file(REMOVE_RECURSE\n"; for (std::string const& file : files) { - std::string fc = this->MaybeConvertToRelativePath(currentBinDir, file); + std::string fc = this->MaybeRelativeToCurBinDir(file); fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n"; } fout << ")\n"; } { - std::string remove = - cmStrCat("$(CMAKE_COMMAND) -P ", - this->ConvertToOutputFormat( - this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), cleanfile), - cmOutputConverter::SHELL)); + std::string remove = cmStrCat( + "$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat(this->MaybeRelativeToCurBinDir(cleanfile), + cmOutputConverter::SHELL)); commands.push_back(std::move(remove)); } @@ -1146,7 +1137,6 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( } const auto& rootLG = this->GetGlobalGenerator()->GetLocalGenerators().at(0); - std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory(); std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory(); std::string cleanfile = cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake"); @@ -1159,19 +1149,18 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( } fout << "file(REMOVE_RECURSE\n"; for (std::string const& cfl : cleanFiles) { - std::string fc = rootLG->MaybeConvertToRelativePath( - binaryDir, cmSystemTools::CollapseFullPath(cfl, currentBinaryDir)); + std::string fc = rootLG->MaybeRelativeToCurBinDir( + cmSystemTools::CollapseFullPath(cfl, currentBinaryDir)); fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n"; } fout << ")\n"; } // Create command { - std::string remove = - cmStrCat("$(CMAKE_COMMAND) -P ", - this->ConvertToOutputFormat( - rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile), - cmOutputConverter::SHELL)); + std::string remove = cmStrCat( + "$(CMAKE_COMMAND) -P ", + this->ConvertToOutputFormat(rootLG->MaybeRelativeToCurBinDir(cleanfile), + cmOutputConverter::SHELL)); commands.push_back(std::move(remove)); } } @@ -1521,13 +1510,11 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( // Setup relative path top directories. if (cmProp relativePathTopSource = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) { - this->StateSnapshot.GetDirectory().SetRelativePathTopSource( - relativePathTopSource->c_str()); + this->SetRelativePathTopSource(*relativePathTopSource); } if (cmProp relativePathTopBinary = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) { - this->StateSnapshot.GetDirectory().SetRelativePathTopBinary( - relativePathTopBinary->c_str()); + this->SetRelativePathTopBinary(*relativePathTopBinary); } } else { cmSystemTools::Error("Directory Information file not found"); @@ -1964,8 +1951,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir)); } for (std::string const& include : includes) { - cmakefileStream << " \"" - << this->MaybeConvertToRelativePath(binaryDir, include) + cmakefileStream << " \"" << this->MaybeRelativeToTopBinDir(include) << "\"\n"; } cmakefileStream << " )\n"; @@ -2004,12 +1990,9 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( for (auto const& compilerPair : compilerPairs) { for (auto const& src : compilerPair.second) { cmakefileStream << R"( "" ")" - << this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), compilerPair.first) + << this->MaybeRelativeToTopBinDir(compilerPair.first) << R"(" "custom" ")" - << this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), src) - << "\"\n"; + << this->MaybeRelativeToTopBinDir(src) << "\"\n"; } } } else { @@ -2018,11 +2001,9 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( for (auto const& compilerPair : compilerPairs) { for (auto const& src : compilerPair.second) { cmakefileStream << " \"" << src << "\" \"" - << this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), compilerPair.first) + << this->MaybeRelativeToTopBinDir(compilerPair.first) << "\" \"" << depFormat << "\" \"" - << this->MaybeConvertToRelativePath( - this->GetBinaryDirectory(), compilerPair.first) + << this->MaybeRelativeToTopBinDir(compilerPair.first) << ".d\"\n"; } } @@ -2066,8 +2047,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall( // Add the target. if (!tgt.empty()) { // The make target is always relative to the top of the build tree. - std::string tgt2 = - this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), tgt); + std::string tgt2 = this->MaybeRelativeToTopBinDir(tgt); // The target may have been written with windows paths. cmSystemTools::ConvertToOutputSlashes(tgt2); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index a3940ea..c50cc5d 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -784,8 +784,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY"); std::string modDir; if (target_mod_dir) { - modDir = this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), *target_mod_dir); + modDir = this->MaybeRelativeToCurBinDir(*target_mod_dir); } else { modDir = "."; } @@ -1214,7 +1213,7 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool( cmProp additionalFiles = target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES"); - if (dir == nullptr && additionalFiles == nullptr) { + if (!dir && !additionalFiles) { return; } @@ -1228,7 +1227,7 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool( << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str()) << "\"/>\n"; - if (dir != nullptr) { + if (dir) { std::string const exe = *dir + "\\" + target->GetFullName(config); fout << "\t\t\t<DebuggerTool\n" @@ -1254,11 +1253,9 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries( std::ostream& fout, ItemVector const& libs) { cmLocalVisualStudio7Generator* lg = this->LocalGenerator; - std::string currentBinDir = lg->GetCurrentBinaryDirectory(); for (auto const& lib : libs) { if (lib.IsPath) { - std::string rel = - lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.Value); + std::string rel = lg->MaybeRelativeToCurBinDir(lib.Value.Value); fout << lg->ConvertToXMLOutputPath(rel) << " "; } else if (!lib.Target || lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { @@ -1274,7 +1271,6 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects( // VS < 8 does not support per-config source locations so we // list object library content on the link line instead. cmLocalVisualStudio7Generator* lg = this->LocalGenerator; - std::string currentBinDir = lg->GetCurrentBinaryDirectory(); std::vector<cmSourceFile const*> objs; gt->GetExternalObjects(objs, configName); @@ -1283,7 +1279,7 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects( for (cmSourceFile const* obj : objs) { if (!obj->GetObjectLibrary().empty()) { std::string const& objFile = obj->GetFullPath(); - std::string rel = lg->MaybeConvertToRelativePath(currentBinDir, objFile); + std::string rel = lg->MaybeRelativeToCurBinDir(objFile); fout << sep << lg->ConvertToXMLOutputPath(rel); sep = " "; } @@ -1294,7 +1290,6 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories( std::ostream& fout, std::vector<std::string> const& dirs) { const char* comma = ""; - std::string currentBinDir = this->GetCurrentBinaryDirectory(); for (std::string dir : dirs) { // Remove any trailing slash and skip empty paths. if (dir.back() == '/') { @@ -1306,7 +1301,7 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories( // Switch to a relative path specification if it is shorter. if (cmSystemTools::FileIsFullPath(dir)) { - std::string rel = this->MaybeConvertToRelativePath(currentBinDir, dir); + std::string rel = this->MaybeRelativeToCurBinDir(dir); if (rel.size() < dir.size()) { dir = rel; } diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 6d6ed9f..002f484 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -207,10 +207,8 @@ std::string cmLocalVisualStudioGenerator::ConstructScript( } if (workingDirectory.empty()) { - script += - this->ConvertToOutputFormat(this->MaybeConvertToRelativePath( - this->GetCurrentBinaryDirectory(), cmd), - cmOutputConverter::SHELL); + script += this->ConvertToOutputFormat( + this->MaybeRelativeToCurBinDir(cmd), cmOutputConverter::SHELL); } else { script += this->ConvertToOutputFormat(cmd.c_str(), SHELL); } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index dd25406..675ff1d 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -800,7 +800,7 @@ void cmMakefile::RunListFile(cmListFile const& listFile, for (size_t i = 0; i < defer->Commands.size(); ++i) { DeferCommand& d = defer->Commands[i]; if (d.Id.empty()) { - // Cancelled. + // Canceled. continue; } // Mark as executed. @@ -1222,7 +1222,7 @@ void cmMakefile::AddCustomCommandOldStyle( // Each output must get its own copy of this rule. cmsys::RegularExpression sourceFiles( - "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|cu|m|mm|" + "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|ixx|cppm|cu|m|mm|" "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" "hm|hpp|hxx|in|txx|inl)$"); @@ -1963,6 +1963,8 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, } this->GetCMakeInstance()->AddCacheEntry(name, value, doc, type); // if there was a definition then remove it + // The method cmFindBase::NormalizeFindResult also apply same workflow. + // See #22038 for problems raised by this behavior. this->StateSnapshot.RemoveDefinition(name); } @@ -2479,7 +2481,7 @@ const std::string& cmMakefile::GetRequiredDefinition( const std::string& name) const { static std::string const empty; - const std::string* def = this->GetDefinition(name); + cmProp def = this->GetDefinition(name); if (!def) { cmSystemTools::Error("Error required internal CMake variable not " "set, cmake may not be built correctly.\n" @@ -2507,6 +2509,20 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const return def != nullptr; } +bool cmMakefile::IsNormalDefinitionSet(const std::string& name) const +{ + cmProp def = this->StateSnapshot.GetDefinition(name); +#ifndef CMAKE_BOOTSTRAP + if (cmVariableWatch* vv = this->GetVariableWatch()) { + if (!def) { + vv->VariableAccessed( + name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS, nullptr, this); + } + } +#endif + return def != nullptr; +} + cmProp cmMakefile::GetDefinition(const std::string& name) const { cmProp def = this->StateSnapshot.GetDefinition(name); @@ -2539,7 +2555,7 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const { static std::string const empty; - const std::string* def = this->GetDefinition(name); + cmProp def = this->GetDefinition(name); if (!def) { return empty; } @@ -3053,7 +3069,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( if (filename && variable == lineVar) { varresult = std::to_string(line); } else { - const std::string* def = this->GetDefinition(variable); + cmProp def = this->GetDefinition(variable); if (def) { varresult = *def; } else if (!this->SuppressSideEffects) { @@ -4393,7 +4409,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, // Deprecate old policies, especially those that require a lot // of code to maintain the old behavior. - if (status == cmPolicies::OLD && id <= cmPolicies::CMP0075 && + if (status == cmPolicies::OLD && id <= cmPolicies::CMP0081 && !(this->GetCMakeInstance()->GetIsInTryCompile() && ( // Policies set by cmCoreTryCompile::TryCompileCode. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 71d765c..77e9c74 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -486,6 +486,7 @@ public: const std::string& GetSafeDefinition(const std::string&) const; const std::string& GetRequiredDefinition(const std::string& name) const; bool IsDefinitionSet(const std::string&) const; + bool IsNormalDefinitionSet(const std::string&) const; bool GetDefExpandList(const std::string& name, std::vector<std::string>& out, bool emptyArgs = false) const; /** @@ -992,7 +993,7 @@ private: struct DeferCommand { - // Id is empty for an already-executed or cancelled operation. + // Id is empty for an already-executed or canceled operation. std::string Id; std::string FilePath; cmListFileFunction Command; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 1750e37..2940b8b 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -104,13 +104,11 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = - cmStrCat("Linking CUDA device code ", - this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - this->DeviceLinkObject), - cmOutputConverter::SHELL)); + std::string buildEcho = cmStrCat( + "Linking CUDA device code ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeRelativeToCurBinDir(this->DeviceLinkObject), + cmOutputConverter::SHELL)); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -152,8 +150,8 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( // Construct a list of files associated with this executable that // may need to be cleaned. std::vector<std::string> exeCleanFiles; - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput)); + exeCleanFiles.push_back( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput)); // Determine whether a link script will be used. bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); @@ -203,17 +201,14 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); objectDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir), cmOutputConverter::SHELL); cmOutputConverter::OutputFormat output = (useWatcomQuote) ? cmOutputConverter::WATCOMQUOTE : cmOutputConverter::SHELL; std::string target = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput), - output); + this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput), output); std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB(this->GetConfigName()); @@ -330,18 +325,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) targetFullPathPDB, cmOutputConverter::SHELL); // Convert to the output path to use in constructing commands. std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath), cmOutputConverter::SHELL); std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal), cmOutputConverter::SHELL); std::string targetOutPathImport = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - targetFullPathImport), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport), cmOutputConverter::SHELL); // Get the language to use for linking this executable. @@ -384,11 +375,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) if (this->GeneratorTarget->IsWin32Executable( this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"))) { this->LocalGenerator->AppendFlags( - linkFlags, this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE")); + linkFlags, + this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"))); } else { this->LocalGenerator->AppendFlags( linkFlags, - this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE")); + this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"))); } // Add symbol export flags if necessary. @@ -433,36 +427,34 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Construct a list of files associated with this executable that // may need to be cleaned. std::vector<std::string> exeCleanFiles; - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath)); + exeCleanFiles.push_back( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath)); #ifdef _WIN32 // There may be a manifest file for this target. Add it to the // clean set just in case. - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), + exeCleanFiles.push_back(this->LocalGenerator->MaybeRelativeToCurBinDir( targetFullPath + ".manifest")); #endif if (this->TargetNames.Real != this->TargetNames.Output) { - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal)); + exeCleanFiles.push_back( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal)); } if (!this->TargetNames.ImportLibrary.empty()) { - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - targetFullPathImport)); + exeCleanFiles.push_back( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport)); std::string implib; if (this->GeneratorTarget->GetImplibGNUtoMS( this->GetConfigName(), targetFullPathImport, implib)) { - exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), implib)); + exeCleanFiles.push_back( + this->LocalGenerator->MaybeRelativeToCurBinDir(implib)); } } // List the PDB for cleaning only when the whole target is // cleaned. We do not want to delete the .pdb file just before // linking the target. - this->CleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB)); + this->CleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathPDB)); // Add the pre-build and pre-link rules building but not when relinking. if (!relink) { @@ -526,8 +518,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) if (!this->DeviceLinkObject.empty()) { buildObjs += " " + this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToCurBinDir( this->DeviceLinkObject), cmOutputConverter::SHELL); } @@ -546,16 +537,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); objectDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir), cmOutputConverter::SHELL); vars.ObjectDir = objectDir.c_str(); cmOutputConverter::OutputFormat output = (useWatcomQuote) ? cmOutputConverter::WATCOMQUOTE : cmOutputConverter::SHELL; std::string target = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal), output); vars.Target = target.c_str(); vars.TargetPDB = targetOutPathPDB.c_str(); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index ce64e2c..f96bcde 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -250,13 +250,11 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( cmLocalUnixMakefileGenerator3::EchoProgress progress; this->MakeEchoProgress(progress); // Add the link message. - std::string buildEcho = - cmStrCat("Linking CUDA device code ", - this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - this->DeviceLinkObject), - cmOutputConverter::SHELL)); + std::string buildEcho = cmStrCat( + "Linking CUDA device code ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeRelativeToCurBinDir(this->DeviceLinkObject), + cmOutputConverter::SHELL)); this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } @@ -293,8 +291,8 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules( // Clean files associated with this library. std::set<std::string> libCleanFiles; - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput)); // Determine whether a link script will be used. bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); @@ -342,14 +340,11 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules( std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); objectDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir), cmOutputConverter::SHELL); std::string target = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput), - output); + this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput), output); std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB(this->GetConfigName()); @@ -519,22 +514,17 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( targetFullPathPDB, cmOutputConverter::SHELL); std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath), cmOutputConverter::SHELL); std::string targetOutPathSO = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathSO), cmOutputConverter::SHELL); std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal), cmOutputConverter::SHELL); std::string targetOutPathImport = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - targetFullPathImport), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport), cmOutputConverter::SHELL); this->NumberOfProgressActions++; @@ -567,8 +557,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // Clean files associated with this library. std::set<std::string> libCleanFiles; - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal)); std::vector<std::string> commands1; // Add a command to remove any existing files for this library. @@ -584,38 +574,36 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } if (this->TargetNames.Output != this->TargetNames.Real) { - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath)); } if (this->TargetNames.SharedObject != this->TargetNames.Real && this->TargetNames.SharedObject != this->TargetNames.Output) { - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathSO)); } if (!this->TargetNames.ImportLibrary.empty()) { - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - targetFullPathImport)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport)); std::string implib; if (this->GeneratorTarget->GetImplibGNUtoMS( this->GetConfigName(), targetFullPathImport, implib)) { - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), implib)); + libCleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(implib)); } } // List the PDB for cleaning only when the whole target is // cleaned. We do not want to delete the .pdb file just before // linking the target. - this->CleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB)); + this->CleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathPDB)); #ifdef _WIN32 // There may be a manifest file for this target. Add it to the // clean set just in case. if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) { - libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), + libCleanFiles.insert(this->LocalGenerator->MaybeRelativeToCurBinDir( targetFullPath + ".manifest")); } #endif @@ -723,8 +711,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( if (!this->DeviceLinkObject.empty()) { buildObjs += " " + this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToCurBinDir( this->DeviceLinkObject), cmOutputConverter::SHELL); } @@ -765,8 +752,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); objectDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir), cmOutputConverter::SHELL); vars.ObjectDir = objectDir.c_str(); @@ -774,15 +760,17 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( ? cmOutputConverter::WATCOMQUOTE : cmOutputConverter::SHELL; std::string target = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal), output); vars.Target = target.c_str(); vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); + std::string targetOutSOName; if (this->GeneratorTarget->HasSOName(this->GetConfigName())) { vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage); - vars.TargetSOName = this->TargetNames.SharedObject.c_str(); + targetOutSOName = this->LocalGenerator->ConvertToOutputFormat( + this->TargetNames.SharedObject.c_str(), cmOutputConverter::SHELL); + vars.TargetSOName = targetOutSOName.c_str(); } vars.LinkFlags = linkFlags.c_str(); @@ -836,8 +824,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // only occur on archives which have CUDA_RESOLVE_DEVICE_SYMBOLS enabled if (!this->DeviceLinkObject.empty()) { object_strings.push_back(this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToCurBinDir( this->DeviceLinkObject), cmOutputConverter::SHELL)); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 4918bf6..4542672 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -218,15 +218,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } - std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); - // Look for ISPC extra object files generated by this target auto ispcAdditionalObjs = this->GeneratorTarget->GetGeneratedISPCObjects(this->GetConfigName()); for (std::string const& ispcObj : ispcAdditionalObjs) { - this->CleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - currentBinDir, ispcObj)); + this->CleanFiles.insert( + this->LocalGenerator->MaybeRelativeToCurBinDir(ispcObj)); } // add custom commands to the clean rules? @@ -251,14 +248,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() const std::vector<std::string>& outputs = ccg.GetOutputs(); for (std::string const& output : outputs) { this->CleanFiles.insert( - this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, - output)); + this->LocalGenerator->MaybeRelativeToCurBinDir(output)); } const std::vector<std::string>& byproducts = ccg.GetByproducts(); for (std::string const& byproduct : byproducts) { this->CleanFiles.insert( - this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, - byproduct)); + this->LocalGenerator->MaybeRelativeToCurBinDir(byproduct)); } } } @@ -279,8 +274,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() const std::vector<std::string>& byproducts = beg.GetByproducts(); for (std::string const& byproduct : byproducts) { this->CleanFiles.insert( - this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, - byproduct)); + this->LocalGenerator->MaybeRelativeToCurBinDir(byproduct)); } } } @@ -327,8 +321,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() << "# Include any dependencies generated for this target.\n" << this->GlobalGenerator->IncludeDirective << " " << root << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), dependFileNameFull)) + this->LocalGenerator->MaybeRelativeToTopBinDir(dependFileNameFull)) << "\n"; std::string depsUseCompiler = "CMAKE_DEPENDS_USE_COMPILER"; @@ -336,14 +329,14 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() this->Makefile->IsOn(depsUseCompiler)) { std::string compilerDependFile = cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make"); - *this->BuildFileStream - << "# Include any dependencies generated by the " - "compiler for this target.\n" - << this->GlobalGenerator->IncludeDirective << " " << root - << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), compilerDependFile)) - << "\n\n"; + *this->BuildFileStream << "# Include any dependencies generated by the " + "compiler for this target.\n" + << this->GlobalGenerator->IncludeDirective << " " + << root + << cmSystemTools::ConvertToOutputPath( + this->LocalGenerator->MaybeRelativeToTopBinDir( + compilerDependFile)) + << "\n\n"; // Write an empty dependency file. cmGeneratedFileStream depFileStream( @@ -399,8 +392,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() << "# Include the progress variables for this target.\n" << this->GlobalGenerator->IncludeDirective << " " << root << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToTopBinDir( this->ProgressFileNameFull)) << "\n\n"; } @@ -423,8 +415,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() << "# Include the compile flags for this target's objects.\n" << this->GlobalGenerator->IncludeDirective << " " << root << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), this->FlagFileNameFull)) + this->LocalGenerator->MaybeRelativeToTopBinDir( + this->FlagFileNameFull)) << "\n\n"; } @@ -491,10 +483,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()( std::string output = cmStrCat(macdir, '/', cmSystemTools::GetFilenameName(input)); this->Generator->CleanFiles.insert( - this->Generator->LocalGenerator->MaybeConvertToRelativePath( - this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output)); - output = this->Generator->LocalGenerator->MaybeConvertToRelativePath( - this->Generator->LocalGenerator->GetBinaryDirectory(), output); + this->Generator->LocalGenerator->MaybeRelativeToCurBinDir(output)); + output = this->Generator->LocalGenerator->MaybeRelativeToTopBinDir(output); // Create a rule to copy the content into the bundle. std::vector<std::string> depends; @@ -663,7 +653,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( cmProp ispcSuffixProp = this->GeneratorTarget->GetProperty("ISPC_HEADER_SUFFIX"); - assert(ispcSuffixProp != nullptr); + assert(ispcSuffixProp); std::string directory = this->GeneratorTarget->GetObjectDirectory(config); if (cmProp prop = @@ -797,15 +787,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( } targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal), cmOutputConverter::SHELL); targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat( targetFullPathPDB, cmOutputConverter::SHELL); targetOutPathCompilePDB = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), - targetFullPathCompilePDB), + this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathCompilePDB), cmOutputConverter::SHELL); if (this->LocalGenerator->IsMinGWMake() && @@ -834,14 +821,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( vars.Object = shellObj.c_str(); std::string objectDir = this->GeneratorTarget->GetSupportDirectory(); objectDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir), cmOutputConverter::SHELL); vars.ObjectDir = objectDir.c_str(); std::string objectFileDir = cmSystemTools::GetFilenamePath(obj); objectFileDir = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectFileDir), + this->LocalGenerator->MaybeRelativeToCurBinDir(objectFileDir), cmOutputConverter::SHELL); vars.ObjectFileDir = objectFileDir.c_str(); vars.Flags = flags.c_str(); @@ -854,7 +839,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( vars.Defines = definesString.c_str(); std::string includesString = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, lang, true, false, config); + includes, this->GeneratorTarget, lang, config); this->LocalGenerator->AppendFlags(includesString, "$(" + lang + "_INCLUDES)"); vars.Includes = includesString.c_str(); @@ -865,8 +850,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( if (compilerGenerateDeps) { dependencyTarget = this->LocalGenerator->EscapeForShell( this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), relativeObj))); + this->LocalGenerator->MaybeRelativeToTopBinDir(relativeObj))); vars.DependencyTarget = dependencyTarget.c_str(); auto depFile = cmStrCat(obj, ".d"); @@ -875,8 +859,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( vars.DependencyFile = shellDependencyFile.c_str(); this->CleanFiles.insert(depFile); - dependencyTimestamp = this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), + dependencyTimestamp = this->LocalGenerator->MaybeRelativeToTopBinDir( cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts")); } @@ -1302,12 +1285,11 @@ bool cmMakefileTargetGenerator::WriteMakeRule( // For multiple outputs, make the extra ones depend on the first one. std::vector<std::string> const output_depends(1, outputs[0]); - std::string binDir = this->LocalGenerator->GetBinaryDirectory(); for (std::string const& output : cmMakeRange(outputs).advance(1)) { // Touch the extra output so "make" knows that it was updated, // but only if the output was actually created. std::string const out = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, output), + this->LocalGenerator->MaybeRelativeToTopBinDir(output), cmOutputConverter::SHELL); std::vector<std::string> output_commands; @@ -1515,14 +1497,12 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule( const std::string objectDir = this->GeneratorTarget->ObjectDirectory; const std::string relObjectDir = - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir); + this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir); // Construct a list of files associated with this executable that // may need to be cleaned. std::vector<std::string> cleanFiles; - cleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), output)); + cleanFiles.push_back(this->LocalGenerator->MaybeRelativeToCurBinDir(output)); std::string profiles; std::vector<std::string> fatbinaryDepends; @@ -1547,8 +1527,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule( // generate it only on the first invocation to reduce overhead. if (fatbinaryDepends.size() == 1) { std::string registerFileRel = - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), registerFile); + this->LocalGenerator->MaybeRelativeToCurBinDir(registerFile); registerFileCmd = cmStrCat(" --register-link-binaries=", registerFileRel); cleanFiles.push_back(registerFileRel); @@ -1572,8 +1551,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule( const std::string fatbinaryOutput = cmStrCat(objectDir, "cmake_cuda_fatbin.h"); const std::string fatbinaryOutputRel = - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), fatbinaryOutput); + this->LocalGenerator->MaybeRelativeToCurBinDir(fatbinaryOutput); this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, fatbinaryOutputRel, fatbinaryDepends, @@ -1640,8 +1618,7 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile( if (!ccg.GetCC().GetDepfile().empty()) { // Add dependency over timestamp file for dependencies management auto dependTimestamp = cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToTopBinDir( cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"))); depends.push_back(dependTimestamp); @@ -1743,11 +1720,8 @@ void cmMakefileTargetGenerator::WriteObjectsVariable( << this->GeneratorTarget->GetName() << "\n" << variableNameExternal << " ="; /* clang-format on */ - std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); for (std::string const& obj : this->ExternalObjects) { - object = - this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, obj); + object = this->LocalGenerator->MaybeRelativeToCurBinDir(obj); *this->BuildFileStream << " " << lineContinue; *this->BuildFileStream << cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath( @@ -1775,7 +1749,8 @@ public: { // Construct the name of the next object. this->NextObject = this->OutputConverter->ConvertToOutputFormat( - this->MaybeConvertToRelativePath(obj), cmOutputConverter::RESPONSE); + this->OutputConverter->MaybeRelativeToCurBinDir(obj), + cmOutputConverter::RESPONSE); // Roll over to next string if the limit will be exceeded. if (this->LengthLimit != std::string::npos && @@ -1796,15 +1771,6 @@ public: void Done() { this->Strings.push_back(this->CurrentString); } private: - std::string MaybeConvertToRelativePath(std::string const& obj) - { - if (!this->StateDir.ContainsBoth(this->StateDir.GetCurrentBinary(), obj)) { - return obj; - } - return cmSystemTools::ForceToRelativePath( - this->StateDir.GetCurrentBinary(), obj); - } - std::vector<std::string>& Strings; cmOutputConverter* OutputConverter; cmStateDirectory StateDir; @@ -1847,8 +1813,8 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget); std::string buildTargetRuleName = cmStrCat(dir, relink ? "/preinstall" : "/build"); - buildTargetRuleName = this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), buildTargetRuleName); + buildTargetRuleName = + this->LocalGenerator->MaybeRelativeToTopBinDir(buildTargetRuleName); // Build the list of target outputs to drive. std::vector<std::string> depends; @@ -1985,13 +1951,12 @@ void cmMakefileTargetGenerator::CreateLinkScript( } // Create the makefile command to invoke the link script. - std::string link_command = cmStrCat( - "$(CMAKE_COMMAND) -E cmake_link_script ", - this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName), - cmOutputConverter::SHELL), - " --verbose=$(VERBOSE)"); + std::string link_command = + cmStrCat("$(CMAKE_COMMAND) -E cmake_link_script ", + this->LocalGenerator->ConvertToOutputFormat( + this->LocalGenerator->MaybeRelativeToCurBinDir(linkScriptName), + cmOutputConverter::SHELL), + " --verbose=$(VERBOSE)"); makefile_commands.push_back(std::move(link_command)); makefile_depends.push_back(std::move(linkScriptName)); } @@ -2058,7 +2023,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile( // Create the response file. std::string responseFileNameFull = cmStrCat(this->TargetBuildDirectoryFull, '/', name); - cmGeneratedFileStream responseStream(responseFileNameFull); + cmGeneratedFileStream responseStream( + responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); responseStream.SetCopyIfDifferent(true); responseStream << options << "\n"; @@ -2195,8 +2161,8 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, lang, this->GetConfigName()); std::string includeFlags = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, lang, false, useResponseFile, - this->GetConfigName()); + includes, this->GeneratorTarget, lang, this->GetConfigName(), + useResponseFile); if (includeFlags.empty()) { return; } @@ -2232,14 +2198,12 @@ void cmMakefileTargetGenerator::GenDefFile( this->LocalGenerator->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL), " -E __create_def ", this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), mdi->DefFile), + this->LocalGenerator->MaybeRelativeToCurBinDir(mdi->DefFile), cmOutputConverter::SHELL), ' '); std::string objlist_file = mdi->DefFile + ".objs"; cmd += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file), + this->LocalGenerator->MaybeRelativeToCurBinDir(objlist_file), cmOutputConverter::SHELL); cmProp nm_executable = this->Makefile->GetDefinition("CMAKE_NM"); if (cmNonempty(nm_executable)) { diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index a885b17..7f854ee 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -48,8 +48,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles() << "# Include any custom commands dependencies for this target.\n" << this->GlobalGenerator->IncludeDirective << " " << root << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), dependFile)) + this->LocalGenerator->MaybeRelativeToTopBinDir(dependFile)) << "\n\n"; if (!cmSystemTools::FileExists(dependFile)) { // Write an empty dependency file. @@ -78,8 +77,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles() << "# Include the progress variables for this target.\n" << this->GlobalGenerator->IncludeDirective << " " << root << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), + this->LocalGenerator->MaybeRelativeToTopBinDir( this->ProgressFileNameFull)) << "\n\n"; } diff --git a/Source/cmMessageMetadata.h b/Source/cmMessageMetadata.h new file mode 100644 index 0000000..7b56fae --- /dev/null +++ b/Source/cmMessageMetadata.h @@ -0,0 +1,11 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmsys/Terminal.h" + +struct cmMessageMetadata +{ + const char* title = nullptr; + int desiredColor = cmsysTerminal_Color_Normal; +}; diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index af83478..1cb638a 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx @@ -3,6 +3,7 @@ #include "cmMessenger.h" #include "cmDocumentationFormatter.h" +#include "cmMessageMetadata.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -12,6 +13,8 @@ #include <sstream> +#include "cmsys/Terminal.h" + MessageType cmMessenger::ConvertMessageType(MessageType t) const { bool warningsAsErrors; @@ -84,6 +87,21 @@ static bool printMessagePreamble(MessageType t, std::ostream& msg) return true; } +static int getMessageColor(MessageType t) +{ + switch (t) { + case MessageType::INTERNAL_ERROR: + case MessageType::FATAL_ERROR: + case MessageType::AUTHOR_ERROR: + return cmsysTerminal_Color_ForegroundRed; + case MessageType::AUTHOR_WARNING: + case MessageType::WARNING: + return cmsysTerminal_Color_ForegroundYellow; + default: + return cmsysTerminal_Color_Normal; + } +} + void printMessageText(std::ostream& msg, std::string const& text) { msg << ":\n"; @@ -120,12 +138,16 @@ void displayMessage(MessageType t, std::ostringstream& msg) #endif // Output the message. + cmMessageMetadata md; + md.desiredColor = getMessageColor(t); if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR || t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) { cmSystemTools::SetErrorOccured(); - cmSystemTools::Message(msg.str(), "Error"); + md.title = "Error"; + cmSystemTools::Message(msg.str(), md); } else { - cmSystemTools::Message(msg.str(), "Warning"); + md.title = "Warning"; + cmSystemTools::Message(msg.str(), md); } } diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 1597d2c..1b514b8 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -875,7 +875,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( if (genTarget->HasSOName(config)) { vars["SONAME_FLAG"] = this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config)); - vars["SONAME"] = tgtNames.SharedObject; + vars["SONAME"] = localGen.ConvertToOutputFormat(tgtNames.SharedObject, + cmOutputConverter::SHELL); if (genTarget->GetType() == cmStateEnums::SHARED_LIBRARY) { std::string install_dir = this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config); @@ -1183,7 +1184,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( } if (gt->HasSOName(config)) { vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage(config)); - vars["SONAME"] = tgtNames.SharedObject; + vars["SONAME"] = localGen.ConvertToOutputFormat(tgtNames.SharedObject, + cmOutputConverter::SHELL); if (targetType == cmStateEnums::SHARED_LIBRARY) { std::string install_dir = gt->GetInstallNameDirForBuildTree(config); if (!install_dir.empty()) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index b4838d6..3ebf364 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -263,9 +263,10 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags, language, config); // Add include directory flags. std::string includeFlags = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, language, - language == "RC", // full include paths for RC needed by cmcldeps - false, config); + includes, this->GeneratorTarget, language, config, false, + // full include paths for RC needed by cmcldeps + language == "RC" ? cmLocalGenerator::IncludePathStyle::Absolute + : cmLocalGenerator::IncludePathStyle::Default); if (this->GetGlobalGenerator()->IsGCCOnWindows()) { std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/'); } @@ -324,7 +325,8 @@ std::string cmNinjaTargetGenerator::ComputeIncludes( } std::string includesString = this->LocalGenerator->GetIncludeFlags( - includes, this->GeneratorTarget, language, true, false, config); + includes, this->GeneratorTarget, language, config, false, + cmLocalGenerator::IncludePathStyle::Absolute); this->LocalGenerator->AppendFlags(includesString, this->GetIncludes(language, config)); @@ -526,7 +528,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi, const std::string& ddiFile) { return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, - " --lang=", lang, " --src=$in", " --pp=", ppFile, + " --lang=", lang, " --pp=", ppFile, " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile); } @@ -1383,8 +1385,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( cmSystemTools::GetParentDirectory(source->GetFullPath())); std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags( - sourceDirectory, this->GeneratorTarget, language, false, false, - config); + sourceDirectory, this->GeneratorTarget, language, config, false, + cmLocalGenerator::IncludePathStyle::Default); vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]); } @@ -1442,7 +1444,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( cmProp ispcSuffixProp = this->GeneratorTarget->GetProperty("ISPC_HEADER_SUFFIX"); - assert(ispcSuffixProp != nullptr); + assert(ispcSuffixProp); std::string ispcHeaderDirectory = this->GeneratorTarget->GetObjectDirectory(config); diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h index 320f41b..c8a411e 100644 --- a/Source/cmNinjaTypes.h +++ b/Source/cmNinjaTypes.h @@ -53,6 +53,7 @@ public: std::string Rule; cmNinjaDeps Outputs; cmNinjaDeps ImplicitOuts; + cmNinjaDeps WorkDirOuts; // For cmake_ninja_workdir. cmNinjaDeps ExplicitDeps; cmNinjaDeps ImplicitDeps; cmNinjaDeps OrderOnlyDeps; diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 7a04c47..1f5a7ff 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -73,7 +73,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmNinjaBuild phonyBuild("phony"); std::vector<std::string> commands; cmNinjaDeps deps; - cmNinjaDeps util_outputs(1, utilCommandName); + cmGlobalNinjaGenerator::CCOutputs util_outputs(gg); + util_outputs.ExplicitOuts.emplace_back(utilCommandName); bool uses_terminal = false; { @@ -86,10 +87,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmCustomCommandGenerator ccg(ci, fileConfig, lg); lg->AppendCustomCommandDeps(ccg, deps, fileConfig); lg->AppendCustomCommandLines(ccg, commands); - std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); - std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(util_outputs), - this->MapToNinjaPath()); + util_outputs.Add(ccg.GetByproducts()); if (ci.GetUsesTerminal()) { uses_terminal = true; } @@ -124,7 +122,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) { lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(), config); - std::copy(util_outputs.begin(), util_outputs.end(), + std::copy(util_outputs.ExplicitOuts.begin(), + util_outputs.ExplicitOuts.end(), std::back_inserter(gg->GetByproductsForCleanTarget())); } lg->AppendTargetDepends(genTarget, deps, config, fileConfig, @@ -166,10 +165,6 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( return; } - for (std::string const& util_output : util_outputs) { - gg->SeenCustomCommandOutput(util_output); - } - std::string ccConfig; if (genTarget->Target->IsPerConfig() && genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { @@ -180,7 +175,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( gg->WriteCustomCommandBuild( command, desc, "Utility command for " + this->GetTargetName(), /*depfile*/ "", /*job_pool*/ "", uses_terminal, - /*restat*/ true, util_outputs, ccConfig, deps); + /*restat*/ true, ccConfig, std::move(util_outputs), std::move(deps)); } phonyBuild.ExplicitDeps.push_back(utilCommandName); diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 0369af0..37c4afc 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -359,7 +359,7 @@ void cmOrderDirectories::SetLinkExtensionInfo( std::string const& removeExtRegex) { this->LinkExtensions = linkExtensions; - this->RemoveLibraryExtension.compile(removeExtRegex.c_str()); + this->RemoveLibraryExtension.compile(removeExtRegex); } void cmOrderDirectories::CollectOriginalDirectories() @@ -512,7 +512,7 @@ void cmOrderDirectories::VisitDirectory(unsigned int i) } // Now that all directories required to come before this one have - // been emmitted, emit this directory. + // been emitted, emit this directory. this->OrderedDirectories.push_back(this->OriginalDirectories[i]); } diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index ec54537..840fdb9 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -9,14 +9,108 @@ #include <vector> #include "cmState.h" +#include "cmStateDirectory.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { +bool PathEqOrSubDir(std::string const& a, std::string const& b) +{ + return (cmSystemTools::ComparePath(a, b) || + cmSystemTools::IsSubDirectory(a, b)); +}; +} + cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot) : StateSnapshot(snapshot) , LinkScriptShell(false) { assert(this->StateSnapshot.IsValid()); + this->ComputeRelativePathTopSource(); + this->ComputeRelativePathTopBinary(); +} + +void cmOutputConverter::ComputeRelativePathTopSource() +{ + // Walk up the buildsystem directory tree to find the highest source + // directory that contains the current source directory. + cmStateSnapshot snapshot = this->StateSnapshot; + for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent(); + parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) { + if (cmSystemTools::IsSubDirectory( + snapshot.GetDirectory().GetCurrentSource(), + parent.GetDirectory().GetCurrentSource())) { + snapshot = parent; + } + } + this->RelativePathTopSource = snapshot.GetDirectory().GetCurrentSource(); +} + +void cmOutputConverter::ComputeRelativePathTopBinary() +{ + // Walk up the buildsystem directory tree to find the highest binary + // directory that contains the current binary directory. + cmStateSnapshot snapshot = this->StateSnapshot; + for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent(); + parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) { + if (cmSystemTools::IsSubDirectory( + snapshot.GetDirectory().GetCurrentBinary(), + parent.GetDirectory().GetCurrentBinary())) { + snapshot = parent; + } + } + + this->RelativePathTopBinary = snapshot.GetDirectory().GetCurrentBinary(); +} + +std::string const& cmOutputConverter::GetRelativePathTopSource() const +{ + return this->RelativePathTopSource; +} + +std::string const& cmOutputConverter::GetRelativePathTopBinary() const +{ + return this->RelativePathTopBinary; +} + +void cmOutputConverter::SetRelativePathTopSource(std::string const& top) +{ + this->RelativePathTopSource = top; +} + +void cmOutputConverter::SetRelativePathTopBinary(std::string const& top) +{ + this->RelativePathTopBinary = top; +} + +std::string cmOutputConverter::MaybeRelativeTo( + std::string const& local_path, std::string const& remote_path) const +{ + bool bothInBinary = + PathEqOrSubDir(local_path, this->RelativePathTopBinary) && + PathEqOrSubDir(remote_path, this->RelativePathTopBinary); + + bool bothInSource = + PathEqOrSubDir(local_path, this->RelativePathTopSource) && + PathEqOrSubDir(remote_path, this->RelativePathTopSource); + + if (bothInBinary || bothInSource) { + return cmSystemTools::ForceToRelativePath(local_path, remote_path); + } + return remote_path; +} + +std::string cmOutputConverter::MaybeRelativeToTopBinDir( + std::string const& path) const +{ + return this->MaybeRelativeTo(this->GetState()->GetBinaryDirectory(), path); +} + +std::string cmOutputConverter::MaybeRelativeToCurBinDir( + std::string const& path) const +{ + return this->MaybeRelativeTo( + this->StateSnapshot.GetDirectory().GetCurrentBinary(), path); } std::string cmOutputConverter::ConvertToOutputForExisting( diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index f1a8041..865df71 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -17,6 +17,21 @@ class cmOutputConverter public: cmOutputConverter(cmStateSnapshot const& snapshot); + /** + * Convert the given remote path to a relative path with respect to + * one of our common work directories. The path must use forward + * slashes and not already be escaped or quoted. + * The conversion is skipped if the paths are not both in the source + * or both in the binary tree. + */ + std::string MaybeRelativeToTopBinDir(std::string const& path) const; + std::string MaybeRelativeToCurBinDir(std::string const& path) const; + + std::string const& GetRelativePathTopSource() const; + std::string const& GetRelativePathTopBinary() const; + void SetRelativePathTopSource(std::string const& top); + void SetRelativePathTopBinary(std::string const& top); + enum OutputFormat { SHELL, @@ -102,6 +117,9 @@ public: }; static FortranPreprocess GetFortranPreprocess(cm::string_view value); +protected: + cmStateSnapshot StateSnapshot; + private: cmState* GetState() const; @@ -111,7 +129,17 @@ private: static bool Shell_ArgumentNeedsQuotes(cm::string_view in, int flags); static std::string Shell_GetArgument(cm::string_view in, int flags); - cmStateSnapshot StateSnapshot; - bool LinkScriptShell; + + // The top-most directories for relative path conversion. Both the + // source and destination location of a relative path conversion + // must be underneath one of these directories (both under source or + // both under binary) in order for the relative path to be evaluated + // safely by the build tools. + std::string RelativePathTopSource; + std::string RelativePathTopBinary; + void ComputeRelativePathTopSource(); + void ComputeRelativePathTopBinary(); + std::string MaybeRelativeTo(std::string const& local_path, + std::string const& remote_path) const; }; diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 2194b0f..3ebb17d 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -359,7 +359,24 @@ class cmMakefile; 3, 20, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0120, \ "The WriteCompilerDetectionHeader module is removed.", 3, 20, 0, \ - cmPolicies::WARN) + cmPolicies::WARN) \ + SELECT(POLICY, CMP0121, \ + "The list() command now validates parsing of index arguments.", 3, \ + 21, 0, cmPolicies::WARN) \ + SELECT( \ + POLICY, CMP0122, \ + "UseSWIG use standard library name conventions for csharp language.", 3, \ + 21, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0123, \ + "ARMClang cpu/arch compile and link flags must be set explicitly.", \ + 3, 21, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0124, \ + "foreach() loop variables are only available in the loop scope.", 3, \ + 21, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0125, \ + "find_(path|file|library|program) have consistent behavior for " \ + "cache variables.", \ + 3, 21, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index ed32de9..acdb09f 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -59,6 +59,11 @@ bool cmProjectCommand(std::vector<std::string> const& args, mf.AddDefinition("PROJECT_NAME", projectName); + mf.AddDefinitionBool("PROJECT_IS_TOP_LEVEL", mf.IsRootMakefile()); + mf.AddCacheDefinition(projectName + "_IS_TOP_LEVEL", + mf.IsRootMakefile() ? "ON" : "OFF", + "Value Computed by CMake", cmStateEnums::STATIC); + // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands // in the same CMakeLists.txt file, and it is the top level diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index f8d18f2..77fe87e 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -119,7 +119,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( target->GetSafeProperty(this->kw().AUTORCC_EXECUTABLE); // We support Qt4, Qt5 and Qt6 - auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get()); + auto qtVersion = + cmQtAutoGenInitializer::GetQtVersion(target.get(), mocExec); bool const validQt = (qtVersion.first.Major == 4) || (qtVersion.first.Major == 5) || (qtVersion.first.Major == 6); @@ -184,7 +185,7 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( { cmProp folder = makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER"); - if (folder != nullptr) { + if (folder) { target->SetProperty("FOLDER", *folder); } } diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index a1816f1..2894201 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -6,8 +6,8 @@ #include <deque> #include <initializer_list> #include <map> -#include <ostream> #include <set> +#include <sstream> // for basic_ios, istringstream #include <string> #include <unordered_set> #include <utility> @@ -114,10 +114,10 @@ bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, // Collect all static_library dependencies from the test target cmLinkImplementationLibraries const* libs = testTarget->GetLinkImplementationLibraries(config); - if (libs != nullptr) { + if (libs) { for (cmLinkItem const& item : libs->Libraries) { cmGeneratorTarget const* depTarget = item.Target; - if ((depTarget != nullptr) && + if (depTarget && (depTarget->GetType() == cmStateEnums::STATIC_LIBRARY) && knownLibs.insert(depTarget).second) { testLibs.push_back(depTarget); @@ -294,6 +294,17 @@ bool InfoWriter::Save(std::string const& filename) return fileStream.Close(); } +void AddAutogenExecutableToDependencies( + cmQtAutoGenInitializer::GenVarsT const& genVars, + std::vector<std::string>& dependencies) +{ + if (genVars.ExecutableTarget != nullptr) { + dependencies.push_back(genVars.ExecutableTarget->Target->GetName()); + } else if (!genVars.Executable.empty()) { + dependencies.push_back(genVars.Executable); + } +} + } // End of unnamed namespace cmQtAutoGenInitializer::cmQtAutoGenInitializer( @@ -346,15 +357,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets() { cmProp folder = this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER"); - if (folder == nullptr) { + if (!folder) { folder = this->Makefile->GetState()->GetGlobalProperty( "AUTOGEN_TARGETS_FOLDER"); } // Inherit FOLDER property from target (#13688) - if (folder == nullptr) { + if (!folder) { folder = this->GenTarget->GetProperty("FOLDER"); } - if (folder != nullptr) { + if (folder) { this->TargetsFolder = *folder; } } @@ -419,12 +430,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets() cmSystemTools::ConvertToUnixSlashes(this->Dir.Work); // Include directory - this->ConfigFileNames(this->Dir.Include, - cmStrCat(this->Dir.Build, "/include"), ""); - this->Dir.IncludeGenExp = this->Dir.Include.Default; - if (this->MultiConfig) { - this->Dir.IncludeGenExp += "_$<CONFIG>"; - } + this->ConfigFileNamesAndGenex(this->Dir.Include, this->Dir.IncludeGenExp, + cmStrCat(this->Dir.Build, "/include"), ""); } // Moc, Uic and _autogen target settings @@ -483,7 +490,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() for (std::string const& depName : cmExpandedList(deps)) { // Allow target and file dependencies auto* depTarget = this->Makefile->FindTargetToUse(depName); - if (depTarget != nullptr) { + if (depTarget) { this->AutogenTarget.DependTargets.insert(depTarget); } else { this->AutogenTarget.DependFiles.insert(depName); @@ -575,15 +582,9 @@ bool cmQtAutoGenInitializer::InitMoc() cmStrCat(this->Dir.Build, "/mocs_compilation.cpp"); this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default; } else { - this->ConfigFileNames(this->Moc.CompilationFile, - cmStrCat(this->Dir.Build, "/mocs_compilation"), - ".cpp"); - if (this->MultiConfig) { - this->Moc.CompilationFileGenex = - cmStrCat(this->Dir.Build, "/mocs_compilation_$<CONFIG>.cpp"_s); - } else { - this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default; - } + this->ConfigFileNamesAndGenex( + this->Moc.CompilationFile, this->Moc.CompilationFileGenex, + cmStrCat(this->Dir.Build, "/mocs_compilation"_s), ".cpp"_s); } // Moc predefs @@ -661,7 +662,7 @@ bool cmQtAutoGenInitializer::InitMoc() return false; } // Let the _autogen target depend on the moc executable - if (this->Moc.ExecutableTarget != nullptr) { + if (this->Moc.ExecutableTarget) { this->AutogenTarget.DependTargets.insert( this->Moc.ExecutableTarget->Target); } @@ -709,7 +710,7 @@ bool cmQtAutoGenInitializer::InitUic() return false; } // Let the _autogen target depend on the uic executable - if (this->Uic.ExecutableTarget != nullptr) { + if (this->Uic.ExecutableTarget) { this->AutogenTarget.DependTargets.insert( this->Uic.ExecutableTarget->Target); } @@ -864,7 +865,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() auto constexpr locationKind = cmSourceFileLocationKind::Known; cmSourceFile* sf = this->Makefile->GetSource(fullPath, locationKind); - if (sf != nullptr) { + if (sf) { // Check if we know about this header already if (cm::contains(this->AutogenTarget.Headers, sf)) { continue; @@ -879,7 +880,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() sf = this->Makefile->CreateSource(fullPath, false, locationKind); } - if (sf != nullptr) { + if (sf) { auto eMuf = makeMUFile(sf, fullPath, muf.Configs, true); // Only process moc/uic when the parent is processed as well if (!muf.MocIt) { @@ -935,9 +936,35 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!skipUic) { // Check if the .ui file has uic options std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS); - if (!uicOpts.empty()) { - this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts)); + if (uicOpts.empty()) { + this->Uic.UiFilesNoOptions.emplace_back(fullPath); + } else { + this->Uic.UiFilesWithOptions.emplace_back(fullPath, + cmExpandedList(uicOpts)); } + + auto uiHeaderRelativePath = cmSystemTools::RelativePath( + this->LocalGen->GetCurrentSourceDirectory(), + cmSystemTools::GetFilenamePath(fullPath)); + + // Avoid creating a path containing adjacent slashes + if (!uiHeaderRelativePath.empty() && + uiHeaderRelativePath.back() != '/') { + uiHeaderRelativePath += '/'; + } + + auto uiHeaderFilePath = cmStrCat( + '/', uiHeaderRelativePath, "ui_"_s, + cmSystemTools::GetFilenameWithoutLastExtension(fullPath), ".h"_s); + + ConfigString uiHeader; + std::string uiHeaderGenex; + this->ConfigFileNamesAndGenex( + uiHeader, uiHeaderGenex, cmStrCat(this->Dir.Build, "/include"_s), + uiHeaderFilePath); + + this->Uic.UiHeaders.emplace_back( + std::make_pair(uiHeader, uiHeaderGenex)); } else { // Register skipped .ui file this->Uic.SkipUi.insert(fullPath); @@ -1091,6 +1118,13 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() autogenByproducts.push_back(this->Moc.CompilationFileGenex); } + if (this->Uic.Enabled) { + for (const auto& file : this->Uic.UiHeaders) { + this->AddGeneratedSource(file.first, this->Uic); + autogenByproducts.push_back(file.second); + } + } + // Compose target comment std::string autogenComment; { @@ -1149,6 +1183,42 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() this->Makefile); } + if (!this->Uic.UiFilesNoOptions.empty() || + !this->Uic.UiFilesWithOptions.empty()) { + // Add a generated timestamp file + ConfigString timestampFile; + std::string timestampFileGenex; + ConfigFileNamesAndGenex(timestampFile, timestampFileGenex, + cmStrCat(this->Dir.Build, "/autouic"_s), + ".stamp"_s); + this->AddGeneratedSource(timestampFile, this->Uic); + + // Add a step in the pre-build command to touch the timestamp file + commandLines.push_back( + cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", "touch", + timestampFileGenex })); + + // UIC needs to be re-run if any of the known UI files change or the + // executable itself has been updated + auto uicDependencies = this->Uic.UiFilesNoOptions; + for (auto const& uiFile : this->Uic.UiFilesWithOptions) { + uicDependencies.push_back(uiFile.first); + } + AddAutogenExecutableToDependencies(this->Uic, uicDependencies); + + // Add a rule file to cause the target to build if a dependency has + // changed, which will trigger the pre-build command to run autogen + std::string no_main_dependency; + cmCustomCommandLines no_command_lines; + this->LocalGen->AddCustomCommandToOutput( + timestampFileGenex, uicDependencies, no_main_dependency, + no_command_lines, /*comment=*/"", this->Dir.Work.c_str(), + /*cmp0116=*/cmPolicies::NEW, /*replace=*/false, + /*escapeOldStyle=*/false, /*uses_terminal=*/false, + /*command_expand_lists=*/false, /*depfile=*/"", /*job_pool=*/"", + stdPipesUTF8); + } + // Add the pre-build command directly to bypass the OBJECT_LIBRARY // rejection in cmMakefile::AddCustomCommandToTarget because we know // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. @@ -1173,10 +1243,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() for (std::string const& config : this->ConfigsList) { cmLinkImplementationLibraries const* libs = this->GenTarget->GetLinkImplementationLibraries(config); - if (libs != nullptr) { + if (libs) { for (cmLinkItem const& item : libs->Libraries) { cmGeneratorTarget const* libTarget = item.Target; - if ((libTarget != nullptr) && + if (libTarget && !StaticLibraryCycle(this->GenTarget, libTarget, config)) { // Increment target config count commonTargets[libTarget]++; @@ -1241,16 +1311,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() dependencies.clear(); dependencies.push_back(timestampTargetName); - if (this->Moc.ExecutableTarget != nullptr) { - dependencies.push_back(this->Moc.ExecutableTarget->Target->GetName()); - } else if (!this->Moc.Executable.empty()) { - dependencies.push_back(this->Moc.Executable); - } - if (this->Uic.ExecutableTarget != nullptr) { - dependencies.push_back(this->Uic.ExecutableTarget->Target->GetName()); - } else if (!this->Uic.Executable.empty()) { - dependencies.push_back(this->Uic.Executable); - } + AddAutogenExecutableToDependencies(this->Moc, dependencies); + AddAutogenExecutableToDependencies(this->Uic, dependencies); // Create the custom command that outputs the timestamp file. const char timestampFileName[] = "timestamp"; @@ -1589,7 +1651,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() uic_skip.insert(this->Uic.SkipUi.begin(), this->Uic.SkipUi.end()); info.SetArray("UIC_SKIP", uic_skip); - info.SetArrayArray("UIC_UI_FILES", this->Uic.UiFiles, + info.SetArrayArray("UIC_UI_FILES", this->Uic.UiFilesWithOptions, [](Json::Value& jval, UicT::UiFileT const& uiFile) { jval.resize(2u); jval[0u] = uiFile.first; @@ -1718,7 +1780,7 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, // Generate a source group on demand if (!groupName.empty()) { sourceGroup = this->Makefile->GetOrCreateSourceGroup(groupName); - if (sourceGroup == nullptr) { + if (!sourceGroup) { cmSystemTools::Error( cmStrCat(genNameUpper, " error in ", property, ": Could not find or create the source group ", @@ -1726,7 +1788,7 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, } } } - if (sourceGroup != nullptr) { + if (sourceGroup) { sourceGroup->AddGroupFile(fileName); } } @@ -1749,6 +1811,18 @@ void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString, } } +void cmQtAutoGenInitializer::ConfigFileNamesAndGenex( + ConfigString& configString, std::string& genex, cm::string_view const prefix, + cm::string_view const suffix) +{ + this->ConfigFileNames(configString, prefix, suffix); + if (this->MultiConfig) { + genex = cmStrCat(prefix, "_$<CONFIG>"_s, suffix); + } else { + genex = configString.Default; + } +} + void cmQtAutoGenInitializer::ConfigFileClean(ConfigString& configString) { this->AddCleanFile(configString.Default); @@ -1759,20 +1833,75 @@ void cmQtAutoGenInitializer::ConfigFileClean(ConfigString& configString) } } +static cmQtAutoGen::IntegerVersion parseMocVersion(std::string str) +{ + cmQtAutoGen::IntegerVersion result; + + static const std::string prelude = "moc "; + size_t pos = str.find(prelude); + if (pos == std::string::npos) { + return result; + } + + str.erase(0, prelude.size() + pos); + std::istringstream iss(str); + std::string major; + std::string minor; + if (!std::getline(iss, major, '.') || !std::getline(iss, minor, '.')) { + return result; + } + + result.Major = static_cast<unsigned int>(std::stoi(major)); + result.Minor = static_cast<unsigned int>(std::stoi(minor)); + return result; +} + +static cmQtAutoGen::IntegerVersion GetMocVersion( + const std::string& mocExecutablePath) +{ + std::string capturedStdOut; + int exitCode; + if (!cmSystemTools::RunSingleCommand({ mocExecutablePath, "--version" }, + &capturedStdOut, nullptr, &exitCode, + nullptr, cmSystemTools::OUTPUT_NONE)) { + return {}; + } + + if (exitCode != 0) { + return {}; + } + + return parseMocVersion(capturedStdOut); +} + +static std::string FindMocExecutableFromMocTarget(cmMakefile* makefile, + unsigned int qtMajorVersion) +{ + std::string result; + const std::string mocTargetName = + "Qt" + std::to_string(qtMajorVersion) + "::moc"; + cmTarget* mocTarget = makefile->FindTargetToUse(mocTargetName); + if (mocTarget) { + result = mocTarget->GetSafeProperty("IMPORTED_LOCATION"); + } + return result; +} + std::pair<cmQtAutoGen::IntegerVersion, unsigned int> -cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target) +cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target, + std::string mocExecutable) { // Converts a char ptr to an unsigned int value auto toUInt = [](const char* const input) -> unsigned int { unsigned long tmp = 0; - if (input != nullptr && cmStrToULong(input, &tmp)) { + if (input && cmStrToULong(input, &tmp)) { return static_cast<unsigned int>(tmp); } return 0u; }; auto toUInt2 = [](cmProp input) -> unsigned int { unsigned long tmp = 0; - if (input != nullptr && cmStrToULong(*input, &tmp)) { + if (input && cmStrToULong(*input, &tmp)) { return static_cast<unsigned int>(tmp); } return 0u; @@ -1835,6 +1964,21 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target) } } } + + if (res.first.Major == 0) { + // We could not get the version number from variables or directory + // properties. This might happen if the find_package call for Qt is wrapped + // in a function. Try to find the moc executable path from the available + // targets and call "moc --version" to get the Qt version. + if (mocExecutable.empty()) { + mocExecutable = + FindMocExecutableFromMocTarget(target->Makefile, res.second); + } + if (!mocExecutable.empty()) { + res.first = GetMocVersion(mocExecutable); + } + } + return res; } @@ -1929,7 +2073,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, // Find target cmGeneratorTarget* genTarget = this->LocalGen->FindGeneratorTargetToUse(targetName); - if (genTarget != nullptr) { + if (genTarget) { genVars.ExecutableTargetName = targetName; genVars.ExecutableTarget = genTarget; if (genTarget->IsImported()) { diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index f7e126d..e76817b 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -98,9 +98,11 @@ public: , GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){}; }; - /** @return The detected Qt version and the required Qt major version. */ + /** @param mocExecutable The file path to the moc executable. Will be used as + fallback to query the version + @return The detected Qt version and the required Qt major version. */ static std::pair<IntegerVersion, unsigned int> GetQtVersion( - cmGeneratorTarget const* genTarget); + cmGeneratorTarget const* genTarget, std::string mocExecutable); cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* genTarget, @@ -141,6 +143,8 @@ private: void ConfigFileNames(ConfigString& configString, cm::string_view prefix, cm::string_view suffix); + void ConfigFileNamesAndGenex(ConfigString& configString, std::string& genex, + cm::string_view prefix, cm::string_view suffix); void ConfigFileClean(ConfigString& configString); std::string GetMocBuildPath(MUFile const& muf); @@ -236,9 +240,12 @@ private: : GenVarsT(GenT::UIC){}; std::set<std::string> SkipUi; - std::vector<UiFileT> UiFiles; + std::vector<std::string> UiFilesNoOptions; + std::vector<UiFileT> UiFilesWithOptions; ConfigStrings<std::vector<std::string>> Options; std::vector<std::string> SearchPaths; + std::vector<std::pair<ConfigString /*ui header*/, std::string /*genex*/>> + UiHeaders; } Uic; /** rcc variables. */ diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 6e88e26..568926e 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -116,7 +116,7 @@ bool cmQtAutoGenerator::MakeParentDirectory(std::string const& filename) bool success = true; std::string const dirName = cmSystemTools::GetFilenamePath(filename); if (!dirName.empty()) { - success = cmSystemTools::MakeDirectory(dirName); + success = static_cast<bool>(cmSystemTools::MakeDirectory(dirName)); } return success; } diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index f583162..f5c195f 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -1588,14 +1588,14 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi( }; // Vicinity of the source - if (findUi(cmStrCat(sourceDirPrefix, this->UiName))) { - return true; - } if (!includePrefix.empty()) { if (findUi(cmStrCat(sourceDirPrefix, includePrefix, this->UiName))) { return true; } } + if (findUi(cmStrCat(sourceDirPrefix, this->UiName))) { + return true; + } // Additional AUTOUIC search paths auto const& searchPaths = this->UicConst().SearchPaths; if (!searchPaths.empty()) { @@ -2723,6 +2723,9 @@ void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap) std::string cmQtAutoMocUicT::CollapseFullPathTS(std::string const& path) const { std::lock_guard<std::mutex> guard(this->CMakeLibMutex_); +#if defined(__NVCOMPILER) + static_cast<void>(guard); // convince compiler var is used +#endif return cmSystemTools::CollapseFullPath(path, this->ProjectDirs().CurrentSource); } @@ -2962,6 +2965,9 @@ std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile( const char* filePath) { std::lock_guard<std::mutex> guard(this->CMakeLibMutex_); +#if defined(__NVCOMPILER) + static_cast<void>(guard); // convince compiler var is used +#endif auto const content = cmReadGccDepfile(filePath); if (!content || content->empty()) { return {}; diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx index f988fe4..e66f96d 100644 --- a/Source/cmScanDepFormat.cxx +++ b/Source/cmScanDepFormat.cxx @@ -74,7 +74,8 @@ static Json::Value EncodeFilename(std::string const& path) } \ } while (0) -bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) +bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, + cmScanDepInfo* info) { Json::Value ppio; Json::Value const& ppi = ppio; @@ -116,15 +117,6 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) return false; } - Json::Value const& depends = rule["depends"]; - if (depends.isArray()) { - std::string depend_filename; - for (auto const& depend : depends) { - PARSE_FILENAME(depend, depend_filename); - info->Includes.push_back(depend_filename); - } - } - if (rule.isMember("future-compile")) { Json::Value const& future_compile = rule["future-compile"]; @@ -194,8 +186,7 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) } bool cmScanDepFormat_P1689_Write(std::string const& path, - std::string const& input, - cmSourceInfo const& info) + cmScanDepInfo const& info) { Json::Value ddi(Json::objectValue); ddi["version"] = 0; @@ -204,16 +195,6 @@ bool cmScanDepFormat_P1689_Write(std::string const& path, Json::Value& rules = ddi["rules"] = Json::arrayValue; Json::Value rule(Json::objectValue); - Json::Value& inputs = rule["inputs"] = Json::arrayValue; - inputs.append(EncodeFilename(input)); - - Json::Value& rule_outputs = rule["outputs"] = Json::arrayValue; - rule_outputs.append(EncodeFilename(path)); - - Json::Value& depends = rule["depends"] = Json::arrayValue; - for (auto const& include : info.Includes) { - depends.append(EncodeFilename(include)); - } Json::Value& future_compile = rule["future-compile"] = Json::objectValue; diff --git a/Source/cmScanDepFormat.h b/Source/cmScanDepFormat.h index 1ad0ecf..51ceec1 100644 --- a/Source/cmScanDepFormat.h +++ b/Source/cmScanDepFormat.h @@ -11,20 +11,16 @@ struct cmSourceReqInfo std::string CompiledModulePath; }; -struct cmSourceInfo +struct cmScanDepInfo { std::string PrimaryOutput; // Set of provided and required modules. std::vector<cmSourceReqInfo> Provides; std::vector<cmSourceReqInfo> Requires; - - // Set of files included in the translation unit. - std::vector<std::string> Includes; }; bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, - cmSourceInfo* info); + cmScanDepInfo* info); bool cmScanDepFormat_P1689_Write(std::string const& path, - std::string const& input, - cmSourceInfo const& info); + cmScanDepInfo const& info); diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 76a5ded..32ed687 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -175,7 +175,7 @@ private: #define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$" #define CM_SOURCE_REGEX \ - "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \ + "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|ixx|cppm|cu|f|f90|for|fpp|ftn|m|mm|" \ "rc|def|r|odl|idl|hpj|bat)$" #define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$" diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx index bf6925e..85411e6 100644 --- a/Source/cmStandardLevelResolver.cxx +++ b/Source/cmStandardLevelResolver.cxx @@ -184,7 +184,7 @@ struct StanardLevelComputer auto needed = this->HighestStandardNeeded(makefile, feature); cmProp existingStandard = currentLangStandardValue; - if (existingStandard == nullptr) { + if (!existingStandard) { cmProp defaultStandard = makefile->GetDefinition( cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT")); if (cmNonempty(defaultStandard)) { @@ -308,8 +308,9 @@ struct StanardLevelComputer std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping = { { "C", - StanardLevelComputer{ "C", std::vector<int>{ 90, 99, 11 }, - std::vector<std::string>{ "90", "99", "11" } } }, + StanardLevelComputer{ + "C", std::vector<int>{ 90, 99, 11, 17, 23 }, + std::vector<std::string>{ "90", "99", "11", "17", "23" } } }, { "CXX", StanardLevelComputer{ "CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 }, diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h index b871f5f..417f14d 100644 --- a/Source/cmStandardLexer.h +++ b/Source/cmStandardLexer.h @@ -50,6 +50,11 @@ # endif #endif +#if defined(__NVCOMPILER) +# pragma diag_suppress 111 /* statement is unreachable */ +# pragma diag_suppress 550 /* variable set but never used */ +#endif + /* Make sure isatty is available. */ #if defined(_WIN32) && !defined(__CYGWIN__) # include <io.h> diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 7ce362a..9ae2861 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -24,68 +24,6 @@ static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS"; static std::string const kSOURCE_DIR = "SOURCE_DIR"; static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES"; -void cmStateDirectory::ComputeRelativePathTopSource() -{ - // Relative path conversion inside the source tree is not used to - // construct relative paths passed to build tools so it is safe to use - // even when the source is a network path. - - cmStateSnapshot snapshot = this->Snapshot_; - std::vector<cmStateSnapshot> snapshots; - snapshots.push_back(snapshot); - while (true) { - snapshot = snapshot.GetBuildsystemDirectoryParent(); - if (snapshot.IsValid()) { - snapshots.push_back(snapshot); - } else { - break; - } - } - - std::string result = snapshots.front().GetDirectory().GetCurrentSource(); - - for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { - std::string currentSource = snp.GetDirectory().GetCurrentSource(); - if (cmSystemTools::IsSubDirectory(result, currentSource)) { - result = currentSource; - } - } - this->DirectoryState->RelativePathTopSource = result; -} - -void cmStateDirectory::ComputeRelativePathTopBinary() -{ - cmStateSnapshot snapshot = this->Snapshot_; - std::vector<cmStateSnapshot> snapshots; - snapshots.push_back(snapshot); - while (true) { - snapshot = snapshot.GetBuildsystemDirectoryParent(); - if (snapshot.IsValid()) { - snapshots.push_back(snapshot); - } else { - break; - } - } - - std::string result = snapshots.front().GetDirectory().GetCurrentBinary(); - - for (cmStateSnapshot const& snp : cmMakeRange(snapshots).advance(1)) { - std::string currentBinary = snp.GetDirectory().GetCurrentBinary(); - if (cmSystemTools::IsSubDirectory(result, currentBinary)) { - result = currentBinary; - } - } - - // The current working directory on Windows cannot be a network - // path. Therefore relative paths cannot work when the binary tree - // is a network path. - if (result.size() < 2 || result.substr(0, 2) != "//") { - this->DirectoryState->RelativePathTopBinary = result; - } else { - this->DirectoryState->RelativePathTopBinary.clear(); - } -} - std::string const& cmStateDirectory::GetCurrentSource() const { return this->DirectoryState->Location; @@ -97,9 +35,6 @@ void cmStateDirectory::SetCurrentSource(std::string const& dir) loc = dir; cmSystemTools::ConvertToUnixSlashes(loc); loc = cmSystemTools::CollapseFullPath(loc); - - this->ComputeRelativePathTopSource(); - this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc); } @@ -114,60 +49,9 @@ void cmStateDirectory::SetCurrentBinary(std::string const& dir) loc = dir; cmSystemTools::ConvertToUnixSlashes(loc); loc = cmSystemTools::CollapseFullPath(loc); - - this->ComputeRelativePathTopBinary(); - this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc); } -std::string const& cmStateDirectory::GetRelativePathTopSource() const -{ - return this->DirectoryState->RelativePathTopSource; -} - -std::string const& cmStateDirectory::GetRelativePathTopBinary() const -{ - return this->DirectoryState->RelativePathTopBinary; -} - -void cmStateDirectory::SetRelativePathTopSource(const char* dir) -{ - this->DirectoryState->RelativePathTopSource = dir; -} - -void cmStateDirectory::SetRelativePathTopBinary(const char* dir) -{ - this->DirectoryState->RelativePathTopBinary = dir; -} - -bool cmStateDirectory::ContainsBoth(std::string const& local_path, - std::string const& remote_path) const -{ - auto PathEqOrSubDir = [](std::string const& a, std::string const& b) { - return (cmSystemTools::ComparePath(a, b) || - cmSystemTools::IsSubDirectory(a, b)); - }; - - bool bothInBinary = - PathEqOrSubDir(local_path, this->GetRelativePathTopBinary()) && - PathEqOrSubDir(remote_path, this->GetRelativePathTopBinary()); - - bool bothInSource = - PathEqOrSubDir(local_path, this->GetRelativePathTopSource()) && - PathEqOrSubDir(remote_path, this->GetRelativePathTopSource()); - - return bothInBinary || bothInSource; -} - -std::string cmStateDirectory::ConvertToRelPathIfNotContained( - std::string const& local_path, std::string const& remote_path) const -{ - if (!this->ContainsBoth(local_path, remote_path)) { - return remote_path; - } - return cmSystemTools::ForceToRelativePath(local_path, remote_path); -} - cmStateDirectory::cmStateDirectory( cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter, const cmStateSnapshot& snapshot) diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index 70c19bc..ce00dbb 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -28,17 +28,6 @@ public: std::string const& GetCurrentBinary() const; void SetCurrentBinary(std::string const& dir); - std::string const& GetRelativePathTopSource() const; - std::string const& GetRelativePathTopBinary() const; - void SetRelativePathTopSource(const char* dir); - void SetRelativePathTopBinary(const char* dir); - - bool ContainsBoth(std::string const& local_path, - std::string const& remote_path) const; - - std::string ConvertToRelPathIfNotContained( - std::string const& local_path, std::string const& remote_path) const; - cmStringRange GetIncludeDirectoriesEntries() const; cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const; void AppendIncludeDirectoriesEntry(std::string const& vec, @@ -94,9 +83,6 @@ public: void AddNormalTargetName(std::string const& name); private: - void ComputeRelativePathTopSource(); - void ComputeRelativePathTopBinary(); - cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator DirectoryState; cmStateSnapshot Snapshot_; diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h index 4892644..a437ce2 100644 --- a/Source/cmStatePrivate.h +++ b/Source/cmStatePrivate.h @@ -67,14 +67,6 @@ struct cmStateDetail::BuildsystemDirectoryStateType std::string Location; std::string OutputLocation; - // The top-most directories for relative path conversion. Both the - // source and destination location of a relative path conversion - // must be underneath one of these directories (both under source or - // both under binary) in order for the relative path to be evaluated - // safely by the build tools. - std::string RelativePathTopSource; - std::string RelativePathTopBinary; - std::vector<std::string> IncludeDirectories; std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces; diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx index 1e20abb..fbf47ef 100644 --- a/Source/cmStateSnapshot.cxx +++ b/Source/cmStateSnapshot.cxx @@ -16,16 +16,9 @@ #include "cmState.h" #include "cmStateDirectory.h" #include "cmStatePrivate.h" +#include "cmSystemTools.h" #include "cmVersion.h" -#if !defined(_WIN32) -# include <sys/utsname.h> -#endif - -#if defined(__CYGWIN__) -# include "cmSystemTools.h" -#endif - cmStateSnapshot::cmStateSnapshot(cmState* state) : State(state) { @@ -292,34 +285,26 @@ void InitializeContentFromParent(T& parentContent, T& thisContent, void cmStateSnapshot::SetDefaultDefinitions() { -/* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. - With CMake must separate between target and host platform. In most cases - the tests for WIN32, UNIX and APPLE will be for the target system, so an - additional set of variables for the host system is required -> - CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. - WIN32, UNIX and APPLE are now set in the platform files in - Modules/Platforms/. - To keep cmake scripts (-P) and custom language and compiler modules - working, these variables are still also set here in this place, but they - will be reset in CMakeSystemSpecificInformation.cmake before the platform - files are executed. */ -#if defined(_WIN32) - this->SetDefinition("WIN32", "1"); - this->SetDefinition("CMAKE_HOST_WIN32", "1"); - this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", "Windows"); -#else - this->SetDefinition("UNIX", "1"); - this->SetDefinition("CMAKE_HOST_UNIX", "1"); - -# if defined(__ANDROID__) - this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", "Android"); -# else - struct utsname uts_name; - if (uname(&uts_name) >= 0) { - this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", uts_name.sysname); + /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. + With CMake must separate between target and host platform. In most cases + the tests for WIN32, UNIX and APPLE will be for the target system, so an + additional set of variables for the host system is required -> + CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. + WIN32, UNIX and APPLE are now set in the platform files in + Modules/Platforms/. + To keep cmake scripts (-P) and custom language and compiler modules + working, these variables are still also set here in this place, but they + will be reset in CMakeSystemSpecificInformation.cmake before the platform + files are executed. */ + cm::string_view hostSystemName = cmSystemTools::GetSystemName(); + this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", hostSystemName); + if (hostSystemName == "Windows") { + this->SetDefinition("WIN32", "1"); + this->SetDefinition("CMAKE_HOST_WIN32", "1"); + } else { + this->SetDefinition("UNIX", "1"); + this->SetDefinition("CMAKE_HOST_UNIX", "1"); } -# endif -#endif #if defined(__CYGWIN__) std::string legacy; if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) && diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 23fc3e0..5fa309d 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -241,7 +241,7 @@ bool RegexMatch(std::vector<std::string> const& args, status.GetMakefile().ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; - if (!re.compile(regex.c_str())) { + if (!re.compile(regex)) { std::string e = "sub-command REGEX, mode MATCH failed to compile regex \"" + regex + "\"."; @@ -283,7 +283,7 @@ bool RegexMatchAll(std::vector<std::string> const& args, status.GetMakefile().ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; - if (!re.compile(regex.c_str())) { + if (!re.compile(regex)) { std::string e = "sub-command REGEX, mode MATCHALL failed to compile regex \"" + regex + "\"."; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index c1ce7ec..9b81bf2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -19,6 +19,7 @@ #include <cm3p/uv.h> #include "cmDuration.h" +#include "cmMessageMetadata.h" #include "cmProcessOutput.h" #include "cmRange.h" #include "cmStringAlgorithms.h" @@ -86,6 +87,7 @@ # include <unistd.h> # include <sys/time.h> +# include <sys/types.h> #endif #if defined(_WIN32) && \ @@ -101,6 +103,10 @@ # include <malloc.h> /* for malloc/free on QNX */ #endif +#if !defined(_WIN32) && !defined(__ANDROID__) +# include <sys/utsname.h> +#endif + namespace { cmSystemTools::InterruptCallback s_InterruptCallback; @@ -258,8 +264,15 @@ void cmSystemTools::Stdout(const std::string& s) void cmSystemTools::Message(const std::string& m, const char* title) { + cmMessageMetadata md; + md.title = title; + Message(m, md); +} + +void cmSystemTools::Message(const std::string& m, const cmMessageMetadata& md) +{ if (s_MessageCallback) { - s_MessageCallback(m, title); + s_MessageCallback(m, md); } else { std::cerr << m << std::endl; } @@ -951,21 +964,87 @@ void cmSystemTools::InitializeLibUV() #ifdef _WIN32 namespace { -bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname) +bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname, + cmSystemTools::Replace replace) { // Not only ignore any previous error, but clear any memory of it. SetLastError(0); - // Use MOVEFILE_REPLACE_EXISTING to replace an existing destination file. - return MoveFileExW(oldname.c_str(), newname.c_str(), - MOVEFILE_REPLACE_EXISTING); + DWORD flags = 0; + if (replace == cmSystemTools::Replace::Yes) { + // Use MOVEFILE_REPLACE_EXISTING to replace an existing destination file. + flags = flags | MOVEFILE_REPLACE_EXISTING; + } + + return MoveFileExW(oldname.c_str(), newname.c_str(), flags); } } #endif +bool cmSystemTools::CopySingleFile(const std::string& oldname, + const std::string& newname) +{ + return cmSystemTools::CopySingleFile(oldname, newname, CopyWhen::Always) == + CopyResult::Success; +} + +cmSystemTools::CopyResult cmSystemTools::CopySingleFile( + std::string const& oldname, std::string const& newname, CopyWhen when, + std::string* err) +{ + switch (when) { + case CopyWhen::Always: + break; + case CopyWhen::OnlyIfDifferent: + if (!FilesDiffer(oldname, newname)) { + return CopyResult::Success; + } + break; + } + + mode_t perm = 0; + cmsys::Status perms = SystemTools::GetPermissions(oldname, perm); + + // If files are the same do not copy + if (SystemTools::SameFile(oldname, newname)) { + return CopyResult::Success; + } + + cmsys::Status status; + status = cmsys::SystemTools::CloneFileContent(oldname, newname); + if (!status) { + // if cloning did not succeed, fall back to blockwise copy + status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname); + } + if (!status) { + if (err) { + *err = status.GetString(); + } + return CopyResult::Failure; + } + if (perms) { + status = SystemTools::SetPermissions(newname, perm); + if (!status) { + if (err) { + *err = status.GetString(); + } + return CopyResult::Failure; + } + } + return CopyResult::Success; +} + bool cmSystemTools::RenameFile(const std::string& oldname, const std::string& newname) { + return cmSystemTools::RenameFile(oldname, newname, Replace::Yes) == + RenameResult::Success; +} + +cmSystemTools::RenameResult cmSystemTools::RenameFile( + std::string const& oldname, std::string const& newname, Replace replace, + std::string* err) +{ #ifdef _WIN32 # ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) @@ -987,7 +1066,7 @@ bool cmSystemTools::RenameFile(const std::string& oldname, oldname_wstr, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); DWORD move_last_error = 0; - while (!cmMoveFile(oldname_wstr, newname_wstr) && --retry.Count) { + while (!cmMoveFile(oldname_wstr, newname_wstr, replace) && --retry.Count) { move_last_error = GetLastError(); // There was no error ==> the operation is not yet complete. @@ -1003,7 +1082,13 @@ bool cmSystemTools::RenameFile(const std::string& oldname, // 3) Windows Explorer has an associated directory already opened. if (move_last_error != ERROR_ACCESS_DENIED && move_last_error != ERROR_SHARING_VIOLATION) { - return false; + if (replace == Replace::No && move_last_error == ERROR_ALREADY_EXISTS) { + return RenameResult::NoReplace; + } + if (err) { + *err = cmsys::Status::Windows(move_last_error).GetString(); + } + return RenameResult::Failure; } DWORD const attrs = GetFileAttributesW(newname_wstr.c_str()); @@ -1027,10 +1112,37 @@ bool cmSystemTools::RenameFile(const std::string& oldname, save_restore_file_attributes.SetPath(newname_wstr); } SetLastError(move_last_error); - return retry.Count > 0; + if (retry.Count > 0) { + return RenameResult::Success; + } + if (replace == Replace::No && GetLastError() == ERROR_ALREADY_EXISTS) { + return RenameResult::NoReplace; + } + if (err) { + *err = cmsys::Status::Windows_GetLastError().GetString(); + } + return RenameResult::Failure; #else - /* On UNIX we have an OS-provided call to do this atomically. */ - return rename(oldname.c_str(), newname.c_str()) == 0; + // On UNIX we have OS-provided calls to create 'newname' atomically. + if (replace == Replace::No) { + if (link(oldname.c_str(), newname.c_str()) == 0) { + return RenameResult::Success; + } + if (errno == EEXIST) { + return RenameResult::NoReplace; + } + if (err) { + *err = cmsys::Status::POSIX_errno().GetString(); + } + return RenameResult::Failure; + } + if (rename(oldname.c_str(), newname.c_str()) == 0) { + return RenameResult::Success; + } + if (err) { + *err = cmsys::Status::POSIX_errno().GetString(); + } + return RenameResult::Failure; #endif } @@ -1387,6 +1499,20 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path, return relative; } +std::string cmSystemTools::RelativeIfUnder(std::string const& top, + std::string const& in) +{ + std::string out; + if (in == top) { + out = "."; + } else if (cmSystemTools::IsSubDirectory(in, top)) { + out = in.substr(top.size() + 1); + } else { + out = in; + } + return out; +} + #ifndef CMAKE_BOOTSTRAP bool cmSystemTools::UnsetEnv(const char* value) { @@ -1693,7 +1819,7 @@ bool copy_data(struct archive* ar, struct archive* aw) return false; } } -# if !defined(__clang__) && !defined(__HP_aCC) +# if !defined(__clang__) && !defined(__NVCOMPILER) && !defined(__HP_aCC) return false; /* this should not happen but it quiets some compilers */ # endif } @@ -3021,7 +3147,7 @@ bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir) } return false; #else - return cmSystemTools::RemoveADirectory(dir); + return static_cast<bool>(cmSystemTools::RemoveADirectory(dir)); #endif } @@ -3054,9 +3180,9 @@ std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes) return out; } -bool cmSystemTools::CreateSymlink(const std::string& origName, - const std::string& newName, - std::string* errorMessage) +cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName, + std::string const& newName, + std::string* errorMessage) { uv_fs_t req; int flags = 0; @@ -3067,37 +3193,96 @@ bool cmSystemTools::CreateSymlink(const std::string& origName, #endif int err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(), flags, nullptr); + cmsys::Status status; if (err) { - std::string e = - "failed to create symbolic link '" + newName + "': " + uv_strerror(err); +#if defined(_WIN32) + status = cmsys::Status::Windows(uv_fs_get_system_error(&req)); +#elif UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 38) + status = cmsys::Status::POSIX(uv_fs_get_system_error(&req)); +#else + status = cmsys::Status::POSIX(-err); +#endif + std::string e = cmStrCat("failed to create symbolic link '", newName, + "': ", status.GetString()); if (errorMessage) { *errorMessage = std::move(e); } else { cmSystemTools::Error(e); } - return false; } - - return true; + return status; } -bool cmSystemTools::CreateLink(const std::string& origName, - const std::string& newName, - std::string* errorMessage) +cmsys::Status cmSystemTools::CreateLink(std::string const& origName, + std::string const& newName, + std::string* errorMessage) { uv_fs_t req; int err = uv_fs_link(nullptr, &req, origName.c_str(), newName.c_str(), nullptr); + cmsys::Status status; if (err) { +#if defined(_WIN32) + status = cmsys::Status::Windows(uv_fs_get_system_error(&req)); +#elif UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 38) + status = cmsys::Status::POSIX(uv_fs_get_system_error(&req)); +#else + status = cmsys::Status::POSIX(-err); +#endif std::string e = - "failed to create link '" + newName + "': " + uv_strerror(err); + cmStrCat("failed to create link '", newName, "': ", status.GetString()); if (errorMessage) { *errorMessage = std::move(e); } else { cmSystemTools::Error(e); } - return false; } + return status; +} - return true; +cm::string_view cmSystemTools::GetSystemName() +{ +#if defined(_WIN32) + return "Windows"; +#elif defined(__ANDROID__) + return "Android"; +#else + static struct utsname uts_name; + static bool initialized = false; + static cm::string_view systemName; + if (initialized) { + return systemName; + } + if (uname(&uts_name) >= 0) { + initialized = true; + systemName = uts_name.sysname; + + if (cmIsOff(systemName)) { + systemName = "UnknownOS"; + } + + // fix for BSD/OS, remove the / + static const cmsys::RegularExpression bsdOsRegex("BSD.OS"); + cmsys::RegularExpressionMatch match; + if (bsdOsRegex.find(uts_name.sysname, match)) { + systemName = "BSDOS"; + } + + // fix for GNU/kFreeBSD, remove the GNU/ + if (systemName.find("kFreeBSD") != cm::string_view::npos) { + systemName = "kFreeBSD"; + } + + // fix for CYGWIN and MSYS which have windows version in them + if (systemName.find("CYGWIN") != cm::string_view::npos) { + systemName = "CYGWIN"; + } + + if (systemName.find("MSYS") != cm::string_view::npos) { + systemName = "MSYS"; + } + return systemName; + } + return ""; +#endif } diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 5bbbb0c..5c3b5a9 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -12,12 +12,15 @@ #include <cm/string_view> #include "cmsys/Process.h" +#include "cmsys/Status.hxx" // IWYU pragma: export #include "cmsys/SystemTools.hxx" // IWYU pragma: export #include "cmCryptoHash.h" #include "cmDuration.h" #include "cmProcessOutput.h" +struct cmMessageMetadata; + /** \class cmSystemTools * \brief A collection of useful functions for CMake. * @@ -39,7 +42,8 @@ public: /** Map help document name to file name. */ static std::string HelpFileName(cm::string_view); - using MessageCallback = std::function<void(const std::string&, const char*)>; + using MessageCallback = + std::function<void(const std::string&, const cmMessageMetadata&)>; /** * Set the function used by GUIs to display error messages * Function gets passed: message as a const char*, @@ -56,6 +60,7 @@ public: * Display a message. */ static void Message(const std::string& m, const char* title = nullptr); + static void Message(const std::string& m, const cmMessageMetadata& md); using OutputCallback = std::function<void(std::string const&)>; @@ -128,10 +133,43 @@ public: static bool SimpleGlob(const std::string& glob, std::vector<std::string>& files, int type = 0); + enum class CopyWhen + { + Always, + OnlyIfDifferent, + }; + enum class CopyResult + { + Success, + Failure, + }; + + /** Copy a file. */ + static bool CopySingleFile(const std::string& oldname, + const std::string& newname); + static CopyResult CopySingleFile(std::string const& oldname, + std::string const& newname, CopyWhen when, + std::string* err = nullptr); + + enum class Replace + { + Yes, + No, + }; + enum class RenameResult + { + Success, + NoReplace, + Failure, + }; + /** Rename a file or directory within a single disk volume (atomic if possible). */ static bool RenameFile(const std::string& oldname, const std::string& newname); + static RenameResult RenameFile(std::string const& oldname, + std::string const& newname, Replace replace, + std::string* err = nullptr); //! Rename a file if contents are different, delete the source otherwise static void MoveFileIfDifferent(const std::string& source, @@ -152,7 +190,7 @@ public: * * Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no * user-viewable output from the program being run will be generated. - * OUTPUT_MERGE is the legacy behaviour where stdout and stderr are merged + * OUTPUT_MERGE is the legacy behavior where stdout and stderr are merged * into stdout. OUTPUT_FORWARD copies the output to stdout/stderr as * it was received. OUTPUT_PASSTHROUGH passes through the original handles. * @@ -312,6 +350,12 @@ public: static std::string ForceToRelativePath(std::string const& local_path, std::string const& remote_path); + /** + * Express the 'in' path relative to 'top' if it does not start in '../'. + */ + static std::string RelativeIfUnder(std::string const& top, + std::string const& in); + #ifndef CMAKE_BOOTSTRAP /** Remove an environment variable */ static bool UnsetEnv(const char* value); @@ -455,15 +499,18 @@ public: /** Create a symbolic link if the platform supports it. Returns whether creation succeeded. */ - static bool CreateSymlink(const std::string& origName, - const std::string& newName, - std::string* errorMessage = nullptr); + static cmsys::Status CreateSymlink(std::string const& origName, + std::string const& newName, + std::string* errorMessage = nullptr); /** Create a hard link if the platform supports it. Returns whether creation succeeded. */ - static bool CreateLink(const std::string& origName, - const std::string& newName, - std::string* errorMessage = nullptr); + static cmsys::Status CreateLink(std::string const& origName, + std::string const& newName, + std::string* errorMessage = nullptr); + + /** Get the system name. */ + static cm::string_view GetSystemName(); private: static bool s_ForceUnixPaths; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 91dcd0e..29e361c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -929,12 +929,10 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const const char* sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain"); s << "The uses of the " << sigString << " signature are here:\n"; - cmStateDirectory cmDir = - this->impl->Makefile->GetStateSnapshot().GetDirectory(); for (auto const& cmd : this->impl->TLLCommands) { if (cmd.first == sig) { cmListFileContext lfc = cmd.second; - lfc.FilePath = cmDir.ConvertToRelPathIfNotContained( + lfc.FilePath = cmSystemTools::RelativeIfUnder( this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath); s << " * " << lfc << '\n'; } diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx index 78aa4b2..6927300 100644 --- a/Source/cmTransformDepfile.cxx +++ b/Source/cmTransformDepfile.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTransformDepfile.h" +#include <functional> #include <string> #include <type_traits> #include <utility> @@ -13,6 +14,7 @@ #include "cmGccDepfileReader.h" #include "cmGccDepfileReaderTypes.h" +#include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmSystemTools.h" @@ -34,10 +36,18 @@ void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename) } } -void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg, - const cmGccDepfileContent& content) +void WriteDepfile(cmDepfileFormat format, cmsys::ofstream& fout, + const cmLocalGenerator& lg, + const cmGccDepfileContent& content) { - const auto& binDir = lg.GetBinaryDirectory(); + std::function<std::string(const std::string&)> formatPath = + [&lg](const std::string& path) -> std::string { + return lg.MaybeRelativeToTopBinDir(path); + }; + if (lg.GetGlobalGenerator()->GetName() == "Xcode") { + // full paths must be preserved for Xcode compliance + formatPath = [](const std::string& path) -> std::string { return path; }; + } for (auto const& dep : content) { bool first = true; @@ -46,15 +56,27 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg, fout << " \\\n "; } first = false; - WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, rule)); + WriteFilenameGcc(fout, formatPath(rule)); } fout << ':'; for (auto const& path : dep.paths) { fout << " \\\n "; - WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, path)); + WriteFilenameGcc(fout, formatPath(path)); } fout << '\n'; } + + if (format == cmDepfileFormat::MakeDepfile) { + // In this case, phony targets must be added for all dependencies + fout << "\n"; + for (auto const& dep : content) { + for (auto const& path : dep.paths) { + fout << "\n"; + WriteFilenameGcc(fout, formatPath(path)); + fout << ":\n"; + } + } + } } // tlog format : always windows paths on Windows regardless the generator @@ -70,8 +92,6 @@ std::string ConvertToTLogOutputPath(const std::string& path) void WriteVsTlog(cmsys::ofstream& fout, const cmLocalGenerator& lg, const cmGccDepfileContent& content) { - const auto& binDir = lg.GetBinaryDirectory(); - for (auto const& dep : content) { fout << '^'; bool first = true; @@ -80,13 +100,11 @@ void WriteVsTlog(cmsys::ofstream& fout, const cmLocalGenerator& lg, fout << '|'; } first = false; - fout << ConvertToTLogOutputPath( - lg.MaybeConvertToRelativePath(binDir, rule)); + fout << ConvertToTLogOutputPath(lg.MaybeRelativeToTopBinDir(rule)); } fout << "\r\n"; for (auto const& path : dep.paths) { - fout << ConvertToTLogOutputPath( - lg.MaybeConvertToRelativePath(binDir, path)) + fout << ConvertToTLogOutputPath(lg.MaybeRelativeToTopBinDir(path)) << "\r\n"; } } @@ -112,7 +130,8 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, } switch (format) { case cmDepfileFormat::GccDepfile: - WriteGccDepfile(fout, lg, content); + case cmDepfileFormat::MakeDepfile: + WriteDepfile(format, fout, lg, content); break; case cmDepfileFormat::VsTlog: WriteVsTlog(fout, lg, content); diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h index c43a45f..c31e4ab 100644 --- a/Source/cmTransformDepfile.h +++ b/Source/cmTransformDepfile.h @@ -8,6 +8,7 @@ enum class cmDepfileFormat { GccDepfile, VsTlog, + MakeDepfile }; class cmLocalGenerator; diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx index 8ea1942..e05b2d52 100644 --- a/Source/cmUVHandlePtr.cxx +++ b/Source/cmUVHandlePtr.cxx @@ -128,7 +128,7 @@ template <> struct uv_handle_deleter<uv_async_t> { /*** - * Wile uv_async_send is itself thread-safe, there are + * While uv_async_send is itself thread-safe, there are * no strong guarantees that close hasn't already been * called on the handle; and that it might be deleted * as the send call goes through. This mutex guards diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 965ac3e..1c8b672 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -498,7 +498,7 @@ void cmVisualStudio10TargetGenerator::Generate() cmProp targetFramework = this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK"); if (targetFramework) { - if (std::strchr(targetFramework->c_str(), ';') != nullptr) { + if (targetFramework->find(';') != std::string::npos) { e1.Element("TargetFrameworks", *targetFramework); } else { e1.Element("TargetFramework", *targetFramework); @@ -545,7 +545,7 @@ void cmVisualStudio10TargetGenerator::Generate() e1.Element( "CudaToolkitCustomDir", this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() + - "nvcc"); + this->GlobalGenerator->GetPlatformToolsetCudaNvccSubdirString()); } } @@ -654,8 +654,9 @@ void cmVisualStudio10TargetGenerator::Generate() std::string cudaPath = customDir.empty() ? "$(VCTargetsPath)\\BuildCustomizations\\" : customDir + - "CUDAVisualStudioIntegration\\extras\\" - "visual_studio_integration\\MSBuildExtensions\\"; + this->GlobalGenerator + ->GetPlatformToolsetCudaVSIntegrationSubdirString() + + "extras\\visual_studio_integration\\MSBuildExtensions\\"; Elem(e1, "Import") .Attribute("Project", std::move(cudaPath) + "CUDA " + @@ -747,8 +748,9 @@ void cmVisualStudio10TargetGenerator::Generate() std::string cudaPath = customDir.empty() ? "$(VCTargetsPath)\\BuildCustomizations\\" : customDir + - "CUDAVisualStudioIntegration\\extras\\" - "visual_studio_integration\\MSBuildExtensions\\"; + this->GlobalGenerator + ->GetPlatformToolsetCudaVSIntegrationSubdirString() + + "extras\\visual_studio_integration\\MSBuildExtensions\\"; Elem(e1, "Import") .Attribute("Project", std::move(cudaPath) + "CUDA " + @@ -2275,6 +2277,20 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) std::back_inserter(exclude_configs)); Elem e2(e1, tool); + bool isCSharp = (si.Source->GetLanguage() == "CSharp"); + if (isCSharp && exclude_configs.size() > 0) { + std::stringstream conditions; + bool firstConditionSet{ false }; + for (const auto& ci : include_configs) { + if (firstConditionSet) { + conditions << " Or "; + } + conditions << "('$(Configuration)|$(Platform)'=='" + + this->Configurations[ci] + "|" + this->Platform + "')"; + firstConditionSet = true; + } + e2.Attribute("Condition", conditions.str()); + } this->WriteSource(e2, si.Source); bool useNativeUnityBuild = false; @@ -2319,7 +2335,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) { e2.Element("PrecompiledHeader", "NotUsing"); } - if (!exclude_configs.empty()) { + if (!isCSharp && !exclude_configs.empty()) { this->WriteExcludeFromBuild(e2, exclude_configs); } } @@ -3340,8 +3356,6 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( // cmLinkLineDeviceComputer cmComputeLinkInformation& cli = *pcli; std::vector<std::string> libVec; - const std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); const auto& libs = cli.GetItems(); for (cmComputeLinkInformation::Item const& l : libs) { @@ -3378,8 +3392,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( } if (l.IsPath) { - std::string path = this->LocalGenerator->MaybeConvertToRelativePath( - currentBinDir, l.Value.Value); + std::string path = + this->LocalGenerator->MaybeRelativeToCurBinDir(l.Value.Value); ConvertToWindowsSlash(path); if (!cmVS10IsTargetsFile(l.Value.Value)) { libVec.push_back(path); @@ -3930,12 +3944,10 @@ bool cmVisualStudio10TargetGenerator::ComputeLibOptions( cmComputeLinkInformation& cli = *pcli; using ItemVector = cmComputeLinkInformation::ItemVector; const ItemVector& libs = cli.GetItems(); - std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmComputeLinkInformation::Item const& l : libs) { if (l.IsPath && cmVS10IsTargetsFile(l.Value.Value)) { - std::string path = this->LocalGenerator->MaybeConvertToRelativePath( - currentBinDir, l.Value.Value); + std::string path = + this->LocalGenerator->MaybeRelativeToCurBinDir(l.Value.Value); ConvertToWindowsSlash(path); this->AddTargetsFileAndConfigPair(path, config); } @@ -3975,8 +3987,6 @@ void cmVisualStudio10TargetGenerator::AddLibraries( { using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& libs = cli.GetItems(); - std::string currentBinDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmComputeLinkInformation::Item const& l : libs) { if (l.Target) { auto managedType = l.Target->GetManagedType(config); @@ -4019,8 +4029,8 @@ void cmVisualStudio10TargetGenerator::AddLibraries( } if (l.IsPath) { - std::string path = this->LocalGenerator->MaybeConvertToRelativePath( - currentBinDir, l.Value.Value); + std::string path = + this->LocalGenerator->MaybeRelativeToCurBinDir(l.Value.Value); ConvertToWindowsSlash(path); if (cmVS10IsTargetsFile(l.Value.Value)) { vsTargetVec.push_back(path); @@ -4237,11 +4247,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) if (dt->IsCSharpOnly() || cmHasLiteralSuffix(path, "csproj")) { e2.Element("SkipGetTargetFrameworkProperties", "true"); } - // Don't reference targets that don't produce any output. - if (this->Configurations.empty() || - dt->GetManagedType(this->Configurations[0]) == - cmGeneratorTarget::ManagedType::Undefined) { + else if (this->Configurations.empty() || + dt->GetManagedType(this->Configurations[0]) == + cmGeneratorTarget::ManagedType::Undefined) { e2.Element("ReferenceOutputAssembly", "false"); e2.Element("CopyToOutputDirectory", "Never"); } @@ -5035,7 +5044,9 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( { // For out of source files, we first check if a matching source group // for this file exists, otherwise we check if the path relative to current - // source- or binary-dir is used within the link and return that + // source- or binary-dir is used within the link and return that. + // In case of .cs files we can't do that automatically for files in the + // binary directory, because this leads to compilation errors. std::string link; std::string sourceGroupedFile; std::string const& fullFileName = source->GetFullPath(); @@ -5057,7 +5068,8 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( link = sourceGroupedFile; } else if (cmHasPrefix(fullFileName, srcDir)) { link = fullFileName.substr(srcDir.length() + 1); - } else if (cmHasPrefix(fullFileName, binDir)) { + } else if (!cmHasSuffix(fullFileName, ".cs") && + cmHasPrefix(fullFileName, binDir)) { link = fullFileName.substr(binDir.length() + 1); } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) { link = *l; diff --git a/Source/cmVisualStudio10ToolsetOptions.cxx b/Source/cmVisualStudio10ToolsetOptions.cxx deleted file mode 100644 index 7fc33e6..0000000 --- a/Source/cmVisualStudio10ToolsetOptions.cxx +++ /dev/null @@ -1,143 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmVisualStudio10ToolsetOptions.h" - -#include "cmAlgorithms.h" -#include "cmIDEFlagTable.h" -#include "cmVisualStudioGeneratorOptions.h" - -std::string cmVisualStudio10ToolsetOptions::GetClFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if (toolset == "v142") { - return "v142"; - } else if (toolset == "v141") { - return "v141"; - } else if (useToolset == "v140") { - return "v140"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetCSharpFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if (useToolset == "v142") { - return "v142"; - } else if (useToolset == "v141") { - return "v141"; - } else if (useToolset == "v140") { - return "v140"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetRcFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if ((useToolset == "v140") || (useToolset == "v141") || - (useToolset == "v142")) { - return "v14"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetLibFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if ((useToolset == "v140") || (useToolset == "v141") || - (useToolset == "v142")) { - return "v14"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetLinkFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if (useToolset == "v142") { - return "v142"; - } else if (useToolset == "v141") { - return "v141"; - } else if (useToolset == "v140") { - return "v140"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetMasmFlagTableName( - std::string const& name, std::string const& toolset) const -{ - std::string const useToolset = this->GetToolsetName(name, toolset); - - if ((useToolset == "v140") || (useToolset == "v141") || - (useToolset == "v142")) { - return "v14"; - } else if (useToolset == "v120") { - return "v12"; - } else if (useToolset == "v110") { - return "v11"; - } else if (useToolset == "v100") { - return "v10"; - } else { - return ""; - } -} - -std::string cmVisualStudio10ToolsetOptions::GetToolsetName( - std::string const& name, std::string const& toolset) const -{ - static_cast<void>(name); - std::size_t length = toolset.length(); - - if (cmHasLiteralSuffix(toolset, "_xp")) { - length -= 3; - } - - return toolset.substr(0, length); -} diff --git a/Source/cmVisualStudio10ToolsetOptions.h b/Source/cmVisualStudio10ToolsetOptions.h deleted file mode 100644 index 85cc2b6..0000000 --- a/Source/cmVisualStudio10ToolsetOptions.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#pragma once - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <string> - -/** \class cmVisualStudio10ToolsetOptions - * \brief Retrieves toolset options for MSBuild. - * - * cmVisualStudio10ToolsetOptions manages toolsets within MSBuild - */ -class cmVisualStudio10ToolsetOptions -{ -public: - std::string GetClFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetCSharpFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetRcFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetLibFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetLinkFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetMasmFlagTableName(std::string const& name, - std::string const& toolset) const; - std::string GetToolsetName(std::string const& name, - std::string const& toolset) const; -}; diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx index 5700b1c..12fae12 100644 --- a/Source/cmWorkingDirectory.cxx +++ b/Source/cmWorkingDirectory.cxx @@ -19,7 +19,7 @@ cmWorkingDirectory::~cmWorkingDirectory() bool cmWorkingDirectory::SetDirectory(std::string const& newdir) { - if (cmSystemTools::ChangeDirectory(newdir) == 0) { + if (cmSystemTools::ChangeDirectory(newdir)) { this->ResultCode = 0; return true; } diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index 55e941d..e4329af 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -324,7 +324,7 @@ bool cmXCodeScheme::WriteLaunchActionBooleanAttribute( bool defaultValue) { cmProp property = Target->GetTarget()->GetProperty(varName); - bool isOn = (property == nullptr && defaultValue) || cmIsOn(property); + bool isOn = (!property && defaultValue) || cmIsOn(property); if (isOn) { xout.Attribute(attrName.c_str(), "YES"); diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx index 15f83e0..216d3f0 100644 --- a/Source/cm_codecvt.cxx +++ b/Source/cm_codecvt.cxx @@ -31,6 +31,7 @@ codecvt::codecvt(Encoding e) // We don't know which ANSI encoding to use for other platforms than // Windows so we don't do any conversion there case codecvt::UTF8: + case codecvt::UTF8_WITH_BOM: // Assume internal encoding is UTF-8 case codecvt::None: // No encoding diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx index 1860211..b73204f 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -14,6 +14,7 @@ public: { None, UTF8, + UTF8_WITH_BOM, ANSI }; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 4d03821..315bd20 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -28,6 +28,7 @@ #include "cm_sys_stat.h" +#include "cmCMakePath.h" #include "cmCMakePresetsFile.h" #include "cmCommandLineArgument.h" #include "cmCommands.h" @@ -156,7 +157,8 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/, #endif cmake::cmake(Role role, cmState::Mode mode) - : FileTimeCache(cm::make_unique<cmFileTimeCache>()) + : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory()) + , FileTimeCache(cm::make_unique<cmFileTimeCache>()) #ifndef CMAKE_BOOTSTRAP , VariableWatch(cm::make_unique<cmVariableWatch>()) #endif @@ -208,9 +210,9 @@ cmake::cmake(Role role, cmState::Mode mode) }; // The "c" extension MUST precede the "C" extension. - setupExts( - this->CLikeSourceFileExtensions, - { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", "mm" }); + setupExts(this->CLikeSourceFileExtensions, + { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", + "mm", "ixx", "cppm" }); setupExts(this->HeaderFileExtensions, { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" }); setupExts(this->CudaFileExtensions, { "cu" }); @@ -258,6 +260,13 @@ Json::Value cmake::ReportCapabilitiesJson() const gen["name"] = gi.name; gen["toolsetSupport"] = gi.supportsToolset; gen["platformSupport"] = gi.supportsPlatform; + if (!gi.supportedPlatforms.empty()) { + Json::Value supportedPlatforms = Json::arrayValue; + for (std::string const& platform : gi.supportedPlatforms) { + supportedPlatforms.append(platform); + } + gen["supportedPlatforms"] = std::move(supportedPlatforms); + } gen["extraGenerators"] = Json::arrayValue; generatorMap[gi.name] = gen; } else { @@ -484,7 +493,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) auto ScriptLambda = [&](std::string const& path, cmake* state) -> bool { // Register fake project commands that hint misuse in script mode. GetProjectCommandsInScriptMode(state->GetState()); - // Documented behaviour of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be + // Documented behavior of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be // set to $PWD for -P mode. state->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); state->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); @@ -493,26 +502,61 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return true; }; + auto PrefixLambda = [&](std::string const& path, cmake* state) -> bool { + const std::string var = "CMAKE_INSTALL_PREFIX"; + cmStateEnums::CacheEntryType type = cmStateEnums::PATH; + cmCMakePath absolutePath(path); + if (absolutePath.IsAbsolute()) { +#ifndef CMAKE_BOOTSTRAP + state->UnprocessedPresetVariables.erase(var); +#endif + state->ProcessCacheArg(var, path, type); + return true; + } + cmSystemTools::Error("Absolute paths are required for --install-prefix"); + return false; + }; + + auto ToolchainLambda = [&](std::string const& path, cmake* state) -> bool { + const std::string var = "CMAKE_TOOLCHAIN_FILE"; + cmStateEnums::CacheEntryType type = cmStateEnums::FILEPATH; +#ifndef CMAKE_BOOTSTRAP + state->UnprocessedPresetVariables.erase(var); +#endif + state->ProcessCacheArg(var, path, type); + return true; + }; + std::vector<CommandArgument> arguments = { CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, DefineLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, DefineLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, WarningLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, WarningLambda }, CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, UnSetLambda }, - CommandArgument{ "-C", "-C must be followed by a file name.", CommandArgument::Values::One, - [&](std::string const& value, cmake* state) -> bool { - cmSystemTools::Stdout("loading initial cache file " + - value + "\n"); - // Resolve script path specified on command line - // relative to $PWD. - auto path = cmSystemTools::CollapseFullPath(value); - state->ReadListFile(args, path); - return true; - } }, + CommandArgument::RequiresSeparator::No, UnSetLambda }, + CommandArgument{ + "-C", "-C must be followed by a file name.", + CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, + [&](std::string const& value, cmake* state) -> bool { + cmSystemTools::Stdout("loading initial cache file " + value + "\n"); + // Resolve script path specified on command line + // relative to $PWD. + auto path = cmSystemTools::CollapseFullPath(value); + state->ReadListFile(args, path); + return true; + } }, + CommandArgument{ "-P", "-P must be followed by a file name.", - CommandArgument::Values::One, ScriptLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ScriptLambda }, + CommandArgument{ "--toolchain", "No file specified for --toolchain", + CommandArgument::Values::One, ToolchainLambda }, + CommandArgument{ "--install-prefix", + "No install directory specified for --install-prefix", + CommandArgument::Values::One, PrefixLambda }, CommandArgument{ "--find-package", CommandArgument::Values::Zero, [&](std::string const&, cmake*) -> bool { findPackageMode = true; @@ -649,7 +693,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args) this->GlobalGenerator->CreateGenerationObjects(); const auto& lg = this->GlobalGenerator->LocalGenerators[0]; std::string includeFlags = - lg->GetIncludeFlags(includeDirs, nullptr, language); + lg->GetIncludeFlags(includeDirs, nullptr, language, std::string()); std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS"); printf("%s %s\n", includeFlags.c_str(), definitions.c_str()); @@ -790,31 +834,49 @@ void cmake::SetArgs(const std::vector<std::string>& args) std::vector<CommandArgument> arguments = { CommandArgument{ "-S", "No source directory specified for -S", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-H", "No source directory specified for -H", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-O", CommandArgument::Values::Zero, IgnoreAndTrueLambda }, CommandArgument{ "-B", "No build directory specified for -B", - CommandArgument::Values::One, BuildArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, BuildArgLambda }, CommandArgument{ "-P", "-P must be followed by a file name.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const&, cmake*) -> bool { scriptMode = true; return true; } }, CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-C", "-C must be followed by a file name.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, - CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, + CommandArgument{ + "-U", "-U must be followed with VAR.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, IgnoreAndTrueLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-A", "No platform specified for -A", - CommandArgument::Values::One, PlatformLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, PlatformLambda }, CommandArgument{ "-T", "No toolset specified for -T", - CommandArgument::Values::One, ToolsetLamda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ToolsetLamda }, + CommandArgument{ "--toolchain", "No file specified for --toolchain", + CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument{ "--install-prefix", + "No install directory specified for --install-prefix", + CommandArgument::Values::One, IgnoreAndTrueLambda }, CommandArgument{ "--check-build-system", CommandArgument::Values::Two, [](std::string const& value, cmake* state) -> bool { @@ -1034,6 +1096,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) bool badGeneratorName = false; CommandArgument generatorCommand( "-G", "No generator specified for -G", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const& value, cmake* state) -> bool { bool valid = state->CreateAndSetGlobalGenerator(value, true); badGeneratorName = !valid; @@ -1194,11 +1257,17 @@ void cmake::SetArgs(const std::vector<std::string>& args) "\": Invalid macro expansion")); return; } + if (!expandedPreset->ConditionResult) { + cmSystemTools::Error(cmStrCat("Could not use disabled preset \"", + preset->second.Unexpanded.Name, "\"")); + return; + } - if (!this->State->IsCacheLoaded() && !haveBArg) { + if (!this->State->IsCacheLoaded() && !haveBArg && + !expandedPreset->BinaryDir.empty()) { this->SetHomeOutputDirectory(expandedPreset->BinaryDir); } - if (!this->GlobalGenerator) { + if (!this->GlobalGenerator && !expandedPreset->Generator.empty()) { if (!this->CreateAndSetGlobalGenerator(expandedPreset->Generator, false)) { return; @@ -1207,6 +1276,19 @@ void cmake::SetArgs(const std::vector<std::string>& args) this->UnprocessedPresetVariables = expandedPreset->CacheVariables; this->UnprocessedPresetEnvironment = expandedPreset->Environment; + if (!expandedPreset->InstallDir.empty() && + !this->State->GetInitializedCacheValue("CMAKE_INSTALL_PREFIX")) { + this->UnprocessedPresetVariables["CMAKE_INSTALL_PREFIX"] = { + "PATH", expandedPreset->InstallDir + }; + } + if (!expandedPreset->ToolchainFile.empty() && + !this->State->GetInitializedCacheValue("CMAKE_TOOLCHAIN_FILE")) { + this->UnprocessedPresetVariables["CMAKE_TOOLCHAIN_FILE"] = { + "FILEPATH", expandedPreset->ToolchainFile + }; + } + if (!expandedPreset->ArchitectureStrategy || expandedPreset->ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set) { @@ -3023,12 +3105,16 @@ static bool cmakeCheckStampFile(const std::string& stampName) cmsys::ofstream stamp(stampTemp.c_str()); stamp << "# CMake generation timestamp file for this directory.\n"; } - if (cmSystemTools::RenameFile(stampTemp, stampName)) { + std::string err; + if (cmSystemTools::RenameFile(stampTemp, stampName, + cmSystemTools::Replace::Yes, &err) == + cmSystemTools::RenameResult::Success) { // CMake does not need to re-run because the stamp file is up-to-date. return true; } cmSystemTools::RemoveFile(stampTemp); - cmSystemTools::Error("Cannot restore timestamp " + stampName); + cmSystemTools::Error( + cmStrCat("Cannot restore timestamp \"", stampName, "\": ", err)); return false; } @@ -3133,6 +3219,14 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } + if (!expandedPreset->ConditionResult) { + cmSystemTools::Error(cmStrCat("Cannot use disabled build preset in ", + this->GetHomeDirectory(), ": \"", + presetName, '"')); + settingsFile.PrintBuildPresetList(); + return 1; + } + auto configurePresetPair = settingsFile.ConfigurePresets.find(expandedPreset->ConfigurePreset); if (configurePresetPair == settingsFile.ConfigurePresets.end()) { @@ -3159,7 +3253,9 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets, return 1; } - dir = expandedConfigurePreset->BinaryDir; + if (!expandedConfigurePreset->BinaryDir.empty()) { + dir = expandedConfigurePreset->BinaryDir; + } this->UnprocessedPresetEnvironment = expandedPreset->Environment; this->ProcessPresetEnvironment(); diff --git a/Source/cmake.h b/Source/cmake.h index 82e028c..e845662 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -194,6 +194,14 @@ public: //@} /** + * Working directory at CMake launch + */ + std::string const& GetCMakeWorkingDirectory() const + { + return this->CMakeWorkingDirectory; + } + + /** * Handle a command line invocation of cmake. */ int Run(const std::vector<std::string>& args) @@ -628,6 +636,7 @@ protected: void GenerateGraphViz(const std::string& fileName) const; private: + std::string CMakeWorkingDirectory; ProgressCallbackType ProgressCallback; WorkingMode CurrentWorkingMode = NORMAL_MODE; bool DebugOutput = false; @@ -712,6 +721,10 @@ private: "Specify toolset name if supported by generator." }, \ { "-A <platform-name>", \ "Specify platform name if supported by generator." }, \ + { "--toolchain <file>", \ + "Specify toolchain file [CMAKE_TOOLCHAIN_FILE]." }, \ + { "--install-prefix <directory>", \ + "Specify install directory [CMAKE_INSTALL_PREFIX]." }, \ { "-Wdev", "Enable developer warnings." }, \ { "-Wno-dev", "Suppress developer warnings." }, \ { "-Werror=dev", "Make developer warnings errors." }, \ @@ -739,6 +752,8 @@ private: F(c_std_90) \ F(c_std_99) \ F(c_std_11) \ + F(c_std_17) \ + F(c_std_23) \ FOR_EACH_C90_FEATURE(F) \ FOR_EACH_C99_FEATURE(F) \ FOR_EACH_C11_FEATURE(F) diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index ad64818..d83183f 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -6,6 +6,7 @@ #include <algorithm> #include <cassert> #include <climits> +#include <cstdio> #include <cstring> #include <iostream> #include <sstream> @@ -23,6 +24,7 @@ #include "cmDocumentationEntry.h" // IWYU pragma: keep #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmMessageMetadata.h" #include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" @@ -37,6 +39,7 @@ #endif #include "cmsys/Encoding.hxx" +#include "cmsys/Terminal.h" namespace { #ifndef CMAKE_BOOTSTRAP @@ -147,10 +150,12 @@ std::string cmakemainGetStack(cmake* cm) return msg; } -void cmakemainMessageCallback(const std::string& m, const char* /*unused*/, - cmake* cm) +void cmakemainMessageCallback(const std::string& m, + const cmMessageMetadata& md, cmake* cm) { - std::cerr << m << cmakemainGetStack(cm) << std::endl; + cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str()); + fflush(stderr); // stderr is buffered in some cases. + std::cerr << cmakemainGetStack(cm) << "\n"; } void cmakemainProgressCallback(const std::string& m, float prog, cmake* cm) @@ -271,6 +276,7 @@ int do_cmake(int ac, char const* const* av) } }, CommandArgument{ "-P", "No script specified for argument -P", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const& value) -> bool { workingMode = cmake::SCRIPT_MODE; parsedArgs.emplace_back("-P"); @@ -342,8 +348,8 @@ int do_cmake(int ac, char const* const* av) cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -476,9 +482,10 @@ int do_build(int ac, char const* const* av) listPresets = true; return true; } }, - CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda }, + CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, + CommandArgument::RequiresSeparator::No, jLambda }, CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, - parallelLambda }, + CommandArgument::RequiresSeparator::No, parallelLambda }, CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda }, CommandArgument{ "--target", CommandArgument::Values::OneOrMore, targetLambda }, @@ -624,8 +631,8 @@ int do_build(int ac, char const* const* av) cmake cm(cmake::RoleInternal, cmState::Project); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -857,8 +864,8 @@ int do_install(int ac, char const* const* av) cmake cm(cmake::RoleScript, cmState::Script); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -938,8 +945,8 @@ int do_open(int ac, char const* const* av) cmake cm(cmake::RoleInternal, cmState::Unknown); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 6713cc3..727e412 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -74,7 +74,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, std::vector<std::string>::const_iterator argEnd); namespace { -void CMakeCommandUsage(const char* program) +void CMakeCommandUsage(std::string const& program) { std::ostringstream errorStream; @@ -704,7 +704,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, } else if (args[2] == "--ignore-eol") { filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]); } else { - CMakeCommandUsage(args[0].c_str()); + CMakeCommandUsage(args[0]); return 2; } @@ -1085,7 +1085,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, std::string const& directory = args[2]; if (!cmSystemTools::FileExists(directory)) { cmSystemTools::Error("Directory does not exist for chdir command: " + - args[2]); + directory); return 1; } @@ -1152,7 +1152,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, << "\n"; return 1; } - if (!cmSystemTools::CreateSymlink(args[2], args[3])) { + if (!cmSystemTools::CreateSymlink(args[2], destinationFileName)) { return 1; } return 0; @@ -1161,12 +1161,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, // Command to create a hard link. Fails on platforms not // supporting them. if (args[1] == "create_hardlink" && args.size() == 4) { - const char* SouceFileName = args[2].c_str(); - const char* destinationFileName = args[3].c_str(); + std::string const& sourceFileName = args[2]; + std::string const& destinationFileName = args[3]; - if (!cmSystemTools::FileExists(SouceFileName)) { + if (!cmSystemTools::FileExists(sourceFileName)) { std::cerr << "failed to create hard link because source path '" - << SouceFileName << "' does not exist \n"; + << sourceFileName << "' does not exist \n"; return 1; } @@ -1180,7 +1180,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, return 1; } - if (!cmSystemTools::CreateLink(args[2], args[3])) { + if (!cmSystemTools::CreateLink(sourceFileName, destinationFileName)) { return 1; } return 0; @@ -1270,11 +1270,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); snapshot.GetDirectory().SetCurrentBinary(startOutDir); snapshot.GetDirectory().SetCurrentSource(startDir); - snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str()); - snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str()); cmMakefile mf(cm.GetGlobalGenerator(), snapshot); auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + // FIXME: With advanced add_subdirectory usage, these are + // not necessarily the same as the generator originally used. + // We should pass all these directories through an info file. + lgd->SetRelativePathTopSource(homeDir); + lgd->SetRelativePathTopBinary(homeOutDir); + // Actually scan dependencies. return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2; } @@ -1527,6 +1531,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, format = cmDepfileFormat::GccDepfile; } else if (args[3] == "vstlog") { format = cmDepfileFormat::VsTlog; + } else if (args[3] == "makedepfile") { + format = cmDepfileFormat::MakeDepfile; } else { return 1; } @@ -1549,18 +1555,22 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); snapshot.GetDirectory().SetCurrentBinary(startOutDir); snapshot.GetDirectory().SetCurrentSource(startDir); - snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str()); - snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str()); cmMakefile mf(cm.GetGlobalGenerator(), snapshot); auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + // FIXME: With advanced add_subdirectory usage, these are + // not necessarily the same as the generator originally used. + // We should pass all these directories through an info file. + lgd->SetRelativePathTopSource(homeDir); + lgd->SetRelativePathTopBinary(homeOutDir); + return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2; } return 1; } } - CMakeCommandUsage(args[0].c_str()); + CMakeCommandUsage(args[0]); return 1; } @@ -1601,14 +1611,18 @@ int cmcmd::SymlinkLibrary(std::vector<std::string> const& args) cmSystemTools::ConvertToUnixSlashes(soName); cmSystemTools::ConvertToUnixSlashes(name); if (soName != realName) { - if (!cmcmd::SymlinkInternal(realName, soName)) { - cmSystemTools::ReportLastSystemError("cmake_symlink_library"); + cmsys::Status status = cmcmd::SymlinkInternal(realName, soName); + if (!status) { + cmSystemTools::Error( + cmStrCat("cmake_symlink_library: System Error: ", status.GetString())); result = 1; } } if (name != soName) { - if (!cmcmd::SymlinkInternal(soName, name)) { - cmSystemTools::ReportLastSystemError("cmake_symlink_library"); + cmsys::Status status = cmcmd::SymlinkInternal(soName, name); + if (!status) { + cmSystemTools::Error( + cmStrCat("cmake_symlink_library: System Error: ", status.GetString())); result = 1; } } @@ -1621,23 +1635,37 @@ int cmcmd::SymlinkExecutable(std::vector<std::string> const& args) std::string const& realName = args[2]; std::string const& name = args[3]; if (name != realName) { - if (!cmcmd::SymlinkInternal(realName, name)) { - cmSystemTools::ReportLastSystemError("cmake_symlink_executable"); + cmsys::Status status = cmcmd::SymlinkInternal(realName, name); + if (!status) { + cmSystemTools::Error(cmStrCat("cmake_symlink_executable: System Error: ", + status.GetString())); result = 1; } } return result; } -bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link) +cmsys::Status cmcmd::SymlinkInternal(std::string const& file, + std::string const& link) { if (cmSystemTools::FileExists(link) || cmSystemTools::FileIsSymlink(link)) { cmSystemTools::RemoveFile(link); } + std::string linktext = cmSystemTools::GetFilenameName(file); #if defined(_WIN32) && !defined(__CYGWIN__) - return cmSystemTools::CopyFileAlways(file, link); + std::string errorMessage; + cmsys::Status status = + cmSystemTools::CreateSymlink(linktext, link, &errorMessage); + // Creating a symlink will fail with ERROR_PRIVILEGE_NOT_HELD if the user + // does not have SeCreateSymbolicLinkPrivilege, or if developer mode is not + // active. In that case, we try to copy the file. + if (status.GetWindows() == ERROR_PRIVILEGE_NOT_HELD) { + status = cmSystemTools::CopyFileAlways(file, link); + } else if (!status) { + cmSystemTools::Error(errorMessage); + } + return status; #else - std::string linktext = cmSystemTools::GetFilenameName(file); return cmSystemTools::CreateSymlink(linktext, link); #endif } @@ -1927,8 +1955,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args) skipNextArg = false; continue; } - // We use ++ as seperator between the preprocessing step definition and - // the rc compilation step becase we need to prepend a -- to seperate the + // We use ++ as separator between the preprocessing step definition and + // the rc compilation step because we need to prepend a -- to separate the // source file properly from other options when using clang-cl for // preprocessing. if (arg == "++") { diff --git a/Source/cmcmd.h b/Source/cmcmd.h index a2e0b1e..ba78edb 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cmsys/Status.hxx" + #include "cmCryptoHash.h" class cmConsoleBuf; @@ -28,8 +30,8 @@ protected: cmCryptoHash::Algo algo); static int SymlinkLibrary(std::vector<std::string> const& args); static int SymlinkExecutable(std::vector<std::string> const& args); - static bool SymlinkInternal(std::string const& file, - std::string const& link); + static cmsys::Status SymlinkInternal(std::string const& file, + std::string const& link); static int ExecuteEchoColor(std::vector<std::string> const& args); static int ExecuteLinkScript(std::vector<std::string> const& args); static int WindowsCEEnvironment(const char* version, diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 3c331d3..cad27fa 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -50,13 +50,15 @@ static const char* cmDocumentationOptions[][2] = { "given number of jobs." }, { "-Q,--quiet", "Make ctest quiet." }, { "-O <file>, --output-log <file>", "Output to log file" }, + { "--output-junit <file>", "Output test results to JUnit XML file." }, { "-N,--show-only[=format]", "Disable actual execution of tests. The optional 'format' defines the " "format of the test information and can be 'human' for the current text " "format or 'json-v1' for json format. Defaults to 'human'." }, { "-L <regex>, --label-regex <regex>", - "Run tests with labels matching " - "regular expression." }, + "Run tests with labels matching regular expression. " + "With multiple -L, run tests where each " + "regular expression matches at least one label." }, { "-R <regex>, --tests-regex <regex>", "Run tests matching regular " "expression." }, @@ -64,8 +66,9 @@ static const char* cmDocumentationOptions[][2] = { "Exclude tests matching regular " "expression." }, { "-LE <regex>, --label-exclude <regex>", - "Exclude tests with labels " - "matching regular expression." }, + "Exclude tests with labels matching regular expression. " + "With multiple -LE, exclude tests where each " + "regular expression matches at least one label." }, { "-FA <regex>, --fixture-exclude-any <regex>", "Do not automatically " "add any tests for " diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index b0a8542..ef615b3 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -98,6 +98,16 @@ foreach(p endif() endforeach() +# Some configure checks depend upon the deployment target. Clear checks when +# the deployment target changes. +if (APPLE) + if (NOT CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL KWSYS_LAST_OSX_DEPLOYMENT_TARGET) + unset(KWSYS_CXX_HAS_UTIMENSAT CACHE) + endif () + set(KWSYS_LAST_OSX_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}" + CACHE INTERNAL "remember the last deployment target to trigger configure rechecks") +endif () + #----------------------------------------------------------------------------- # If a namespace is not specified, use "kwsys" and enable testing. # This should be the case only when kwsys is not included inside @@ -142,6 +152,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) set(KWSYS_USE_MD5 1) set(KWSYS_USE_Process 1) set(KWSYS_USE_RegularExpression 1) + set(KWSYS_USE_Status 1) set(KWSYS_USE_System 1) set(KWSYS_USE_SystemTools 1) set(KWSYS_USE_CommandLineArguments 1) @@ -157,6 +168,7 @@ if(KWSYS_USE_SystemTools) set(KWSYS_USE_Directory 1) set(KWSYS_USE_FStream 1) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_Status 1) endif() if(KWSYS_USE_Glob) set(KWSYS_USE_Directory 1) @@ -177,6 +189,7 @@ if(KWSYS_USE_System) endif() if(KWSYS_USE_Directory) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_Status 1) endif() if(KWSYS_USE_DynamicLoader) set(KWSYS_USE_Encoding 1) @@ -630,7 +643,7 @@ set(KWSYS_HXX_FILES Configure String) # Add selected C++ classes. set(cppclasses Directory DynamicLoader Encoding Glob RegularExpression SystemTools - CommandLineArguments FStream SystemInformation ConsoleBuf + CommandLineArguments FStream SystemInformation ConsoleBuf Status ) foreach(cpp ${cppclasses}) if(KWSYS_USE_${cpp}) @@ -963,6 +976,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # C++ tests set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testConfigure.cxx + testStatus.cxx testSystemTools.cxx testCommandLineArguments.cxx testCommandLineArguments1.cxx diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 0c2190a..2e8aa83 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -94,7 +94,7 @@ void Directory::Clear() namespace KWSYS_NAMESPACE { -bool Directory::Load(const std::string& name, std::string* errorMessage) +Status Directory::Load(std::string const& name, std::string* errorMessage) { this->Clear(); intptr_t srchHandle; @@ -121,7 +121,11 @@ bool Directory::Load(const std::string& name, std::string* errorMessage) delete[] buf; if (srchHandle == -1) { - return 0; + Status status = Status::POSIX_errno(); + if (errorMessage) { + *errorMessage = status.GetString(); + } + return status; } // Loop through names @@ -129,7 +133,14 @@ bool Directory::Load(const std::string& name, std::string* errorMessage) this->Internal->Files.push_back(Encoding::ToNarrow(data.name)); } while (_wfindnext(srchHandle, &data) != -1); this->Internal->Path = name; - return _findclose(srchHandle) != -1; + if (_findclose(srchHandle) == -1) { + Status status = Status::POSIX_errno(); + if (errorMessage) { + *errorMessage = status.GetString(); + } + return status; + } + return Status::Success(); } unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, @@ -152,6 +163,20 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, delete[] buf; if (srchHandle == -1) { + if (errorMessage) { + if (unsigned int errorId = GetLastError()) { + LPSTR message = nullptr; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, nullptr); + *errorMessage = std::string(message, size); + LocalFree(message); + } else { + *errorMessage = "Unknown error."; + } + } return 0; } @@ -192,7 +217,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, namespace KWSYS_NAMESPACE { -bool Directory::Load(const std::string& name, std::string* errorMessage) +Status Directory::Load(std::string const& name, std::string* errorMessage) { this->Clear(); @@ -203,7 +228,7 @@ bool Directory::Load(const std::string& name, std::string* errorMessage) if (errorMessage != nullptr) { *errorMessage = std::string(strerror(errno)); } - return false; + return Status::POSIX_errno(); } errno = 0; @@ -214,12 +239,12 @@ bool Directory::Load(const std::string& name, std::string* errorMessage) if (errorMessage != nullptr) { *errorMessage = std::string(strerror(errno)); } - return false; + return Status::POSIX_errno(); } this->Internal->Path = name; closedir(dir); - return true; + return Status::Success(); } unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in index 7bc9db0..d501116 100644 --- a/Source/kwsys/Directory.hxx.in +++ b/Source/kwsys/Directory.hxx.in @@ -4,6 +4,7 @@ #define @KWSYS_NAMESPACE@_Directory_hxx #include <@KWSYS_NAMESPACE@/Configure.h> +#include <@KWSYS_NAMESPACE@/Status.hxx> #include <string> @@ -32,10 +33,9 @@ public: /** * Load the specified directory and load the names of the files - * in that directory. 0 is returned if the directory can not be - * opened, 1 if it is opened. + * in that directory. */ - bool Load(const std::string&, std::string* errorMessage = nullptr); + Status Load(std::string const&, std::string* errorMessage = nullptr); /** * Return the number of files in the current directory. diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in index e8474e2..fd39775 100644 --- a/Source/kwsys/Glob.hxx.in +++ b/Source/kwsys/Glob.hxx.in @@ -54,6 +54,9 @@ public: Glob(); ~Glob(); + Glob(const Glob&) = delete; + void operator=(const Glob&) = delete; + //! Find all files that match the pattern. bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr); @@ -124,10 +127,6 @@ protected: std::vector<std::string> VisitedSymlinks; bool ListDirs; bool RecurseListDirs; - -private: - Glob(const Glob&) = delete; - void operator=(const Glob&) = delete; }; } // namespace @KWSYS_NAMESPACE@ diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index e1e7721..a8a15dd 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -122,6 +122,10 @@ static inline void kwsysProcess_usleep(unsigned int msec) /* The maximum amount to read from a pipe at a time. */ #define KWSYSPE_PIPE_BUFFER_SIZE 1024 +#if defined(__NVCOMPILER) +# pragma diag_suppress 550 /* variable set but never used (in FD_ZERO) */ +#endif + /* Keep track of times using a signed representation. Switch to the native (possibly unsigned) representation only when calling native functions. */ @@ -2890,10 +2894,10 @@ static void kwsysProcessesSignalHandler(int signum /* Re-Install our handler. Repeat call until it is not interrupted. */ { struct sigaction newSigAction; - struct sigaction& oldSigAction; + struct sigaction* oldSigAction; memset(&newSigAction, 0, sizeof(struct sigaction)); - newSigChldAction.sa_handler = kwsysProcessesSignalHandler; - newSigChldAction.sa_flags = SA_NOCLDSTOP; + newSigAction.sa_handler = kwsysProcessesSignalHandler; + newSigAction.sa_flags = SA_NOCLDSTOP; sigemptyset(&newSigAction.sa_mask); switch (signum) { case SIGCHLD: @@ -2908,7 +2912,7 @@ static void kwsysProcessesSignalHandler(int signum oldSigAction = &kwsysProcessesOldSigTermAction; break; default: - return 0; + return; } while ((sigaction(signum, &newSigAction, oldSigAction) < 0) && (errno == EINTR)) diff --git a/Source/kwsys/Status.cxx b/Source/kwsys/Status.cxx new file mode 100644 index 0000000..503d1e1 --- /dev/null +++ b/Source/kwsys/Status.cxx @@ -0,0 +1,60 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(Status.hxx) + +// Work-around CMake dependency scanning limitation. This must +// duplicate the above list of headers. +#if 0 +# include "Status.hxx.in" +#endif + +#include <cerrno> +#include <cstring> +#include <string> + +#if defined(_WIN32) +# include <windows.h> +#endif + +namespace KWSYS_NAMESPACE { + +Status Status::POSIX_errno() +{ + return Status::POSIX(errno); +} + +#ifdef _WIN32 +Status Status::Windows_GetLastError() +{ + return Status::Windows(GetLastError()); +} +#endif + +std::string Status::GetString() const +{ + std::string err; + switch (this->Kind_) { + case Kind::Success: + err = "Success"; + break; + case Kind::POSIX: + err = strerror(this->POSIX_); + break; +#ifdef _WIN32 + case Kind::Windows: { + LPSTR message = NULL; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, this->Windows_, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, NULL); + err = std::string(message, size); + LocalFree(message); + } break; +#endif + }; + return err; +} + +} // namespace KWSYS_NAMESPACE diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in new file mode 100644 index 0000000..ed46d5c --- /dev/null +++ b/Source/kwsys/Status.hxx.in @@ -0,0 +1,101 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#ifndef @KWSYS_NAMESPACE@_Status_hxx +#define @KWSYS_NAMESPACE@_Status_hxx + +#include <@KWSYS_NAMESPACE@/Configure.hxx> + +#include <string> + +namespace @KWSYS_NAMESPACE@ { + +/** \class Status + * \brief OS-specific status of a system operation. + */ +class @KWSYS_NAMESPACE@_EXPORT Status +{ +public: + enum class Kind + { + Success, + POSIX, +#ifdef _WIN32 + Windows, +#endif + }; + + /** Construct with kind "Success". */ + Status() = default; + + /** Construct with kind "Success". */ + static Status Success() { return Status(); } + + /** Construct with kind "POSIX" using given errno-style value. */ + static Status POSIX(int e) + { + Status s(Kind::POSIX); + s.POSIX_ = e; + return s; + } + + /** Construct with kind "POSIX" using errno. */ + static Status POSIX_errno(); + +#ifdef _WIN32 + /** Construct with kind "Windows" using given GetLastError()-style value. */ + static Status Windows(unsigned int e) + { + Status s(Kind::Windows); + s.Windows_ = e; + return s; + } + + /** Construct with kind "Windows" using GetLastError(). */ + static Status Windows_GetLastError(); +#endif + + /** Return true on "Success", false otherwise. */ + explicit operator bool() const { return this->Kind_ == Kind::Success; } + + /** Return the kind of status. */ + Kind GetKind() const { return this->Kind_; } + + /** If the kind is "POSIX", returns the errno-style value. + Otherwise, returns 0. */ + int GetPOSIX() const + { + return this->Kind_ == Kind::POSIX ? this->POSIX_ : 0; + } + +#ifdef _WIN32 + /** If the kind is "Windows", returns the GetLastError()-style value. + Otherwise, returns 0. */ + unsigned int GetWindows() const + { + return this->Kind_ == Kind::Windows ? this->Windows_ : 0; + } +#endif + + /** Return a human-readable description of the status. */ + std::string GetString() const; + +private: + Status(Kind kind) + : Kind_(kind) + { + } + + Kind Kind_ = Kind::Success; + + union + { + int POSIX_; +#ifdef _WIN32 + unsigned int Windows_; +#endif + }; +}; + +} // namespace @KWSYS_NAMESPACE@ + +#endif diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 7743eab..117ff8d 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -3472,6 +3472,10 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() // We want to record the total number of cores in this->NumberOfPhysicalCPU // (checking only the first proc) std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores"); + if (Cores.empty()) { + // Linux Sparc is different + Cores = this->ExtractValueFromCpuInfoFile(buffer, "ncpus probed"); + } auto NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str()); NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u); this->NumberOfPhysicalCPU = @@ -3490,6 +3494,9 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() if (this->NumberOfPhysicalCPU <= 0) { this->NumberOfPhysicalCPU = 1; } + if (this->NumberOfLogicalCPU == 0) { + this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; + } // LogicalProcessorsPerPhysical>1 => SMT. this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = this->NumberOfLogicalCPU / this->NumberOfPhysicalCPU; @@ -3503,8 +3510,18 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() else { // Linux Sparc: CPU speed is in Hz and encoded in hexadecimal CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "Cpu0ClkTck"); - this->CPUSpeedInMHz = - static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 16)) / 1000000.0f; + if (!CPUSpeed.empty()) { + this->CPUSpeedInMHz = + static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 16)) / + 1000000.0f; + } else { + // if the kernel is build as Sparc32 it's in decimal, note the different + // case + CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "CPU0ClkTck"); + this->CPUSpeedInMHz = + static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 10)) / + 1000000.0f; + } } #endif diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 6144d9c..006495d 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -93,9 +93,43 @@ # ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) # endif +# ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2) +# endif # if defined(_MSC_VER) && _MSC_VER >= 1800 # define KWSYS_WINDOWS_DEPRECATED_GetVersionEx # endif +// from ntifs.h, which can only be used by drivers +typedef struct _REPARSE_DATA_BUFFER +{ + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union + { + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct + { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; #endif #if !KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H @@ -244,7 +278,7 @@ inline int Chdir(const std::string& dir) return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); } inline void Realpath(const std::string& path, std::string& resolved_path, - std::string* errorMessage = 0) + std::string* errorMessage = nullptr) { std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path); wchar_t* ptemp; @@ -882,21 +916,24 @@ FILE* SystemTools::Fopen(const std::string& file, const char* mode) #endif } -bool SystemTools::MakeDirectory(const char* path, const mode_t* mode) +Status SystemTools::MakeDirectory(const char* path, const mode_t* mode) { if (!path) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::MakeDirectory(std::string(path), mode); } -bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) +Status SystemTools::MakeDirectory(std::string const& path, const mode_t* mode) { - if (SystemTools::PathExists(path)) { - return SystemTools::FileIsDirectory(path); - } if (path.empty()) { - return false; + return Status::POSIX(EINVAL); + } + if (SystemTools::PathExists(path)) { + if (SystemTools::FileIsDirectory(path)) { + return Status::Success(); + } + return Status::POSIX(EEXIST); } std::string dir = path; SystemTools::ConvertToUnixSlashes(dir); @@ -914,15 +951,11 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) ++pos; } topdir = dir; - if (Mkdir(topdir, mode) != 0) { - // if it is some other error besides directory exists - // then return false - if (errno != EEXIST) { - return false; - } + if (Mkdir(topdir, mode) != 0 && errno != EEXIST) { + return Status::POSIX_errno(); } - return true; + return Status::Success(); } // replace replace with with as many times as it shows up in source. @@ -1411,18 +1444,18 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf) #endif } -bool SystemTools::Touch(const std::string& filename, bool create) +Status SystemTools::Touch(std::string const& filename, bool create) { if (!SystemTools::FileExists(filename)) { if (create) { FILE* file = Fopen(filename, "a+b"); if (file) { fclose(file); - return true; + return Status::Success(); } - return false; + return Status::POSIX_errno(); } else { - return true; + return Status::Success(); } } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1430,31 +1463,32 @@ bool SystemTools::Touch(const std::string& filename, bool create) FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (!h) { - return false; + return Status::Windows_GetLastError(); } FILETIME mtime; GetSystemTimeAsFileTime(&mtime); if (!SetFileTime(h, 0, 0, &mtime)) { + Status status = Status::Windows_GetLastError(); CloseHandle(h); - return false; + return status; } CloseHandle(h); #elif KWSYS_CXX_HAS_UTIMENSAT // utimensat is only available on newer Unixes and macOS 10.13+ if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) { - return false; + return Status::POSIX_errno(); } #else // fall back to utimes if (utimes(filename.c_str(), nullptr) < 0) { - return false; + return Status::POSIX_errno(); } #endif - return true; + return Status::Success(); } -bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, - int* result) +Status SystemTools::FileTimeCompare(std::string const& f1, + std::string const& f2, int* result) { // Default to same time. *result = 0; @@ -1462,11 +1496,11 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, // POSIX version. Use stat function to get file modification time. struct stat s1; if (stat(f1.c_str(), &s1) != 0) { - return false; + return Status::POSIX_errno(); } struct stat s2; if (stat(f2.c_str(), &s2) != 0) { - return false; + return Status::POSIX_errno(); } # if KWSYS_CXX_STAT_HAS_ST_MTIM // Compare using nanosecond resolution. @@ -1504,17 +1538,17 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, WIN32_FILE_ATTRIBUTE_DATA f2d; if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(), GetFileExInfoStandard, &f1d)) { - return false; + return Status::Windows_GetLastError(); } if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(), GetFileExInfoStandard, &f2d)) { - return false; + return Status::Windows_GetLastError(); } // Compare the file times using resolution provided by system call. *result = (int)CompareFileTime(&f1d.ftLastWriteTime, &f2d.ftLastWriteTime); #endif - return true; + return Status::Success(); } // Return a capitalized string (i.e the first letter is uppercased, all other @@ -2129,8 +2163,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir) return new_destination + '/' + SystemTools::GetFilenameName(source); } -bool SystemTools::CopyFileIfDifferent(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileIfDifferent(std::string const& source, + std::string const& destination) { // special check for a destination that is a directory // FilesDiffer does not handle file to directory compare @@ -2147,7 +2181,7 @@ bool SystemTools::CopyFileIfDifferent(const std::string& source, } } // at this point the files must be the same so return true - return true; + return Status::Success(); } #define KWSYS_ST_BUFFER 4096 @@ -2273,16 +2307,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1, return false; } -/** - * Blockwise copy source to destination file - */ -static bool CopyFileContentBlockwise(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileContentBlockwise(std::string const& source, + std::string const& destination) { // Open files kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary); if (!fin) { - return false; + return Status::POSIX_errno(); } // try and remove the destination file so that read only destination files @@ -2294,7 +2325,7 @@ static bool CopyFileContentBlockwise(const std::string& source, kwsys::ofstream fout(destination.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); if (!fout) { - return false; + return Status::POSIX_errno(); } // This copy loop is very sensitive on certain platforms with @@ -2323,10 +2354,10 @@ static bool CopyFileContentBlockwise(const std::string& source, fout.close(); if (!fout) { - return false; + return Status::POSIX_errno(); } - return true; + return Status::Success(); } /** @@ -2341,13 +2372,13 @@ static bool CopyFileContentBlockwise(const std::string& source, * - The underlying filesystem does not support file cloning * - An unspecified error occurred */ -static bool CloneFileContent(const std::string& source, - const std::string& destination) +Status SystemTools::CloneFileContent(std::string const& source, + std::string const& destination) { #if defined(__linux) && defined(FICLONE) int in = open(source.c_str(), O_RDONLY); if (in < 0) { - return false; + return Status::POSIX_errno(); } SystemTools::RemoveFile(destination); @@ -2355,38 +2386,42 @@ static bool CloneFileContent(const std::string& source, int out = open(destination.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (out < 0) { + Status status = Status::POSIX_errno(); close(in); - return false; + return status; } - int result = ioctl(out, FICLONE, in); + Status status = Status::Success(); + if (ioctl(out, FICLONE, in) < 0) { + status = Status::POSIX_errno(); + } close(in); close(out); - if (result < 0) { - return false; - } - - return true; + return status; #else (void)source; (void)destination; - return false; + return Status::POSIX(ENOSYS); #endif } /** * Copy a file named by "source" to the file named by "destination". */ -bool SystemTools::CopyFileAlways(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileAlways(std::string const& source, + std::string const& destination) { + Status status; mode_t perm = 0; - bool perms = SystemTools::GetPermissions(source, perm); + Status perms = SystemTools::GetPermissions(source, perm); std::string real_destination = destination; if (SystemTools::FileIsDirectory(source)) { - SystemTools::MakeDirectory(destination); + status = SystemTools::MakeDirectory(destination); + if (!status) { + return status; + } } else { // If destination is a directory, try to create a file with the same // name as the source in that directory. @@ -2403,30 +2438,34 @@ bool SystemTools::CopyFileAlways(const std::string& source, } // If files are the same do not copy if (SystemTools::SameFile(source, real_destination)) { - return true; + return status; } // Create destination directory - - SystemTools::MakeDirectory(destination_dir); - - if (!CloneFileContent(source, real_destination)) { - // if cloning did not succeed, fall back to blockwise copy - if (!CopyFileContentBlockwise(source, real_destination)) { - return false; + if (!destination_dir.empty()) { + status = SystemTools::MakeDirectory(destination_dir); + if (!status) { + return status; } } + + status = SystemTools::CloneFileContent(source, real_destination); + // if cloning did not succeed, fall back to blockwise copy + if (!status) { + status = SystemTools::CopyFileContentBlockwise(source, real_destination); + } + if (!status) { + return status; + } } if (perms) { - if (!SystemTools::SetPermissions(real_destination, perm)) { - return false; - } + status = SystemTools::SetPermissions(real_destination, perm); } - return true; + return status; } -bool SystemTools::CopyAFile(const std::string& source, - const std::string& destination, bool always) +Status SystemTools::CopyAFile(std::string const& source, + std::string const& destination, bool always) { if (always) { return SystemTools::CopyFileAlways(source, destination); @@ -2439,18 +2478,21 @@ bool SystemTools::CopyAFile(const std::string& source, * Copy a directory content from "source" directory to the directory named by * "destination". */ -bool SystemTools::CopyADirectory(const std::string& source, - const std::string& destination, bool always) +Status SystemTools::CopyADirectory(std::string const& source, + std::string const& destination, bool always) { + Status status; Directory dir; - if (dir.Load(source) == 0) { - return false; + status = dir.Load(source); + if (!status) { + return status; } - size_t fileNum; - if (!SystemTools::MakeDirectory(destination)) { - return false; + status = SystemTools::MakeDirectory(destination); + if (!status) { + return status; } - for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { + + for (size_t fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 && strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) { std::string fullPath = source; @@ -2460,18 +2502,20 @@ bool SystemTools::CopyADirectory(const std::string& source, std::string fullDestPath = destination; fullDestPath += "/"; fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum)); - if (!SystemTools::CopyADirectory(fullPath, fullDestPath, always)) { - return false; + status = SystemTools::CopyADirectory(fullPath, fullDestPath, always); + if (!status) { + return status; } } else { - if (!SystemTools::CopyAFile(fullPath, destination, always)) { - return false; + status = SystemTools::CopyAFile(fullPath, destination, always); + if (!status) { + return status; } } } } - return true; + return status; } // return size of file; also returns zero if no file exists @@ -2553,26 +2597,26 @@ std::string SystemTools::GetLastSystemError() return strerror(e); } -bool SystemTools::RemoveFile(const std::string& source) +Status SystemTools::RemoveFile(std::string const& source) { #ifdef _WIN32 std::wstring const& ws = Encoding::ToWindowsExtendedPath(source); if (DeleteFileW(ws.c_str())) { - return true; + return Status::Success(); } DWORD err = GetLastError(); if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { - return true; + return Status::Success(); } if (err != ERROR_ACCESS_DENIED) { - return false; + return Status::Windows(err); } /* The file may be read-only. Try adding write permission. */ mode_t mode; if (!SystemTools::GetPermissions(source, mode) || !SystemTools::SetPermissions(source, S_IWRITE)) { SetLastError(err); - return false; + return Status::Windows(err); } const DWORD DIRECTORY_SOFT_LINK_ATTRS = @@ -2581,26 +2625,29 @@ bool SystemTools::RemoveFile(const std::string& source) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & DIRECTORY_SOFT_LINK_ATTRS) == DIRECTORY_SOFT_LINK_ATTRS && RemoveDirectoryW(ws.c_str())) { - return true; + return Status::Success(); } if (DeleteFileW(ws.c_str()) || GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND) { - return true; + return Status::Success(); } /* Try to restore the original permissions. */ SystemTools::SetPermissions(source, mode); SetLastError(err); - return false; + return Status::Windows(err); #else - return unlink(source.c_str()) == 0 || errno == ENOENT; + if (unlink(source.c_str()) != 0 && errno != ENOENT) { + return Status::POSIX_errno(); + } + return Status::Success(); #endif } -bool SystemTools::RemoveADirectory(const std::string& source) +Status SystemTools::RemoveADirectory(std::string const& source) { // Add write permission to the directory so we can modify its // content to remove files and directories from it. - mode_t mode; + mode_t mode = 0; if (SystemTools::GetPermissions(source, mode)) { #if defined(_WIN32) && !defined(__CYGWIN__) mode |= S_IWRITE; @@ -2610,8 +2657,13 @@ bool SystemTools::RemoveADirectory(const std::string& source) SystemTools::SetPermissions(source, mode); } + Status status; Directory dir; - dir.Load(source); + status = dir.Load(source); + if (!status) { + return status; + } + size_t fileNum; for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 && @@ -2621,18 +2673,23 @@ bool SystemTools::RemoveADirectory(const std::string& source) fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); if (SystemTools::FileIsDirectory(fullPath) && !SystemTools::FileIsSymlink(fullPath)) { - if (!SystemTools::RemoveADirectory(fullPath)) { - return false; + status = SystemTools::RemoveADirectory(fullPath); + if (!status) { + return status; } } else { - if (!SystemTools::RemoveFile(fullPath)) { - return false; + status = SystemTools::RemoveFile(fullPath); + if (!status) { + return status; } } } } - return (Rmdir(source) == 0); + if (Rmdir(source) != 0) { + status = Status::POSIX_errno(); + } + return status; } /** @@ -2985,7 +3042,7 @@ bool SystemTools::FileIsSymlink(const std::string& name) } CloseHandle(hFile); ULONG reparseTag = - reinterpret_cast<PREPARSE_GUID_DATA_BUFFER>(&buffer[0])->ReparseTag; + reinterpret_cast<PREPARSE_DATA_BUFFER>(&buffer[0])->ReparseTag; return (reparseTag == IO_REPARSE_TAG_SYMLINK) || (reparseTag == IO_REPARSE_TAG_MOUNT_POINT); } @@ -3025,45 +3082,109 @@ bool SystemTools::FileIsFIFO(const std::string& name) #endif } -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::CreateSymlink(const std::string&, const std::string&) +Status SystemTools::CreateSymlink(std::string const& origName, + std::string const& newName) { - return false; -} +#if defined(_WIN32) && !defined(__CYGWIN__) + DWORD flags; + if (FileIsDirectory(origName)) { + flags = SYMBOLIC_LINK_FLAG_DIRECTORY; + } else { + flags = 0; + } + + std::wstring origPath = Encoding::ToWindowsExtendedPath(origName); + std::wstring newPath = Encoding::ToWindowsExtendedPath(newName); + + Status status; + if (!CreateSymbolicLinkW(newPath.c_str(), origPath.c_str(), + flags | + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) { + status = Status::Windows_GetLastError(); + } + // Older Windows versions do not understand + // SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE + if (status.GetWindows() == ERROR_INVALID_PARAMETER) { + status = Status::Success(); + if (!CreateSymbolicLinkW(newPath.c_str(), origPath.c_str(), flags)) { + status = Status::Windows_GetLastError(); + } + } + + return status; #else -bool SystemTools::CreateSymlink(const std::string& origName, - const std::string& newName) -{ - return symlink(origName.c_str(), newName.c_str()) >= 0; -} + if (symlink(origName.c_str(), newName.c_str()) < 0) { + return Status::POSIX_errno(); + } + return Status::Success(); #endif +} -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadSymlink(const std::string&, std::string&) +Status SystemTools::ReadSymlink(std::string const& newName, + std::string& origName) { - return false; -} +#if defined(_WIN32) && !defined(__CYGWIN__) + std::wstring newPath = Encoding::ToWindowsExtendedPath(newName); + // FILE_ATTRIBUTE_REPARSE_POINT means: + // * a file or directory that has an associated reparse point, or + // * a file that is a symbolic link. + HANDLE hFile = CreateFileW( + newPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr); + if (hFile == INVALID_HANDLE_VALUE) { + return Status::Windows_GetLastError(); + } + byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + DWORD bytesReturned = 0; + Status status; + if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer, + MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, + nullptr)) { + status = Status::Windows_GetLastError(); + } + CloseHandle(hFile); + if (!status) { + return status; + } + PREPARSE_DATA_BUFFER data = + reinterpret_cast<PREPARSE_DATA_BUFFER>(&buffer[0]); + USHORT substituteNameLength; + PCWSTR substituteNameData; + if (data->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + substituteNameLength = + data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + substituteNameData = data->SymbolicLinkReparseBuffer.PathBuffer + + data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR); + } else if (data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { + substituteNameLength = + data->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + substituteNameData = data->MountPointReparseBuffer.PathBuffer + + data->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR); + } else { + return Status::Windows(ERROR_REPARSE_TAG_MISMATCH); + } + std::wstring substituteName(substituteNameData, substituteNameLength); + origName = Encoding::ToNarrow(substituteName); #else -bool SystemTools::ReadSymlink(const std::string& newName, - std::string& origName) -{ char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1]; int count = static_cast<int>( readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH)); - if (count >= 0) { - // Add null-terminator. - buf[count] = 0; - origName = buf; - return true; - } else { - return false; + if (count < 0) { + return Status::POSIX_errno(); } -} + // Add null-terminator. + buf[count] = 0; + origName = buf; #endif + return Status::Success(); +} -int SystemTools::ChangeDirectory(const std::string& dir) +Status SystemTools::ChangeDirectory(std::string const& dir) { - return Chdir(dir); + if (Chdir(dir) < 0) { + return Status::POSIX_errno(); + } + return Status::Success(); } std::string SystemTools::GetCurrentWorkingDirectory() @@ -3929,7 +4050,7 @@ bool SystemTools::FileIsFullPath(const char* in_name) bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len) { -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) // On Windows, the name must be at least two characters long. if (len < 2) { return false; @@ -3960,7 +4081,8 @@ bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len) return false; } -bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) +Status SystemTools::GetShortPath(std::string const& path, + std::string& shortPath) { #if defined(_WIN32) && !defined(__CYGWIN__) std::string tempPath = path; // create a buffer @@ -3980,14 +4102,14 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) } if (ret == 0) { - return false; + return Status::Windows_GetLastError(); } else { shortPath = Encoding::ToNarrow(&buffer[0]); - return true; + return Status::Success(); } #else shortPath = path; - return true; + return Status::Success(); #endif } @@ -4088,21 +4210,21 @@ int SystemTools::GetTerminalWidth() return width; } -bool SystemTools::GetPermissions(const char* file, mode_t& mode) +Status SystemTools::GetPermissions(const char* file, mode_t& mode) { if (!file) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::GetPermissions(std::string(file), mode); } -bool SystemTools::GetPermissions(const std::string& file, mode_t& mode) +Status SystemTools::GetPermissions(std::string const& file, mode_t& mode) { #if defined(_WIN32) DWORD attr = GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str()); if (attr == INVALID_FILE_ATTRIBUTES) { - return false; + return Status::Windows_GetLastError(); } if ((attr & FILE_ATTRIBUTE_READONLY) != 0) { mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); @@ -4125,27 +4247,27 @@ bool SystemTools::GetPermissions(const std::string& file, mode_t& mode) #else struct stat st; if (stat(file.c_str(), &st) < 0) { - return false; + return Status::POSIX_errno(); } mode = st.st_mode; #endif - return true; + return Status::Success(); } -bool SystemTools::SetPermissions(const char* file, mode_t mode, - bool honor_umask) +Status SystemTools::SetPermissions(const char* file, mode_t mode, + bool honor_umask) { if (!file) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::SetPermissions(std::string(file), mode, honor_umask); } -bool SystemTools::SetPermissions(const std::string& file, mode_t mode, - bool honor_umask) +Status SystemTools::SetPermissions(std::string const& file, mode_t mode, + bool honor_umask) { if (!SystemTools::PathExists(file)) { - return false; + return Status::POSIX(ENOENT); } if (honor_umask) { mode_t currentMask = umask(0); @@ -4158,10 +4280,10 @@ bool SystemTools::SetPermissions(const std::string& file, mode_t mode, if (chmod(file.c_str(), mode) < 0) #endif { - return false; + return Status::POSIX_errno(); } - return true; + return Status::Success(); } std::string SystemTools::GetParentDirectory(const std::string& fileOrDir) diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index 74dc176..e5d115e 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -4,6 +4,7 @@ #define @KWSYS_NAMESPACE@_SystemTools_hxx #include <@KWSYS_NAMESPACE@/Configure.hxx> +#include <@KWSYS_NAMESPACE@/Status.hxx> #include <iosfwd> #include <map> @@ -339,7 +340,7 @@ public: /** Change the modification time or create a file */ - static bool Touch(const std::string& filename, bool create); + static Status Touch(std::string const& filename, bool create); /** * Compare file modification times. @@ -347,8 +348,8 @@ public: * When true is returned, result has -1, 0, +1 for * f1 older, same, or newer than f2. */ - static bool FileTimeCompare(const std::string& f1, const std::string& f2, - int* result); + static Status FileTimeCompare(std::string const& f1, std::string const& f2, + int* result); /** * Get the file extension (including ".") needed for an executable @@ -507,7 +508,7 @@ public: * For windows return the short path for the given path, * Unix just a pass through */ - static bool GetShortPath(const std::string& path, std::string& result); + static Status GetShortPath(std::string const& path, std::string& result); /** * Read line from file. Make sure to read a full line and truncates it if @@ -553,16 +554,16 @@ public: * can make a full path even if none of the directories existed * prior to calling this function. */ - static bool MakeDirectory(const char* path, const mode_t* mode = nullptr); - static bool MakeDirectory(const std::string& path, - const mode_t* mode = nullptr); + static Status MakeDirectory(const char* path, const mode_t* mode = nullptr); + static Status MakeDirectory(std::string const& path, + const mode_t* mode = nullptr); /** * Copy the source file to the destination file only * if the two files differ. */ - static bool CopyFileIfDifferent(const std::string& source, - const std::string& destination); + static Status CopyFileIfDifferent(std::string const& source, + std::string const& destination); /** * Compare the contents of two files. Return true if different @@ -578,6 +579,17 @@ public: const std::string& path2); /** + * Blockwise copy source to destination file + */ + static Status CopyFileContentBlockwise(std::string const& source, + std::string const& destination); + /** + * Clone the source file to the destination file + */ + static Status CloneFileContent(std::string const& source, + std::string const& destination); + + /** * Return true if the two files are the same file */ static bool SameFile(const std::string& file1, const std::string& file2); @@ -585,16 +597,16 @@ public: /** * Copy a file. */ - static bool CopyFileAlways(const std::string& source, - const std::string& destination); + static Status CopyFileAlways(std::string const& source, + std::string const& destination); /** * Copy a file. If the "always" argument is true the file is always * copied. If it is false, the file is copied only if it is new or * has changed. */ - static bool CopyAFile(const std::string& source, - const std::string& destination, bool always = true); + static Status CopyAFile(std::string const& source, + std::string const& destination, bool always = true); /** * Copy content directory to another directory with all files and @@ -602,19 +614,19 @@ public: * always copied. If it is false, only files that have changed or * are new are copied. */ - static bool CopyADirectory(const std::string& source, - const std::string& destination, - bool always = true); + static Status CopyADirectory(std::string const& source, + std::string const& destination, + bool always = true); /** * Remove a file */ - static bool RemoveFile(const std::string& source); + static Status RemoveFile(std::string const& source); /** * Remove a directory */ - static bool RemoveADirectory(const std::string& source); + static Status RemoveADirectory(std::string const& source); /** * Get the maximum full file path length @@ -708,14 +720,14 @@ public: * Create a symbolic link if the platform supports it. Returns whether * creation succeeded. */ - static bool CreateSymlink(const std::string& origName, - const std::string& newName); + static Status CreateSymlink(std::string const& origName, + std::string const& newName); /** * Read the contents of a symbolic link. Returns whether reading * succeeded. */ - static bool ReadSymlink(const std::string& newName, std::string& origName); + static Status ReadSymlink(std::string const& newName, std::string& origName); /** * Try to locate the file 'filename' in the directory 'dir'. @@ -765,12 +777,12 @@ public: * WARNING: A non-thread-safe method is currently used to get the umask * if a honor_umask parameter is set to true. */ - static bool GetPermissions(const char* file, mode_t& mode); - static bool GetPermissions(const std::string& file, mode_t& mode); - static bool SetPermissions(const char* file, mode_t mode, - bool honor_umask = false); - static bool SetPermissions(const std::string& file, mode_t mode, - bool honor_umask = false); + static Status GetPermissions(const char* file, mode_t& mode); + static Status GetPermissions(std::string const& file, mode_t& mode); + static Status SetPermissions(const char* file, mode_t mode, + bool honor_umask = false); + static Status SetPermissions(std::string const& file, mode_t mode, + bool honor_umask = false); /** ----------------------------------------------------------------- * Time Manipulation Routines @@ -867,7 +879,7 @@ public: /** * Change directory to the directory specified */ - static int ChangeDirectory(const std::string& dir); + static Status ChangeDirectory(std::string const& dir); /** * Get the result of strerror(errno) diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index 4d1b46c..20bb5fe 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -10,7 +10,7 @@ #endif /* Configure support for this platform. */ -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) # define KWSYS_TERMINAL_SUPPORT_CONSOLE #endif #if !defined(_WIN32) @@ -173,6 +173,14 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, } } + /* Disable color according to http://bixense.com/clicolors/ convention. */ + { + const char* clicolor = getenv("CLICOLOR"); + if (clicolor && strcmp(clicolor, "0") == 0) { + return 0; + } + } + /* GNU make 4.1+ may tell us that its output is destined for a TTY. */ { const char* termout = getenv("MAKE_TERMOUT"); diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx index eb3ca32..06a22dc 100644 --- a/Source/kwsys/testDirectory.cxx +++ b/Source/kwsys/testDirectory.cxx @@ -88,7 +88,7 @@ int _nonExistentDirectoryTest() errorMessage = "foo"; // Increment res failure if directory lists - res += testdir.Load(testdirpath, &errorMessage); + res += testdir.Load(testdirpath, &errorMessage) ? 1 : 0; #if !defined(_WIN32) || defined(__CYGWIN__) // Increment res failure if errorMessage is unmodified res += (errorMessage == "foo"); @@ -120,7 +120,7 @@ int _copyDirectoryTest() std::cerr << destination << " shouldn't exist before test" << std::endl; return 2; } - const bool copysuccess = SystemTools::CopyADirectory(source, destination); + const Status copysuccess = SystemTools::CopyADirectory(source, destination); const bool destinationexists = SystemTools::PathExists(destination); if (copysuccess) { std::cerr << "CopyADirectory should have returned false" << std::endl; diff --git a/Source/kwsys/testStatus.cxx b/Source/kwsys/testStatus.cxx new file mode 100644 index 0000000..f85ef42 --- /dev/null +++ b/Source/kwsys/testStatus.cxx @@ -0,0 +1,117 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying +file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(Status.hxx) + +// Work-around CMake dependency scanning limitation. This must +// duplicate the above list of headers. +#if 0 +# include "Status.hxx.in" +#endif + +#include <cerrno> +#include <iostream> + +#ifdef _WIN32 +# include <windows.h> +#endif + +int testStatus(int, char* []) +{ + bool res = true; + { + kwsys::Status status; + if (status.GetKind() != kwsys::Status::Kind::Success) { + std::cerr << "Status default constructor does not produce Success\n"; + res = false; + } + + status = kwsys::Status::Success(); + if (status.GetKind() != kwsys::Status::Kind::Success) { + std::cerr << "Status Success constructor does not produce Success\n"; + res = false; + } + if (!status) { + std::cerr << "Status Success kind is not true\n"; + res = false; + } + if (status.GetPOSIX() != 0) { + std::cerr << "Status Success kind does not return POSIX 0\n"; + res = false; + } +#ifdef _WIN32 + if (status.GetWindows() != 0) { + std::cerr << "Status Success kind does not return Windows 0\n"; + res = false; + } +#endif + if (status.GetString() != "Success") { + std::cerr << "Status Success kind does not return \"Success\" string\n"; + res = false; + } + + status = kwsys::Status::POSIX(EINVAL); + if (status.GetKind() != kwsys::Status::Kind::POSIX) { + std::cerr << "Status POSIX constructor does not produce POSIX\n"; + res = false; + } + if (status) { + std::cerr << "Status POSIX kind is not false\n"; + res = false; + } + if (status.GetPOSIX() != EINVAL) { + std::cerr << "Status POSIX kind does not preserve POSIX value\n"; + res = false; + } +#ifdef _WIN32 + if (status.GetWindows() != 0) { + std::cerr << "Status POSIX kind does not return Windows 0\n"; + res = false; + } +#endif + if (status.GetString().empty()) { + std::cerr << "Status POSIX kind returns empty string\n"; + res = false; + } + errno = ENOENT; + status = kwsys::Status::POSIX_errno(); + if (status.GetPOSIX() != ENOENT) { + std::cerr << "Status POSIX_errno did not use errno\n"; + res = false; + } + errno = 0; + +#ifdef _WIN32 + status = kwsys::Status::Windows(ERROR_INVALID_PARAMETER); + if (status.GetKind() != kwsys::Status::Kind::Windows) { + std::cerr << "Status Windows constructor does not produce Windows\n"; + res = false; + } + if (status) { + std::cerr << "Status Windows kind is not false\n"; + res = false; + } + if (status.GetWindows() != ERROR_INVALID_PARAMETER) { + std::cerr << "Status Windows kind does not preserve Windows value\n"; + res = false; + } + if (status.GetPOSIX() != 0) { + std::cerr << "Status Windows kind does not return POSIX 0\n"; + res = false; + } + if (status.GetString().empty()) { + std::cerr << "Status Windows kind returns empty string\n"; + res = false; + } + + SetLastError(ERROR_FILE_NOT_FOUND); + status = kwsys::Status::Windows_GetLastError(); + if (status.GetWindows() != ERROR_FILE_NOT_FOUND) { + std::cerr << "Status Windows_GetLastError did not use GetLastError()\n"; + res = false; + } + SetLastError(ERROR_SUCCESS); +#endif + } + return res ? 0 : 1; +} diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index cfa420d..700eaf7 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -29,6 +29,7 @@ # ifdef _MSC_VER # define umask _umask # endif +# include <windows.h> #endif #include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */ // Visual C++ does not define mode_t. @@ -290,15 +291,17 @@ static bool CheckFileOperations() res = false; } + std::cerr << std::oct; // Reset umask -#if defined(_WIN32) && !defined(__CYGWIN__) +#ifdef __MSYS__ + mode_t fullMask = S_IWRITE; +#elif defined(_WIN32) && !defined(__CYGWIN__) // NOTE: Windows doesn't support toggling _S_IREAD. mode_t fullMask = _S_IWRITE; #else // On a normal POSIX platform, we can toggle all permissions. mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO; #endif - mode_t orig_umask = umask(fullMask); // Test file permissions without umask mode_t origPerm, thisPerm; @@ -370,6 +373,7 @@ static bool CheckFileOperations() res = false; } + mode_t orig_umask = umask(fullMask); // Test setting file permissions while honoring umask if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true)) { std::cerr << "Problem with SetPermissions (3) for: " << testNewFile @@ -422,21 +426,28 @@ static bool CheckFileOperations() res = false; } -#if !defined(_WIN32) std::string const testBadSymlink(testNewDir + "/badSymlink.txt"); std::string const testBadSymlinkTgt(testNewDir + "/missing/symlinkTgt.txt"); - if (!kwsys::SystemTools::CreateSymlink(testBadSymlinkTgt, testBadSymlink)) { - std::cerr << "Problem with CreateSymlink for: " << testBadSymlink << " -> " - << testBadSymlinkTgt << std::endl; - res = false; - } + kwsys::Status const symlinkStatus = + kwsys::SystemTools::CreateSymlink(testBadSymlinkTgt, testBadSymlink); +#if defined(_WIN32) + // Under Windows, the user may not have enough privileges to create symlinks + if (symlinkStatus.GetWindows() != ERROR_PRIVILEGE_NOT_HELD) +#endif + { + if (!symlinkStatus) { + std::cerr << "CreateSymlink for: " << testBadSymlink << " -> " + << testBadSymlinkTgt + << " failed: " << symlinkStatus.GetString() << std::endl; + res = false; + } - if (!kwsys::SystemTools::Touch(testBadSymlink, false)) { - std::cerr << "Problem with Touch (no create) for: " << testBadSymlink - << std::endl; - res = false; + if (!kwsys::SystemTools::Touch(testBadSymlink, false)) { + std::cerr << "Problem with Touch (no create) for: " << testBadSymlink + << std::endl; + res = false; + } } -#endif if (!kwsys::SystemTools::Touch(testNewDir, false)) { std::cerr << "Problem with Touch (no create) for: " << testNewDir @@ -496,6 +507,7 @@ static bool CheckFileOperations() } #endif + std::cerr << std::dec; return res; } @@ -1093,7 +1105,7 @@ static bool CheckCopyFileIfDifferent() ret = false; continue; } - std::string bdata = readFile("file_b"); + std::string bdata = readFile(cptarget); if (diff_test_cases[i].a != bdata) { std::cerr << "Incorrect CopyFileIfDifferent file contents in test case " << i + 1 << "." << std::endl; diff --git a/Templates/MSBuild/FlagTables/v10_CSharp.json b/Templates/MSBuild/FlagTables/v10_CSharp.json index 5989aea..9f21d9a 100644 --- a/Templates/MSBuild/FlagTables/v10_CSharp.json +++ b/Templates/MSBuild/FlagTables/v10_CSharp.json @@ -363,52 +363,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/MSBuild/FlagTables/v11_CSharp.json b/Templates/MSBuild/FlagTables/v11_CSharp.json index 5989aea..9f21d9a 100644 --- a/Templates/MSBuild/FlagTables/v11_CSharp.json +++ b/Templates/MSBuild/FlagTables/v11_CSharp.json @@ -363,52 +363,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/MSBuild/FlagTables/v12_CSharp.json b/Templates/MSBuild/FlagTables/v12_CSharp.json index 5989aea..9f21d9a 100644 --- a/Templates/MSBuild/FlagTables/v12_CSharp.json +++ b/Templates/MSBuild/FlagTables/v12_CSharp.json @@ -363,52 +363,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/MSBuild/FlagTables/v140_CSharp.json b/Templates/MSBuild/FlagTables/v140_CSharp.json index 5989aea..9f21d9a 100644 --- a/Templates/MSBuild/FlagTables/v140_CSharp.json +++ b/Templates/MSBuild/FlagTables/v140_CSharp.json @@ -363,52 +363,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/MSBuild/FlagTables/v141_CSharp.json b/Templates/MSBuild/FlagTables/v141_CSharp.json index 5989aea..9f21d9a 100644 --- a/Templates/MSBuild/FlagTables/v141_CSharp.json +++ b/Templates/MSBuild/FlagTables/v141_CSharp.json @@ -363,52 +363,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/MSBuild/FlagTables/v142_CSharp.json b/Templates/MSBuild/FlagTables/v142_CSharp.json index 4dcea9d..ae1bd47 100644 --- a/Templates/MSBuild/FlagTables/v142_CSharp.json +++ b/Templates/MSBuild/FlagTables/v142_CSharp.json @@ -381,52 +381,13 @@ }, { "name": "LangVersion", - "switch": "langversion:ISO-1", + "switch": "langversion:", "comment": "", - "value": "ISO-1", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:ISO-2", - "comment": "", - "value": "ISO-2", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:3", - "comment": "", - "value": "3", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:4", - "comment": "", - "value": "4", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:5", - "comment": "", - "value": "5", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:6", - "comment": "", - "value": "6", - "flags": [] - }, - { - "name": "LangVersion", - "switch": "langversion:default", - "comment": "", - "value": "default", - "flags": [] + "value": "", + "flags": [ + "UserValue", + "UserRequired" + ] }, { "name": "DelaySign", diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in index 3e47d6a..e3efa79 100644 --- a/Templates/TestDriver.cxx.in +++ b/Templates/TestDriver.cxx.in @@ -2,6 +2,7 @@ #include <stdio.h> /* NOLINT */ #include <stdlib.h> /* NOLINT */ #include <string.h> /* NOLINT */ +#include <time.h> #if defined(_MSC_VER) #pragma warning(disable : 4996) /* deprecation */ @@ -62,11 +63,23 @@ static char* lowercase(const char* string) return new_string; } +int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) { + int i; + for (i = 0; i < n_skipped_tests; i++) { + if (strcmp(name, skipped_tests[i]) == 0) { + return 1; + } + } + + return 0; +} + int main(int ac, char* av[]) { int i; int testNum = 0; int partial_match; + int run_all; char *arg; int testToRun = -1; @@ -95,15 +108,43 @@ int main(int ac, char* av[]) av++; } partial_match = 0; + run_all = 0; arg = CM_NULL; /* NOLINT */ - /* If partial match is requested. */ + /* If partial match or running all tests are requested. */ if (testToRun == -1 && ac > 1) { partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0; + run_all = (strcmp(av[1], "-A") == 0) ? 1 : 0; } if (partial_match != 0 && ac < 3) { printf("-R needs an additional parameter.\n"); return -1; } + if (run_all == 1) { + clock_t t; + int status = 0; + const char* status_message = NULL; + printf("TAP version 13\n"); + printf("1..%d\n", NumTests); + for (i = 0; i < NumTests; ++i) { + const char *name = cmakeGeneratedFunctionMapEntries[i].name; + if (ac > 2) { + if (isTestSkipped(name, ac - 2, av + 2) == 1) { + printf("ok %d %s # SKIP\n", i + 1, name); + continue; + } + } + t = clock(); + status = (*cmakeGeneratedFunctionMapEntries[i].func)(ac, av); + t = clock() - t; + double time_taken = ((double)t) / CLOCKS_PER_SEC; + status_message = (status == -1) ? "not ok" : "ok"; + printf("%s %d %s # %f\n", status_message, i + 1, name, time_taken); + } + printf("All tests finished.\n"); + + return 0; + } + if (testToRun == -1) { arg = lowercase(av[1 + partial_match]); } diff --git a/Tests/BundleGeneratorTest/CMakeLists.txt b/Tests/BundleGeneratorTest/CMakeLists.txt index 037df09..cf7e2ce 100644 --- a/Tests/BundleGeneratorTest/CMakeLists.txt +++ b/Tests/BundleGeneratorTest/CMakeLists.txt @@ -1,6 +1,6 @@ project(BundleGeneratorTest) -cmake_minimum_required(VERSION 2.7) +cmake_minimum_required(VERSION 2.8.12) # Build a shared library and install it in lib/ add_library(Library SHARED Library.cxx) diff --git a/Tests/CMakeLib/testVisualStudioSlnParser.cxx b/Tests/CMakeLib/testVisualStudioSlnParser.cxx index 3c06960..7fdba9a 100644 --- a/Tests/CMakeLib/testVisualStudioSlnParser.cxx +++ b/Tests/CMakeLib/testVisualStudioSlnParser.cxx @@ -33,7 +33,7 @@ int testVisualStudioSlnParser(int, char* []) // Test clean parser if (parser.GetParseResult() != cmVisualStudioSlnParser::ResultOK) { - std::cerr << "cmVisualStudioSlnParser initialisation failed" << std::endl; + std::cerr << "cmVisualStudioSlnParser initialization failed" << std::endl; return 1; } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 8e7c04f..38b4301 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -25,14 +25,14 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/CheckSwift.cmake) # Fake a user home directory to avoid polluting the real one. -if(DEFINED ENV{HOME} AND NOT CTEST_NO_TEST_HOME) +if(NOT CTEST_NO_TEST_HOME AND (NOT WIN32 OR DEFINED ENV{HOME})) set(TEST_HOME "${CMake_BINARY_DIR}/Tests/CMakeFiles/TestHome") file(MAKE_DIRECTORY "${TEST_HOME}") file(WRITE "${TEST_HOME}/.cvspass" ":pserver:anoncvs@www.cmake.org:/cvsroot/KWSys A\n") set(TEST_HOME_ENV_CODE "# Fake a user home directory to avoid polluting the real one. # But provide original ENV{HOME} value in ENV{CTEST_REAL_HOME} for tests that # need access to the real HOME directory. -if(NOT DEFINED ENV{CTEST_REAL_HOME}) +if(DEFINED ENV{HOME} AND NOT DEFINED ENV{CTEST_REAL_HOME}) set(ENV{CTEST_REAL_HOME} \"\$ENV{HOME}\") endif() set(ENV{HOME} \"${TEST_HOME}\") @@ -96,7 +96,7 @@ if(BUILD_TESTING) # some old versions of make simply cannot handle spaces in paths if (MAKE_IS_GNU OR CMAKE_MAKE_PROGRAM MATCHES "nmake|gmake|wmake" OR - CMAKE_GENERATOR MATCHES "Visual Studio|Xcode|Borland") + CMAKE_GENERATOR MATCHES "Visual Studio|Xcode|Borland|Ninja") set(MAKE_SUPPORTS_SPACES 1) else() set(MAKE_SUPPORTS_SPACES 0) @@ -460,7 +460,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(OutName exe.OutName.exe) ADD_TEST_MACRO(ObjectLibrary UseCshared) ADD_TEST_MACRO(NewlineArgs NewlineArgs) - ADD_TEST_MACRO(SetLang SetLang) + ADD_TEST_MACRO(SetLang SetLangX) ADD_TEST_MACRO(EmptyProperty EmptyProperty) ADD_TEST_MACRO(ExternalOBJ ExternalOBJ) if(NOT CMake_TEST_EXTERNAL_CMAKE) @@ -804,6 +804,7 @@ if(BUILD_TESTING) ${build_generator_args} --build-project Framework --build-options + -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES} "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/Framework/Install" --test-command bar) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Framework") @@ -828,6 +829,8 @@ if(BUILD_TESTING) ${build_generator_args} --build-project LibName --build-exe-dir "${CMake_BINARY_DIR}/Tests/LibName/lib" + --build-options + -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES} --test-command foobar ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LibName") @@ -1421,6 +1424,7 @@ if(BUILD_TESTING) CURL Cups Doxygen + DevIL EnvModules EXPAT Fontconfig @@ -1693,7 +1697,7 @@ if(BUILD_TESTING) ${build_generator_args} --build-project ${import_name} --build-options - "-DCMAKE_PREFIX_PATH:PATH=${install_dir}/lib/cmake") + "-DCMAKE_PREFIX_PATH:PATH=${install_dir}") set_tests_properties(${import_test_name} PROPERTIES DEPENDS ${export_test_name}) list(APPEND TEST_BUILD_DIRS "${import_build_dir}") endfunction() @@ -1738,33 +1742,61 @@ if(BUILD_TESTING) add_test(testdriver1 ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/TestDriver" - "${CMake_BINARY_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver1" ${build_generator_args} --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" --build-project TestDriverTest --test-command TestDriverTest test1 ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver1") add_test(testdriver2 ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/TestDriver" - "${CMake_BINARY_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver2" ${build_generator_args} --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" --build-project TestDriverTest --test-command TestDriverTest test2 ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver2") add_test(testdriver3 ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/TestDriver" - "${CMake_BINARY_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver3" ${build_generator_args} --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" --build-project TestDriverTest --test-command TestDriverTest subdir/test3 ) - list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver") + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver3") + + add_test(testdriver4 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver4" + ${build_generator_args} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --build-project TestDriverTest + --test-command TestDriverTest -A test2 + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver4") + + add_test(testdriver5 ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/TestDriver" + "${CMake_BINARY_DIR}/Tests/TestDriver5" + ${build_generator_args} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin" + --build-project TestDriverTest + --test-command TestDriverTest -A test2 + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver5") + set_tests_properties(testdriver5 PROPERTIES + PASS_REGULAR_EXPRESSION + "TAP version 13\n1\\.\\.3.+ok 1 test1 # [0-9]+\\.[0-9]+.*All tests finished." + ) add_test(Dependency ${CMAKE_CTEST_COMMAND} --build-and-test diff --git a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt index 7ca68ec..aca99ce 100644 --- a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt @@ -36,7 +36,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES Intel) string (REGEX REPLACE ".*Version ([0-9]+(\\.[0-9]+)+).*" "\\1" _intel_version "${_intel_version_info}") endif() -message("Platform:\n WIN32: ${WIN32}\n UNIX: ${UNIX}\n APPLE: ${APPLE}\n MINGW: ${MINGW}\n CYGWIN: ${CYGWIN}\n" +message("Platform:\n WIN32: ${WIN32}\n UNIX: ${UNIX}\n APPLE: ${APPLE}\n MINGW: ${MINGW}\n CYGWIN: ${CYGWIN}\n MSYS: ${MSYS}\n" " MSVC: ${MSVC}\n MSVC60: ${MSVC60}\n MSVC70: ${MSVC70}\n MSVC71: ${MSVC71}\n MSVC80: ${MSVC80}\n MSVC90: ${MSVC90}\n MSVC10: ${MSVC10}\n" " GCC: ${_gcc_version}\n" " Clang: ${_clang_version}\n" diff --git a/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt index 2028a13..2784e3b 100644 --- a/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt @@ -9,7 +9,7 @@ project(CheckCXXSymbolExists CXX) -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/../CheckSymbolExists") diff --git a/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt index 1570c37..2e5d8d3 100644 --- a/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 2.8.12) project(CheckLanguage NONE) include(CheckLanguage) diff --git a/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt b/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt index 7f01463..9a9bb2a 100644 --- a/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt @@ -9,7 +9,7 @@ project(CheckSymbolExists C) -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt b/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt index 56e449a..d66eb06 100644 --- a/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt +++ b/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 2.8.12) project(LinkInterfaceLoop C) # Add a shared library that incorrectly names itself as a diff --git a/Tests/CMakeOnly/TargetScope/CMakeLists.txt b/Tests/CMakeOnly/TargetScope/CMakeLists.txt index fa5d8e2..faf2250 100644 --- a/Tests/CMakeOnly/TargetScope/CMakeLists.txt +++ b/Tests/CMakeOnly/TargetScope/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 2.8.12) project(TargetScope NONE) add_subdirectory(Sub) diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index 6bbbe7d..52959e6 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -7,6 +7,7 @@ macro(AddCMakeTest TestName PreArgs) add_test(NAME CMake.${TestName} COMMAND ${CMAKE_EXECUTABLE} ${PreArgs} -P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN}) + set_tests_properties("CMake.${TestName}" PROPERTIES LABELS "CMake;command") endmacro() diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in index f01e616..1254ff9 100644 --- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in +++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in @@ -459,7 +459,28 @@ set(msys_g77_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/so list(APPEND platforms msys_g77) #----------------------------------------------------------------------------- -# MSYS2 +# MSYS2-runtime + +# gcc dummy.c -v +set(msys2rt_gcc_text " /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --dll-search-prefix=msys- /usr/lib/gcc/i686-pc-msys/6.4.0/../../../crt0.o -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0/../../.. /home/user/AppData/Local/Temp/cczg1Arh.o -lgcc -lmsys-2.0 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc") +set(msys2rt_gcc_libs "msys-2.0;user32;kernel32;advapi32;shell32") +set(msys2rt_gcc_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib") +list(APPEND platforms msysrt_gcc) + +# g++ dummy.cxx -v +set(msys2rt_g++_text " /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --dll-search-prefix=msys- /usr/lib/gcc/i686-pc-msys/6.4.0/../../../crt0.o -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0/../../.. /home/user/AppData/Local/Temp/ccsvcDO6.o -lstdc++ -lgcc -lmsys-2.0 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc") +set(msys2rt_g++_libs "stdc++;msys-2.0;user32;kernel32;advapi32;shell32") +set(msys2rt_g++_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib") +list(APPEND platforms msysrt_g++) + +# g77 dummy.f -v +set(msys2rt_g77_text "Configured with: ... LD=/opt/gcc-tools/bin/ld.exe /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --dll-search-prefix=msys- -u ___register_frame_info -u ___deregister_frame_info /usr/lib/gcc/i686-pc-msys/6.4.0/../../../crt0.o /usr/lib/gcc/i686-pc-msys/6.4.0/crtbegin.o -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0/../../.. /home/user/AppData/Local/Temp/ccqRWKWg.o -lgfortranbegin -lgfortran -lgcc_s -lgcc_s -lgcc -lmsys-2.0 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc_s -lgcc_s -lgcc /usr/lib/gcc/i686-pc-msys/6.4.0/crtend.o") +set(msys2rt_g77_libs "stdc++;msys-2.0;user32;kernel32;advapi32;shell32") +set(msys2rt_g77_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib") +list(APPEND platforms msysrt_g77) + +#----------------------------------------------------------------------------- +# MSYS2-mingw # gcc dummy.c -v set(msys2_gcc_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/ccikz9Wf.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccK0dTUv.o -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o") diff --git a/Tests/CPackComponents/CMakeLists.txt b/Tests/CPackComponents/CMakeLists.txt index 5b03c9e..c1b348e 100644 --- a/Tests/CPackComponents/CMakeLists.txt +++ b/Tests/CPackComponents/CMakeLists.txt @@ -4,7 +4,7 @@ # application (mylibapp). We create a binary installer that allows # users to select which pieces will be installed: the example # application, the library binaries, and/or the header file. -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(CPackComponents) # Create the mylib library diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake index 8f7c198..b61e62d 100644 --- a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake @@ -146,7 +146,7 @@ endfunction() # This function runs dpkg-deb on a .deb and returns its output -# the default behaviour it to run "--info" on the specified Debian package +# the default behavior it to run "--info" on the specified Debian package # ACTION is one of the option accepted by dpkg-deb function(run_dpkgdeb dpkg_deb_output) set(${dpkg_deb_output} "" PARENT_SCOPE) diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index f3d3ad0..31e843a 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -404,7 +404,7 @@ if(CPackGen MATCHES "RPM") elseif("${symlink_name}" STREQUAL "symlink_other_relocatable_path" OR "${symlink_name}" STREQUAL "symlink_from_non_relocatable_path" OR "${symlink_name}" STREQUAL "symlink_relocatable_subpath") - # these links were not canged - post install script only - ignore them + # these links were not changed - post install script only - ignore them else() message(FATAL_ERROR "error: unexpected rpm symbolic link '${check_symlink}'") endif() diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt index 195af05..f7928b6 100644 --- a/Tests/CSharpOnly/CMakeLists.txt +++ b/Tests/CSharpOnly/CMakeLists.txt @@ -9,8 +9,13 @@ source_group(nested FILES nested/lib1.cs) add_library(lib2 SHARED lib2.cs) add_executable(CSharpOnly csharponly.cs) - target_link_libraries(CSharpOnly lib1 lib2) +add_executable(CSharpConfigSpecific + $<$<CONFIG:Debug>:config_specific_main_debug.cs> + $<$<NOT:$<CONFIG:Debug>>:config_specific_main_not_debug.cs> + $<$<CONFIG:NotAConfig>:config_specific_main_no_exist.cs> + ) + add_custom_target(CSharpCustom ALL SOURCES empty.cs) add_custom_target(custom.cs ALL DEPENDS empty.txt) diff --git a/Tests/CSharpOnly/config_specific_main_debug.cs b/Tests/CSharpOnly/config_specific_main_debug.cs new file mode 100644 index 0000000..b62524b --- /dev/null +++ b/Tests/CSharpOnly/config_specific_main_debug.cs @@ -0,0 +1,10 @@ +namespace CSharpConfigSpecific +{ + class CSharpConfigSpecific + { + public static void Main(string[] args) + { + return; + } + } +} diff --git a/Tests/CSharpOnly/config_specific_main_no_exist.cs b/Tests/CSharpOnly/config_specific_main_no_exist.cs new file mode 100644 index 0000000..b62524b --- /dev/null +++ b/Tests/CSharpOnly/config_specific_main_no_exist.cs @@ -0,0 +1,10 @@ +namespace CSharpConfigSpecific +{ + class CSharpConfigSpecific + { + public static void Main(string[] args) + { + return; + } + } +} diff --git a/Tests/CSharpOnly/config_specific_main_not_debug.cs b/Tests/CSharpOnly/config_specific_main_not_debug.cs new file mode 100644 index 0000000..b62524b --- /dev/null +++ b/Tests/CSharpOnly/config_specific_main_not_debug.cs @@ -0,0 +1,10 @@ +namespace CSharpConfigSpecific +{ + class CSharpConfigSpecific + { + public static void Main(string[] args) + { + return; + } + } +} diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in index a9bbc52..d5d4d2f 100644 --- a/Tests/CTestTest2/test.cmake.in +++ b/Tests/CTestTest2/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestBadExe/test.cmake.in b/Tests/CTestTestBadExe/test.cmake.in index 43a8572..dd180f0 100644 --- a/Tests/CTestTestBadExe/test.cmake.in +++ b/Tests/CTestTestBadExe/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestChecksum/test.cmake.in b/Tests/CTestTestChecksum/test.cmake.in index 2a435d2..3bac0e0 100644 --- a/Tests/CTestTestChecksum/test.cmake.in +++ b/Tests/CTestTestChecksum/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestCostSerial/test.cmake.in b/Tests/CTestTestCostSerial/test.cmake.in index 9b32a46..1c46d4c 100644 --- a/Tests/CTestTestCostSerial/test.cmake.in +++ b/Tests/CTestTestCostSerial/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestCrash/CMakeLists.txt b/Tests/CTestTestCrash/CMakeLists.txt index 77986df..663d2e4 100644 --- a/Tests/CTestTestCrash/CMakeLists.txt +++ b/Tests/CTestTestCrash/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestCrash) include(CTest) diff --git a/Tests/CTestTestCrash/test.cmake.in b/Tests/CTestTestCrash/test.cmake.in index 3641cb0..916d4e9 100644 --- a/Tests/CTestTestCrash/test.cmake.in +++ b/Tests/CTestTestCrash/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestCycle/CMakeLists.txt b/Tests/CTestTestCycle/CMakeLists.txt index 6ba6b8c..19f4dd7 100644 --- a/Tests/CTestTestCycle/CMakeLists.txt +++ b/Tests/CTestTestCycle/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestCycle) include(CTest) diff --git a/Tests/CTestTestCycle/test.cmake.in b/Tests/CTestTestCycle/test.cmake.in index 4a63dd6..507d46b 100644 --- a/Tests/CTestTestCycle/test.cmake.in +++ b/Tests/CTestTestCycle/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestDepends/CMakeLists.txt b/Tests/CTestTestDepends/CMakeLists.txt index 5cd6d66..462ad8c 100644 --- a/Tests/CTestTestDepends/CMakeLists.txt +++ b/Tests/CTestTestDepends/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestDepends) include(CTest) diff --git a/Tests/CTestTestDepends/test.cmake.in b/Tests/CTestTestDepends/test.cmake.in index 74fddb3..11bc92a 100644 --- a/Tests/CTestTestDepends/test.cmake.in +++ b/Tests/CTestTestDepends/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestFailure/CMakeLists.txt b/Tests/CTestTestFailure/CMakeLists.txt index 01fbb2c..db14b3d 100644 --- a/Tests/CTestTestFailure/CMakeLists.txt +++ b/Tests/CTestTestFailure/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestFailure) include(CTest) diff --git a/Tests/CTestTestFailure/testNoBuild.cmake.in b/Tests/CTestTestFailure/testNoBuild.cmake.in index 86333af..47d254f 100644 --- a/Tests/CTestTestFailure/testNoBuild.cmake.in +++ b/Tests/CTestTestFailure/testNoBuild.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestFailure/testNoExe.cmake.in b/Tests/CTestTestFailure/testNoExe.cmake.in index 8875cee..8496c80 100644 --- a/Tests/CTestTestFailure/testNoExe.cmake.in +++ b/Tests/CTestTestFailure/testNoExe.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestLabelRegExp/test.cmake.in b/Tests/CTestTestLabelRegExp/test.cmake.in index 5c0c9d7..dd40c3b 100644 --- a/Tests/CTestTestLabelRegExp/test.cmake.in +++ b/Tests/CTestTestLabelRegExp/test.cmake.in @@ -27,11 +27,15 @@ expect_test_list("test1.*test3.*Total Tests: 2" --label-regex foo) expect_test_list("test2.*test3.*Total Tests: 2" --label-regex bar) expect_test_list("test1.*test2.*test3.*Total Tests: 3" --label-regex foo|bar) expect_test_list("Total Tests: 0" --label-regex baz) +expect_test_list("Total Tests: 0" --label-regex foo --label-regex baz) +expect_test_list("test3.*Total Tests: 1" --label-regex foo --label-regex bar) expect_test_list("test2.*Total Tests: 1" --label-exclude foo) expect_test_list("test1.*Total Tests: 1" --label-exclude bar) expect_test_list("Total Tests: 0" --label-exclude foo|bar) expect_test_list("test1.*test2.*test3.*Total Tests: 3" --label-exclude baz) +expect_test_list("test1.*test2.*Total Tests: 2" --label-exclude foo --label-exclude bar) +expect_test_list("test1.*test2.*test3.*Total Tests: 3" --label-exclude foo --label-exclude baz) expect_test_list("test1.*Total Tests: 1" --label-regex foo --label-exclude bar) expect_test_list("test2.*Total Tests: 1" --label-regex bar --label-exclude foo) diff --git a/Tests/CTestTestParallel/CMakeLists.txt b/Tests/CTestTestParallel/CMakeLists.txt index e47085a..819fee4 100644 --- a/Tests/CTestTestParallel/CMakeLists.txt +++ b/Tests/CTestTestParallel/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestParallel) include(CTest) diff --git a/Tests/CTestTestParallel/test.cmake.in b/Tests/CTestTestParallel/test.cmake.in index 045a4ca..517db72 100644 --- a/Tests/CTestTestParallel/test.cmake.in +++ b/Tests/CTestTestParallel/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestResourceLock/CMakeLists.txt b/Tests/CTestTestResourceLock/CMakeLists.txt index 4001643..4bc4366 100644 --- a/Tests/CTestTestResourceLock/CMakeLists.txt +++ b/Tests/CTestTestResourceLock/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestResourceLock) include(CTest) diff --git a/Tests/CTestTestResourceLock/test.cmake.in b/Tests/CTestTestResourceLock/test.cmake.in index 67dde18..826226d 100644 --- a/Tests/CTestTestResourceLock/test.cmake.in +++ b/Tests/CTestTestResourceLock/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestScheduler/CMakeLists.txt b/Tests/CTestTestScheduler/CMakeLists.txt index ccd7b2c..a3f0f27 100644 --- a/Tests/CTestTestScheduler/CMakeLists.txt +++ b/Tests/CTestTestScheduler/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (CTestTestScheduler) include (CTest) diff --git a/Tests/CTestTestScheduler/test.cmake.in b/Tests/CTestTestScheduler/test.cmake.in index f8c8ab7..5dcfb63 100644 --- a/Tests/CTestTestScheduler/test.cmake.in +++ b/Tests/CTestTestScheduler/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestSkipReturnCode/test.cmake.in b/Tests/CTestTestSkipReturnCode/test.cmake.in index 112b0cd..2988d2f 100644 --- a/Tests/CTestTestSkipReturnCode/test.cmake.in +++ b/Tests/CTestTestSkipReturnCode/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestStopTime/CMakeLists.txt b/Tests/CTestTestStopTime/CMakeLists.txt index bd8bebd..08116e2 100644 --- a/Tests/CTestTestStopTime/CMakeLists.txt +++ b/Tests/CTestTestStopTime/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestStopTime) include(CTest) diff --git a/Tests/CTestTestStopTime/test.cmake.in b/Tests/CTestTestStopTime/test.cmake.in index d3a9a4a..3797d40 100644 --- a/Tests/CTestTestStopTime/test.cmake.in +++ b/Tests/CTestTestStopTime/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestSubdir/CMakeLists.txt b/Tests/CTestTestSubdir/CMakeLists.txt index b7cc7e2..87c4604 100644 --- a/Tests/CTestTestSubdir/CMakeLists.txt +++ b/Tests/CTestTestSubdir/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestSubdir) include(CTest) diff --git a/Tests/CTestTestSubdir/test.cmake.in b/Tests/CTestTestSubdir/test.cmake.in index 8b3957b..3b1fb5f 100644 --- a/Tests/CTestTestSubdir/test.cmake.in +++ b/Tests/CTestTestSubdir/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestTimeout/test.cmake.in b/Tests/CTestTestTimeout/test.cmake.in index 4b5157e..ce9c497 100644 --- a/Tests/CTestTestTimeout/test.cmake.in +++ b/Tests/CTestTestTimeout/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestUpload/CMakeLists.txt b/Tests/CTestTestUpload/CMakeLists.txt index 90d811c..5e02b2f 100644 --- a/Tests/CTestTestUpload/CMakeLists.txt +++ b/Tests/CTestTestUpload/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestUpload) add_executable (Sleep sleep.c) diff --git a/Tests/CTestTestUpload/test.cmake.in b/Tests/CTestTestUpload/test.cmake.in index 701439d..74fd1ec 100644 --- a/Tests/CTestTestUpload/test.cmake.in +++ b/Tests/CTestTestUpload/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestVerboseOutput/CMakeLists.txt b/Tests/CTestTestVerboseOutput/CMakeLists.txt index 4cdd29c..3792385 100644 --- a/Tests/CTestTestVerboseOutput/CMakeLists.txt +++ b/Tests/CTestTestVerboseOutput/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CTestTestVerboseOutput) include(CTest) diff --git a/Tests/CTestTestVerboseOutput/test.cmake.in b/Tests/CTestTestVerboseOutput/test.cmake.in index 7f49548..9c9a4dc 100644 --- a/Tests/CTestTestVerboseOutput/test.cmake.in +++ b/Tests/CTestTestVerboseOutput/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CTestTestZeroTimeout/CMakeLists.txt b/Tests/CTestTestZeroTimeout/CMakeLists.txt index 4d2b79d..2d404c8 100644 --- a/Tests/CTestTestZeroTimeout/CMakeLists.txt +++ b/Tests/CTestTestZeroTimeout/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (CTestTestZeroTimeout) include (CTest) diff --git a/Tests/CTestTestZeroTimeout/test.cmake.in b/Tests/CTestTestZeroTimeout/test.cmake.in index b829fef..50dbba0 100644 --- a/Tests/CTestTestZeroTimeout/test.cmake.in +++ b/Tests/CTestTestZeroTimeout/test.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.12) # Settings: set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake index 33e1bfb..36293f5 100644 --- a/Tests/CheckFortran.cmake +++ b/Tests/CheckFortran.cmake @@ -7,7 +7,7 @@ if(NOT DEFINED CMAKE_Fortran_COMPILER) message(STATUS ${_desc}) file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran/CMakeLists.txt" - "cmake_minimum_required(VERSION 2.4) + "cmake_minimum_required(VERSION 2.8.12) project(CheckFortran Fortran) file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" \"set(CMAKE_Fortran_COMPILER \\\"\${CMAKE_Fortran_COMPILER}\\\")\\n\" diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt index cff98e3..20988ac 100644 --- a/Tests/CompileFeatures/CMakeLists.txt +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -18,7 +18,7 @@ macro(run_test feature lang) endif() endmacro() -if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM)$") +if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES) list(FILTER c_features EXCLUDE REGEX "^c_std_[0-9][0-9]") foreach(feature ${c_features}) @@ -26,7 +26,7 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM)$") endforeach() endif() -if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM)$") +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES) list(FILTER cxx_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]") foreach(feature ${cxx_features}) @@ -237,6 +237,8 @@ if (C_expected_features) if (std_flag_idx EQUAL -1) add_executable(default_dialect_C default_dialect.c) target_compile_definitions(default_dialect_C PRIVATE + DEFAULT_C23=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},23> + DEFAULT_C17=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},17> DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11> DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99> DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90> diff --git a/Tests/CompileFeatures/cxx_contextual_conversions.cpp b/Tests/CompileFeatures/cxx_contextual_conversions.cpp index 247f13f..fe8d5c0 100644 --- a/Tests/CompileFeatures/cxx_contextual_conversions.cpp +++ b/Tests/CompileFeatures/cxx_contextual_conversions.cpp @@ -1,4 +1,3 @@ - #define assert(E) \ if (!(E)) \ return 1; @@ -38,6 +37,7 @@ int someFunc() } int* vp = new int[i]; + delete[] vp; return 0; } diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c index 6160c2f..b990e53 100644 --- a/Tests/CompileFeatures/default_dialect.c +++ b/Tests/CompileFeatures/default_dialect.c @@ -1,5 +1,13 @@ -#if DEFAULT_C11 +#if DEFAULT_C23 +# if __STDC_VERSION__ <= 201710L +# error Unexpected value for __STDC_VERSION__. +# endif +#elif DEFAULT_C17 +# if __STDC_VERSION__ < 201710L +# error Unexpected value for __STDC_VERSION__. +# endif +#elif DEFAULT_C11 # if __STDC_VERSION__ < 201112L # error Unexpected value for __STDC_VERSION__. # endif diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index a3d98f6..38475f8 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.0) get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build" FORCE) endif() @@ -74,10 +75,10 @@ add_custom_command(APPEND VERBATIM ) foreach(n RANGE 1 5) - set_property(SOURCE custom${n}_Debug.cpp PROPERTY COMPILE_DEFINITIONS CUSTOM_CFG_DEBUG) - foreach(other Release RelWithDebInfo MinSizeRel) + foreach(other ${CMAKE_BUILD_TYPE} Release RelWithDebInfo MinSizeRel) set_property(SOURCE custom${n}_${other}.cpp PROPERTY COMPILE_DEFINITIONS CUSTOM_CFG_OTHER) endforeach() + set_property(SOURCE custom${n}_Debug.cpp PROPERTY COMPILE_DEFINITIONS CUSTOM_CFG_DEBUG) endforeach() add_library(Custom STATIC custom1_$<CONFIG>.cpp diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 80545c4..fa06a94 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -1,7 +1,7 @@ # # Wrapping # -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (CustomCommand) add_subdirectory(GeneratedHeader) @@ -583,6 +583,6 @@ set_target_properties(mac_fw PROPERTIES add_custom_command(OUTPUT mac_fw.txt COMMAND ${CMAKE_COMMAND} -E touch mac_fw.txt DEPENDS mac_fw) add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt) -# Test empty COMMANDs are ommited +# Test empty COMMANDs are omitted add_executable(empty_command empty_command.cxx) add_custom_command(TARGET empty_command POST_BUILD COMMAND $<0:date>) diff --git a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt index 3bab1fe..7697a9b 100644 --- a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt +++ b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(TestWorkingDir) add_custom_command( diff --git a/Tests/Dependency/CMakeLists.txt b/Tests/Dependency/CMakeLists.txt index ebc2d10..58d3fb7 100644 --- a/Tests/Dependency/CMakeLists.txt +++ b/Tests/Dependency/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project( Dependency ) # to test directories with only one character One was changed to 1 diff --git a/Tests/ExportImport/Import/Interface/pch_iface_test.cpp b/Tests/ExportImport/Import/Interface/pch_iface_test.cpp index a18bbde..d676a5b 100644 --- a/Tests/ExportImport/Import/Interface/pch_iface_test.cpp +++ b/Tests/ExportImport/Import/Interface/pch_iface_test.cpp @@ -3,7 +3,8 @@ # ifndef PCH_PCH_H_INCLUDED # error "Expected PCH_PCH_H_INCLUDED." # endif -#elif defined(__PGIC__) || defined(__ibmxl__) || defined(_CRAYC) +#elif defined(__PGIC__) || defined(__ibmxl__) || defined(_CRAYC) || \ + defined(__FUJITSU) // No PCH expected but these compilers define macros below. #elif defined(__GNUC__) || defined(__clang__) || defined(_INTEL_COMPILER) || \ defined(_MSC_VER) diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt index 9a0241c..57e8105 100644 --- a/Tests/ExternalProjectLocal/CMakeLists.txt +++ b/Tests/ExternalProjectLocal/CMakeLists.txt @@ -41,7 +41,7 @@ set(TutorialStep5_install_dir ${install_dir}) set(proj TutorialStep5-Local-TestAfterInstall) ExternalProject_Add(${proj} URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" -CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_ARGS --install-prefix=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF TEST_AFTER_INSTALL 1 LOG_TEST 1 @@ -51,7 +51,7 @@ set_property(TARGET ${proj} PROPERTY FOLDER "Local") set(proj TutorialStep5-Local-TestExcludeFromMainBefore) ExternalProject_Add(${proj} URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" -CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_ARGS --install-prefix=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF TEST_BEFORE_INSTALL 1 TEST_EXCLUDE_FROM_MAIN 1 @@ -63,7 +63,7 @@ set_property(TARGET ${proj} PROPERTY FOLDER "Local") set(proj TutorialStep5-Local-TestExcludeFromMainAfter) ExternalProject_Add(${proj} URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" -CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_ARGS --install-prefix=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF TEST_AFTER_INSTALL 1 TEST_EXCLUDE_FROM_MAIN 1 diff --git a/Tests/FindBLAS/CMakeLists.txt b/Tests/FindBLAS/CMakeLists.txt index 667195d..63ef1dd 100644 --- a/Tests/FindBLAS/CMakeLists.txt +++ b/Tests/FindBLAS/CMakeLists.txt @@ -1,10 +1,25 @@ -add_test(NAME FindBLAS.Test COMMAND - ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> - --build-and-test - "${CMake_SOURCE_DIR}/Tests/FindBLAS/Test" - "${CMake_BINARY_DIR}/Tests/FindBLAS/Test" - ${build_generator_args} - --build-project TestFindBLAS - --build-options ${build_options} - --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> - ) +foreach(vendor IN LISTS CMake_TEST_FindBLAS) + add_test(NAME FindBLAS.Test_${vendor} COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindBLAS/Test" + "${CMake_BINARY_DIR}/Tests/FindBLAS/Test_${vendor}" + ${build_generator_args} + --build-project TestFindBLAS + --build-options ${build_options} -DBLA_VENDOR=${vendor} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +endforeach() + +foreach(vendor IN LISTS CMake_TEST_FindBLAS_STATIC) + add_test(NAME FindBLAS.Test_${vendor}_Static COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindBLAS/Test" + "${CMake_BINARY_DIR}/Tests/FindBLAS/Test_${vendor}_Static" + ${build_generator_args} + --build-project TestFindBLAS + --build-options ${build_options} -DBLA_VENDOR=${vendor} -DBLA_STATIC=ON + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +endforeach() diff --git a/Tests/FindBLAS/Test/CMakeLists.txt b/Tests/FindBLAS/Test/CMakeLists.txt index 59418f3..98e12d5 100644 --- a/Tests/FindBLAS/Test/CMakeLists.txt +++ b/Tests/FindBLAS/Test/CMakeLists.txt @@ -11,3 +11,9 @@ add_test(NAME test_tgt COMMAND test_tgt) add_executable(test_var main.c) target_link_libraries(test_var PRIVATE ${BLAS_LIBRARIES}) add_test(NAME test_var COMMAND test_var) + +if(BLA_VENDOR STREQUAL "Intel10_64lp") + if(NOT BLAS_LIBRARIES MATCHES "^(-Wl,--start-group;)?[^;]*mkl_intel_lp64") + message(FATAL_ERROR "BLAS_LIBRARIES does not start in mkl_intel_lp64:\n ${BLAS_LIBRARIES}") + endif() +endif() diff --git a/Tests/FindDevIL/CMakeLists.txt b/Tests/FindDevIL/CMakeLists.txt new file mode 100644 index 0000000..d37d50f --- /dev/null +++ b/Tests/FindDevIL/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindDevIL.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindDevIL/Test" + "${CMake_BINARY_DIR}/Tests/FindDevIL/Test" + ${build_generator_args} + --build-project TestFindDevIL + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/FindDevIL/Test/CMakeLists.txt b/Tests/FindDevIL/Test/CMakeLists.txt new file mode 100644 index 0000000..c2c1322 --- /dev/null +++ b/Tests/FindDevIL/Test/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.1) +project(TestFindDevIL C) +include(CTest) + +find_package(DevIL) + +#FIXME: check version too. +# add_definitions( +# -DCMAKE_EXPECTED_SDL_VERSION_MAJOR=${SDL_VERSION_MAJOR} +# -DCMAKE_EXPECTED_SDL_VERSION_MINOR=${SDL_VERSION_MINOR} +# -DCMAKE_EXPECTED_SDL_VERSION_PATCH=${SDL_VERSION_PATCH}) + +add_executable(test_devil_var main.c) +target_include_directories(test_devil_var PRIVATE ${IL_INCLUDE_DIRS}) +target_link_libraries(test_devil_var PRIVATE ${IL_LIBRARIES}) +add_test(NAME test_devil_var COMMAND test_devil_var) + +add_executable(test_devil_il_tgt main.c) +target_link_libraries(test_devil_il_tgt DevIL::IL) +add_test(NAME test_devil_il_tgt COMMAND test_devil_il_tgt) + +add_executable(test_devil_ilu_tgt main_ilu.c) +target_link_libraries(test_devil_ilu_tgt DevIL::ILU) + +add_executable(test_devil_ilu_var main_ilu.c) +target_include_directories(test_devil_ilu_var PRIVATE ${IL_INCLUDE_DIRS} ${ILU_INCLUDE_DIRS}) +target_link_libraries(test_devil_ilu_var ${IL_LIBRARIES} ${ILU_LIBRARIES}) + +#FIXME: Check DevIL::ILUT target diff --git a/Tests/FindDevIL/Test/main.c b/Tests/FindDevIL/Test/main.c new file mode 100644 index 0000000..4a07087 --- /dev/null +++ b/Tests/FindDevIL/Test/main.c @@ -0,0 +1,10 @@ +#include <IL/il.h> + +int main() +{ + // Test 1 requires to link to the library. + ilInit(); + + ilShutDown(); + return 0; +} diff --git a/Tests/FindDevIL/Test/main_ilu.c b/Tests/FindDevIL/Test/main_ilu.c new file mode 100644 index 0000000..a9e7819 --- /dev/null +++ b/Tests/FindDevIL/Test/main_ilu.c @@ -0,0 +1,8 @@ +#include <IL/ilu.h> + +int main() +{ + // IL Utilities requires only initialization. + // Unlike main DevIL there are no shutdown function. + iluInit(); +} diff --git a/Tests/FindLAPACK/CMakeLists.txt b/Tests/FindLAPACK/CMakeLists.txt index 2081d59..eab5bb4 100644 --- a/Tests/FindLAPACK/CMakeLists.txt +++ b/Tests/FindLAPACK/CMakeLists.txt @@ -1,10 +1,25 @@ -add_test(NAME FindLAPACK.Test COMMAND - ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> - --build-and-test - "${CMake_SOURCE_DIR}/Tests/FindLAPACK/Test" - "${CMake_BINARY_DIR}/Tests/FindLAPACK/Test" - ${build_generator_args} - --build-project TestFindLAPACK - --build-options ${build_options} - --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> - ) +foreach(vendor IN LISTS CMake_TEST_FindLAPACK) + add_test(NAME FindLAPACK.Test_${vendor} COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindLAPACK/Test" + "${CMake_BINARY_DIR}/Tests/FindLAPACK/Test_${vendor}" + ${build_generator_args} + --build-project TestFindLAPACK + --build-options ${build_options} -DBLA_VENDOR=${vendor} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +endforeach() + +foreach(vendor IN LISTS CMake_TEST_FindLAPACK_STATIC) + add_test(NAME FindLAPACK.Test_${vendor}_Static COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindLAPACK/Test" + "${CMake_BINARY_DIR}/Tests/FindLAPACK/Test_${vendor}_Static" + ${build_generator_args} + --build-project TestFindLAPACK + --build-options ${build_options} -DBLA_VENDOR=${vendor} -DBLA_STATIC=ON + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +endforeach() diff --git a/Tests/FindLAPACK/Test/CMakeLists.txt b/Tests/FindLAPACK/Test/CMakeLists.txt index 8afa36a..bb33482 100644 --- a/Tests/FindLAPACK/Test/CMakeLists.txt +++ b/Tests/FindLAPACK/Test/CMakeLists.txt @@ -11,3 +11,9 @@ add_test(NAME test_tgt COMMAND test_tgt) add_executable(test_var main.c) target_link_libraries(test_var PRIVATE ${LAPACK_LIBRARIES}) add_test(NAME test_var COMMAND test_var) + +if(BLA_VENDOR STREQUAL "Intel10_64lp") + if(NOT LAPACK_LIBRARIES MATCHES "^(-Wl,--start-group;)?[^;]*mkl_intel_lp64") + message(FATAL_ERROR "LAPACK_LIBRARIES does not start in mkl_intel_lp64:\n ${LAPACK_LIBRARIES}") + endif() +endif() diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt index 8a87a8c..0b15be8 100644 --- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt +++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt @@ -19,12 +19,16 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile" AND # configure a FindFoo.cmake so it knows where the library can be found configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY) - # Need the -isysroot flag on recentish macOS after command line tools - # no longer provide headers in /usr/include - if(APPLE AND CMAKE_OSX_SYSROOT) - set(__EXTRA_OSX_SYSROOT_FLAGS "-isysroot ${CMAKE_OSX_SYSROOT}") - else() - set(__EXTRA_OSX_SYSROOT_FLAGS "") + set(EXTRA_FLAGS "") + if(APPLE) + # Need the -isysroot flag on recentish macOS after command line tools + # no longer provide headers in /usr/include + if(CMAKE_OSX_SYSROOT) + string(APPEND EXTRA_FLAGS " -isysroot ${CMAKE_OSX_SYSROOT}") + endif() + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + string(APPEND EXTRA_FLAGS " -arch ${arch}") + endforeach() endif() # now set up the test: diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in index af9fa96..695c64f 100644 --- a/Tests/FindPackageModeMakefileTest/Makefile.in +++ b/Tests/FindPackageModeMakefileTest/Makefile.in @@ -5,7 +5,7 @@ CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@" CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@" CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@" CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@ -__EXTRA_OSX_SYSROOT_FLAGS = @__EXTRA_OSX_SYSROOT_FLAGS@ +EXTRA_FLAGS = @EXTRA_FLAGS@ CMAKE_FOO = $(CMAKE) --find-package -DCMAKE_MODULE_PATH=$(CMAKE_CURRENT_BINARY_DIR) -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=$(CMAKE_CXX_COMPILER_ID) @@ -16,7 +16,7 @@ all: pngtest main.o: clean main.cpp @$(CMAKE_FOO) -DMODE=COMPILE >$(tmp) @foo="`cat $(tmp)`"; \ - printf '"%s" %s %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$$foo" >$(tmp) + printf '"%s" %s %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(EXTRA_FLAGS)" "$$foo" >$(tmp) @cat $(tmp) @sh $(tmp) @rm -f $(tmp) @@ -24,7 +24,7 @@ main.o: clean main.cpp pngtest: main.o @$(CMAKE_FOO) -DMODE=LINK >$(tmp) @foo="`cat $(tmp)`"; \ - printf '"%s" %s %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp) + printf '"%s" %s %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(EXTRA_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp) @cat $(tmp) @sh $(tmp) @rm -f $(tmp) diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 7217f43..c25b2c3 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -24,7 +24,7 @@ find_package(VTK QUIET) add_executable(FindPackageTest FindPackageTest.cxx) -# test behaviour of cmFindBase wrt. the CMAKE_PREFIX_PATH variable +# test behavior of cmFindBase wrt. the CMAKE_PREFIX_PATH variable # foo.h should be found in ${CMAKE_CURRENT_SOURCE_DIR}/include: set(CMAKE_PREFIX_PATH /blub /blah "${CMAKE_CURRENT_SOURCE_DIR}") @@ -189,7 +189,9 @@ find_package(ArchD 4.0 EXACT NAMES zot) unset(CMAKE_LIBRARY_ARCHITECTURE) # Test find_package() with CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS enabled -if(UNIX) +if(UNIX + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) # Create ./symlink pointing back here. execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink . "${CMAKE_CURRENT_SOURCE_DIR}/symlink") diff --git a/Tests/FindProtobuf/CMakeLists.txt b/Tests/FindProtobuf/CMakeLists.txt index 1cdb2ae..b4ca29b 100644 --- a/Tests/FindProtobuf/CMakeLists.txt +++ b/Tests/FindProtobuf/CMakeLists.txt @@ -6,5 +6,6 @@ add_test(NAME FindProtobuf.Test COMMAND ${build_generator_args} --build-project TestFindProtobuf --build-options ${build_options} + "-DCMake_TEST_FindProtobuf_gRPC=${CMake_TEST_FindProtobuf_gRPC}" --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) diff --git a/Tests/FindProtobuf/Test/CMakeLists.txt b/Tests/FindProtobuf/Test/CMakeLists.txt index fc6b37e..84041ea 100644 --- a/Tests/FindProtobuf/Test/CMakeLists.txt +++ b/Tests/FindProtobuf/Test/CMakeLists.txt @@ -52,3 +52,16 @@ target_include_directories(test_desc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(test_desc msgs ${Protobuf_LIBRARIES}) target_compile_features(test_desc PRIVATE cxx_std_11) add_test(NAME test_desc COMMAND test_desc ${DESC_PROTO_DESC}) + +if(CMake_TEST_FindProtobuf_gRPC) + find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) + add_library(msgs_grpc msgs/example_service.proto) + target_include_directories(msgs_grpc PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(msgs_grpc PUBLIC ${Protobuf_LIBRARIES}) + protobuf_generate(TARGET msgs_grpc LANGUAGE cpp) + protobuf_generate(TARGET msgs_grpc LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}") + + add_executable(test_generate_grpc main-generate-grpc.cxx) + target_link_libraries(test_generate_grpc PRIVATE msgs_grpc) + add_test(NAME test_generate_grpc COMMAND test_generate_grpc) +endif() diff --git a/Tests/FindProtobuf/Test/main-generate-grpc.cxx b/Tests/FindProtobuf/Test/main-generate-grpc.cxx new file mode 100644 index 0000000..070c6b4 --- /dev/null +++ b/Tests/FindProtobuf/Test/main-generate-grpc.cxx @@ -0,0 +1,6 @@ +#include <msgs/example_service.grpc.pb.h> + +int main() +{ + return 0; +} diff --git a/Tests/FindProtobuf/Test/msgs/example_service.proto b/Tests/FindProtobuf/Test/msgs/example_service.proto new file mode 100644 index 0000000..f35eeb5 --- /dev/null +++ b/Tests/FindProtobuf/Test/msgs/example_service.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package example.msgs; + +import "google/protobuf/empty.proto"; + +service ExampleService { + rpc nothing(google.protobuf.Empty) returns (google.protobuf.Empty) {} +} diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt index 1868892..2fc47a5 100644 --- a/Tests/Fortran/CMakeLists.txt +++ b/Tests/Fortran/CMakeLists.txt @@ -46,7 +46,7 @@ function(test_fortran_c_interface_module) FortranCInterface_VERIFY() FortranCInterface_VERIFY(CXX) if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|PathScale|Absoft") + if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|PathScale|Absoft|Fujitsu") set(module_expected 1) endif() if(FortranCInterface_MODULE_FOUND OR module_expected) @@ -131,7 +131,7 @@ else() # as a language, cmake needs language specific versions # of these variables.... if(WIN32 AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU") - set(CMAKE_CREATE_CONSOLE_EXE ) + set(CMAKE_Fortran_CREATE_CONSOLE_EXE ) set(CMAKE_LIBRARY_PATH_FLAG "-L") set(CMAKE_LINK_LIBRARY_FLAG "-l") set(CMAKE_LINK_LIBRARY_SUFFIX ) diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt index b7a6f68..94f5939 100644 --- a/Tests/FortranModules/CMakeLists.txt +++ b/Tests/FortranModules/CMakeLists.txt @@ -1,6 +1,11 @@ cmake_minimum_required (VERSION 3.9) project(FortranModules Fortran) +if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "^Intel(LLVM)?;MSVC$") + string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Z7") + string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO " -Z7") +endif() + if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}") endif() diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index b5b5e56..ee47da4 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 2.8.12) project(FortranOnly Fortran) message("CTEST_FULL_OUTPUT ") +if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "^Intel(LLVM)?;MSVC$") + string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Z7") + string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO " -Z7") +endif() + # create a library with hello and world functions add_library(FortranOnlylib hello.f world.f) set_property(TARGET FortranOnlylib PROPERTY Fortran_FORMAT FIXED) @@ -117,15 +122,9 @@ if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") target_compile_definitions(IntelIfDef PRIVATE SOME_DEF) endif() -# Skip these tests if compiler/version doesn't have preprocessing flags -if((CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4) - OR (CMAKE_Fortran_COMPILER_ID STREQUAL "XL" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6)) - set(test_pp_flags 0) -else() - set(test_pp_flags 1) -endif() - -if(test_pp_flags) +# Skip these tests if compiler/version does enable and disable preprocessing +if(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON AND + CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF) # Test that we can always preprocess a target add_executable(preprocess_target preprocess2.f) set_property(TARGET preprocess_target PROPERTY Fortran_PREPROCESS ON) @@ -145,17 +144,22 @@ set_property(SOURCE no_preprocess_source_lower.f PROPERTY Fortran_PREPROCESS OFF # Test that we can explicitly not preprocess a target or source. # This will not work on certain compilers due to either missing a -# "don't preprocess" flag, or due to choice of file extension. -if(test_pp_flags AND NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|NVHPC|SunPro|XL)") +# "don't preprocess" flag, or due to the flags being ignored for +# extensions like '.F' and '.fpp'. +if(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF AND + NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|NVHPC|SunPro|XL)") add_library(no_preprocess_target STATIC no_preprocess_target_upper.F) target_compile_options(no_preprocess_target PRIVATE -DINTEGER=nonsense) + add_library(no_preprocess_source STATIC no_preprocess_source_upper.F) target_compile_options(no_preprocess_source PRIVATE -DINTEGER=nonsense) + if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "Cray" AND NOT "${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "Intel(LLVM)?;MSVC") target_sources(no_preprocess_target PRIVATE no_preprocess_target_fpp.fpp) target_sources(no_preprocess_source PRIVATE no_preprocess_source_fpp.fpp) endif() + set_property(TARGET no_preprocess_target PROPERTY Fortran_PREPROCESS OFF) set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF) endif() diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt index aabf6b4..287be94 100644 --- a/Tests/Framework/CMakeLists.txt +++ b/Tests/Framework/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(Framework) add_library(foo SHARED @@ -83,7 +83,7 @@ if(NOT XCODE OR NOT XCODE_VERSION VERSION_LESS 5) target_link_libraries(barStatic fooStatic) endif() -if(XCODE) +if(MAKE_SUPPORTS_SPACES AND NOT CMAKE_GENERATOR STREQUAL "Watcom WMake") add_library(space SHARED space.c) set_target_properties(space PROPERTIES FRAMEWORK TRUE diff --git a/Tests/FunctionTest/CMakeLists.txt b/Tests/FunctionTest/CMakeLists.txt index 68da972..6450447 100644 --- a/Tests/FunctionTest/CMakeLists.txt +++ b/Tests/FunctionTest/CMakeLists.txt @@ -1,5 +1,5 @@ # a simple C only test case -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (FunctionTest) function(FAILED testname) diff --git a/Tests/JCTest/CMakeLists.txt b/Tests/JCTest/CMakeLists.txt index 31dcc3a..b120640 100644 --- a/Tests/JCTest/CMakeLists.txt +++ b/Tests/JCTest/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(TestTime) enable_testing() add_executable(TestTime TestTime.cxx) diff --git a/Tests/Java/CMakeLists.txt b/Tests/Java/CMakeLists.txt index aea4282..1d8d7ac 100644 --- a/Tests/Java/CMakeLists.txt +++ b/Tests/Java/CMakeLists.txt @@ -1,6 +1,6 @@ project(hello Java) -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) set(CMAKE_VERBOSE_MAKEFILE 1) include(CTest) @@ -17,9 +17,16 @@ add_jar(hello2 @${CMAKE_CURRENT_BINARY_DIR}/java_fileslist) # use listing file to specify sources and specify output directory (issue #17316) add_jar(hello3 @${CMAKE_CURRENT_BINARY_DIR}/java_fileslist OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/hello3") +add_jar(ResourceNS + SOURCES ResourceNS.java + RESOURCES NAMESPACE ns/ns1 HelloWorld.txt + NAMESPACE ns/ns2 HelloWorld.txt) # add a second namespace + add_test (NAME Java.Jar COMMAND "${Java_JAVA_EXECUTABLE}" -classpath hello.jar HelloWorld) add_test (NAME Java.JarSourceList COMMAND "${Java_JAVA_EXECUTABLE}" -classpath hello2.jar HelloWorld) add_test (NAME Java.JarSourceListAndOutput COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${CMAKE_CURRENT_BINARY_DIR}/hello3/hello3.jar" HelloWorld) +add_test (NAME Java.JarResourceNS + COMMAND "${Java_JAVA_EXECUTABLE}" -classpath ResourceNS.jar ResourceNS) diff --git a/Tests/Java/HelloWorld.txt b/Tests/Java/HelloWorld.txt new file mode 100644 index 0000000..d7407a1 --- /dev/null +++ b/Tests/Java/HelloWorld.txt @@ -0,0 +1 @@ +Hello World ! diff --git a/Tests/Java/ResourceNS.java b/Tests/Java/ResourceNS.java new file mode 100644 index 0000000..7289e6e --- /dev/null +++ b/Tests/Java/ResourceNS.java @@ -0,0 +1,48 @@ +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; + +class ResourceNS +{ + public static void main(String args[]) + { + ResourceNS res = new ResourceNS(); + res.displayResourceText(); + } + + public void displayResourceText() + { + /* + * Since Java SE 9, invoking getResourceXXX on a class in a named + * module will only locate the resource in that module, it will + * not search the class path as it did in previous release. So when + * you use Class.getClassLoader().getResource() it will attempt to + * locate the resource in the module containing the ClassLoader, + * possibly something like: + * jdk.internal.loader.ClassLoaders.AppClassLoader + * which is probably not the module that your resource is in, so it + * returns null. + * + * You have to make java 9+ search for the file in your module. + * Do that by changing Class to any class defined in your module in + * order to make java use the proper class loader. + */ + + // Namespaces are relative, use leading '/' for full namespace + InputStream is = + ResourceNS.class.getResourceAsStream("/ns/ns1/HelloWorld.txt"); + // C++: cout << is.readline(); // oh, well ! + InputStreamReader isr = new InputStreamReader(is); + BufferedReader reader = new BufferedReader(isr); + String out = ""; + try{ + out = reader.readLine(); + } catch(IOException e) { + e.printStackTrace(); + System.out.println(e); + } + + System.out.println(out); + } +} diff --git a/Tests/JavaJavah/CMakeLists.txt b/Tests/JavaJavah/CMakeLists.txt index 77c292a..b56cc21 100644 --- a/Tests/JavaJavah/CMakeLists.txt +++ b/Tests/JavaJavah/CMakeLists.txt @@ -1,6 +1,6 @@ project(helloJavah Java CXX) -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) set(CMAKE_VERBOSE_MAKEFILE 1) include(CTest) diff --git a/Tests/JavaNativeHeaders/CMakeLists.txt b/Tests/JavaNativeHeaders/CMakeLists.txt index f3cc89d..2471e01 100644 --- a/Tests/JavaNativeHeaders/CMakeLists.txt +++ b/Tests/JavaNativeHeaders/CMakeLists.txt @@ -1,6 +1,6 @@ project(helloJavaNativeHeaders Java CXX) -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) set(CMAKE_VERBOSE_MAKEFILE 1) include (CTest) diff --git a/Tests/LibName/CMakeLists.txt b/Tests/LibName/CMakeLists.txt index 3ac125f..b8f0890 100644 --- a/Tests/LibName/CMakeLists.txt +++ b/Tests/LibName/CMakeLists.txt @@ -24,3 +24,11 @@ set_target_properties(verFoo PROPERTIES VERSION 3.1.4 SOVERSION 3) add_executable(verFoobar foobar.c) target_link_libraries(verFoobar verFoo) + +if(MAKE_SUPPORTS_SPACES AND NOT CMAKE_GENERATOR STREQUAL "Watcom WMake") + # check with lib version and space + add_library(ver_space SHARED ver_space.c) + set_target_properties(ver_space PROPERTIES VERSION 3.1.4 SOVERSION 3 OUTPUT_NAME "ver space") + add_executable(use_ver_space use_ver_space.c) + target_link_libraries(use_ver_space ver_space) +endif() diff --git a/Tests/LibName/use_ver_space.c b/Tests/LibName/use_ver_space.c new file mode 100644 index 0000000..a6a733d --- /dev/null +++ b/Tests/LibName/use_ver_space.c @@ -0,0 +1,9 @@ +#ifdef _WIN32 +__declspec(dllimport) +#endif + int ver_space(void); + +int main(void) +{ + return ver_space(); +} diff --git a/Tests/LibName/ver_space.c b/Tests/LibName/ver_space.c new file mode 100644 index 0000000..669a3b5 --- /dev/null +++ b/Tests/LibName/ver_space.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int ver_space(void) +{ + return 0; +} diff --git a/Tests/LoadCommand/CMakeCommands/CMakeLists.txt b/Tests/LoadCommand/CMakeCommands/CMakeLists.txt index 99b1aba..cafa99b 100644 --- a/Tests/LoadCommand/CMakeCommands/CMakeLists.txt +++ b/Tests/LoadCommand/CMakeCommands/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CMAKE_LOADED_COMMANDS) if (MUDSLIDE_TYPE MATCHES MUCHO) diff --git a/Tests/LoadCommand/CMakeLists.txt b/Tests/LoadCommand/CMakeLists.txt index cfaebad..e1c4998 100644 --- a/Tests/LoadCommand/CMakeLists.txt +++ b/Tests/LoadCommand/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(LoadCommand) # set a definition diff --git a/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt index 5ee2ed0..dc029a4 100644 --- a/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt +++ b/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(CMAKE_LOADED_COMMANDS) if (MUDSLIDE_TYPE MATCHES MUCHO) diff --git a/Tests/LoadCommandOneConfig/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeLists.txt index 65de042..fef4bb7 100644 --- a/Tests/LoadCommandOneConfig/CMakeLists.txt +++ b/Tests/LoadCommandOneConfig/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(LoadCommand) # set a definition diff --git a/Tests/MakeClean/CMakeLists.txt b/Tests/MakeClean/CMakeLists.txt index fbd4995..809d65b 100644 --- a/Tests/MakeClean/CMakeLists.txt +++ b/Tests/MakeClean/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(MakeClean) # Build the to-clean project. diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index 0cf74bf..e406758 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt @@ -52,7 +52,7 @@ endmacro() # detailed features tables, not just meta-features if (CMAKE_C_COMPILE_FEATURES) - if(NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM)$") + if (NOT CMAKE_C_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") set(C_expected_features ${CMAKE_C_COMPILE_FEATURES}) list(FILTER C_expected_features EXCLUDE REGEX "^c_std_[0-9][0-9]") endif() @@ -95,7 +95,7 @@ if (C_expected_features) endif() if (CMAKE_CXX_COMPILE_FEATURES) - if(NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM)$") + if (NOT CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|IntelLLVM|Fujitsu|FujitsuClang)$") set(CXX_expected_features ${CMAKE_CXX_COMPILE_FEATURES}) list(FILTER CXX_expected_features EXCLUDE REGEX "^cxx_std_[0-9][0-9]") endif() diff --git a/Tests/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt index e49ebea..567fb4b 100644 --- a/Tests/ModuleDefinition/CMakeLists.txt +++ b/Tests/ModuleDefinition/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(ModuleDefinition C) # Test .def file source recognition for DLLs. diff --git a/Tests/NewlineArgs/CMakeLists.txt b/Tests/NewlineArgs/CMakeLists.txt index 7551601..3e4b436 100644 --- a/Tests/NewlineArgs/CMakeLists.txt +++ b/Tests/NewlineArgs/CMakeLists.txt @@ -1,5 +1,5 @@ # a simple CXX only test case -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (NewlineArgs CXX) add_definitions("-DTEST_FLAG_1 diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt index 729bba3..ec22bf4 100644 --- a/Tests/Plugin/CMakeLists.txt +++ b/Tests/Plugin/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) cmake_policy(SET CMP0054 NEW) project(Plugin) @@ -46,7 +46,7 @@ target_link_libraries(example_mod_1 example_exe) if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND "${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG") # Verify that targets export with proper IMPORTED SONAME properties. - export(TARGETS example_mod_1 NAMESPACE exp_ + export(TARGETS example_mod_1 example_exe NAMESPACE exp_ FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake) include(ExternalProject) diff --git a/Tests/PositionIndependentTargets/interface/CMakeLists.txt b/Tests/PositionIndependentTargets/interface/CMakeLists.txt index 65f3b76..90186a3 100644 --- a/Tests/PositionIndependentTargets/interface/CMakeLists.txt +++ b/Tests/PositionIndependentTargets/interface/CMakeLists.txt @@ -12,6 +12,9 @@ set_property(TARGET sharedlib PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL) add_executable(test_iface_via_shared "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp") target_link_libraries(test_iface_via_shared sharedlib) +add_library(objectlib OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp") +target_link_libraries(objectlib piciface) + add_library(sharedlibpic SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp") set_property(TARGET sharedlibpic PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) set_property(TARGET sharedlibpic PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL) diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt index bf2af64..4347459 100644 --- a/Tests/Preprocess/CMakeLists.txt +++ b/Tests/Preprocess/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(Preprocess) # This test is meant both as a test and as a reference for supported diff --git a/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt b/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt new file mode 100644 index 0000000..1f636af --- /dev/null +++ b/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt @@ -0,0 +1,102 @@ +cmake_minimum_required(VERSION 3.17) +project(RerunUicOnFileChange) +include("../AutogenGuiTest.cmake") + +# Utility variables +set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/UicOnFileChange") +set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange") +set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange-build") + +set(TEST_CONFIG "Release") + +macro(sleep) + message(STATUS "Sleeping for a few seconds.") + execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) +endmacro() +macro(rebuild buildName) + message(STATUS "Starting build ${buildName}.") + execute_process(COMMAND "${CMAKE_COMMAND}" --build . --config "${TEST_CONFIG}" + WORKING_DIRECTORY "${testProjectBinDir}" RESULT_VARIABLE result + ) + if (result) + message(FATAL_ERROR "Build ${buildName} failed.") + else() + message(STATUS "Build ${buildName} finished.") + endif() +endmacro() + +configure_file("${testProjectTemplateDir}/mocwidget.h" "${testProjectSrc}/mocwidget.h" COPYONLY) +configure_file("${testProjectTemplateDir}/main.cpp" "${testProjectSrc}/main.cpp" COPYONLY) +configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY) + +set(Num 1) +configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY) + +if(CMAKE_GENERATOR_INSTANCE) + set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}") +else() + set(_D_CMAKE_GENERATOR_INSTANCE "") +endif() + +get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(is_multi) + set(build_type_extra "-DCMAKE_CONFIGURATION_TYPES=${TEST_CONFIG}") + set(extra_bin_path "${TEST_CONFIG}/") +else() + set(build_type_extra "-DCMAKE_BUILD_TYPE=${TEST_CONFIG}") +endif() + +# Set the environment PATH/LD_LIBRARY_PATH variables to run the resulting executable +if(WIN32 AND TARGET ${QT_QTCORE_TARGET}) + get_target_property(qtcore_path ${QT_QTCORE_TARGET} LOCATION) + if(NOT qtcore_path) + get_target_property(qtcore_path ${QT_QTCORE_TARGET} IMPORTED_LOCATION) + endif() + get_filename_component(qtcore_path "${qtcore_path}" DIRECTORY) + set(ENV{PATH} "${qtcore_path};$ENV{PATH}") +endif() + +execute_process( + COMMAND "${CMAKE_COMMAND}" -B "${testProjectBinDir}" -S "${testProjectSrc}" + -G "${CMAKE_GENERATOR}" + -A "${CMAKE_GENERATOR_PLATFORM}" + -T "${CMAKE_GENERATOR_TOOLSET}" + ${_D_CMAKE_GENERATOR_INSTANCE} + "${build_type_extra}" + "-DQT_TEST_VERSION=${QT_TEST_VERSION}" + "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}" + "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE output + ERROR_VARIABLE output +) +if(NOT exit_code EQUAL 0) + message(FATAL_ERROR "Initial configuration of UicOnFileChange failed. Output: ${output}") +endif() + +# Initial build +execute_process( + COMMAND "${CMAKE_COMMAND}" --build "${testProjectBinDir}" --config "${TEST_CONFIG}" + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE output + ERROR_VARIABLE output +) +if(NOT exit_code EQUAL 0) + message(FATAL_ERROR "Initial build of UicOnFileChange failed. Output: ${output}") +endif() + +execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result) +if(NOT result EQUAL "1") + message(FATAL_ERROR "Initial build of UicOnFileChange test result is: ${result}") +endif() + +sleep() + +set(Num 2) +configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY) +rebuild(2) + +execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result) +if(NOT result EQUAL "0") + message(FATAL_ERROR "Rebuild of UicOnFileChange test result is: ${result}") +endif() diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in new file mode 100644 index 0000000..fa9dd6b --- /dev/null +++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.10) + +project(UicOnFileChange) +include("@CMAKE_CURRENT_LIST_DIR@/../AutogenGuiTest.cmake") + +# Enable CMAKE_AUTOUIC for all targets +set(CMAKE_AUTOUIC ON) + +add_executable(UicOnFileChange main.cpp mainwindow.ui) +target_include_directories(UicOnFileChange PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(UicOnFileChange ${QT_QTCORE_TARGET} ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp new file mode 100644 index 0000000..fd810fa --- /dev/null +++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp @@ -0,0 +1,9 @@ +#include "ui_mainwindow.h" + +int main(int argc, char* argv[]) +{ + MocWidget mw; + Ui::Widget mwUi; + mwUi.setupUi(&mw); + return mw.objectName() == "Widget2" ? 0 : 1; +} diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in new file mode 100644 index 0000000..8f39e55 --- /dev/null +++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="MocWidget" name="Widget@Num@"/> + <resources/> + <connections/> +</ui> diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h new file mode 100644 index 0000000..87fc177 --- /dev/null +++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h @@ -0,0 +1,5 @@ +#include <QtCore/QObject> + +class MocWidget : public QObject +{ +}; diff --git a/Tests/QtAutogen/TestMacros.cmake b/Tests/QtAutogen/TestMacros.cmake index 1024996..9dcf31f 100644 --- a/Tests/QtAutogen/TestMacros.cmake +++ b/Tests/QtAutogen/TestMacros.cmake @@ -43,6 +43,7 @@ macro(ADD_AUTOGEN_TEST NAME) --build-options ${build_options} ${Autogen_BUILD_OPTIONS} ${_TestCommand} ) + set_tests_properties("${_QtXAutogen}.${NAME}" PROPERTIES LABELS "Qt${QT_TEST_VERSION}") list(APPEND TEST_BUILD_DIRS "${_BuildDir}") unset(_TestCommand) unset(_QtXAutogen) diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake index b1337d6..a3c57a5 100644 --- a/Tests/QtAutogen/Tests.cmake +++ b/Tests/QtAutogen/Tests.cmake @@ -24,6 +24,7 @@ ADD_AUTOGEN_TEST(RerunMocOnAddFile) ADD_AUTOGEN_TEST(RerunMocOnMissingDependency) ADD_AUTOGEN_TEST(RerunRccConfigChange) ADD_AUTOGEN_TEST(RerunRccDepends) +ADD_AUTOGEN_TEST(RerunUicOnFileChange) ADD_AUTOGEN_TEST(SameName sameName) ADD_AUTOGEN_TEST(StaticLibraryCycle slc) ADD_AUTOGEN_TEST(UicInclude uicInclude) @@ -35,7 +36,9 @@ ADD_AUTOGEN_TEST(UnityMocSource) if(QT_TEST_ALLOW_QT_MACROS) ADD_AUTOGEN_TEST(MocCMP0071) + set_property(TEST "Qt${QT_TEST_VERSION}Autogen.MocCMP0071" APPEND PROPERTY LABELS "policy") ADD_AUTOGEN_TEST(MocCMP0100) + set_property(TEST "Qt${QT_TEST_VERSION}Autogen.MocCMP0100" APPEND PROPERTY LABELS "policy") ADD_AUTOGEN_TEST(MocInclude) ADD_AUTOGEN_TEST(MocIncludeSymlink) ADD_AUTOGEN_TEST(MocSkipSource) @@ -46,6 +49,7 @@ if(QT_TEST_VERSION GREATER 4) ADD_AUTOGEN_TEST(MocMacroName mocMacroName) ADD_AUTOGEN_TEST(MocOsMacros) ADD_AUTOGEN_TEST(RerunMocPlugin) + ADD_AUTOGEN_TEST(WrappedFindPackage) if(APPLE) ADD_AUTOGEN_TEST(MacOsFW) endif() diff --git a/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt b/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt new file mode 100644 index 0000000..e8f50d5 --- /dev/null +++ b/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.20) +project(WrappedFindPackage) + +# Wrap the find_package call in a function. +# Test whether AutoMoc can retrieve the Qt version from the moc executable. +function(find_qt_package) + include("../AutogenCoreTest.cmake") + set(QT_LIBRARIES "${QT_LIBRARIES}" PARENT_SCOPE) +endfunction() + +find_qt_package() + +set(CMAKE_AUTOMOC ON) + +add_executable(wrappedFindPackage main.cpp) +target_link_libraries(wrappedFindPackage PRIVATE ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/WrappedFindPackage/main.cpp b/Tests/QtAutogen/WrappedFindPackage/main.cpp new file mode 100644 index 0000000..1e2c63f --- /dev/null +++ b/Tests/QtAutogen/WrappedFindPackage/main.cpp @@ -0,0 +1,19 @@ +#include <qobject.h> + +class MyObject : public QObject +{ + Q_OBJECT +public: + MyObject(QObject* parent = 0) + : QObject(parent) + { + } +}; + +int main() +{ + MyObject obj; + return 0; +} + +#include "main.moc" diff --git a/Tests/ReturnTest/CMakeLists.txt b/Tests/ReturnTest/CMakeLists.txt index c4c606c..78e3fc1 100644 --- a/Tests/ReturnTest/CMakeLists.txt +++ b/Tests/ReturnTest/CMakeLists.txt @@ -1,5 +1,5 @@ # a simple C only test case -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project (ReturnTest) function (FAILED testname) diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake index 01eac91..e4fdb4a 100644 --- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake +++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake @@ -3,15 +3,15 @@ enable_language(C) add_custom_command( OUTPUT topcc.c - DEPFILE topcc.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" + DEPFILE topcc_$<CONFIG>.c.d + COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc_$<CONFIG>.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" ) add_custom_target(topcc ALL DEPENDS topcc.c) add_custom_command( OUTPUT topexe.c - DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/topexe.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=topexe.c "-DINFILE=${CMAKE_CURRENT_BINARY_DIR}/topexedep.txt" -DDEPFILE=topexe.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" + DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/topexe_$<CONFIG>.c.d + COMMAND ${CMAKE_COMMAND} -DOUTFILE=topexe.c "-DINFILE=${CMAKE_CURRENT_BINARY_DIR}/topexedep.txt" -DDEPFILE=topexe_$<CONFIG>.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" ) add_executable(topexe "${CMAKE_CURRENT_BINARY_DIR}/topexe.c") diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake new file mode 100644 index 0000000..22e7f27 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake @@ -0,0 +1,19 @@ +enable_language(C) + +add_custom_command( + OUTPUT main.c + COMMAND ${CMAKE_COMMAND} -E copy main.c.in main.c + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/main.c.in + ) +add_executable(main main.c) +set_property(TARGET main PROPERTY UNITY_BUILD ON) + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c.in\" + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\" + ) +set(check_exes + \"$<TARGET_FILE:main>\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake new file mode 100644 index 0000000..87576eb --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[ +int main(void) { return 1; } +]]) diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake new file mode 100644 index 0000000..69b21b8 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[ +int main(void) { return 2; } +]]) diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 6232634..0a80580 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -1,5 +1,22 @@ include(RunCMake) +if(RunCMake_GENERATOR MATCHES "Ninja") + # Detect ninja version so we know what tests can be supported. + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" --version + OUTPUT_VARIABLE ninja_out + ERROR_VARIABLE ninja_out + RESULT_VARIABLE ninja_res + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+") + set(ninja_version "${ninja_out}") + message(STATUS "ninja version: ${ninja_version}") + else() + message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}") + endif() +endif() + if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR RunCMake_GENERATOR STREQUAL "Watcom WMake") set(fs_delay 3) @@ -155,7 +172,7 @@ if (RunCMake_GENERATOR MATCHES "Makefiles") run_cmake(CustomCommandDependencies-BadArgs) endif() -if(RunCMake_GENERATOR MATCHES "Make|Ninja") +if(RunCMake_GENERATOR MATCHES "Make|Ninja|Xcode") unset(run_BuildDepends_skip_step_3) run_BuildDepends(CustomCommandDepfile) set(run_BuildDepends_skip_step_3 1) @@ -164,3 +181,11 @@ endif() if(RunCMake_GENERATOR MATCHES "Make") run_BuildDepends(MakeDependencies) endif() + +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 " OR + (RunCMake_GENERATOR MATCHES "Ninja" AND ninja_version VERSION_LESS 1.7)) + # This build tool misses the dependency. + set(run_BuildDepends_skip_step_2 1) +endif() +run_BuildDepends(CustomCommandUnityBuild) +unset(run_BuildDepends_skip_step_2) diff --git a/Tests/RunCMake/BundleUtilities/CMP0080-COMMAND-OLD-stderr.txt b/Tests/RunCMake/BundleUtilities/CMP0080-COMMAND-OLD-stderr.txt new file mode 100644 index 0000000..31a0207 --- /dev/null +++ b/Tests/RunCMake/BundleUtilities/CMP0080-COMMAND-OLD-stderr.txt @@ -0,0 +1,9 @@ +^CMake Deprecation Warning at [^ +]*/Tests/RunCMake/BundleUtilities/CMP0080-COMMAND.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0080 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD.$ diff --git a/Tests/RunCMake/BundleUtilities/CMP0080-OLD-stderr.txt b/Tests/RunCMake/BundleUtilities/CMP0080-OLD-stderr.txt new file mode 100644 index 0000000..2ff5d60 --- /dev/null +++ b/Tests/RunCMake/BundleUtilities/CMP0080-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0080-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0080 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMP0041/RunCMakeTest.cmake b/Tests/RunCMake/CMP0041/RunCMakeTest.cmake index e7f27a1..f47bb2e 100644 --- a/Tests/RunCMake/CMP0041/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0041/RunCMakeTest.cmake @@ -6,6 +6,10 @@ set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/NotDefa run_cmake(CMP0041-OLD) run_cmake(CMP0041-NEW) run_cmake(CMP0041-WARN) + +# Protect tests from running inside the default install prefix. +set(RunCMake_TEST_OPTIONS "--install-prefix ${RunCMake_BINARY_DIR}/NotDefaultPrefix") + run_cmake(CMP0041-tid-OLD) run_cmake(CMP0041-tid-NEW) run_cmake(CMP0041-tid-WARN) diff --git a/Tests/RunCMake/CMP0081/CMP0081-OLD-result.txt b/Tests/RunCMake/CMP0081/CMP0081-OLD-result.txt deleted file mode 100644 index 573541a..0000000 --- a/Tests/RunCMake/CMP0081/CMP0081-OLD-result.txt +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/Tests/RunCMake/CMP0081/CMP0081-OLD-stderr.txt b/Tests/RunCMake/CMP0081/CMP0081-OLD-stderr.txt new file mode 100644 index 0000000..ff339fa --- /dev/null +++ b/Tests/RunCMake/CMP0081/CMP0081-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0081-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0081 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-Common.cmake new file mode 100644 index 0000000..5594be8 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-Common.cmake @@ -0,0 +1,8 @@ +set(listvar a b c d e) + +list(GET listvar + 18446744073709551616 # 2^64 + 2147483648 # 2^31 + 4294967296 # 2^32; errors out-of-range as -2147483643 due to underflow + out) +message("ERANGE: -->${out}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-stderr.txt new file mode 100644 index 0000000..0166e14 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-ERANGE-Common.cmake:3 \(list\): + list index: 18446744073709551616 is not a valid index +Call Stack \(most recent call first\): + CMP0121-ERANGE-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +ERANGE: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW.cmake new file mode 100644 index 0000000..68e564d --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-ERANGE-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-result.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt new file mode 100644 index 0000000..5a03559 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-ERANGE-Common.cmake:3 \(list\): + list index: (-2147483643|2147483647) out of range \(-5, 4\) +Call Stack \(most recent call first\): + CMP0121-ERANGE-OLD.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +ERANGE: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD.cmake new file mode 100644 index 0000000..32f0b56 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-ERANGE-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-result.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt new file mode 100644 index 0000000..1e7b127 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt @@ -0,0 +1,18 @@ +CMake Warning \(dev\) at CMP0121-ERANGE-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "18446744073709551616". +Call Stack \(most recent call first\): + CMP0121-ERANGE-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Error at CMP0121-ERANGE-Common.cmake:3 \(list\): + list index: (-2147483643|2147483647) out of range \(-5, 4\) +Call Stack \(most recent call first\): + CMP0121-ERANGE-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +ERANGE: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN.cmake new file mode 100644 index 0000000..9655290 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-ERANGE-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-GET-Common.cmake new file mode 100644 index 0000000..e4986f0 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-Common.cmake @@ -0,0 +1,4 @@ +set(listvar a b c d e) + +list(GET listvar 0 2junk out) +message("GET: -->${out}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-stderr.txt new file mode 100644 index 0000000..d502b86 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-GET-Common.cmake:3 \(list\): + list index: 2junk is not a valid index +Call Stack \(most recent call first\): + CMP0121-GET-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +GET: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW.cmake new file mode 100644 index 0000000..1ab054d --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-GET-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-GET-OLD-stderr.txt new file mode 100644 index 0000000..96375e9 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-OLD-stderr.txt @@ -0,0 +1 @@ +GET: -->a;c<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-GET-OLD.cmake new file mode 100644 index 0000000..ef4526f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-GET-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-GET-WARN-stderr.txt new file mode 100644 index 0000000..ecfad2c --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-WARN-stderr.txt @@ -0,0 +1,11 @@ +CMake Warning \(dev\) at CMP0121-GET-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "2junk". +Call Stack \(most recent call first\): + CMP0121-GET-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +GET: -->a;c<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-GET-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-GET-WARN.cmake new file mode 100644 index 0000000..b08620b --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-GET-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-GET-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-INSERT-Common.cmake new file mode 100644 index 0000000..4950881 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-Common.cmake @@ -0,0 +1,4 @@ +set(listvar a b c d e) + +list(INSERT listvar junk2 new) +message("INSERT: -->${listvar}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-stderr.txt new file mode 100644 index 0000000..2241962 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-INSERT-Common.cmake:3 \(list\): + list index: junk2 is not a valid index +Call Stack \(most recent call first\): + CMP0121-INSERT-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +INSERT: -->a;b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW.cmake new file mode 100644 index 0000000..db627d1 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-INSERT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD-stderr.txt new file mode 100644 index 0000000..52f34ad --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD-stderr.txt @@ -0,0 +1 @@ +INSERT: -->new;a;b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD.cmake new file mode 100644 index 0000000..60364d7 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-INSERT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN-stderr.txt new file mode 100644 index 0000000..5fa7d17 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN-stderr.txt @@ -0,0 +1,11 @@ +CMake Warning \(dev\) at CMP0121-INSERT-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "junk2". +Call Stack \(most recent call first\): + CMP0121-INSERT-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +INSERT: -->new;a;b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN.cmake new file mode 100644 index 0000000..55f13e2 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-INSERT-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-INSERT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-Common.cmake new file mode 100644 index 0000000..ec92387 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-Common.cmake @@ -0,0 +1,4 @@ +set(listvar a b c d e) + +list(REMOVE_AT listvar 0 invalid) +message("REMOVE_AT: -->${listvar}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-stderr.txt new file mode 100644 index 0000000..f17bafd --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-REMOVE_AT-Common.cmake:3 \(list\): + list index: invalid is not a valid index +Call Stack \(most recent call first\): + CMP0121-REMOVE_AT-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +REMOVE_AT: -->a;b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW.cmake new file mode 100644 index 0000000..d1f09e3 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-REMOVE_AT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD-stderr.txt new file mode 100644 index 0000000..09af1ae --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD-stderr.txt @@ -0,0 +1 @@ +REMOVE_AT: -->b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD.cmake new file mode 100644 index 0000000..ac83226 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-REMOVE_AT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN-stderr.txt new file mode 100644 index 0000000..e2d47af --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN-stderr.txt @@ -0,0 +1,11 @@ +CMake Warning \(dev\) at CMP0121-REMOVE_AT-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "invalid". +Call Stack \(most recent call first\): + CMP0121-REMOVE_AT-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +REMOVE_AT: -->b;c;d;e<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN.cmake new file mode 100644 index 0000000..2b4a824 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-REMOVE_AT-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-REMOVE_AT-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-Common.cmake new file mode 100644 index 0000000..93f46c5 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-Common.cmake @@ -0,0 +1,4 @@ +set(listvar a b c d e) + +list(SUBLIST listvar 0 invalid out) +message("SUBLIST-length: -->${out}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-stderr.txt new file mode 100644 index 0000000..28bd362 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-SUBLIST-length-Common.cmake:3 \(list\): + list index: invalid is not a valid index +Call Stack \(most recent call first\): + CMP0121-SUBLIST-length-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +SUBLIST-length: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW.cmake new file mode 100644 index 0000000..c7875cb --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-SUBLIST-length-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD-stderr.txt new file mode 100644 index 0000000..00fcf07 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD-stderr.txt @@ -0,0 +1 @@ +SUBLIST-length: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD.cmake new file mode 100644 index 0000000..e9b78ee --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-SUBLIST-length-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN-stderr.txt new file mode 100644 index 0000000..bd06c2f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN-stderr.txt @@ -0,0 +1,11 @@ +CMake Warning \(dev\) at CMP0121-SUBLIST-length-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "invalid". +Call Stack \(most recent call first\): + CMP0121-SUBLIST-length-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +SUBLIST-length: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN.cmake new file mode 100644 index 0000000..27318bf --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-length-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-SUBLIST-length-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-Common.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-Common.cmake new file mode 100644 index 0000000..33f57a3 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-Common.cmake @@ -0,0 +1,4 @@ +set(listvar a b c d e) + +list(SUBLIST listvar invalid 2 out) +message("SUBLIST-start: -->${out}<--") diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-result.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-stderr.txt new file mode 100644 index 0000000..9819f95 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at CMP0121-SUBLIST-start-Common.cmake:3 \(list\): + list index: invalid is not a valid index +Call Stack \(most recent call first\): + CMP0121-SUBLIST-start-NEW.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) + + +SUBLIST-start: --><-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW.cmake new file mode 100644 index 0000000..3d676a3 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 NEW) +include(CMP0121-SUBLIST-start-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD-stderr.txt new file mode 100644 index 0000000..8da2881 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD-stderr.txt @@ -0,0 +1 @@ +SUBLIST-start: -->a;b<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD.cmake new file mode 100644 index 0000000..268f317 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0121 OLD) +include(CMP0121-SUBLIST-start-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN-stderr.txt new file mode 100644 index 0000000..39d0e0e --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN-stderr.txt @@ -0,0 +1,11 @@ +CMake Warning \(dev\) at CMP0121-SUBLIST-start-Common.cmake:3 \(list\): + Policy CMP0121 is not set: The list\(\) command now validates parsing of + index arguments. Run "cmake --help-policy CMP0121" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + Invalid list index "invalid". +Call Stack \(most recent call first\): + CMP0121-SUBLIST-start-WARN.cmake:2 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +SUBLIST-start: -->a;b<-- diff --git a/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN.cmake b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN.cmake new file mode 100644 index 0000000..a407879 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMP0121-SUBLIST-start-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0121-SUBLIST-start-Common.cmake) diff --git a/Tests/RunCMake/CMP0121/CMakeLists.txt b/Tests/RunCMake/CMP0121/CMakeLists.txt new file mode 100644 index 0000000..7cabeb6 --- /dev/null +++ b/Tests/RunCMake/CMP0121/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.20) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0121/RunCMakeTest.cmake b/Tests/RunCMake/CMP0121/RunCMakeTest.cmake new file mode 100644 index 0000000..1ed5b1a --- /dev/null +++ b/Tests/RunCMake/CMP0121/RunCMakeTest.cmake @@ -0,0 +1,7 @@ +include(RunCMake) + +foreach (subcommand IN ITEMS ERANGE GET INSERT REMOVE_AT SUBLIST-length SUBLIST-start) + run_cmake(CMP0121-${subcommand}-WARN) + run_cmake(CMP0121-${subcommand}-OLD) + run_cmake(CMP0121-${subcommand}-NEW) +endforeach () diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_file-Common.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_file-Common.cmake new file mode 100644 index 0000000..a85978b --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_file-Common.cmake @@ -0,0 +1,51 @@ + +find_file(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_file(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_file(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "") +find_file(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH=${RELATIVE_PATH}") +message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}") + +message("ABSOLUTE_PATH=${ABSOLUTE_PATH}") +message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}") + +message("NOTFOUND_PATH=${NOTFOUND_PATH}") +message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}") + +message("FILE_NAME=${FILE_NAME}") +message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}") + + +set(RELATIVE_PATH_AND_LOCAL relative_local) +set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local) +set(ABSOLUTE_PATH_AND_LOCAL /absolute_local) +set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local) +set(NOTFOUND_AND_LOCAL "${FILE_NAME}") +set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}") + +find_file(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_file(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_file(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_file(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}") +message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}") + +message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}") +message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}") + +message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}") +message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}") diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW-stderr.txt new file mode 100644 index 0000000..10f95bc --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=/.+/CMP0125/file\.txt +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt +FILE_NAME=/.+/CMP0125/CMP0125-find_file-NEW-build/file2\.txt +FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_file-NEW-build/file2\.txt +RELATIVE_PATH_AND_LOCAL=relative_local +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute_local +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/file.txt +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW.cmake new file mode 100644 index 0000000..4f04834 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_file-NEW.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 NEW) + +include(CMP0125-find_file-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD-stderr.txt new file mode 100644 index 0000000..5b25f92 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=/.+/CMP0125/CMP0125-find_file-OLD-build/relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=NOTFOUND +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt +FILE_NAME=/.+/CMP0125/CMP0125-find_file-OLD-build/file2\.txt +FILE_NAME_WITH_TYPE=file2\.txt +RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_file-OLD-build/relative +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=NOTFOUND +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file\.txt diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD.cmake new file mode 100644 index 0000000..21884b5 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_file-OLD.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 OLD) + +include(CMP0125-find_file-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_library-Common.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_library-Common.cmake new file mode 100644 index 0000000..d2bc006 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_library-Common.cmake @@ -0,0 +1,52 @@ + +find_library(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_library(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_library(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "") +file(CHMOD "${CMAKE_BINARY_DIR}/${FILE_NAME}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) +find_library(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH=${RELATIVE_PATH}") +message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}") + +message("ABSOLUTE_PATH=${ABSOLUTE_PATH}") +message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}") + +message("NOTFOUND_PATH=${NOTFOUND_PATH}") +message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}") + +message("FILE_NAME=${FILE_NAME}") +message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}") + + +set(RELATIVE_PATH_AND_LOCAL relative_local) +set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local) +set(ABSOLUTE_PATH_AND_LOCAL /absolute_local) +set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local) +set(NOTFOUND_AND_LOCAL "${FILE_NAME}") +set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}") + +find_library(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_library(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_library(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_library(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}") +message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}") + +message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}") +message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}") + +message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}") +message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}") diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW-stderr.txt new file mode 100644 index 0000000..d180833 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=/.+/CMP0125/libfile\.(so|dylib) +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/libfile\.(so|dylib) +FILE_NAME=/.+/CMP0125/CMP0125-find_library-NEW-build/libfile2\.(so|dylib) +FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_library-NEW-build/libfile2\.(so|dylib) +RELATIVE_PATH_AND_LOCAL=relative_local +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute_local +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/libfile.(so|dylib) +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/libfile.(so|dylib) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW.cmake new file mode 100644 index 0000000..31f5441 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_library-NEW.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0125 NEW) + +enable_language(C) + +include(CMP0125-find_library-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD-stderr.txt new file mode 100644 index 0000000..cd3af56 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=/.+/CMP0125/CMP0125-find_library-OLD-build/relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=NOTFOUND +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/libfile\.(so|dylib) +FILE_NAME=/.+/CMP0125/CMP0125-find_library-OLD-build/libfile2\.(so|dylib) +FILE_NAME_WITH_TYPE=libfile2\.(so|dylib) +RELATIVE_PATH_AND_LOCAL=relative_local +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute_local +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/libfile\.(so|dylib) +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/libfile\.(so|dylib) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD.cmake new file mode 100644 index 0000000..1dc4a95 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_library-OLD.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0125 OLD) + +enable_language(C) + +include(CMP0125-find_library-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_path-Common.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_path-Common.cmake new file mode 100644 index 0000000..37680c2 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_path-Common.cmake @@ -0,0 +1,51 @@ + +find_path(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_path(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_path(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "") +find_path(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH=${RELATIVE_PATH}") +message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}") + +message("ABSOLUTE_PATH=${ABSOLUTE_PATH}") +message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}") + +message("NOTFOUND_PATH=${NOTFOUND_PATH}") +message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}") + +message("FILE_NAME=${FILE_NAME}") +message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}") + + +set(RELATIVE_PATH_AND_LOCAL relative_local) +set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local) +set(ABSOLUTE_PATH_AND_LOCAL /absolute_local) +set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local) +set(NOTFOUND_AND_LOCAL "${FILE_NAME}") +set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}") + +find_path(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_path(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_path(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_path(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}") +message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}") + +message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}") +message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}") + +message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}") +message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}") diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW-stderr.txt new file mode 100644 index 0000000..c3f0208 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=/.+/CMP0125 +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125 +FILE_NAME=/.+/CMP0125/CMP0125-find_path-NEW-build/file2\.txt +FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_path-NEW-build/file2\.txt +RELATIVE_PATH_AND_LOCAL=relative_local +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute_local +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125 +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125 diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW.cmake new file mode 100644 index 0000000..d6a8544 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_path-NEW.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 NEW) + +include(CMP0125-find_path-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD-stderr.txt new file mode 100644 index 0000000..b84c869 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=/.+/CMP0125/CMP0125-find_path-OLD-build/relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=NOTFOUND +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125 +FILE_NAME=/.+/CMP0125/CMP0125-find_path-OLD-build/file2\.txt +FILE_NAME_WITH_TYPE=file2\.txt +RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_path-OLD-build/relative +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=NOTFOUND +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125 diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD.cmake new file mode 100644 index 0000000..2e98ded --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_path-OLD.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 OLD) + +include(CMP0125-find_path-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_program-Common.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_program-Common.cmake new file mode 100644 index 0000000..fee4c34 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_program-Common.cmake @@ -0,0 +1,52 @@ + +find_program(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_program(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_program(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "") +file(CHMOD "${CMAKE_BINARY_DIR}/${FILE_NAME}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) +find_program(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH=${RELATIVE_PATH}") +message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}") + +message("ABSOLUTE_PATH=${ABSOLUTE_PATH}") +message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}") + +message("NOTFOUND_PATH=${NOTFOUND_PATH}") +message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}") + +message("FILE_NAME=${FILE_NAME}") +message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}") + + +set(RELATIVE_PATH_AND_LOCAL relative_local) +set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local) +set(ABSOLUTE_PATH_AND_LOCAL /absolute_local) +set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local) +set(NOTFOUND_AND_LOCAL "${FILE_NAME}") +set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}") + +find_program(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_program(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +find_program(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) +find_program(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH}) + +message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}") +message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}") + +message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}") +message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}") + +message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}") +message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}") diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW-stderr.txt new file mode 100644 index 0000000..62da5bf --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=/.+/CMP0125/file\.txt +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt +FILE_NAME=/.+/CMP0125/CMP0125-find_program-NEW-build/file2\.txt +FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_program-NEW-build/file2\.txt +RELATIVE_PATH_AND_LOCAL=relative_local +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute_local +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/file.txt +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW.cmake new file mode 100644 index 0000000..c02f23b --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_program-NEW.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 NEW) + +include(CMP0125-find_program-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD-stderr.txt b/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD-stderr.txt new file mode 100644 index 0000000..a97fc07 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD-stderr.txt @@ -0,0 +1,14 @@ +RELATIVE_PATH=/.+/CMP0125/CMP0125-find_program-OLD-build/relative +RELATIVE_PATH_WITH_TYPE=relative +ABSOLUTE_PATH=/absolute +ABSOLUTE_PATH_WITH_TYPE=/absolute +NOTFOUND_PATH=NOTFOUND +NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt +FILE_NAME=/.+/CMP0125/CMP0125-find_program-OLD-build/file2\.txt +FILE_NAME_WITH_TYPE=file2\.txt +RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_program-OLD-build/relative +RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local +ABSOLUTE_PATH_AND_LOCAL=/absolute +ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local +NOTFOUND_PATH_AND_LOCAL=NOTFOUND +NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt diff --git a/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD.cmake b/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD.cmake new file mode 100644 index 0000000..6be8534 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMP0125-find_program-OLD.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0125 OLD) + +include(CMP0125-find_program-Common.cmake) diff --git a/Tests/RunCMake/CMP0125/CMakeLists.txt b/Tests/RunCMake/CMP0125/CMakeLists.txt new file mode 100644 index 0000000..7cabeb6 --- /dev/null +++ b/Tests/RunCMake/CMP0125/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.20) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0125/RunCMakeTest.cmake b/Tests/RunCMake/CMP0125/RunCMakeTest.cmake new file mode 100644 index 0000000..56d4c86 --- /dev/null +++ b/Tests/RunCMake/CMP0125/RunCMakeTest.cmake @@ -0,0 +1,36 @@ +include(RunCMake) + +file(WRITE "${RunCMake_BINARY_DIR}/file.txt" "") +file(CHMOD "${RunCMake_BINARY_DIR}/file.txt" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) + +set(options -DRELATIVE_PATH=relative -DABSOLUTE_PATH=/absolute + -DRELATIVE_PATH_WITH_TYPE:PATH=relative -DABSOLUTE_PATH_WITH_TYPE:PATH=/absolute + -DNOTFOUND_PATH=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE:PATH=NOTFOUND + -DFILE_NAME=file2.txt -DFILE_NAME_WITH_TYPE:PATH=file2.txt + -DSEARCH_NAME=file.txt "-DSEARCH_PATH=${RunCMake_BINARY_DIR}" + -DRELATIVE_PATH_AND_LOCAL=relative -DABSOLUTE_PATH_AND_LOCAL=/absolute + -DRELATIVE_PATH_WITH_TYPE_AND_LOCAL:PATH=relative -DABSOLUTE_PATH_WITH_TYPE_AND_LOCAL:PATH=/absolute + -DNOTFOUND_PATH_AND_LOCAL=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE_AND_LOCAL:PATH=NOTFOUND + -DFILE_NAME=file2.txt -DFILE_NAME_WITH_TYPE:PATH=file2.txt + -DSEARCH_NAME=file.txt "-DSEARCH_PATH=${RunCMake_BINARY_DIR}") + +run_cmake_with_options(CMP0125-find_file-OLD ${options}) +run_cmake_with_options(CMP0125-find_file-NEW ${options}) +run_cmake_with_options(CMP0125-find_path-OLD ${options}) +run_cmake_with_options(CMP0125-find_path-NEW ${options}) +run_cmake_with_options(CMP0125-find_program-OLD ${options}) +run_cmake_with_options(CMP0125-find_program-NEW ${options}) + + +file(WRITE "${RunCMake_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}file${CMAKE_SHARED_LIBRARY_SUFFIX}" "") +file(CHMOD "${RunCMake_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}file${CMAKE_SHARED_LIBRARY_SUFFIX}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) + +set(options -DRELATIVE_PATH=relative -DABSOLUTE_PATH=/absolute + -DRELATIVE_PATH_WITH_TYPE:PATH=relative -DABSOLUTE_PATH_WITH_TYPE:PATH=/absolute + -DNOTFOUND_PATH=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE:PATH=NOTFOUND + -DFILE_NAME=${CMAKE_SHARED_LIBRARY_PREFIX}file2${CMAKE_SHARED_LIBRARY_SUFFIX} + -DFILE_NAME_WITH_TYPE:PATH=${CMAKE_SHARED_LIBRARY_PREFIX}file2${CMAKE_SHARED_LIBRARY_SUFFIX} + -DSEARCH_NAME=file "-DSEARCH_PATH=${RunCMake_BINARY_DIR}") + +run_cmake_with_options(CMP0125-find_library-OLD ${options}) +run_cmake_with_options(CMP0125-find_library-NEW ${options}) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 78e0b6a..afaeaef 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -29,6 +29,10 @@ macro(add_RunCMake_test test) ${TEST_ARGS} -P "${CMAKE_CURRENT_SOURCE_DIR}/${Test_Dir}/RunCMakeTest.cmake" ) + set_tests_properties("RunCMake.${test}" PROPERTIES LABELS "CMake;run") + if(${test} MATCHES ^CMP) + set_property(TEST "RunCMake.${test}" APPEND PROPERTY LABELS "policy") + endif() endmacro() function(add_RunCMake_test_group test types) @@ -131,6 +135,11 @@ if(CMAKE_GENERATOR MATCHES "Ninja") endif() add_RunCMake_test(CMP0118) add_RunCMake_test(CMP0119 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) +add_RunCMake_test(CMP0121) +if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)") + add_RunCMake_test(CMP0125 -DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX} + -DCMAKE_SHARED_LIBRARY_SUFFIX=${CMAKE_SHARED_LIBRARY_SUFFIX}) +endif() # The test for Policy 65 requires the use of the # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode @@ -160,7 +169,7 @@ if(CMAKE_GENERATOR MATCHES "Ninja") endif() add_RunCMake_test(Ninja) set(NinjaMultiConfig_ARGS - -DCYGWIN=${CYGWIN} + -DCYGWIN=${CYGWIN} -DMSYS=${MSYS} ) if(CMake_TEST_Qt5 AND Qt5Core_FOUND) list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1 -DQt5Core_DIR=${Qt5Core_DIR} -DCMAKE_TEST_Qt5Core_Version=${Qt5Core_VERSION}) @@ -262,6 +271,7 @@ add_RunCMake_test(GenEx-HOST_LINK) add_RunCMake_test(GenEx-DEVICE_LINK) add_RunCMake_test(GenEx-TARGET_FILE -DLINKER_SUPPORTS_PDB=${LINKER_SUPPORTS_PDB}) add_RunCMake_test(GenEx-GENEX_EVAL) +add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS) add_RunCMake_test(GeneratorExpression) add_RunCMake_test(GeneratorInstance) add_RunCMake_test(GeneratorPlatform) @@ -276,7 +286,7 @@ add_RunCMake_test(Graphviz) add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) add_RunCMake_test(LinkStatic) -if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang)$") +if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|NVHPC|XL|XLClang|Fujitsu|FujitsuClang)$") add_RunCMake_test(MetaCompileFeatures) endif() if(MSVC) @@ -340,7 +350,7 @@ add_RunCMake_test(export) add_RunCMake_test(cmake_language) add_RunCMake_test(cmake_minimum_required) add_RunCMake_test(cmake_parse_arguments) -add_RunCMake_test(cmake_path) +add_RunCMake_test(cmake_path -DMSYS=${MSYS}) add_RunCMake_test(continue) add_executable(color_warning color_warning.c) add_executable(fake_build_command fake_build_command.c) @@ -355,20 +365,22 @@ if(COVERAGE_COMMAND) endif() add_RunCMake_test(ctest_start) add_RunCMake_test(ctest_submit) -add_RunCMake_test(ctest_test) +add_RunCMake_test(ctest_test + -DIMAGE_DIR=${CMAKE_SOURCE_DIR}/Utilities/Sphinx/static +) add_RunCMake_test(ctest_disabled_test) add_RunCMake_test(ctest_skipped_test) add_RunCMake_test(ctest_update) add_RunCMake_test(ctest_upload) add_RunCMake_test(ctest_fixtures) -add_RunCMake_test(file) -add_RunCMake_test(file-CHMOD) +add_RunCMake_test(file -DMSYS=${MSYS}) +add_RunCMake_test(file-CHMOD -DMSYS=${MSYS}) if(HAVE_ELF_H OR CMAKE_SYSTEM_NAME STREQUAL "AIX") add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DHAVE_ELF_H=${HAVE_ELF_H}) endif() add_RunCMake_test(find_file) -add_RunCMake_test(find_library -DCYGWIN=${CYGWIN}) -add_RunCMake_test(find_package) +add_RunCMake_test(find_library -DCYGWIN=${CYGWIN} -DMSYS=${MSYS}) +add_RunCMake_test(find_package -DMSYS=${MSYS}) add_RunCMake_test(find_path) add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}) add_RunCMake_test(foreach) @@ -420,6 +432,15 @@ function(add_RunCMake_test_try_compile) set(CMAKE_C_STANDARD_DEFAULT "") endif() endif() + if(CMAKE_VERSION VERSION_LESS 3.20.20210225 AND "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang") + # Older CMake versions do not know about Clang MSVC compatibility mode + # standards. Approximate the logic from Clang-C.cmake. + if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + set(CMAKE_C_STANDARD_DEFAULT 17) + elseif(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.5.2) + set(CMAKE_C_STANDARD_DEFAULT 11) + endif() + endif() foreach(var CMAKE_SYSTEM_NAME CMAKE_C_COMPILER_ID @@ -497,7 +518,9 @@ else() message(STATUS "Could not find ctresalloc") endif() -if(NOT WIN32) +if(NOT WIN32 + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) add_RunCMake_test(SymlinkTrees) endif () @@ -539,7 +562,7 @@ endif() if(XCODE_VERSION) add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION}) - add_RunCMake_test(XcodeProject-Embed) + add_RunCMake_test(XcodeProject-Embed -DXCODE_VERSION=${XCODE_VERSION}) # This test can take a very long time due to lots of combinations. # Use a long default timeout and provide an option to customize it. @@ -601,7 +624,8 @@ endif() add_executable(pseudo_llvm-rc pseudo_llvm-rc.c) -add_RunCMake_test(CommandLine -DLLVM_RC=$<TARGET_FILE:pseudo_llvm-rc> -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) +add_RunCMake_test(CommandLine -DLLVM_RC=$<TARGET_FILE:pseudo_llvm-rc> -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} + -DCYGWIN=${CYGWIN} -DMSYS=${MSYS} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) add_RunCMake_test(CommandLineTar) if(CMAKE_PLATFORM_NO_VERSIONED_SONAME OR (NOT CMAKE_SHARED_LIBRARY_SONAME_FLAG AND NOT CMAKE_SHARED_LIBRARY_SONAME_C_FLAG)) @@ -610,7 +634,7 @@ else() set(NO_NAMELINK 0) endif() -add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN} +add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN} -DMSYS=${MSYS} -DCMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN=${CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG=${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG} diff --git a/Tests/RunCMake/CMakePresets/ConditionFuture-result.txt b/Tests/RunCMake/CMakePresets/ConditionFuture-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ConditionFuture-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt b/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt new file mode 100644 index 0000000..ea5f47f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ConditionFuture-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ConditionFuture: File version must be 3 or higher for condition support$ diff --git a/Tests/RunCMake/CMakePresets/ConditionFuture.json.in b/Tests/RunCMake/CMakePresets/ConditionFuture.json.in new file mode 100644 index 0000000..9d4798b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ConditionFuture.json.in @@ -0,0 +1,11 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "ConditionFuture", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "condition": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/Conditions.json.in b/Tests/RunCMake/CMakePresets/Conditions.json.in new file mode 100644 index 0000000..9c0c6bd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Conditions.json.in @@ -0,0 +1,406 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "Base", + "hidden": true, + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "SimpleTrue", + "inherits": "Base", + "condition": true + }, + { + "name": "SimpleFalse", + "inherits": "Base", + "condition": false + }, + { + "name": "Null", + "inherits": "Base", + "condition": null + }, + { + "name": "ConstTrue", + "inherits": "Base", + "condition": { + "type": "const", + "value": true + } + }, + { + "name": "ConstFalse", + "inherits": "Base", + "condition": { + "type": "const", + "value": false + } + }, + { + "name": "EqualsTrue", + "inherits": "Base", + "condition": { + "type": "equals", + "lhs": "abc", + "rhs": "abc" + } + }, + { + "name": "EqualsFalse", + "inherits": "Base", + "condition": { + "type": "equals", + "lhs": "abc", + "rhs": "abcd" + } + }, + { + "name": "EqualsMacroLeft", + "inherits": "Base", + "condition": { + "type": "equals", + "lhs": "${presetName}", + "rhs": "EqualsMacroLeft" + } + }, + { + "name": "EqualsMacroRight", + "inherits": "Base", + "condition": { + "type": "equals", + "lhs": "EqualsMacroRight", + "rhs": "${presetName}" + } + }, + { + "name": "NotEqualsTrue", + "inherits": "Base", + "condition": { + "type": "notEquals", + "lhs": "abc", + "rhs": "abcd" + } + }, + { + "name": "NotEqualsFalse", + "inherits": "Base", + "condition": { + "type": "notEquals", + "lhs": "abc", + "rhs": "abc" + } + }, + { + "name": "InListTrue", + "inherits": "Base", + "condition": { + "type": "inList", + "string": "b", + "list": [ + "a", + "b", + "c" + ] + } + }, + { + "name": "InListFalse", + "inherits": "Base", + "condition": { + "type": "inList", + "string": "d", + "list": [ + "a", + "b", + "c" + ] + } + }, + { + "name": "InListMacroString", + "inherits": "Base", + "condition": { + "type": "inList", + "string": "${presetName}", + "list": [ + "InListMacroString", + "AnotherString" + ] + } + }, + { + "name": "InListMacroList", + "inherits": "Base", + "condition": { + "type": "inList", + "string": "InListMacroList", + "list": [ + "${presetName}", + "AnotherString" + ] + } + }, + { + "name": "InListShortCircuit", + "inherits": "Base", + "condition": { + "type": "inList", + "string": "a", + "list": [ + "a", + "${invalidMacro}" + ] + } + }, + { + "name": "NotInListTrue", + "inherits": "Base", + "condition": { + "type": "notInList", + "string": "d", + "list": [ + "a", + "b", + "c" + ] + } + }, + { + "name": "NotInListFalse", + "inherits": "Base", + "condition": { + "type": "notInList", + "string": "a", + "list": [ + "a", + "b", + "c" + ] + } + }, + { + "name": "MatchesTrue", + "inherits": "Base", + "condition": { + "type": "matches", + "string": "aaa", + "regex": "^a*$" + } + }, + { + "name": "MatchesFalse", + "inherits": "Base", + "condition": { + "type": "matches", + "string": "aab", + "regex": "^a*$" + } + }, + { + "name": "MatchesMacroString", + "inherits": "Base", + "condition": { + "type": "matches", + "string": "${presetName}", + "regex": "^Matches" + } + }, + { + "name": "MatchesMacroRegex", + "inherits": "Base", + "condition": { + "type": "matches", + "string": "stuff", + "regex": "$env{CONDITION_REGEX}" + }, + "environment": { + "CONDITION_REGEX": "^stuf*$" + } + }, + { + "name": "NotMatchesTrue", + "inherits": "Base", + "condition": { + "type": "notMatches", + "string": "aab", + "regex": "^a*$" + } + }, + { + "name": "NotMatchesFalse", + "inherits": "Base", + "condition": { + "type": "notMatches", + "string": "aaa", + "regex": "^a*$" + } + }, + { + "name": "AnyOfTrue1", + "inherits": "Base", + "condition": { + "type": "anyOf", + "conditions": [ + true, + false + ] + } + }, + { + "name": "AnyOfTrue2", + "inherits": "Base", + "condition": { + "type": "anyOf", + "conditions": [ + false, + true + ] + } + }, + { + "name": "AnyOfFalse", + "inherits": "Base", + "condition": { + "type": "anyOf", + "conditions": [ + false, + { + "type": "equals", + "lhs": "abc", + "rhs": "abcd" + } + ] + } + }, + { + "name": "AnyOfShortCircuit", + "inherits": "Base", + "condition": { + "type": "anyOf", + "conditions": [ + true, + { + "type": "equals", + "lhs": "${invalidMacro}", + "rhs": "" + } + ] + } + }, + { + "name": "AnyOfEmpty", + "inherits": "Base", + "condition": { + "type": "anyOf", + "conditions": [] + } + }, + { + "name": "AllOfTrue", + "inherits": "Base", + "condition": { + "type": "allOf", + "conditions": [ + true, + { + "type": "equals", + "lhs": "abc", + "rhs": "abc" + } + ] + } + }, + { + "name": "AllOfFalse1", + "inherits": "Base", + "condition": { + "type": "allOf", + "conditions": [ + false, + true + ] + } + }, + { + "name": "AllOfFalse2", + "inherits": "Base", + "condition": { + "type": "allOf", + "conditions": [ + true, + false + ] + } + }, + { + "name": "AllOfShortCircuit", + "inherits": "Base", + "condition": { + "type": "allOf", + "conditions": [ + false, + { + "type": "equals", + "lhs": "${invalidMacro}", + "rhs": "" + } + ] + } + }, + { + "name": "AllOfEmpty", + "inherits": "Base", + "condition": { + "type": "allOf", + "conditions": [] + } + }, + { + "name": "NotTrue", + "inherits": "Base", + "condition": { + "type": "not", + "condition": true + } + }, + { + "name": "NotFalse", + "inherits": "Base", + "condition": { + "type": "not", + "condition": false + } + }, + { + "name": "InheritanceBase", + "inherits": "Base", + "hidden": true, + "condition": { + "type": "equals", + "lhs": "${presetName}", + "rhs": "InheritanceChildTrue" + } + }, + { + "name": "InheritanceChildTrue", + "inherits": "InheritanceBase" + }, + { + "name": "InheritanceChildFalse", + "inherits": "InheritanceBase" + }, + { + "name": "InheritanceNull", + "inherits": "Null" + }, + { + "name": "InheritanceNullFalse", + "inherits": [ + "Null", + "SimpleFalse" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-result.txt b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt new file mode 100644 index 0000000..36123bd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField: File version must be 3 or higher for installDir preset support.$ diff --git a/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField.json.in b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField.json.in new file mode 100644 index 0000000..2e5f7d5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetInstallDirField.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "FuturePresetInstallDirField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "installDir": "${sourceDir}/install" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt new file mode 100644 index 0000000..9382423 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/FuturePresetToolchainField: File version must be 3 or higher for toolchainFile preset support.$ diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in new file mode 100644 index 0000000..646ee0f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "FuturePresetToolchainField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "toolchainFile": "${sourceDir}/toolchain.cmake" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodInstall.json.in b/Tests/RunCMake/CMakePresets/GoodInstall.json.in new file mode 100644 index 0000000..6287c65 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInstall.json.in @@ -0,0 +1,30 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "GoodInstallDefault", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/${presetName}", + "installDir": "${sourceDir}/build/install_dir1" + }, + { + "name": "GoodInstallInherit", + "inherits": "GoodInstallDefault", + "cacheVariables": { + "CMAKE_INSTALL_PREFIX": { + "type": "PATH", + "value": "${sourceDir}/build/bad_path" + } + } + }, + { + "name": "GoodInstallOverride", + "inherits": "GoodInstallInherit", + "installDir": "${sourceDir}/build/install_dir2" + }, + { + "name": "GoodInstallCommandLine", + "inherits": "GoodInstallOverride" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodInstallCommandLine.cmake b/Tests/RunCMake/CMakePresets/GoodInstallCommandLine.cmake new file mode 100644 index 0000000..a4f6178 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInstallCommandLine.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_INSTALL_PREFIX" "PATH" "${RunCMake_SOURCE_DIR}/path/passed/on/command_line") diff --git a/Tests/RunCMake/CMakePresets/GoodInstallDefault.cmake b/Tests/RunCMake/CMakePresets/GoodInstallDefault.cmake new file mode 100644 index 0000000..656fda0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInstallDefault.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_INSTALL_PREFIX" "PATH" "${CMAKE_SOURCE_DIR}/build/install_dir1") diff --git a/Tests/RunCMake/CMakePresets/GoodInstallInherit.cmake b/Tests/RunCMake/CMakePresets/GoodInstallInherit.cmake new file mode 100644 index 0000000..656fda0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInstallInherit.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_INSTALL_PREFIX" "PATH" "${CMAKE_SOURCE_DIR}/build/install_dir1") diff --git a/Tests/RunCMake/CMakePresets/GoodInstallOverride.cmake b/Tests/RunCMake/CMakePresets/GoodInstallOverride.cmake new file mode 100644 index 0000000..3d12b07 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInstallOverride.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_INSTALL_PREFIX" "PATH" "${CMAKE_SOURCE_DIR}/build/install_dir2") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchain.json.in b/Tests/RunCMake/CMakePresets/GoodToolchain.json.in new file mode 100644 index 0000000..69dafcf --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchain.json.in @@ -0,0 +1,30 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "GoodToolchainDefault", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/${presetName}", + "toolchainFile": "${sourceDir}/toolchain.cmake" + }, + { + "name": "GoodToolchainInherit", + "inherits": "GoodToolchainDefault", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/toolchain_bad.cmake" + } + } + }, + { + "name": "GoodToolchainOverride", + "inherits": "GoodToolchainInherit", + "toolchainFile": "override_toolchain.cmake" + }, + { + "name": "GoodToolchainCommandLine", + "inherits": "GoodToolchainOverride" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake new file mode 100644 index 0000000..c37421c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/cmd_line_toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake new file mode 100644 index 0000000..53c938b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake new file mode 100644 index 0000000..53c938b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake new file mode 100644 index 0000000..558134c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/override_toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/HostSystemName.cmake b/Tests/RunCMake/CMakePresets/HostSystemName.cmake new file mode 100644 index 0000000..dc0998a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HostSystemName.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(TEST_HOST_SYSTEM_NAME "" "${CMAKE_HOST_SYSTEM_NAME}") diff --git a/Tests/RunCMake/CMakePresets/HostSystemName.json.in b/Tests/RunCMake/CMakePresets/HostSystemName.json.in new file mode 100644 index 0000000..7fcd8c8 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HostSystemName.json.in @@ -0,0 +1,13 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "HostSystemName", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "TEST_HOST_SYSTEM_NAME": "${hostSystemName}" + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/HostSystemNameFuture-result.txt b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt new file mode 100644 index 0000000..7f4bb9a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HostSystemNameFuture-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/HostSystemNameFuture: Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/HostSystemNameFuture.json.in b/Tests/RunCMake/CMakePresets/HostSystemNameFuture.json.in new file mode 100644 index 0000000..7a2f0aa --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HostSystemNameFuture.json.in @@ -0,0 +1,13 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "HostSystemNameFuture", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "TEST_HOST_SYSTEM_NAME": "${hostSystemName}" + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt b/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt new file mode 100644 index 0000000..5b500e4 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidRegex: Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex.json.in b/Tests/RunCMake/CMakePresets/InvalidRegex.json.in new file mode 100644 index 0000000..69114d2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRegex.json.in @@ -0,0 +1,15 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "InvalidRegex", + "binaryDir": "${sourceDir}/build", + "generator": "@RunCMake_GENERATOR@", + "condition": { + "type": "matches", + "string": "a", + "regex": "+" + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt b/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt new file mode 100644 index 0000000..91e0017 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt @@ -0,0 +1,26 @@ +Available configure presets: + + "SimpleTrue" + "Null" + "ConstTrue" + "EqualsTrue" + "EqualsMacroLeft" + "EqualsMacroRight" + "NotEqualsTrue" + "InListTrue" + "InListMacroString" + "InListMacroList" + "InListShortCircuit" + "NotInListTrue" + "MatchesTrue" + "MatchesMacroString" + "MatchesMacroRegex" + "NotMatchesTrue" + "AnyOfTrue1" + "AnyOfTrue2" + "AnyOfShortCircuit" + "AllOfTrue" + "AllOfEmpty" + "NotFalse" + "InheritanceChildTrue" + "InheritanceNull"$ diff --git a/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.cmake b/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.cmake new file mode 100644 index 0000000..49e7a25 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") diff --git a/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.json.in b/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.json.in new file mode 100644 index 0000000..ee17a22 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OptionalBinaryDirField.json.in @@ -0,0 +1,9 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "OptionalBinaryDirField", + "generator": "@RunCMake_GENERATOR@" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/OptionalGeneratorField.cmake b/Tests/RunCMake/CMakePresets/OptionalGeneratorField.cmake new file mode 100644 index 0000000..4319e72 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OptionalGeneratorField.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_GENERATOR "" "${RunCMake_GENERATOR}") diff --git a/Tests/RunCMake/CMakePresets/OptionalGeneratorField.json.in b/Tests/RunCMake/CMakePresets/OptionalGeneratorField.json.in new file mode 100644 index 0000000..920d056 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/OptionalGeneratorField.json.in @@ -0,0 +1,9 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "OptionalGeneratorField", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index dfc56ee..3b9806a 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -11,14 +11,23 @@ set(RunCMake-check-file check.cmake) include("${RunCMake_SOURCE_DIR}/validate_schema.cmake") +function(reset_cmake_presets_directory name) + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") +endfunction() + function(run_cmake_presets name) set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") set(_source_arg "${RunCMake_TEST_SOURCE_DIR}") if(CMakePresets_SOURCE_ARG) set(_source_arg "${CMakePresets_SOURCE_ARG}") endif() - file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") - file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + + if(NOT RunCMake_TEST_SOURCE_DIR_NO_CLEAN) + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + endif() configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY) if(NOT CMakePresets_FILE) @@ -94,6 +103,8 @@ run_cmake_presets(InvalidVariableValue) run_cmake_presets(ExtraRootField) run_cmake_presets(ExtraPresetField) run_cmake_presets(ExtraVariableField) +run_cmake_presets(FuturePresetInstallDirField) +run_cmake_presets(FuturePresetToolchainField) run_cmake_presets(InvalidPresetVendor) set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) run_cmake_presets(DuplicatePresets) @@ -116,7 +127,10 @@ run_cmake_presets(NoSuchMacro) run_cmake_presets(EnvCycle) run_cmake_presets(EmptyEnv) run_cmake_presets(EmptyPenv) +run_cmake_presets(InvalidRegex) set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) +run_cmake_presets(ConditionFuture) +run_cmake_presets(SubConditionNull) # Test cmakeMinimumRequired field run_cmake_presets(MinimumRequiredInvalid) @@ -181,6 +195,35 @@ run_cmake_presets(GoodInheritanceMulti) run_cmake_presets(GoodInheritanceMultiSecond) run_cmake_presets(GoodInheritanceMacro) +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodInstall.json.in") +run_cmake_presets(GoodInstallDefault) +run_cmake_presets(GoodInstallInherit) +run_cmake_presets(GoodInstallOverride) +run_cmake_presets(GoodInstallCommandLine "--install-prefix=${RunCMake_SOURCE_DIR}/path/passed/on/command_line") + +set(RunCMake_TEST_SOURCE_DIR_NO_CLEAN 1) +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodToolchain.json.in") + +reset_cmake_presets_directory(GoodToolchainInherit) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainDefault/toolchain.cmake" "") +run_cmake_presets(GoodToolchainDefault) + +reset_cmake_presets_directory(GoodToolchainInherit) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainInherit/toolchain.cmake" "") +run_cmake_presets(GoodToolchainInherit) + +reset_cmake_presets_directory(GoodToolchainOverride) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainOverride/override_toolchain.cmake" "") +run_cmake_presets(GoodToolchainOverride) + +reset_cmake_presets_directory(GoodToolchainCommandLine) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake" "") +run_cmake_presets(GoodToolchainCommandLine "--toolchain=${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake") + +unset(RunCMake_TEST_SOURCE_DIR_NO_CLEAN) + + +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in") # Test bad preset arguments run_cmake_presets(VendorMacro) run_cmake_presets(InvalidGenerator) @@ -253,9 +296,29 @@ set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Debug.json.in") run_cmake_presets(NoDebug) run_cmake_presets(Debug) +# Test ${hostSystemName} macro +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemName.json.in") +run_cmake_presets(HostSystemName) +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/HostSystemNameFuture.json.in") +run_cmake_presets(HostSystemNameFuture) + +# Test conditions +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Conditions.json.in") +run_cmake_presets(ListConditions --list-presets) +run_cmake_presets(SimpleTrue) +run_cmake_presets(SimpleFalse) +unset(CMakePresets_FILE) + +# Test optional generator and buildDir fields +run_cmake_presets(OptionalBinaryDirField -B "${RunCMake_BINARY_DIR}/OptionalBinaryDirField/build") +run_cmake_presets(OptionalGeneratorField -G "${RunCMake_GENERATOR}") + # Test the example from the documentation file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example) string(REPLACE "\"generator\": \"Ninja\"" "\"generator\": \"@RunCMake_GENERATOR@\"" _example "${_example}") +if(CMAKE_HOST_WIN32) + string(REPLACE [["PATH": "$env{HOME}/ninja/bin:$penv{PATH}"]] [["PATH": "$env{HOME}/ninja/bin;$penv{PATH}"]] _example "${_example}") +endif() file(WRITE "${RunCMake_BINARY_DIR}/example.json.in" "${_example}") set(CMakePresets_FILE "${RunCMake_BINARY_DIR}/example.json.in") run_cmake_presets(DocumentationExample --preset=default) diff --git a/Tests/RunCMake/CMakePresets/SimpleFalse-result.txt b/Tests/RunCMake/CMakePresets/SimpleFalse-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SimpleFalse-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/SimpleFalse-stderr.txt b/Tests/RunCMake/CMakePresets/SimpleFalse-stderr.txt new file mode 100644 index 0000000..6a9a7de --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SimpleFalse-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Could not use disabled preset "SimpleFalse"$ diff --git a/Tests/RunCMake/CMakePresets/SimpleTrue.cmake b/Tests/RunCMake/CMakePresets/SimpleTrue.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SimpleTrue.cmake diff --git a/Tests/RunCMake/CMakePresets/SubConditionNull-result.txt b/Tests/RunCMake/CMakePresets/SubConditionNull-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SubConditionNull-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt b/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt new file mode 100644 index 0000000..42b74d6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SubConditionNull-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/SubConditionNull: Invalid preset condition$ diff --git a/Tests/RunCMake/CMakePresets/SubConditionNull.json.in b/Tests/RunCMake/CMakePresets/SubConditionNull.json.in new file mode 100644 index 0000000..eed3da6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/SubConditionNull.json.in @@ -0,0 +1,14 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "SubConditionNull", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "condition": { + "type": "not", + "condition": null + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-result.txt b/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-stderr.txt new file mode 100644 index 0000000..c35f5d7 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/Condition-build-disabled-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Cannot use disabled build preset in [^ +]*/Tests/RunCMake/CMakePresetsBuild/Condition: "disabled"$ diff --git a/Tests/RunCMake/CMakePresetsBuild/Condition.cmake b/Tests/RunCMake/CMakePresetsBuild/Condition.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/Condition.cmake diff --git a/Tests/RunCMake/CMakePresetsBuild/Condition.json.in b/Tests/RunCMake/CMakePresetsBuild/Condition.json.in new file mode 100644 index 0000000..aaee96a --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/Condition.json.in @@ -0,0 +1,22 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "buildPresets": [ + { + "name": "enabled", + "configurePreset": "default", + "condition": true + }, + { + "name": "disabled", + "configurePreset": "default", + "condition": false + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-result.txt b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt new file mode 100644 index 0000000..f08f4c1 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture-build-conditionFuture-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresetsBuild/ConditionFuture: File version must be 3 or higher for condition support$ diff --git a/Tests/RunCMake/CMakePresetsBuild/ConditionFuture.json.in b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture.json.in new file mode 100644 index 0000000..2f3f7d8 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsBuild/ConditionFuture.json.in @@ -0,0 +1,17 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "buildPresets": [ + { + "name": "conditionFuture", + "configurePreset": "default", + "condition": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsBuild/ListPresets-build-x-stdout.txt b/Tests/RunCMake/CMakePresetsBuild/ListPresets-build-x-stdout.txt index 4d30707..2d362d4 100644 --- a/Tests/RunCMake/CMakePresetsBuild/ListPresets-build-x-stdout.txt +++ b/Tests/RunCMake/CMakePresetsBuild/ListPresets-build-x-stdout.txt @@ -1,5 +1,6 @@ -Available build presets: +^Available build presets: "build-default" - build-default displayName "empty" "display" - display displayName + "true"$ diff --git a/Tests/RunCMake/CMakePresetsBuild/ListPresets.json.in b/Tests/RunCMake/CMakePresetsBuild/ListPresets.json.in index 3f5e02c..26504d3 100644 --- a/Tests/RunCMake/CMakePresetsBuild/ListPresets.json.in +++ b/Tests/RunCMake/CMakePresetsBuild/ListPresets.json.in @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "configurePresets": [ { "name": "default", @@ -26,6 +26,16 @@ { "name": "hidden", "hidden": true + }, + { + "name": "true", + "inherits": "build-default", + "condition": true + }, + { + "name": "false", + "inherits": "build-default", + "condition": false } ] } diff --git a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake index 2559b12..afa22eb 100644 --- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake @@ -64,6 +64,7 @@ set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject") run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset") +run_cmake_build_presets(Condition "default" "enabled;disabled") set(CMakePresetsBuild_BUILD_ONLY 1) run_cmake_build_presets(ListPresets "x" "x" "--list-presets") @@ -72,5 +73,6 @@ run_cmake_build_presets(Invalid "x" "hidden;vendorMacro") set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) run_cmake_build_presets(PresetsUnsupported "x" "x") +run_cmake_build_presets(ConditionFuture "x" "conditionFuture") set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) set(CMakePresetsBuild_BUILD_ONLY 0) diff --git a/Tests/RunCMake/CMakePresetsTest/Condition.json.in b/Tests/RunCMake/CMakePresetsTest/Condition.json.in new file mode 100644 index 0000000..0baf176 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/Condition.json.in @@ -0,0 +1,22 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "testPresets": [ + { + "name": "enabled", + "configurePreset": "default", + "condition": true + }, + { + "name": "disabled", + "configurePreset": "default", + "condition": false + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-result.txt b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt new file mode 100644 index 0000000..b814bbb --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionFuture-test-x-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresetsTest/ConditionFuture: File version must be 3 or higher for condition support$ diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionFuture.json.in b/Tests/RunCMake/CMakePresetsTest/ConditionFuture.json.in new file mode 100644 index 0000000..4b9f33f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionFuture.json.in @@ -0,0 +1,17 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "default", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "testPresets": [ + { + "name": "conditionFuture", + "configurePreset": "default", + "condition": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionListPresets-test-x-stdout.txt b/Tests/RunCMake/CMakePresetsTest/ConditionListPresets-test-x-stdout.txt new file mode 100644 index 0000000..11918e5 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionListPresets-test-x-stdout.txt @@ -0,0 +1,3 @@ +^Available test presets: + + "enabled"$ diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-result.txt b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-stderr.txt b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-stderr.txt new file mode 100644 index 0000000..5db3b77 --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests-test-disabled-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Cannot use disabled test preset in [^ +]*/Tests/RunCMake/CMakePresetsTest/ConditionRunTests: "disabled"$ diff --git a/Tests/RunCMake/CMakePresetsTest/ConditionRunTests.cmake b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests.cmake new file mode 100644 index 0000000..b29161e --- /dev/null +++ b/Tests/RunCMake/CMakePresetsTest/ConditionRunTests.cmake @@ -0,0 +1,2 @@ +enable_testing() +add_test(true ${CMAKE_COMMAND} -E true) diff --git a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake index c93dff3..70d25d4 100644 --- a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake @@ -90,6 +90,12 @@ run_cmake_test_presets(InvalidConfigurePreset "default" "" "badConfigurePreset") set(CMakePresetsTest_NO_CONFIGURE 1) set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/Good.json.in") run_cmake_test_presets(ListPresets "" "" "x" "--list-presets") + +set(CMakePresetsTest_FILE "${RunCMake_SOURCE_DIR}/Condition.json.in") +run_cmake_test_presets(ConditionListPresets "" "" "x" "--list-presets") +unset(CMakePresetsTest_NO_CONFIGURE) +run_cmake_test_presets(ConditionRunTests "default" "" "enabled;disabled") +set(CMakePresetsTest_NO_CONFIGURE 1) unset(CMakePresetsTest_FILE) run_cmake_test_presets(NoConfigurePreset "" "" "noConfigurePreset") @@ -98,6 +104,7 @@ run_cmake_test_presets(Invalid "" "" "hidden;vendorMacro") set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) run_cmake_test_presets(PresetsUnsupported "" "" "x") +run_cmake_test_presets(ConditionFuture "" "" "x") set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) set(CMakePresetsTest_NO_CONFIGURE 0) diff --git a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake index 3416205..e95cd15 100644 --- a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake +++ b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake @@ -13,4 +13,11 @@ function(get_test_prerequirements found_var config_file) "\nset(RPMBUILD_EXECUTABLE \"${RPMBUILD_EXECUTABLE}\")") set(${found_var} true PARENT_SCOPE) endif() + + # optional tool for some tests + find_program(OBJDUMP_EXECUTABLE objdump) + if(OBJDUMP_EXECUTABLE) + file(APPEND "${config_file}" + "\nset(OBJDUMP_EXECUTABLE \"${OBJDUMP_EXECUTABLE}\")") + endif() endfunction() diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index 15bfb60..a3c72a1 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -16,7 +16,7 @@ run_cpack_test(VERSION "RPM.VERSION;DEB.VERSION" false "MONOLITHIC;COMPONENT") run_cpack_test(EXTRA "DEB.EXTRA" false "COMPONENT") run_cpack_test_subtests(GENERATE_SHLIBS "soversion_not_zero;soversion_zero" "DEB.GENERATE_SHLIBS" true "COMPONENT") run_cpack_test(GENERATE_SHLIBS_LDCONFIG "DEB.GENERATE_SHLIBS_LDCONFIG" true "COMPONENT") -run_cpack_test(INSTALL_SCRIPTS "RPM.INSTALL_SCRIPTS" false "COMPONENT") +run_cpack_test_subtests(INSTALL_SCRIPTS "default;single_debug_info;no_scripts;no_scripts_single_debug_info" "RPM.INSTALL_SCRIPTS" false "COMPONENT") run_cpack_test(LONG_FILENAMES "DEB.LONG_FILENAMES" false "MONOLITHIC") run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM.MAIN_COMPONENT" false "COMPONENT") run_cpack_test(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT") diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake index 0ab545a..294b9e8 100644 --- a/Tests/RunCMake/CPack/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/VerifyResult.cmake @@ -29,8 +29,16 @@ file(READ "${bin_dir}/test_output.txt" output) file(READ "${bin_dir}/test_error.txt" error) file(READ "${config_file}" config_file_content) -set(output_error_message - "\nCPack output: '${output}'\nCPack error: '${error}';\nCPack result: '${PACKAGING_RESULT}';\nconfig file: '${config_file_content}'") +string(REPLACE "\n" "\n cpack-out> " cpack_out "\n${output}") +string(REPLACE "\n" "\n cpack-err> " cpack_err "\n${error}") +string(REPLACE "\n" "\n cpack-res> " cpack_res "\n${PACKAGING_RESULT}") +string(REPLACE "\n" "\n cpack-cfg> " cpack_cfg "\n${config_file_content}") +string(CONCAT output_error_message + "CPack output:${cpack_out}\n" + "CPack error:${cpack_err}\n" + "CPack result:${cpack_res}\n" + "CPack config file:${cpack_cfg}" + ) # generate default expected files data include("${src_dir}/tests/${RunCMake_TEST_FILE_PREFIX}/ExpectedFiles.cmake") @@ -74,22 +82,22 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0) string(REPLACE "\n" "\n actual> " msg_actual "\n${PACKAGE_CONTENT}") string(REPLACE "\n" "\n expect> " msg_expected "\n${EXPECTED_FILE_CONTENT_${file_no_}}") message(FATAL_ERROR - "Unexpected file content for file No. '${file_no_}'!\n" + "Unexpected file content for file ${file_no_}!\n" "The content was:${msg_actual}\n" "which does not match:${msg_expected}\n" "${output_error_message}") endif() elseif(foundFilescount_ EQUAL 0) message(FATAL_ERROR - "Found no files for file No. '${file_no_}'!" - " Globbing expression: '${EXPECTED_FILE_${file_no_}}'" + "Found no files for file ${file_no_}!\n" + "Globbing expression:\n '${EXPECTED_FILE_${file_no_}}'\n" "${output_error_message}") else() message(FATAL_ERROR - "Found more than one file for file No. '${file_no_}'!" - " Found files count '${foundFilesCount_}'." - " Files: '${FOUND_FILE_${file_no_}}'" - " Globbing expression: '${EXPECTED_FILE_${file_no_}}'" + "Found more than one file for file ${file_no_}!\n" + "Found files count '${foundFilesCount_}'.\n" + "Files:\n '${FOUND_FILE_${file_no_}}'\n" + "Globbing expression:\n '${EXPECTED_FILE_${file_no_}}'\n" "${output_error_message}") endif() endforeach() @@ -105,7 +113,8 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0) if(NOT foundFilesCount_ EQUAL allFoundFilesCount_) message(FATAL_ERROR - "Found more files than expected! Found files: '${allFoundFiles_}'" + "Found more files than expected!\n" + "Found files:\n '${allFoundFiles_}'\n" "${output_error_message}") endif() @@ -116,8 +125,9 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0) if(found_ EQUAL -1) message(FATAL_ERROR - "Expected files don't match found files! Found files:" - " '${allFoundFiles_}'" + "Expected files don't match found files!\n" + "Found files:\n" + " '${allFoundFiles_}'\n" "${output_error_message}") endif() endforeach() @@ -127,7 +137,7 @@ else() file(GLOB checkMissingFiles_ RELATIVE "${bin_dir}" "${missing_file_glob_}") if(checkMissingFiles_) - message(FATAL_ERROR "Unexpected files found: '${checkMissingFiles_}'" + message(FATAL_ERROR "Unexpected files found:\n '${checkMissingFiles_}'\n" "${output_error_message}") endif() endforeach() diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/ExpectedFiles.cmake index de38df9..5a87c44 100644 --- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/ExpectedFiles.cmake @@ -1,5 +1,10 @@ +if(RunCMake_SUBTEST_SUFFIX MATCHES ".*single_debug_info") + set(EXPECTED_FILE_1 "install_scripts-0.1.1-1.*.rpm") +else() + set(EXPECTED_FILE_1_COMPONENT "foo") +endif() + set(EXPECTED_FILES_COUNT "2") -set(EXPECTED_FILE_1_COMPONENT "foo") set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt") set(EXPECTED_FILE_2_COMPONENT "bar") set(EXPECTED_FILE_CONTENT_2_LIST "/bar;/bar/CMakeLists.txt") diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-no_scripts_single_debug_info-stderr.txt b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-no_scripts_single_debug_info-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-no_scripts_single_debug_info-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-single_debug_info-stderr.txt b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-single_debug_info-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-COMPONENT-single_debug_info-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake new file mode 100644 index 0000000..90cfe44 --- /dev/null +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake @@ -0,0 +1,11 @@ +function(get_test_prerequirements found_var config_file) + if(SUBTEST_SUFFIX MATCHES ".*single_debug_info") + include(${config_file}) + + if(OBJDUMP_EXECUTABLE) + set(${found_var} true PARENT_SCOPE) + endif() + else() + set(${found_var} true PARENT_SCOPE) + endif() +endfunction() diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake index 1a1e983..0c42d90 100644 --- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake @@ -7,23 +7,34 @@ function(checkScripts_ FILE COMPARE_LIST) ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REPLACE "\n" ";" FILE_SCRIPTS_LIST_ "${FILE_SCRIPTS_}") + if(COMPARE_LIST STREQUAL "") + if(NOT FILE_SCRIPTS_ STREQUAL "") + message(FATAL_ERROR "No scripts were expected in '${FILE}'; file info: '${FILE_SCRIPTS_}'") + endif() + else() + string(REPLACE "\n" ";" FILE_SCRIPTS_LIST_ "${FILE_SCRIPTS_}") + + foreach(COMPARE_REGEX_ IN LISTS COMPARE_LIST) + unset(FOUND_) - foreach(COMPARE_REGEX_ IN LISTS COMPARE_LIST) - unset(FOUND_) + foreach(COMPARE_ IN LISTS FILE_SCRIPTS_LIST_) + if(COMPARE_ MATCHES "${COMPARE_REGEX_}") + set(FOUND_ true) + break() + endif() + endforeach() - foreach(COMPARE_ IN LISTS FILE_SCRIPTS_LIST_) - if(COMPARE_ MATCHES "${COMPARE_REGEX_}") - set(FOUND_ true) - break() + if(NOT FOUND_) + message(FATAL_ERROR "Missing scripts in '${FILE}'; file info: '${FILE_SCRIPTS_}'; missing: '${COMPARE_REGEX_}'") endif() endforeach() - - if(NOT FOUND_) - message(FATAL_ERROR "Missing scripts in '${FILE}'; file info: '${FILE_SCRIPTS_}'; missing: '${COMPARE_REGEX_}'") - endif() - endforeach() + endif() endfunction() -checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\";echo \"pre trans foo\";echo \"post trans foo\"") -checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\";echo \"pre trans\";echo \"post trans\"") +if(RunCMake_SUBTEST_SUFFIX MATCHES "no_scripts.*") + checkScripts_("${FOUND_FILE_1}" "") + checkScripts_("${FOUND_FILE_2}" "") +else() + checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\";echo \"pre trans foo\";echo \"post trans foo\"") + checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\";echo \"pre trans\";echo \"post trans\"") +endif() diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake index c200fa5..ce5db0c 100644 --- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake +++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake @@ -1,60 +1,70 @@ if(GENERATOR_TYPE STREQUAL "RPM") - set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh") - set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_install.sh") - set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh") - set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh") - set(CPACK_RPM_PRE_TRANS_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh") - set(CPACK_RPM_POST_TRANS_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh") - - set(CPACK_RPM_foo_PRE_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh") - set(CPACK_RPM_foo_POST_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_install_foo.sh") - set(CPACK_RPM_foo_PRE_UNINSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh") - set(CPACK_RPM_foo_POST_UNINSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh") - set(CPACK_RPM_foo_PRE_TRANS_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh") - set(CPACK_RPM_foo_POST_TRANS_SCRIPT_FILE - "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh") + if(RunCMake_SUBTEST_SUFFIX MATCHES ".*single_debug_info") + set(CPACK_RPM_MAIN_COMPONENT "foo") + set(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE ON) + set(CPACK_RPM_FOO_FILE_NAME "RPM-DEFAULT") + endif() endif() set(CMAKE_BUILD_WITH_INSTALL_RPATH 1) -# default -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh" - "echo \"pre install\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_install.sh" - "echo \"post install\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh" - "echo \"pre uninstall\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh" - "echo \"post uninstall\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh" - "echo \"pre trans\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh" - "echo \"post trans\"\n") +if(NOT RunCMake_SUBTEST_SUFFIX MATCHES "no_scripts.*") + if(GENERATOR_TYPE STREQUAL "RPM") + set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh") + set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_install.sh") + set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh") + set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh") + set(CPACK_RPM_PRE_TRANS_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh") + set(CPACK_RPM_POST_TRANS_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh") + + set(CPACK_RPM_foo_PRE_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh") + set(CPACK_RPM_foo_POST_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_install_foo.sh") + set(CPACK_RPM_foo_PRE_UNINSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh") + set(CPACK_RPM_foo_POST_UNINSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh") + set(CPACK_RPM_foo_PRE_TRANS_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh") + set(CPACK_RPM_foo_POST_TRANS_SCRIPT_FILE + "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh") + endif() -# specific -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh" - "echo \"pre install foo\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_install_foo.sh" - "echo \"post install foo\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh" - "echo \"pre uninstall foo\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh" - "echo \"post uninstall foo\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh" - "echo \"pre trans foo\"\n") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh" - "echo \"post trans foo\"\n") + # default + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh" + "echo \"pre install\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_install.sh" + "echo \"post install\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh" + "echo \"pre uninstall\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh" + "echo \"post uninstall\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh" + "echo \"pre trans\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh" + "echo \"post trans\"\n") + + # specific + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh" + "echo \"pre install foo\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_install_foo.sh" + "echo \"post install foo\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh" + "echo \"pre uninstall foo\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh" + "echo \"post uninstall foo\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh" + "echo \"pre trans foo\"\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh" + "echo \"post trans foo\"\n") +endif() install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo) install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar) diff --git a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake index 936e4ed..1dc7084 100644 --- a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake @@ -9,7 +9,7 @@ if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL set(EXPECTED_FILE_2 "single_debuginfo*-headers.rpm") set(EXPECTED_FILE_CONTENT_2_LIST "/bar;/bar/CMakeLists.txt") set(EXPECTED_FILE_3 "single_debuginfo*-libs.rpm") - set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so") + set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so;/empty_dir") set(EXPECTED_FILE_4_COMPONENT "debuginfo") set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*") diff --git a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/test.cmake b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/test.cmake index 60e9038..064539e 100644 --- a/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/test.cmake +++ b/Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/test.cmake @@ -30,6 +30,9 @@ if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo") install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers) install(TARGETS test_lib DESTINATION bas COMPONENT libs) + + # test that we correctly handle empty dir in non main component + install(DIRECTORY DESTINATION empty_dir COMPONENT libs) elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component" OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo") set(CPACK_COMPONENTS_ALL applications) diff --git a/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake index 6f37201..af39e5f 100644 --- a/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake +++ b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake @@ -1,6 +1,6 @@ install(FILES CMakeLists.txt DESTINATION foo COMPONENT test) -set(CPACK_THREADS 0) +set(CPACK_THREADS "-4") if(PACKAGING_TYPE STREQUAL "COMPONENT") set(CPACK_COMPONENTS_ALL test) diff --git a/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake index 439d95e..5a8b7a0 100644 --- a/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake @@ -15,6 +15,7 @@ function(run_cpack_symlink_test) run_cmake_command(SrcSymlinksCPack ${CMAKE_CPACK_COMMAND} --config CPackSourceConfig.cmake ) + run_cmake_script(SrcSymlinksCheck) endfunction() run_cpack_symlink_test() diff --git a/Tests/RunCMake/CPackSymlinks/SrcSymlinksCheck.cmake b/Tests/RunCMake/CPackSymlinks/SrcSymlinksCheck.cmake new file mode 100644 index 0000000..0041c92 --- /dev/null +++ b/Tests/RunCMake/CPackSymlinks/SrcSymlinksCheck.cmake @@ -0,0 +1,21 @@ +set(dir ${CMAKE_CURRENT_SOURCE_DIR}) + +set(tarball ${dir}/SrcSymlinks-0.1-Source.tar.gz) +set(extrdir ${dir}/SrcSymlinks-0.1-Source) + +message(STATUS "Extracting ${tarball} in ${dir}...") +execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ${tarball} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE output + WORKING_DIRECTORY ${dir}) +message(STATUS "result='${result}'") +message(STATUS "output='${output}'") + +if(NOT ${result} EQUAL 0) + message(FATAL_ERROR "Cannot unpack source tarball") +endif() + +if(NOT EXISTS ${extrdir}/dirlink/src.h) + message(FATAL_ERROR "${extrdir}/dirlink/src.h not found") +endif() diff --git a/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt index 24ad124..8b1ae57 100644 --- a/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt +++ b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt @@ -1,7 +1,6 @@ -^x CMakeLists.txt -x cygwin/ -x cygwin/build.sh -x cygwin/setup.patch +^x build.sh +x CMakeLists.txt +x dirlink x include/ x include/src.h x link.h diff --git a/Tests/RunCMake/CPackSymlinks/testcpacksym.tar b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar Binary files differindex a44c656..c24af48 100644 --- a/Tests/RunCMake/CPackSymlinks/testcpacksym.tar +++ b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index 6cf1476..afec011 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -202,7 +202,7 @@ function(run_TestLoad name load) add_test(TestLoad1 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\") add_test(TestLoad2 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\") ") - run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -j2 --test-load ${load}) + run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -VV -j2 --test-load ${load}) endfunction() # Tests for the --test-load feature of ctest @@ -397,3 +397,22 @@ function(run_testDir) run_cmake_command(testDir ${CMAKE_CTEST_COMMAND} --test-dir "${RunCMake_TEST_BINARY_DIR}/sub") endfunction() run_testDir() + +# Test --output-junit +function(run_output_junit) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/output-junit) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" " +add_test(test1 \"${CMAKE_COMMAND}\" -E false) +add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"hello world\") +add_test(test3 \"${CMAKE_COMMAND}\" -E true) +set_tests_properties(test3 PROPERTIES DISABLED \"ON\") +add_test(test4 \"${CMAKE_COMMAND}/doesnt_exist\") +add_test(test5 \"${CMAKE_COMMAND}\" -E echo \"please skip\") +set_tests_properties(test5 PROPERTIES SKIP_REGULAR_EXPRESSION \"please skip\") +") + run_cmake_command(output-junit ${CMAKE_CTEST_COMMAND} --output-junit "${RunCMake_TEST_BINARY_DIR}/junit.xml") +endfunction() +run_output_junit() diff --git a/Tests/RunCMake/CTestCommandLine/output-junit-check.cmake b/Tests/RunCMake/CTestCommandLine/output-junit-check.cmake new file mode 100644 index 0000000..b270fdf --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/output-junit-check.cmake @@ -0,0 +1,36 @@ +file(GLOB junit_xml_file "${RunCMake_TEST_BINARY_DIR}/junit.xml") +if(junit_xml_file) + file(READ "${junit_xml_file}" junit_xml LIMIT 4096) + if(NOT "${junit_xml}" MATCHES "tests=\"5\"") + set(RunCMake_TEST_FAILED "tests=\"5\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "failures=\"1\"") + set(RunCMake_TEST_FAILED "failures=\"1\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "disabled=\"1\"") + set(RunCMake_TEST_FAILED "disabled=\"1\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "skipped=\"2\"") + set(RunCMake_TEST_FAILED "skipped=\"2\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<system-out>hello world") + set(RunCMake_TEST_FAILED "<system-out>hello world not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<system-out>Disabled") + set(RunCMake_TEST_FAILED "<system-out>Disabled not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<skipped message=\"Unable to find executable\"/>") + set(RunCMake_TEST_FAILED "<skipped message=\"Unable to find executable\"/> not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<system-out>Unable to find executable:") + set(RunCMake_TEST_FAILED "<system-out>Unable to find executable: not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<skipped message=\"SKIP_REGULAR_EXPRESSION_MATCHED\"/>") + set(RunCMake_TEST_FAILED "<skipped message=\"SKIP_REGULAR_EXPRESSION_MATCHED\"/> not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<system-out>please skip") + set(RunCMake_TEST_FAILED "<system-out>please skip not found when expected") + endif() +else() + set(RunCMake_TEST_FAILED "junit.xml not found") +endif() diff --git a/Tests/RunCMake/CTestCommandLine/output-junit-result.txt b/Tests/RunCMake/CTestCommandLine/output-junit-result.txt new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/output-junit-result.txt @@ -0,0 +1 @@ +8 diff --git a/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt b/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt new file mode 100644 index 0000000..ce30dc8 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/output-junit-stderr.txt @@ -0,0 +1 @@ +Unable to find executable: .*doesnt_exist diff --git a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt index 7ee3dae..5101985 100644 --- a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt +++ b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt @@ -1,7 +1,20 @@ -^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad +Test project [^ +]*/Tests/RunCMake/CTestCommandLine/TestLoad( +[^*][^ +]*)* +test 1 Start 1: TestLoad1 ++( +[^*][^ +]*)* +test 2 Start 2: TestLoad2 -1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec ++( +[^*][^ +]*)* +1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec( +[^*][^ +]*)* 2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 2 diff --git a/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt index 7ee3dae..5101985 100644 --- a/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt +++ b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt @@ -1,7 +1,20 @@ -^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad +Test project [^ +]*/Tests/RunCMake/CTestCommandLine/TestLoad( +[^*][^ +]*)* +test 1 Start 1: TestLoad1 ++( +[^*][^ +]*)* +test 2 Start 2: TestLoad2 -1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec ++( +[^*][^ +]*)* +1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec( +[^*][^ +]*)* 2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 2 diff --git a/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt index 11a768a..db7d7f3 100644 --- a/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt +++ b/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt @@ -1,8 +1,21 @@ -^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad +Test project [^ +]*/Tests/RunCMake/CTestCommandLine/TestLoad( +[^*][^ +]*)* \*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 3, Smallest test TestLoad[1-2] requires 1\*\*\*\*\* +test 1 Start 1: TestLoad1 ++( +[^*][^ +]*)* +test 2 Start 2: TestLoad2 -1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec ++( +[^*][^ +]*)* +1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec( +[^*][^ +]*)* 2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 2 diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt index c76c92d..3df3e52 100644 --- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt +++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt @@ -1 +1 @@ -^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$ +^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":3}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$ diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt index 21e60ee..63a10d8 100644 --- a/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt +++ b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt @@ -1 +1 @@ -^CMake Error: failed to create link .* no such file or directory +^CMake Error: failed to create link '[^']+': [A-Za-z] diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake index 5b97aec..d92554a 100644 --- a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake +++ b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake @@ -1,3 +1,3 @@ -if(${actual_stderr_var} MATCHES "operation not permitted") +if(${actual_stderr_var} MATCHES "A required privilege is not held by the client") unset(msg) endif() diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake b/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake index 5df5f2f..43573bf 100644 --- a/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake +++ b/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake @@ -1,4 +1,4 @@ -if(${actual_stderr_var} MATCHES "operation not permitted") +if(${actual_stderr_var} MATCHES "A required privilege is not held by the client") unset(msg) else() if(NOT IS_SYMLINK ${RunCMake_TEST_BINARY_DIR}/L) diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake b/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake index d37df01..639c223 100644 --- a/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake +++ b/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake @@ -1,4 +1,4 @@ -if(${actual_stderr_var} MATCHES "operation not permitted") +if(${actual_stderr_var} MATCHES "A required privilege is not held by the client") unset(msg) else() if(NOT IS_DIRECTORY ${RunCMake_TEST_BINARY_DIR}/L) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index caf3c88..2eb8784 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -69,6 +69,8 @@ run_cmake_command(build-bad-dir run_cmake_command(build-bad-generator ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator) +run_cmake_command(install-prefix-no-arg ${CMAKE_COMMAND} -B DummyBuildDir --install-prefix) + run_cmake_command(install-no-dir ${CMAKE_COMMAND} --install) run_cmake_command(install-bad-dir @@ -162,6 +164,29 @@ project(ExplicitDirsMissing LANGUAGES NONE) endfunction() run_ExplicitDirs() +function(run_Toolchain) + set(RunCMake_TEST_NO_SOURCE_DIR 1) + set(source_dir ${RunCMake_SOURCE_DIR}/Toolchain) + + run_cmake_with_options(toolchain-no-arg -S ${source_dir} --toolchain=) + run_cmake_with_options(toolchain-valid-abs-path -S ${source_dir} --toolchain "${source_dir}/toolchain.cmake") + run_cmake_with_options(toolchain-valid-rel-src-path -S ${source_dir} --toolchain=toolchain.cmake) + + set(RunCMake_TEST_NO_CLEAN 1) + set(binary_dir ${RunCMake_BINARY_DIR}/Toolchain-build) + set(RunCMake_TEST_BINARY_DIR "${binary_dir}") + file(REMOVE_RECURSE "${binary_dir}") + + # Test that we both search the binary dir for toolchain files, and it takes + # precedence over source dir + file(WRITE ${binary_dir}/toolchain.cmake [=[ +set(CMAKE_SYSTEM_NAME Linux) +set(toolchain_file binary_dir) +]=]) + run_cmake_with_options(toolchain-valid-rel-build-path ${CMAKE_COMMAND} -S ${source_dir} -B ${binary_dir} --toolchain toolchain.cmake) +endfunction() +run_Toolchain() + function(run_BuildDir) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build) @@ -346,7 +371,7 @@ run_cmake_command(E_create_symlink-missing-dir # These tests are special on Windows since it will only fail if the user # running the test does not have the priveldge to create symlinks. If this # happens we clear the msg in the -check.cmake and say that the test passes -set(RunCMake_DEFAULT_stderr "(operation not permitted)?") +set(RunCMake_DEFAULT_stderr "(A required privilege is not held by the client)?") set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/E_create_symlink-broken-build) set(RunCMake_TEST_NO_CLEAN 1) @@ -390,7 +415,7 @@ run_cmake_command(E_create_hardlink-no-directory #On Windows, if the user does not have sufficient privileges #don't fail this test -set(RunCMake_DEFAULT_stderr "(operation not permitted)?") +set(RunCMake_DEFAULT_stderr "(A required privilege is not held by the client)?") run_cmake_command(E_create_hardlink-unresolved-symlink-prereq ${CMAKE_COMMAND} -E create_symlink ${dir}/1 ${dir}/1-symlink ) @@ -549,7 +574,7 @@ file(MAKE_DIRECTORY ${out}) run_cmake_command(E_cat_non_existing_file ${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt) -if(UNIX) +if(UNIX AND NOT MSYS) # test non readable file only if not root execute_process( COMMAND id -u $ENV{USER} @@ -788,7 +813,7 @@ function(reject_fifo) run_cmake_command(reject_fifo ${BASH_EXECUTABLE} -c ${BASH_COMMAND_ARGUMENT}) endif() endfunction() -if(CMAKE_HOST_UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") +if(CMAKE_HOST_UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL "CYGWIN" AND NOT CMAKE_SYSTEM_NAME STREQUAL "MSYS") reject_fifo() run_cmake_command(closed_stdin sh -c "\"${CMAKE_COMMAND}\" --version <&-") run_cmake_command(closed_stdout sh -c "\"${CMAKE_COMMAND}\" --version >&-") diff --git a/Tests/RunCMake/CommandLine/Toolchain/CMakeLists.txt b/Tests/RunCMake/CommandLine/Toolchain/CMakeLists.txt new file mode 100644 index 0000000..80d42b8 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Toolchain/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.20) +project(Toolchain LANGUAGES NONE) +message(FATAL_ERROR "${toolchain_file}") diff --git a/Tests/RunCMake/CommandLine/Toolchain/toolchain.cmake b/Tests/RunCMake/CommandLine/Toolchain/toolchain.cmake new file mode 100644 index 0000000..719556c --- /dev/null +++ b/Tests/RunCMake/CommandLine/Toolchain/toolchain.cmake @@ -0,0 +1,2 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(toolchain_file source_dir) diff --git a/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt b/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt index 5fe2539..fa3adc8 100644 --- a/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt +++ b/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt @@ -1,2 +1 @@ -^CMake Error: '--target=invalid' is invalid syntax for --target -Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\] +^Error: could not load cache diff --git a/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt b/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt index d69338a..e4ad6b2 100644 --- a/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt +++ b/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt @@ -1,2 +1,2 @@ -^CMake Error: '--targetinvalid' is invalid syntax for --target +^Unknown argument --targetinvalid Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/CommandLine/install-prefix-no-arg-result.txt b/Tests/RunCMake/CommandLine/install-prefix-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/install-prefix-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/install-prefix-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/install-prefix-no-arg-stderr.txt new file mode 100644 index 0000000..a464c70 --- /dev/null +++ b/Tests/RunCMake/CommandLine/install-prefix-no-arg-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No install directory specified for --install-prefix diff --git a/Tests/RunCMake/CommandLine/toolchain-no-arg-result.txt b/Tests/RunCMake/CommandLine/toolchain-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/toolchain-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/toolchain-no-arg-stderr.txt new file mode 100644 index 0000000..2fec517 --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-no-arg-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No file specified for --toolchain diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-result.txt b/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-stderr.txt b/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-stderr.txt new file mode 100644 index 0000000..21d5db6 --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-abs-path-stderr.txt @@ -0,0 +1 @@ +^CMake Error.*source_dir diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-result.txt b/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-stderr.txt b/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-stderr.txt new file mode 100644 index 0000000..1980051 --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-rel-build-path-stderr.txt @@ -0,0 +1 @@ +^CMake Error.*binary_dir diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-result.txt b/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-stderr.txt b/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-stderr.txt new file mode 100644 index 0000000..21d5db6 --- /dev/null +++ b/Tests/RunCMake/CommandLine/toolchain-valid-rel-src-path-stderr.txt @@ -0,0 +1 @@ +^CMake Error.*source_dir diff --git a/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake index 2b4fc89..3876ceb 100644 --- a/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake @@ -13,7 +13,7 @@ function(run_single_config_test label config exclude_from_all_value expectation) run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config ${config}) endfunction() -run_single_config_test("explictly not excluded" Debug 0 "should_exist") +run_single_config_test("explicitly not excluded" Debug 0 "should_exist") run_single_config_test("excluded" Debug 1 "should_not_exist") if(RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio)") diff --git a/Tests/RunCMake/ExternalProject/MultiCommand.cmake b/Tests/RunCMake/ExternalProject/MultiCommand.cmake index dbf67eb..0849658 100644 --- a/Tests/RunCMake/ExternalProject/MultiCommand.cmake +++ b/Tests/RunCMake/ExternalProject/MultiCommand.cmake @@ -1,6 +1,6 @@ include(ExternalProject) -# Verify COMMAND keyword is recognised after various *_COMMAND options +# Verify COMMAND keyword is recognized after various *_COMMAND options ExternalProject_Add(multiCommand DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download 1" COMMAND "${CMAKE_COMMAND}" -E echo "download 2" diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateful-check.cmake b/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateful-check.cmake index fb78e87..91cdf7c 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateful-check.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateful-check.cmake @@ -4,6 +4,7 @@ set(expect query/client-foo/query.json reply reply/codemodel-v2-[0-9a-f]+\\.json + .* reply/index-[0-9.T-]+\\.json .* ) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateless-check.cmake b/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateless-check.cmake index 7c6a35a..9aa9e4a 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateless-check.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2-ClientStateless-check.cmake @@ -4,6 +4,7 @@ set(expect query/client-foo/codemodel-v2 reply reply/codemodel-v2-[0-9a-f]+\\.json + .* reply/index-[0-9.T-]+\\.json .* ) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-SharedStateless-check.cmake b/Tests/RunCMake/FileAPI/codemodel-v2-SharedStateless-check.cmake index cc2f31b..43d1a0b 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-SharedStateless-check.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2-SharedStateless-check.cmake @@ -3,6 +3,7 @@ set(expect query/codemodel-v2 reply reply/codemodel-v2-[0-9a-f]+\\.json + .* reply/index-[0-9.T-]+\\.json .* ) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index df2410a..b9a1fbf 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -12,7 +12,7 @@ def read_codemodel_json_data(filename): def check_objects(o, g): assert is_list(o) assert len(o) == 1 - check_index_object(o[0], "codemodel", 2, 2, check_object_codemodel(g)) + check_index_object(o[0], "codemodel", 2, 3, check_object_codemodel(g)) def check_backtrace(t, b, backtrace): btg = t["backtraceGraph"] @@ -55,7 +55,7 @@ def check_backtraces(t, actual, expected): def check_directory(c): def _check(actual, expected): assert is_dict(actual) - expected_keys = ["build", "source", "projectIndex"] + expected_keys = ["build", "jsonFile", "source", "projectIndex"] assert matches(actual["build"], expected["build"]) assert is_int(actual["projectIndex"]) @@ -92,10 +92,103 @@ def check_directory(c): assert sorted(actual.keys()) == sorted(expected_keys) + assert is_string(actual["jsonFile"]) + filepath = os.path.join(reply_dir, actual["jsonFile"]) + with open(filepath) as f: + d = json.load(f) + + assert is_dict(d) + assert sorted(d.keys()) == ["backtraceGraph", "installers", "paths"] + + assert is_string(d["paths"]["source"], actual["source"]) + assert is_string(d["paths"]["build"], actual["build"]) + + check_backtrace_graph(d["backtraceGraph"]) + + assert is_list(d["installers"]) + assert len(d["installers"]) == len(expected["installers"]) + for a, e in zip(d["installers"], expected["installers"]): + assert is_dict(a) + expected_keys = ["component", "type"] + + assert is_string(a["component"], e["component"]) + assert is_string(a["type"], e["type"]) + + if e["destination"] is not None: + expected_keys.append("destination") + assert is_string(a["destination"], e["destination"]) + + if e["paths"] is not None: + expected_keys.append("paths") + assert is_list(a["paths"]) + assert len(a["paths"]) == len(e["paths"]) + + for ap, ep in zip(a["paths"], e["paths"]): + if is_string(ep): + assert matches(ap, ep) + else: + assert is_dict(ap) + assert sorted(ap.keys()) == ["from", "to"] + assert matches(ap["from"], ep["from"]) + assert matches(ap["to"], ep["to"]) + + if e["isExcludeFromAll"] is not None: + expected_keys.append("isExcludeFromAll") + assert is_bool(a["isExcludeFromAll"], e["isExcludeFromAll"]) + + if e["isForAllComponents"] is not None: + expected_keys.append("isForAllComponents") + assert is_bool(a["isForAllComponents"], e["isForAllComponents"]) + + if e["isOptional"] is not None: + expected_keys.append("isOptional") + assert is_bool(a["isOptional"], e["isOptional"]) + + if e["targetId"] is not None: + expected_keys.append("targetId") + assert matches(a["targetId"], e["targetId"]) + + if e["targetIndex"] is not None: + expected_keys.append("targetIndex") + assert is_int(a["targetIndex"]) + assert c["targets"][a["targetIndex"]]["name"] == e["targetIndex"] + + if e["targetIsImportLibrary"] is not None: + expected_keys.append("targetIsImportLibrary") + assert is_bool(a["targetIsImportLibrary"], e["targetIsImportLibrary"]) + + if e["targetInstallNamelink"] is not None: + expected_keys.append("targetInstallNamelink") + assert is_string(a["targetInstallNamelink"], e["targetInstallNamelink"]) + + if e["exportName"] is not None: + expected_keys.append("exportName") + assert is_string(a["exportName"], e["exportName"]) + + if e["exportTargets"] is not None: + expected_keys.append("exportTargets") + assert is_list(a["exportTargets"]) + assert len(a["exportTargets"]) == len(e["exportTargets"]) + for at, et in zip(a["exportTargets"], e["exportTargets"]): + assert is_dict(at) + assert sorted(at.keys()) == ["id", "index"] + assert matches(at["id"], et["id"]) + assert is_int(at["index"]) + assert c["targets"][at["index"]]["name"] == et["index"] + + if e["scriptFile"] is not None: + expected_keys.append("scriptFile") + assert is_string(a["scriptFile"], e["scriptFile"]) + + if e["backtrace"] is not None: + expected_keys.append("backtrace") + check_backtrace(d, a["backtrace"], e["backtrace"]) + + assert sorted(a.keys()) == sorted(expected_keys) + return _check -def check_target_backtrace_graph(t): - btg = t["backtraceGraph"] +def check_backtrace_graph(btg): assert is_dict(btg) assert sorted(btg.keys()) == ["commands", "files", "nodes"] assert is_list(btg["commands"]) @@ -148,7 +241,7 @@ def check_target(c): assert is_string(obj["name"], expected["name"]) assert matches(obj["id"], expected["id"]) assert is_string(obj["type"], expected["type"]) - check_target_backtrace_graph(obj) + check_backtrace_graph(obj["backtraceGraph"]) assert is_dict(obj["paths"]) assert sorted(obj["paths"].keys()) == ["build", "source"] @@ -543,6 +636,20 @@ def gen_check_directories(c, g): for e in expected: e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(ALL_BUILD|ZERO_CHECK)"), e["targetIds"]) + if sys.platform in ("win32", "cygwin", "msys") or "aix" in sys.platform: + for e in expected: + e["installers"] = list(filter(lambda i: i["targetInstallNamelink"] is None or i["targetInstallNamelink"] == "skip", e["installers"])) + for i in e["installers"]: + i["targetInstallNamelink"] = None + + if sys.platform not in ("win32", "cygwin", "msys"): + for e in expected: + e["installers"] = list(filter(lambda i: "_dllExtra" not in i or not i["_dllExtra"], e["installers"])) + if "aix" not in sys.platform: + for i in e["installers"]: + if "pathsNamelink" in i: + i["paths"] = i["pathsNamelink"] + return expected def check_directories(c, g): @@ -705,6 +812,13 @@ def gen_check_targets(c, g, inSource): if sys.platform not in ("win32", "cygwin", "msys"): for e in expected: e["artifacts"] = filter_list(lambda a: not a["_dllExtra"], e["artifacts"]) + if e["install"] is not None: + e["install"]["destinations"] = filter_list(lambda d: "_dllExtra" not in d or not d["_dllExtra"], e["install"]["destinations"]) + + else: + for e in expected: + if e["install"] is not None: + e["install"]["destinations"] = filter_list(lambda d: "_namelink" not in d or not d["_namelink"], e["install"]["destinations"]) if "aix" not in sys.platform: for e in expected: diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json index 9f0c48a..6514910 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json @@ -11,5 +11,6 @@ ], "projectName": "Alias", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json index afd41f3..c89e4f9 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json @@ -11,5 +11,6 @@ ], "projectName": "Custom", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json index a51b6eb..7168306 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json @@ -17,5 +17,6 @@ ], "projectName": "Cxx", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json index afbd43a..8509f08 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json @@ -8,5 +8,6 @@ "targetIds": null, "projectName": "codemodel-v2", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json index 3737ad5..27184cd 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json @@ -6,5 +6,6 @@ "targetIds": null, "projectName": "codemodel-v2", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json index 521e3c7..6d2952d 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json @@ -10,5 +10,71 @@ ], "projectName": "External", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": true, + "installers": [ + { + "component": "Unspecified", + "type": "directory", + "destination": "dir3", + "paths": [ + "^.*/Tests/RunCMake/FileAPIExternalSource/\\.$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 15, + "command": "install", + "hasParent": true + }, + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "directory", + "destination": "dir4", + "paths": [ + "^.*/Tests/RunCMake/FileAPIExternalSource$" + ], + "isExcludeFromAll": true, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": 16, + "command": "install", + "hasParent": true + }, + { + "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json index a41b79b..d127274 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json @@ -14,5 +14,6 @@ ], "projectName": "Imported", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json index b10d496..90664dc 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json @@ -10,5 +10,6 @@ ], "projectName": "Interface", "minimumCMakeVersion": "3.12", - "hasInstallRule": null + "hasInstallRule": null, + "installers": [] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json index 1e647ad..44bc725 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json @@ -13,5 +13,71 @@ ], "projectName": "Object", "minimumCMakeVersion": "3.13", - "hasInstallRule": true + "hasInstallRule": true, + "installers": [ + { + "component": "Unspecified", + "type": "target", + "destination": "bin", + "paths": [ + "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?c_object_exe(\\.exe)?$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^c_object_exe::@5ed5358f70faf8d8af7a$", + "targetIndex": "c_object_exe", + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^object/CMakeLists\\.txt$", + "line": 13, + "command": "install", + "hasParent": true + }, + { + "file": "^object/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "bin", + "paths": [ + "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_object_exe(\\.exe)?$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^cxx_object_exe::@5ed5358f70faf8d8af7a$", + "targetIndex": "cxx_object_exe", + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^object/CMakeLists\\.txt$", + "line": 13, + "command": "install", + "hasParent": true + }, + { + "file": "^object/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json index 736d1f5..99287fb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json @@ -25,5 +25,603 @@ ], "projectName": "codemodel-v2", "minimumCMakeVersion": "3.12", - "hasInstallRule": true + "hasInstallRule": true, + "installers": [ + { + "component": "Tools", + "type": "target", + "destination": "bin", + "paths": [ + "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_exe(\\.exe)?$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^cxx_exe::@a56b12a3f5c0529fb296$", + "targetIndex": "cxx_exe", + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 38, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "lib", + "paths": [ + "^((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(lib|dll\\.a)$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", + "targetIndex": "c_shared_lib", + "targetIsImportLibrary": true, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "_dllExtra": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "lib", + "paths": [ + "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib|cyg|msys-)?c_shared_lib(-1)?\\.(dll|so)$" + ], + "pathsNamelink": [ + "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(so\\.1\\.2\\.3|1\\.2\\.3\\.dylib)$", + "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(so\\.1|1\\.dylib)$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", + "targetIndex": "c_shared_lib", + "targetIsImportLibrary": null, + "targetInstallNamelink": "skip", + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "lib", + "paths": [ + "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?cxx_shared_lib\\.(lib|dll\\.a)$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", + "targetIndex": "cxx_shared_lib", + "targetIsImportLibrary": true, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "_dllExtra": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "lib", + "paths": [ + "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib|cyg|msys-)?cxx_shared_lib\\.(dll|so|dylib)$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", + "targetIndex": "cxx_shared_lib", + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "target", + "destination": "lib", + "paths": [ + "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(dll|so|dylib)$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", + "targetIndex": "c_shared_lib", + "targetIsImportLibrary": null, + "targetInstallNamelink": "only", + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 46, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "file", + "destination": "include", + "paths": [ + { + "from": "^empty\\.h$", + "to": "^empty-renamed\\.h$" + } + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": true, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 48, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "file", + "destination": "include", + "paths": [ + "^codemodel-v2\\.cmake$", + "^empty\\.h$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 49, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "directory", + "destination": "dir1", + "paths": [ + "^\\.$", + "^dir$", + { + "from": "^cxx$", + "to": "^\\.$" + } + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": true, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 50, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "directory", + "destination": "dir2", + "paths": [ + { + "from": "^\\.$", + "to": "^FileAPI$" + }, + "^dir$", + { + "from": "^cxx$", + "to": "^\\.$" + } + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 51, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "export", + "destination": "lib/cmake/foo", + "paths": [ + "^CMakeFiles/Export/lib/cmake/foo/FooTargets\\.cmake$" + ], + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": "FooTargets", + "exportTargets": [ + { + "id": "^cxx_exe::@a56b12a3f5c0529fb296$", + "index": "cxx_exe" + } + ], + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 52, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "script", + "destination": null, + "paths": null, + "isExcludeFromAll": null, + "isForAllComponents": null, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": "InstallScript.cmake", + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 53, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "component": "Unspecified", + "type": "code", + "destination": null, + "paths": null, + "isExcludeFromAll": null, + "isForAllComponents": true, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 54, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json index 176a857..e3a8d0b 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json @@ -90,10 +90,10 @@ } ], "folder": null, - "nameOnDisk": "^(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$", + "nameOnDisk": "^(lib|cyg|msys-)?c_shared_lib(-1)?\\.(so|dylib|dll)$", "artifacts": [ { - "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$", + "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg|msys-)?c_shared_lib(-1)?\\.(so|dylib|dll)$", "_dllExtra": false }, { @@ -101,13 +101,106 @@ "_dllExtra": true }, { - "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.pdb$", + "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg|msys-)?c_shared_lib(-1)?\\.pdb$", "_dllExtra": true } ], "build": "^\\.$", "source": "^\\.$", - "install": null, + "install": { + "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$", + "destinations": [ + { + "path": "lib", + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "lib", + "_dllExtra": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "lib", + "_namelink": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 46, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, "link": { "language": "C", "lto": true, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json index 171a4f5..73e8e12 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json @@ -66,10 +66,10 @@ } ], "folder": null, - "nameOnDisk": "^(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$", + "nameOnDisk": "^(lib|cyg|msys-)?cxx_shared_lib\\.(so|dylib|dll)$", "artifacts": [ { - "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$", + "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg|msys-)?cxx_shared_lib\\.(so|dylib|dll)$", "_dllExtra": false }, { @@ -77,13 +77,106 @@ "_dllExtra": true }, { - "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.pdb$", + "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg|msys-)?cxx_shared_lib\\.pdb$", "_dllExtra": true } ], "build": "^cxx$", "source": "^cxx$", - "install": null, + "install": { + "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$", + "destinations": [ + { + "path": "lib", + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "lib", + "_dllExtra": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 41, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "lib", + "_namelink": true, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 46, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, "link": { "language": "CXX", "lto": null, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake index 2405954..da928eb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake @@ -35,4 +35,20 @@ if(_ipo) file(WRITE "${CMAKE_BINARY_DIR}/ipo_enabled.txt" "") endif() -install(TARGETS cxx_exe) +install(TARGETS cxx_exe COMPONENT Tools EXPORT FooTargets) + +set_target_properties(c_shared_lib PROPERTIES VERSION 1.2.3 SOVERSION 1) +install(TARGETS c_shared_lib cxx_shared_lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION lib + LIBRARY DESTINATION lib NAMELINK_SKIP + ) +install(TARGETS c_shared_lib cxx_shared_lib LIBRARY NAMELINK_ONLY) + +install(FILES empty.h TYPE INCLUDE RENAME empty-renamed.h OPTIONAL) +install(FILES codemodel-v2.cmake empty.h DESTINATION include) +install(DIRECTORY . dir cxx/ OPTIONAL DESTINATION dir1) +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}/cxx/" DESTINATION dir2) +install(EXPORT FooTargets DESTINATION lib/cmake/foo) +install(SCRIPT InstallScript.cmake) +install(CODE "message(foo)" ALL_COMPONENTS) diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt index 76235f5..95c803f 100644 --- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt +++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(cxx_static_exe PRIVATE cxx_static_lib) target_compile_options(cxx_exe PUBLIC TargetCompileOptions) target_link_options(cxx_exe PUBLIC TargetLinkOptions) -target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir") +target_link_directories(cxx_exe PUBLIC "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/TargetLinkDir>") target_precompile_headers(cxx_exe PUBLIC ../empty.h) diff --git a/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt b/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt index b3ca660..2865864 100644 --- a/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt +++ b/Tests/RunCMake/FileAPIExternalSource/CMakeLists.txt @@ -11,3 +11,6 @@ set_property(SOURCE empty.c PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY target_include_directories(generated_exe SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") target_compile_definitions(generated_exe PRIVATE GENERATED_EXE=1 -DTGT_DUMMY) set_source_files_properties(empty.c PROPERTIES COMPILE_OPTIONS SRC_COMPILE_OPTIONS_DUMMY) + +install(DIRECTORY . DESTINATION dir3) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} EXCLUDE_FROM_ALL DESTINATION dir4) diff --git a/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake b/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake index 0000ef9..a5e66dc 100644 --- a/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake +++ b/Tests/RunCMake/File_Generate/CustomFilePermissions.cmake @@ -11,5 +11,6 @@ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/custom add_custom_target(checkCustomFilePermissions ALL COMMAND ${CMAKE_COMMAND} -DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/customfilepermissions.txt + -DMSYS=${MSYS} -P "${CMAKE_CURRENT_SOURCE_DIR}/CustomFilePermissionsVerify.cmake" ) diff --git a/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake b/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake index a87e916..2ef3281 100644 --- a/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake +++ b/Tests/RunCMake/File_Generate/CustomFilePermissionsVerify.cmake @@ -2,7 +2,7 @@ if(NOT EXISTS "${generatedFile}") message(SEND_ERROR "Missing file:\n ${generatedFile}") endif() -if (UNIX) +if (UNIX AND NOT MSYS) find_program(STAT_EXECUTABLE NAMES stat) if(NOT STAT_EXECUTABLE) return() diff --git a/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake b/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake index 7981ccc..5e5b16a 100644 --- a/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake +++ b/Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake @@ -2,7 +2,7 @@ if(NOT EXISTS "${generatedFile}") message(SEND_ERROR "Missing generated file:\n ${generatedFile}") endif() -if (UNIX) +if (UNIX AND NOT MSYS) find_program(STAT_EXECUTABLE NAMES stat) if(NOT STAT_EXECUTABLE) return() diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt index 4c2e35f..4d7370c 100644 --- a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt @@ -3,7 +3,7 @@ CMake Error at OutputNameMatchesObjects.cmake:[0-9]+ \(file\): \$<TARGET_OBJECTS:foo> - Objects of target "foo" referenced but is not an allowed library types - \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). + Objects of target "foo" referenced but is not one of the allowed target + types \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt b/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt new file mode 100644 index 0000000..bd75ccd --- /dev/null +++ b/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt @@ -0,0 +1 @@ +xxx/no/exist/fw\.framework/Versions/A/fwxxx diff --git a/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake b/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake new file mode 100644 index 0000000..42edaea --- /dev/null +++ b/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake @@ -0,0 +1,10 @@ +add_library(fw SHARED IMPORTED) +set_target_properties(fw PROPERTIES + FRAMEWORK TRUE + IMPORTED_LOCATION "/no/exist/fw.framework/Versions/A/fw" + IMPORTED_SONAME "@rpath/fw.framework/Versions/A/fw" + ) + +add_custom_target(print_fw ALL COMMAND + ${CMAKE_COMMAND} -E echo "xxx$<TARGET_SONAME_FILE:fw>xxx" + ) diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake index 6ee61a3..36eaf5c 100644 --- a/Tests/RunCMake/Framework/RunCMakeTest.cmake +++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake @@ -81,3 +81,15 @@ function(framework_multi_config_postfix_test) endfunction() framework_multi_config_postfix_test() + +function(imported_framework_test) + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ImportedFrameworkTest-build") + set(RunCMake_TEST_NO_CLEAN 1) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + run_cmake(ImportedFrameworkTest) + run_cmake_command(ImportedFrameworkTest-build ${CMAKE_COMMAND} --build .) +endfunction() + +imported_framework_test() diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake index 40f7c66..7eec527 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake @@ -58,8 +58,8 @@ set_property (TARGET static3 PROPERTY ARCHIVE_OUTPUT_NAME static3_archive) string (APPEND GENERATE_CONTENT [[ check_value ("TARGET_FILE_BASE_NAME executable all properties" "$<TARGET_FILE_BASE_NAME:exec3>" "exec3_runtime") -check_value ("TARGET_FILE_BASE_NAME shared all properties" "$<TARGET_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared3_runtime,shared3_library>") -check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared3_archive,shared3_library>") +check_value ("TARGET_FILE_BASE_NAME shared all properties" "$<TARGET_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared3_runtime,shared3_library>") +check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared3_archive,shared3_library>") check_value ("TARGET_FILE_BASE_NAME static all properties" "$<TARGET_FILE_BASE_NAME:static3>" "static3_archive") check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:static3>" "static3_archive") ]]) @@ -95,8 +95,8 @@ set_property (TARGET static4 PROPERTY ${FIRST_CONFIG}_POSTFIX _postfix) string (APPEND GENERATE_CONTENT [[ check_value ("TARGET_FILE_BASE_NAME executable all properties + postfix" "$<TARGET_FILE_BASE_NAME:exec4>" "exec4_runtime_postfix") -check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared4_runtime,shared4_library>_postfix") -check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared4_archive,shared4_library>_postfix") +check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>_postfix") +check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>_postfix") check_value ("TARGET_FILE_BASE_NAME static all properties + postfix" "$<TARGET_FILE_BASE_NAME:static4>" "static4_archive_postfix") check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:static4>" "static4_archive_postfix") ]]) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake index f88d710..1963244 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake @@ -72,8 +72,8 @@ set_property (TARGET static3 PROPERTY PDB_NAME static3_pdb) string (APPEND GENERATE_CONTENT [[ check_value ("TARGET_FILE_BASE_NAME executable all properties" "$<TARGET_FILE_BASE_NAME:exec3>" "exec3_runtime") -check_value ("TARGET_FILE_BASE_NAME shared all properties" "$<TARGET_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared3_runtime,shared3_library>") -check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared3_archive,shared3_library>") +check_value ("TARGET_FILE_BASE_NAME shared all properties" "$<TARGET_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared3_runtime,shared3_library>") +check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:shared3>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared3_archive,shared3_library>") check_value ("TARGET_FILE_BASE_NAME static all properties" "$<TARGET_FILE_BASE_NAME:static3>" "static3_archive") check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties" "$<TARGET_LINKER_FILE_BASE_NAME:static3>" "static3_archive") ]]) @@ -118,8 +118,8 @@ set_property (TARGET static4 PROPERTY ${FIRST_CONFIG}_POSTFIX _postfix) string (APPEND GENERATE_CONTENT [[ check_value ("TARGET_FILE_BASE_NAME executable all properties + postfix" "$<TARGET_FILE_BASE_NAME:exec4>" "exec4_runtime_postfix") -check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared4_runtime,shared4_library>_postfix") -check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN>,shared4_archive,shared4_library>_postfix") +check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>_postfix") +check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>_postfix") check_value ("TARGET_FILE_BASE_NAME static all properties + postfix" "$<TARGET_FILE_BASE_NAME:static4>" "static4_archive_postfix") check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:static4>" "static4_archive_postfix") ]]) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake index f52776e..cc9cd5a 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) enable_language (C) -set (win_platforms Windows CYGWIN) +set (win_platforms Windows CYGWIN MSYS) set (GENERATE_CONTENT [[ macro (CHECK_VALUE test_msg value expected) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake index bef7bbf..edfb40c 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) enable_language (C) -set (win_platforms Windows CYGWIN) +set (win_platforms Windows CYGWIN MSYS) set (GENERATE_CONTENT [[ macro (CHECK_VALUE test_msg value expected) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake index cefeb86..3ee42a5 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) enable_language (C) -set (win_platforms Windows CYGWIN) +set (win_platforms Windows CYGWIN MSYS) set (GENERATE_CONTENT [[ macro (CHECK_VALUE test_msg value expected) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake index 39e39fd..1fe75d9 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) enable_language (C) -set (win_platforms Windows CYGWIN) +set (win_platforms Windows CYGWIN MSYS) set (GENERATE_CONTENT [[ macro (CHECK_VALUE test_msg value expected) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/CMakeLists.txt new file mode 100644 index 0000000..ab1a20c --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.19) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/RunCMakeTest.cmake new file mode 100644 index 0000000..edc495c --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/RunCMakeTest.cmake @@ -0,0 +1,7 @@ +include(RunCMake) + +run_cmake(TARGET_RUNTIME_DLLS) +run_cmake(TARGET_RUNTIME_DLLS-static) +run_cmake(TARGET_RUNTIME_DLLS-target_link_libraries) +run_cmake(TARGET_RUNTIME_DLLS-target_link_libraries-cycle1) +run_cmake(TARGET_RUNTIME_DLLS-target_link_libraries-cycle2) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-check.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-check.cmake new file mode 100644 index 0000000..e19598e --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-check.cmake @@ -0,0 +1,15 @@ +function(check_genex expected actual) + if(NOT expected STREQUAL actual) + string(APPEND RunCMake_TEST_FAILED "Expected DLLs:\n") + foreach(dll IN LISTS expected) + string(APPEND RunCMake_TEST_FAILED " ${dll}\n") + endforeach() + string(APPEND RunCMake_TEST_FAILED "Actual DLLs:\n") + foreach(dll IN LISTS actual) + string(APPEND RunCMake_TEST_FAILED " ${dll}\n") + endforeach() + endif() + set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE) +endfunction() + +include("${RunCMake_TEST_BINARY_DIR}/dlls.cmake") diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-result.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-stderr.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-stderr.txt new file mode 100644 index 0000000..7ce588a --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static-stderr.txt @@ -0,0 +1,9 @@ +CMake Error at TARGET_RUNTIME_DLLS-static\.cmake:[0-9]+ \(file\): + Error evaluating generator expression: + + \$<TARGET_RUNTIME_DLLS:static> + + Objects of target "static" referenced but is not one of the allowed target + types \(EXECUTABLE, SHARED, MODULE\)\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static.cmake new file mode 100644 index 0000000..dc900dd --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-static.cmake @@ -0,0 +1,9 @@ +enable_language(C) + +add_library(static STATIC static.c) +set(condition) +get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(multi_config) + set(condition CONDITION "$<CONFIG:Debug>") +endif() +file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/dlls.txt" CONTENT "$<TARGET_RUNTIME_DLLS:static>" ${condition}) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-result.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-stderr.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-stderr.txt new file mode 100644 index 0000000..8cfcf7e --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at TARGET_RUNTIME_DLLS-target_link_libraries-cycle1\.cmake:[0-9]+ \(add_library\): + The SOURCES of "lib1" use a generator expression that depends on the + SOURCES themselves\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1.cmake new file mode 100644 index 0000000..f19e9e6 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle1.cmake @@ -0,0 +1,4 @@ +enable_language(C) + +add_library(lib1 SHARED lib1.c) +target_link_libraries(lib1 PRIVATE $<TARGET_RUNTIME_DLLS:lib1>) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-result.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-stderr.txt b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-stderr.txt new file mode 100644 index 0000000..bacbf63 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at TARGET_RUNTIME_DLLS-target_link_libraries-cycle2\.cmake:[0-9]+ \(add_library\): + The SOURCES of "(lib1|lib2)" use a generator expression that depends on the + SOURCES themselves\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2.cmake new file mode 100644 index 0000000..7d035bd --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries-cycle2.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_library(lib1 SHARED lib1.c) +add_library(lib2 SHARED lib2.c) +target_link_libraries(lib1 PRIVATE $<TARGET_RUNTIME_DLLS:lib2>) +target_link_libraries(lib2 PRIVATE $<TARGET_RUNTIME_DLLS:lib1>) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries.cmake new file mode 100644 index 0000000..f44dbf4 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS-target_link_libraries.cmake @@ -0,0 +1,5 @@ +enable_language(C) + +add_library(lib1 SHARED lib1.c) +add_library(lib2 SHARED lib2.c) +target_link_libraries(lib1 PRIVATE $<TARGET_RUNTIME_DLLS:lib2>) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS.cmake b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS.cmake new file mode 100644 index 0000000..806f0b6 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/TARGET_RUNTIME_DLLS.cmake @@ -0,0 +1,37 @@ +enable_language(C) + +add_executable(exe main.c) +add_library(lib1 SHARED lib1.c) +add_library(lib2 SHARED lib2.c) +add_library(lib3 SHARED lib3.c) +add_library(static STATIC static.c) +add_library(imported SHARED IMPORTED) +set_property(TARGET imported PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/imported.dll") +set_property(TARGET imported PROPERTY IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/imported.lib") +add_library(imported2 SHARED IMPORTED) +if(NOT WIN32 AND NOT CYGWIN) + set_property(TARGET imported2 PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/imported2.dll") +endif() +set_property(TARGET imported2 PROPERTY IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/imported2.lib") + +target_link_libraries(exe PRIVATE lib1 static imported imported2) +target_link_libraries(lib1 PRIVATE lib2) +target_link_libraries(lib1 INTERFACE lib3) + +set(expected_dlls "") +if(WIN32 OR CYGWIN) + set(expected_dlls + "$<TARGET_FILE:lib1>" + "$<TARGET_FILE:imported>" + "$<TARGET_FILE:lib3>" + "$<TARGET_FILE:lib2>" + ) +endif() + +set(content "check_genex(\"${expected_dlls}\" \"$<TARGET_RUNTIME_DLLS:exe>\")\n") +set(condition) +get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(multi_config) + set(condition CONDITION "$<CONFIG:Debug>") +endif() +file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/dlls.cmake" CONTENT "${content}" ${condition}) diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib1.c b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib1.c new file mode 100644 index 0000000..524b5b2 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib1.c @@ -0,0 +1,12 @@ +#ifdef _WIN32 +__declspec(dllimport) +#endif + extern void lib2(void); + +#ifdef _WIN32 +__declspec(dllexport) +#endif + void lib1(void) +{ + lib2(); +} diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib2.c b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib2.c new file mode 100644 index 0000000..e145117 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib2.c @@ -0,0 +1,6 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + void lib2(void) +{ +} diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib3.c b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib3.c new file mode 100644 index 0000000..5392f7a --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/lib3.c @@ -0,0 +1,6 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + void lib3(void) +{ +} diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/main.c b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/static.c b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/static.c new file mode 100644 index 0000000..7f5dab5 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_RUNTIME_DLLS/static.c @@ -0,0 +1,3 @@ +void static_func(void) +{ +} diff --git a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp index dcaa4f2..2cfcd8d 100644 --- a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp +++ b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp @@ -8,6 +8,14 @@ #include "libshared.h" #include "libstatic.h" +static void rtrim(std::string& str, char byte) +{ + size_t const size = str.size(); + if (size && str[size - 1] == byte) { + str.resize(size - 1); + } +} + void compare(const char* refName, const char* testName) { std::ifstream ref; @@ -31,16 +39,14 @@ void compare(const char* refName, const char* testName) // Some very old Borland runtimes (C++ Builder 5 WITHOUT Update 1) add a // trailing null to the string that we need to strip before testing for a // trailing space. - if (refLine.size() && refLine[refLine.size() - 1] == 0) { - refLine.resize(refLine.size() - 1); - } - if (testLine.size() && testLine[testLine.size() - 1] == 0) { - testLine.resize(testLine.size() - 1); - } + rtrim(refLine, 0); + rtrim(testLine, 0); // The reference files never have trailing spaces: - if (testLine.size() && testLine[testLine.size() - 1] == ' ') { - testLine.resize(testLine.size() - 1); - } + rtrim(testLine, ' '); + // Strip trailing CR. LF is not returned by getline, but CR is returned + // on some platforms. + rtrim(refLine, '\r'); + rtrim(testLine, '\r'); if (refLine != testLine) { std::cout << "Ref and test are not the same:\n Ref: \"" << refLine << "\"\n Test: \"" << testLine << "\"\n"; diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake index 27ede06..83e63f9 100644 --- a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake @@ -11,9 +11,9 @@ else() run_cmake(BadPlatform) endif() -set(RunCMake_GENERATOR_TOOLSET "") +set(RunCMake_GENERATOR_PLATFORM "") -set(RunCMake_TEST_OPTIONS -A "Extra Platform") +set(RunCMake_TEST_OPTIONS -A "Test Platform" -A "Extra Platform") run_cmake(TwoPlatforms) unset(RunCMake_TEST_OPTIONS) diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-stderr.txt new file mode 100644 index 0000000..d8b6c5e --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio [^ +]* + + given toolset + + customFlagTableDir=does_not_exist + + that is not an absolute path to an existing directory.$ diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetCustomFlagTableDir.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem-stderr.txt index 5e88e3b..ba7a8f3 100644 --- a/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem-stderr.txt +++ b/Tests/RunCMake/GeneratorToolset/BadToolsetXcodeBuildSystem-stderr.txt @@ -7,4 +7,4 @@ CMake Error at CMakeLists.txt:[0-9]+ \(project\): buildsystem=bad - value is unkonwn. It must be '1' or '12'\.$ + value is unknown. It must be '1' or '12'\.$ diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake index 5f12d79..faed8f7 100644 --- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake @@ -1,5 +1,11 @@ include(RunCMake) +if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]") + run_cmake(VsNormal) + include("${RunCMake_BINARY_DIR}/VsNormal-build/defaults.cmake" OPTIONAL) + message(STATUS "VsNormal: platform='${VsNormal_Platform}' toolset='${VsNormal_Toolset}'") +endif() + set(RunCMake_GENERATOR_TOOLSET "") run_cmake(NoToolset) @@ -12,8 +18,31 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]") run_cmake(TestToolsetCudaVersionOnly) set(RunCMake_GENERATOR_TOOLSET "cuda=0.0") run_cmake(TestToolsetCudaVersionOnly) - set(RunCMake_GENERATOR_TOOLSET "cuda=C:\\dummy\\cuda") + set(RunCMake_GENERATOR_TOOLSET "cuda=${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset") run_cmake(TestToolsetCudaPathOnly) + set(RunCMake_GENERATOR_TOOLSET "cuda=${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset/CUDAVisualStudioIntegration") + run_cmake(TestToolsetCudaPathOnlyOldLayout) + file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/CudaStandaloneToolset") + if (VsNormal_Platform MATCHES "^(x64|Win32)$" AND + EXISTS "${CMAKE_ROOT}/Templates/MSBuild/FlagTables/${VsNormal_Toolset}_CL.json") + set(flagTableDir "${RunCMake_BINARY_DIR}/FlagTables") + file(READ "${CMAKE_ROOT}/Templates/MSBuild/FlagTables/${VsNormal_Toolset}_CL.json" flagTableContent) + string(REPLACE [["WX-"]] [["TESTWX-"]] flagTableContent "${flagTableContent}") + file(REMOVE_RECURSE "${flagTableDir}") + file(WRITE "${flagTableDir}/${VsNormal_Platform}_${VsNormal_Toolset}_CL.json" "${flagTableContent}") + set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=${flagTableDir}") + set(RunCMake_TEST_VARIANT_DESCRIPTION ":${VsNormal_Platform}_${VsNormal_Toolset}_CL.json") + run_cmake(TestToolsetCustomFlagTableDir) + file(REMOVE_RECURSE "${flagTableDir}") + file(WRITE "${flagTableDir}/${VsNormal_Platform}_CL.json" "${flagTableContent}") + set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=${flagTableDir}") + set(RunCMake_TEST_VARIANT_DESCRIPTION ":${VsNormal_Platform}_CL.json") + run_cmake(TestToolsetCustomFlagTableDir) + unset(RunCMake_TEST_VARIANT_DESCRIPTION) + set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=does_not_exist") + run_cmake(BadToolsetCustomFlagTableDir) + endif() if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]") set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64") run_cmake(TestToolsetHostArchBoth) @@ -76,7 +105,7 @@ endif() set(RunCMake_GENERATOR_TOOLSET "") -set(RunCMake_TEST_OPTIONS -T "Extra Toolset") +set(RunCMake_TEST_OPTIONS -T "Test Toolset" -T "Extra Toolset") run_cmake(TwoToolsets) unset(RunCMake_TEST_OPTIONS) diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt index b17745f..5236787 100644 --- a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt @@ -5,8 +5,8 @@ CMake Error at CMakeLists.txt:[0-9]+ \(project\): given toolset - cuda=C:\\dummy\\cuda\\ + cuda=.*/Tests/RunCMake/CudaStandaloneToolset\\ cannot detect Visual Studio integration files in path - C:/dummy/cuda/CUDAVisualStudioIntegration/extras/visual_studio_integration/MSBuildExtensions + .*/Tests/RunCMake/CudaStandaloneToolset/extras/visual_studio_integration/MSBuildExtensions diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-result.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-stderr.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-stderr.txt new file mode 100644 index 0000000..3ce79f8 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio .* + + given toolset + + cuda=.*/Tests/RunCMake/CudaStandaloneToolset\\ + + cannot detect Visual Studio integration files in path + + .*/Tests/RunCMake/CudaStandaloneToolset/CUDAVisualStudioIntegration/extras/visual_studio_integration/MSBuildExtensions diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnlyOldLayout.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir-check.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir-check.cmake new file mode 100644 index 0000000..79752b1 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir-check.cmake @@ -0,0 +1,24 @@ +set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/main.vcxproj") +if(NOT EXISTS "${vcProjectFile}") + set(RunCMake_TEST_FAILED "Project file\n ${vcProjectFile}\ndoes not exist.") + return() +endif() + +set(TreatWarningAsError_FOUND FALSE) +file(STRINGS "${vcProjectFile}" lines) +foreach(line IN LISTS lines) + if(line MATCHES "^ *<TreatWarningAsError>([^<>]*)</TreatWarningAsError>$") + set(TreatWarningAsError_FOUND TRUE) + set(expectedValue "false") + set(actualValue "${CMAKE_MATCH_1}") + if(NOT (${actualValue} STREQUAL ${expectedValue})) + set(RunCMake_TEST_FAILED "TreatWarningAsError \"${actualValue}\" differs from expected value \"${expectedValue}\".") + return() + endif() + endif() +endforeach() + +if(NOT TreatWarningAsError_FOUND) + set(RunCMake_TEST_FAILED "Property TreatWarningAsError not found in project file:\n ${vcProjectFile}.") + return() +endif() diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir.cmake new file mode 100644 index 0000000..91c6b44 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCustomFlagTableDir.cmake @@ -0,0 +1,3 @@ +enable_language(C) +string(APPEND CMAKE_C_FLAGS " -TESTWX-") +add_executable(main main.c) diff --git a/Tests/RunCMake/GeneratorToolset/VsNormal-stdout.txt b/Tests/RunCMake/GeneratorToolset/VsNormal-stdout.txt new file mode 100644 index 0000000..25fa3bf --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/VsNormal-stdout.txt @@ -0,0 +1,2 @@ +-- CMAKE_VS_PLATFORM_NAME='[^']+' +-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+' diff --git a/Tests/RunCMake/GeneratorToolset/VsNormal.cmake b/Tests/RunCMake/GeneratorToolset/VsNormal.cmake new file mode 100644 index 0000000..e891708 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/VsNormal.cmake @@ -0,0 +1,6 @@ +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/defaults.cmake" "# VS Defaults +set(VsNormal_Platform [[${CMAKE_VS_PLATFORM_NAME}]]) +set(VsNormal_Toolset [[${CMAKE_VS_PLATFORM_TOOLSET}]]) +") +message(STATUS "CMAKE_VS_PLATFORM_NAME='${CMAKE_VS_PLATFORM_NAME}'") +message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'") diff --git a/Tests/RunCMake/GeneratorToolset/main.c b/Tests/RunCMake/GeneratorToolset/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/GoogleTest/xml_output.cpp b/Tests/RunCMake/GoogleTest/xml_output.cpp index 82f0d02..743a472 100644 --- a/Tests/RunCMake/GoogleTest/xml_output.cpp +++ b/Tests/RunCMake/GoogleTest/xml_output.cpp @@ -5,7 +5,7 @@ int main(int argc, char** argv) { // Note: GoogleTestXML.cmake doesn't actually depend on Google Test as such; - // it only mimicks the output file creation using the path passed to this + // it only mimics the output file creation using the path passed to this // test without any content for (int i = 0; i < argc; i++) { std::string param(argv[i]); diff --git a/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake index 066c83e..c84e95e 100644 --- a/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake +++ b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake @@ -18,6 +18,9 @@ run_cmake(BinaryDirectoryInInterface) set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/DirInInstallPrefix/prefix") run_cmake(DirInInstallPrefix) +set(RunCMake_TEST_OPTIONS "--install-prefix=${RunCMake_BINARY_DIR}/DirInInstallPrefix/prefix") +run_cmake(DirInInstallPrefix) + configure_file( "${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/copy/CMakeLists.txt" @@ -34,14 +37,13 @@ configure_file( COPYONLY ) set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix" + "--install-prefix=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix" "-DTEST_FILE=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake" ) set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy") run_cmake(InstallInSrcDir) unset(RunCMake_TEST_SOURCE_DIR) -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix") set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix" "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" @@ -77,7 +79,7 @@ foreach(policyStatus NEW OLD "") set(policySuffix -CMP0052-${policyStatus}) endif() set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption} + "--install-prefix ${RunCMake_BINARY_DIR}/prefix" ${policyOption} "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" ) # Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake index 189de64..51f4f52 100644 --- a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake +++ b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake @@ -1,5 +1,10 @@ set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/build.ninja") file(READ "${log}" build_file) + +set(RunCMake_TEST_FAILED) if(NOT "${build_file}" MATCHES "depfile = test\\.d") - set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d") + list(APPEND RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d") +endif() +if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d") + list(APPEND RunCMake_TEST_FAILED "\nLog file:\n ${log}\ndoes not have expected line: depfile = test_Debug.d") endif() diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake index dbef2a5..0838d14 100644 --- a/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake +++ b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake @@ -6,6 +6,17 @@ add_custom_command( WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPFILE "test.d" ) -add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c") + +add_custom_command( + OUTPUT hello.copy2.c + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/hello.c" + hello.copy2.c + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPFILE "test_$<CONFIG>.d" + ) + +add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c" + "${CMAKE_CURRENT_BINARY_DIR}/hello.copy2.c") include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 0c0619d..1350326 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -67,7 +67,7 @@ run_CMP0058(WARN-by) run_CMP0058(NEW-no) run_CMP0058(NEW-by) -run_cmake(CustomCommandDepfile) +run_cmake_with_options(CustomCommandDepfile -DCMAKE_BUILD_TYPE=Debug) run_cmake(CustomCommandJobPool) run_cmake(JobPoolUsesTerminal) diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake index c595b10..a7837ca 100644 --- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake @@ -1,5 +1,10 @@ set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/CMakeFiles/impl-Debug.ninja") file(READ "${log}" build_file) + +set(RunCMake_TEST_FAILED) if(NOT "${build_file}" MATCHES "depfile = test\\.d") - set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d") + list(APPEND RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d") +endif() +if(NOT "${build_file}" MATCHES "depfile = test_Debug\\.d") + list(APPEND RunCMake_TEST_FAILED "\nLog file:\n ${log}\ndoes not have expected line: depfile = test_Debug.d") endif() diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake index 1a42670..4f8c114 100644 --- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake @@ -6,4 +6,15 @@ add_custom_command( WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPFILE "test.d" ) -add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c") + +add_custom_command( + OUTPUT main.copy2.c + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/main.c" + main.copy2.c + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPFILE "test_$<CONFIG>.d" + ) + +add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c" + "${CMAKE_CURRENT_BINARY_DIR}/main.copy2.c") diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt index 4dbd861..6a7c171 100644 --- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt +++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt @@ -3,7 +3,7 @@ CMake Error at BadSourceExpression3.cmake:2 \(add_library\): \$<TARGET_OBJECTS:NotObjLib> - Objects of target "NotObjLib" referenced but is not an allowed library - types \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). + Objects of target "NotObjLib" referenced but is not one of the allowed + target types \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index ea94a5b..b4a57b2 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -23,10 +23,13 @@ function(run_cmake test) endif() string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} platform_name) + #remove all additional bits from cygwin/msys name if(platform_name MATCHES cygwin) - #remove all additional bits from cygwin name set(platform_name cygwin) endif() + if(platform_name MATCHES msys) + set(platform_name msys) + endif() foreach(o out err) if(RunCMake-std${o}-file AND EXISTS ${top_src}/${RunCMake-std${o}-file}) @@ -64,15 +67,6 @@ function(run_cmake test) else() include(${top_src}/${test}-prep.cmake OPTIONAL) endif() - if(NOT DEFINED RunCMake_TEST_OPTIONS) - set(RunCMake_TEST_OPTIONS "") - endif() - if(APPLE) - list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW) - endif() - if(RunCMake_MAKE_PROGRAM) - list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}") - endif() if(RunCMake_TEST_OUTPUT_MERGE) set(actual_stderr_var actual_stdout) set(actual_stderr "") @@ -91,50 +85,51 @@ function(run_cmake test) else() set(maybe_input_file "") endif() - if(RunCMake_TEST_COMMAND) - if(NOT RunCMake_TEST_COMMAND_WORKING_DIRECTORY) - set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + if(NOT RunCMake_TEST_COMMAND) + if(NOT DEFINED RunCMake_TEST_OPTIONS) + set(RunCMake_TEST_OPTIONS "") endif() - execute_process( - COMMAND ${RunCMake_TEST_COMMAND} - WORKING_DIRECTORY "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}" - OUTPUT_VARIABLE actual_stdout - ERROR_VARIABLE ${actual_stderr_var} - RESULT_VARIABLE actual_result - ENCODING UTF8 - ${maybe_timeout} - ${maybe_input_file} - ) - else() - if(RunCMake_GENERATOR_INSTANCE) - set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${RunCMake_GENERATOR_INSTANCE}") - else() - set(_D_CMAKE_GENERATOR_INSTANCE "") + if(APPLE) + list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW) + endif() + if(RunCMake_MAKE_PROGRAM) + list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}") endif() + set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND}) if(NOT RunCMake_TEST_NO_SOURCE_DIR) - set(maybe_source_dir "${RunCMake_TEST_SOURCE_DIR}") - else() - set(maybe_source_dir "") + list(APPEND RunCMake_TEST_COMMAND "${RunCMake_TEST_SOURCE_DIR}") + endif() + list(APPEND RunCMake_TEST_COMMAND -G "${RunCMake_GENERATOR}") + if(RunCMake_GENERATOR_PLATFORM) + list(APPEND RunCMake_TEST_COMMAND -A "${RunCMake_GENERATOR_PLATFORM}") + endif() + if(RunCMake_GENERATOR_TOOLSET) + list(APPEND RunCMake_TEST_COMMAND -T "${RunCMake_GENERATOR_TOOLSET}") + endif() + if(RunCMake_GENERATOR_INSTANCE) + list(APPEND RunCMake_TEST_COMMAND "-DCMAKE_GENERATOR_INSTANCE=${RunCMake_GENERATOR_INSTANCE}") endif() - execute_process( - COMMAND ${CMAKE_COMMAND} - ${maybe_source_dir} - -G "${RunCMake_GENERATOR}" - -A "${RunCMake_GENERATOR_PLATFORM}" - -T "${RunCMake_GENERATOR_TOOLSET}" - ${_D_CMAKE_GENERATOR_INSTANCE} - -DRunCMake_TEST=${test} - --no-warn-unused-cli - ${RunCMake_TEST_OPTIONS} - WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}" - OUTPUT_VARIABLE actual_stdout - ERROR_VARIABLE ${actual_stderr_var} - RESULT_VARIABLE actual_result - ENCODING UTF8 - ${maybe_timeout} - ${maybe_input_file} + list(APPEND RunCMake_TEST_COMMAND + -DRunCMake_TEST=${test} + --no-warn-unused-cli ) + else() + set(RunCMake_TEST_OPTIONS "") endif() + if(NOT RunCMake_TEST_COMMAND_WORKING_DIRECTORY) + set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + endif() + execute_process( + COMMAND ${RunCMake_TEST_COMMAND} + ${RunCMake_TEST_OPTIONS} + WORKING_DIRECTORY "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}" + OUTPUT_VARIABLE actual_stdout + ERROR_VARIABLE ${actual_stderr_var} + RESULT_VARIABLE actual_result + ENCODING UTF8 + ${maybe_timeout} + ${maybe_input_file} + ) set(msg "") if(NOT "${actual_result}" MATCHES "${expect_result}") string(APPEND msg "Result is [${actual_result}], not [${expect_result}].\n") @@ -191,14 +186,18 @@ function(run_cmake test) if(RunCMake_TEST_FAILED) set(msg "${RunCMake_TEST_FAILED}\n${msg}") endif() - if(msg AND RunCMake_TEST_COMMAND) + if(msg) string(REPLACE ";" "\" \"" command "\"${RunCMake_TEST_COMMAND}\"") + if(RunCMake_TEST_OPTIONS) + string(REPLACE ";" "\" \"" options "\"${RunCMake_TEST_OPTIONS}\"") + string(APPEND command " ${options}") + endif() string(APPEND msg "Command was:\n command> ${command}\n") endif() if(msg) string(REGEX REPLACE "\n" "\n actual-out> " actual_out " actual-out> ${actual_stdout}") string(REGEX REPLACE "\n" "\n actual-err> " actual_err " actual-err> ${actual_stderr}") - message(SEND_ERROR "${test} - FAILED:\n" + message(SEND_ERROR "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - FAILED:\n" "${msg}" "${expect_out}" "Actual stdout:\n${actual_out}\n" @@ -206,7 +205,7 @@ function(run_cmake test) "Actual stderr:\n${actual_err}\n" ) else() - message(STATUS "${test} - PASSED") + message(STATUS "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - PASSED") endif() endfunction() diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake index 98fdf20..59db395 100644 --- a/Tests/RunCMake/RunCTest.cmake +++ b/Tests/RunCMake/RunCTest.cmake @@ -11,10 +11,13 @@ function(run_ctest CASE_NAME) endif() configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in ${RunCMake_BINARY_DIR}/${CASE_NAME}/CMakeLists.txt @ONLY) + if(NOT DEFINED RunCTest_VERBOSE_FLAG) + set(RunCTest_VERBOSE_FLAG "-V") + endif() run_cmake_command(${CASE_NAME} ${CMAKE_CTEST_COMMAND} -C Debug -S ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake - -V + ${RunCTest_VERBOSE_FLAG} --output-log ${RunCMake_BINARY_DIR}/${CASE_NAME}-build/testOutput.log --no-compress-output ${ARGN} diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt index 77c4afd..9145a56 100644 --- a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt +++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt @@ -3,7 +3,7 @@ CMake Error at NotObjlibTarget.cmake:[0-9]+ \(file\): \$<TARGET_OBJECTS:IFaceLib> - Objects of target "IFaceLib" referenced but is not an allowed library types - \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). + Objects of target "IFaceLib" referenced but is not one of the allowed + target types \(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT\). Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake b/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake new file mode 100644 index 0000000..be07dc3 --- /dev/null +++ b/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake @@ -0,0 +1,2 @@ +set(C 1) +set(CXX 1) diff --git a/Tests/RunCMake/ToolchainFile/LangVars.cmake b/Tests/RunCMake/ToolchainFile/LangVars.cmake new file mode 100644 index 0000000..169e639 --- /dev/null +++ b/Tests/RunCMake/ToolchainFile/LangVars.cmake @@ -0,0 +1,7 @@ +foreach(test_language C CXX) + enable_language(${test_language}) + if(DEFINED CMAKE_${test_language}_STANDARD_DEFAULT + AND NOT CMAKE_${test_language}_COMPILE_FEATURES) + message(FATAL_ERROR "Compile features not found for ${test_language}") + endif() +endforeach() diff --git a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake index 659523c..304c105 100644 --- a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake +++ b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake @@ -9,6 +9,7 @@ run_cmake_toolchain(CallEnableLanguage) run_cmake_toolchain(CallProject) run_cmake_toolchain(CheckLanguage) run_cmake_toolchain(FlagsInit) +run_cmake_toolchain(LangVars) run_cmake_toolchain(LinkFlagsInit) function(run_IncludeDirectories) diff --git a/Tests/RunCMake/UseSWIG/CMP0078-OLD-stderr.txt b/Tests/RunCMake/UseSWIG/CMP0078-OLD-stderr.txt new file mode 100644 index 0000000..2afdc4f --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0078-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0078-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0078 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake b/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake new file mode 100644 index 0000000..a26c278 --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-NEW-check.cmake @@ -0,0 +1,10 @@ + +cmake_policy(VERSION 3.1) + +file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CMP0122-library-name.txt" prefixes) + +list(GET prefixes 0 std_prefix) +list(GET prefixes 1 lib_prefix) +if (NOT std_prefix STREQUAL lib_prefix) + string (APPEND RunCMake_TEST_FAILED "\nFound prefix: '${lib_prefix}', expected: '${std_prefix}'.") +endif() diff --git a/Tests/RunCMake/UseSWIG/CMP0122-NEW.cmake b/Tests/RunCMake/UseSWIG/CMP0122-NEW.cmake new file mode 100644 index 0000000..fecb7db --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0122 NEW) +include(CMP0122-common.cmake) diff --git a/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake b/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake new file mode 100644 index 0000000..01657d0 --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-OLD-check.cmake @@ -0,0 +1,10 @@ + +cmake_policy(VERSION 3.1) + +file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CMP0122-library-name.txt" prefixes) + +list(GET prefixes 1 lib_prefix) +if (lib_prefix) + # prefix must be empty + string (APPEND RunCMake_TEST_FAILED "\nFound unexpected prefix: '${lib_prefix}'.") +endif() diff --git a/Tests/RunCMake/UseSWIG/CMP0122-OLD.cmake b/Tests/RunCMake/UseSWIG/CMP0122-OLD.cmake new file mode 100644 index 0000000..a787b68 --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0122 OLD) +include(CMP0122-common.cmake) diff --git a/Tests/RunCMake/UseSWIG/CMP0122-WARN-stderr.txt b/Tests/RunCMake/UseSWIG/CMP0122-WARN-stderr.txt new file mode 100644 index 0000000..37c4fbd --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-WARN-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning \(dev\) at .*/Modules/UseSWIG.cmake:[0-9]+ \(message\): + Policy CMP0122 is not set: UseSWIG use standard library name conventions + for csharp language\. Run "cmake --help-policy CMP0122" for policy details\. + Use the cmake_policy command to set the policy and suppress this warning\. + +Call Stack \(most recent call first\): + CMP0122-common.cmake:9 \(swig_add_library\) + CMP0122-WARN.cmake:1 \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/UseSWIG/CMP0122-WARN.cmake b/Tests/RunCMake/UseSWIG/CMP0122-WARN.cmake new file mode 100644 index 0000000..5d571aa --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-WARN.cmake @@ -0,0 +1 @@ +include(CMP0122-common.cmake) diff --git a/Tests/RunCMake/UseSWIG/CMP0122-common.cmake b/Tests/RunCMake/UseSWIG/CMP0122-common.cmake new file mode 100644 index 0000000..be880ec --- /dev/null +++ b/Tests/RunCMake/UseSWIG/CMP0122-common.cmake @@ -0,0 +1,12 @@ + +cmake_policy(SET CMP0078 NEW) +cmake_policy(SET CMP0086 NEW) + +set(SWIG_EXECUTABLE "swig") +set(SWIG_DIR "/swig") +include(UseSWIG) + +swig_add_library(example LANGUAGE csharp TYPE SHARED SOURCES example.i) + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/CMP0122-library-name.txt" + CONTENT "${CMAKE_SHARED_LIBRARY_PREFIX}\n$<TARGET_FILE_PREFIX:example>\n") diff --git a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake index 6acf719..c7a118f 100644 --- a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake +++ b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake @@ -23,3 +23,7 @@ if (CMake_TEST_FindPython) run_cmake_target(CMP0086-NEW build example) endif() + +run_cmake(CMP0122-WARN) +run_cmake(CMP0122-OLD) +run_cmake(CMP0122-NEW) diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in b/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in new file mode 100644 index 0000000..63e5a5c --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +//General Information about an assembly is controlled through the following +//set of attributes. Change these attribute values to modify the information +//associated with an assembly. + +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake index 80d76e4..9c9409c 100644 --- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake @@ -13,6 +13,7 @@ set(SOURCE_GROUPS_TO_FIND "CSharpSourceGroup\\\\nested\\\\baz\\.cs" "CSharpSourceGroup\\\\images\\\\empty\\.bmp" "VsCsharpSourceGroup\\.png" + "AssemblyInfo\\.cs" ) foreach(GROUP_NAME IN LISTS SOURCE_GROUPS_TO_FIND) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake index 510d712..b67868f 100644 --- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake @@ -20,3 +20,11 @@ add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES} ${RESOURCE_FI source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs) source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs) source_group("Images" FILES ${IMAGE_FILES}) + +# Test covering CMake Issue 22104. +# Basically there should not be any link tags for files in the binary directory. +include(CSharpUtilities) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/cmake/AssemblyInfo.cs.in" "Properties/AssemblyInfo.cs") + +target_sources(VsCsharpSourceGroup PRIVATE "Properties/AssemblyInfo.cs") +csharp_set_designer_cs_properties("Properties/AssemblyInfo.cs") diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS-check.cmake new file mode 100644 index 0000000..576be11 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS-check.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake) + +findAttribute(${test} "RemoveHeadersOnCopy" TRUE) +findAttribute(${test} "CodeSignOnCopy" FALSE) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS.cmake new file mode 100644 index 0000000..839f842 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-iOS.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/EmbedAppExtensions.cmake) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS-check.cmake new file mode 100644 index 0000000..576be11 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS-check.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake) + +findAttribute(${test} "RemoveHeadersOnCopy" TRUE) +findAttribute(${test} "CodeSignOnCopy" FALSE) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS.cmake new file mode 100644 index 0000000..839f842 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions-macOS.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/EmbedAppExtensions.cmake) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions.cmake new file mode 100644 index 0000000..d7494ea --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedAppExtensions.cmake @@ -0,0 +1,21 @@ +add_library(app_extension MODULE Empty.txt) +set_target_properties(app_extension PROPERTIES + LINKER_LANGUAGE CXX + BUNDLE YES + XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO" + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" + XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in" + MACOSX_BUNDLE_GUI_IDENTIFIER "com.example.app.app_extension" + XCODE_PRODUCT_TYPE "com.apple.product-type.app-extension" + XCODE_EXPLICIT_FILE_TYPE "wrapper.app-extension" +) + +add_executable(app MACOSX_BUNDLE main.m) +add_dependencies(app app_extension) +set_target_properties(app PROPERTIES + XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO" + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" + XCODE_EMBED_APP_EXTENSIONS app_extension + MACOSX_BUNDLE_GUI_IDENTIFIER "com.example.app" +) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOff-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOff-check.cmake index 9cc03b9..dbd3e87 100644 --- a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOff-check.cmake +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOff-check.cmake @@ -1,14 +1,4 @@ -function(findAttribute project attr) - execute_process( - COMMAND grep ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj - OUTPUT_VARIABLE output_var - RESULT_VARIABLE result_var - ) +include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake) - if(NOT result_var) - set(RunCMake_TEST_FAILED "${attr} attribute is set" PARENT_SCOPE) - endif() -endfunction() - -findAttribute(${test} "RemoveHeadersOnCopy") -findAttribute(${test} "CodeSignOnCopy") +findAttribute(${test} "RemoveHeadersOnCopy" FALSE) +findAttribute(${test} "CodeSignOnCopy" FALSE) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir-check.cmake index 3f62640..0f57820 100644 --- a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir-check.cmake +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnNoSubdir-check.cmake @@ -1,14 +1,4 @@ -function(findAttribute project attr) - execute_process( - COMMAND grep ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj - OUTPUT_VARIABLE output_var - RESULT_VARIABLE result_var - ) +include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake) - if(result_var) - set(RunCMake_TEST_FAILED "${attr} attribute not set" PARENT_SCOPE) - endif() -endfunction() - -findAttribute(${test} "RemoveHeadersOnCopy") -findAttribute(${test} "CodeSignOnCopy") +findAttribute(${test} "RemoveHeadersOnCopy" TRUE) +findAttribute(${test} "CodeSignOnCopy" TRUE) diff --git a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir-check.cmake b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir-check.cmake index 3f62640..0f57820 100644 --- a/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir-check.cmake +++ b/Tests/RunCMake/XcodeProject-Embed/EmbedFrameworksFlagsOnWithSubdir-check.cmake @@ -1,14 +1,4 @@ -function(findAttribute project attr) - execute_process( - COMMAND grep ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj - OUTPUT_VARIABLE output_var - RESULT_VARIABLE result_var - ) +include(${CMAKE_CURRENT_LIST_DIR}/findAttribute.cmake) - if(result_var) - set(RunCMake_TEST_FAILED "${attr} attribute not set" PARENT_SCOPE) - endif() -endfunction() - -findAttribute(${test} "RemoveHeadersOnCopy") -findAttribute(${test} "CodeSignOnCopy") +findAttribute(${test} "RemoveHeadersOnCopy" TRUE) +findAttribute(${test} "CodeSignOnCopy" TRUE) diff --git a/Tests/RunCMake/XcodeProject-Embed/Empty.txt b/Tests/RunCMake/XcodeProject-Embed/Empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/Empty.txt diff --git a/Tests/RunCMake/XcodeProject-Embed/Info.plist.in b/Tests/RunCMake/XcodeProject-Embed/Info.plist.in new file mode 100644 index 0000000..a26f316 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/Info.plist.in @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleDisplayName</key> + <string>SomeExtension</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>com.example.app.app_extension</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>app</string> + <key>CFBundlePackageType</key> + <string>XPC!</string> + <key>CFBundleShortVersionString</key> + <string>1.0.0</string> + <key>CFBundleVersion</key> + <string>1.0.0</string> + <key>NSExtension</key> + <dict> + <key>NSExtensionPointIdentifier</key> + <string>com.apple.widgetkit-extension</string> + <key>NSExtensionPrincipalClass</key> + <string>SomeExtensionBrowserViewController</string> + </dict> +</dict> +</plist> diff --git a/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake index 0dc1cf3..e94d084 100644 --- a/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject-Embed/RunCMakeTest.cmake @@ -41,3 +41,34 @@ endfunction() TestFlagsOn(EmbedFrameworksFlagsOnNoSubdir) TestFlagsOn(EmbedFrameworksFlagsOnWithSubdir) + + +function(TestAppExtension platform) + set(testName EmbedAppExtensions-${platform}) + if(NOT platform STREQUAL "macOS") + set(RunCMake_TEST_OPTIONS -DCMAKE_SYSTEM_NAME=${platform}) + endif() + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(${testName}) + run_cmake_command(${testName}-build + ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} + --config Debug + --target app + ) +endfunction() + +# Isolate device tests from host architecture selection. +unset(ENV{CMAKE_OSX_ARCHITECTURES}) + +if(XCODE_VERSION VERSION_GREATER_EQUAL 8) + # The various flag on/off combinations are tested by the EmbedFrameworks... + # tests, so we don't duplicate all the combinations here. We only verify the + # defaults, which is to remove headers on copy, but not code sign. + TestAppExtension(macOS) + TestAppExtension(iOS) +endif() diff --git a/Tests/RunCMake/XcodeProject-Embed/findAttribute.cmake b/Tests/RunCMake/XcodeProject-Embed/findAttribute.cmake new file mode 100644 index 0000000..b1963e2 --- /dev/null +++ b/Tests/RunCMake/XcodeProject-Embed/findAttribute.cmake @@ -0,0 +1,19 @@ +cmake_policy(VERSION 3.1...3.20) + +function(findAttribute project attr expectPresent) + execute_process( + COMMAND grep ${attr} ${RunCMake_TEST_BINARY_DIR}/${project}.xcodeproj/project.pbxproj + OUTPUT_VARIABLE output_var + RESULT_VARIABLE result_var + ) + + if(${expectPresent}) + if(result_var) + set(RunCMake_TEST_FAILED "${attr} attribute is not set" PARENT_SCOPE) + endif() + else() + if(NOT result_var) + set(RunCMake_TEST_FAILED "${attr} attribute is set" PARENT_SCOPE) + endif() + endif() +endfunction() diff --git a/Tests/RunCMake/XcodeProject/InheritedParameters-check.cmake b/Tests/RunCMake/XcodeProject/InheritedParameters-check.cmake new file mode 100644 index 0000000..4fe42ac --- /dev/null +++ b/Tests/RunCMake/XcodeProject/InheritedParameters-check.cmake @@ -0,0 +1,49 @@ +set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/InheritedParameters.xcodeproj/project.pbxproj") +if(NOT EXISTS "${xcProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.") + return() +endif() + +set(found_inherited_GCC_PREPROCESSOR_DEFINITIONS 1) +set(found_inherited_OTHER_CFLAGS 1) +set(found_inherited_OTHER_LDFLAGS 1) + +file(STRINGS "${xcProjectFile}" lines) +foreach(line IN LISTS lines) + + if(line MATCHES [[GCC_PREPROCESSOR_DEFINITIONS]]) + if(NOT line MATCHES [["\$\(inherited\)"]]) + string(APPEND relevant_lines " ${line}\n") + set(found_inherited_GCC_PREPROCESSOR_DEFINITIONS 0) + endif() + endif() + + if(line MATCHES [[OTHER_CFLAGS]]) + if(NOT line MATCHES [["\$\(inherited\)"]]) + string(APPEND relevant_lines " ${line}\n") + set(found_inherited_OTHER_CFLAGS 0) + endif() + endif() + + if(line MATCHES [[OTHER_LDFLAGS]]) + if(NOT line MATCHES [["\$\(inherited\)"]]) + string(APPEND relevant_lines " ${line}\n") + set(found_inherited_OTHER_LDFLAGS 0) + endif() + endif() + +endforeach() + +if(NOT found_inherited_GCC_PREPROCESSOR_DEFINITIONS) + string(APPEND RunCMake_TEST_FAILED "Found missing inherited value for GCC_PREPROCESSOR_DEFINITIONS in\n ${xcProjectFile}\n") +endif() +if(NOT found_inherited_OTHER_CFLAGS) + string(APPEND RunCMake_TEST_FAILED "Found missing inherited value for OTHER_CFLAGS in\n ${xcProjectFile}\n") +endif() +if(NOT found_inherited_OTHER_LDFLAGS) + string(APPEND RunCMake_TEST_FAILED "Found missing inherited value for OTHER_LDFLAGS in\n ${xcProjectFile}\n") +endif() + +if(RunCMake_TEST_FAILED) + string(APPEND RunCMake_TEST_FAILED "Relevant lines include\n${relevant_lines}") +endif() diff --git a/Tests/RunCMake/XcodeProject/InheritedParameters.cmake b/Tests/RunCMake/XcodeProject/InheritedParameters.cmake new file mode 100644 index 0000000..5b8ec71 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/InheritedParameters.cmake @@ -0,0 +1,8 @@ +enable_language(C) + +add_compile_definitions(TEST_INHERITTEST) +string(APPEND CMAKE_C_FLAGS " -DTESTFLAG=\\\"TEST_INHERITTEST\\\"") + +add_executable(inherit_test main.c) + +target_link_libraries(inherit_test PRIVATE "TEST_INHERITTEST") diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 8b03216..26714c4 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -4,6 +4,7 @@ run_cmake(ExplicitCMakeLists) run_cmake(ImplicitCMakeLists) run_cmake(InterfaceLibSources) run_cmake_with_options(SearchPaths -DCMAKE_CONFIGURATION_TYPES=Debug) +run_cmake(InheritedParameters) run_cmake(XcodeFileType) run_cmake(XcodeAttributeLocation) @@ -387,4 +388,30 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 8) XcodeRemoveExcessiveISystemSDK(iphoneos) XcodeRemoveExcessiveISystemSDK(iphonesimulator) endif() + +if (XCODE_VERSION VERSION_GREATER_EQUAL 7.3) + function(xctest_add_bundle_test SystemName SDK BuildSystemVersion ExpectedOutputDir) + set(RunCMake_TEST_BINARY_DIR + ${RunCMake_BINARY_DIR}/DeploymentTarget-${SystemName}-${SDK}-${BuildSystemVersion}-build) + set(RunCMake_TEST_OPTIONS + "-DCMAKE_SYSTEM_NAME=${SystemName}" + "-DCMAKE_OSX_SYSROOT=${SDK}" + "-DTEST_EXPECTED_OUTPUT_DIR=${ExpectedOutputDir}") + unset(RunCMake_GENERATOR_TOOLSET) + if(BuildSystemVersion) + set(RunCMake_GENERATOR_TOOLSET "buildsystem=${BuildSystemVersion}") + endif() + run_cmake(XCTestAddBundle) + endfunction() + + if(XCODE_VERSION VERSION_GREATER_EQUAL 12) + xctest_add_bundle_test(Darwin macosx "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns") + xctest_add_bundle_test(Darwin macosx "12" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns") + xctest_add_bundle_test(iOS iphoneos "1" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns") + xctest_add_bundle_test(iOS iphoneos "12" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>") + else() + xctest_add_bundle_test(Darwin macosx "" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns") + xctest_add_bundle_test(iOS iphoneos "" "$<TARGET_BUNDLE_CONTENT_DIR:TestedApp>/PlugIns") + endif() +endif() # Please add macOS-only tests above before the device-specific tests. diff --git a/Tests/RunCMake/XcodeProject/XCTestAddBundle.cmake b/Tests/RunCMake/XcodeProject/XCTestAddBundle.cmake new file mode 100644 index 0000000..444c730 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XCTestAddBundle.cmake @@ -0,0 +1,17 @@ +enable_language(Swift) +find_package(XCTest REQUIRED) + +add_executable(TestedApp MACOSX_BUNDLE EXCLUDE_FROM_ALL foo.swift) + +xctest_add_bundle(TestingAppBundle TestedApp foo.swift) + +get_target_property(_lib_output_dir TestingAppBundle LIBRARY_OUTPUT_DIRECTORY) + +if (NOT DEFINED TEST_EXPECTED_OUTPUT_DIR) + message(FATAL_ERROR "Testing variable TEST_EXPECTED_OUTPUT_DIR is not set") +endif() + +if (NOT _lib_output_dir STREQUAL TEST_EXPECTED_OUTPUT_DIR) + message(SEND_ERROR "Property LIBRARY_OUTPUT_DIRECTORY is expected to be ${TEST_EXPECTED_OUTPUT_DIR} " + "but was ${_lib_output_dir}") +endif() diff --git a/Tests/RunCMake/build_command/ParallelLevel.cmake b/Tests/RunCMake/build_command/ParallelLevel.cmake new file mode 100644 index 0000000..1d1e525 --- /dev/null +++ b/Tests/RunCMake/build_command/ParallelLevel.cmake @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0061 NEW) +build_command(cmd PARALLEL_LEVEL 1) +if(NOT cmd MATCHES [[ --parallel "1"]]) + message(FATAL_ERROR "Cannot find the --parallel flag") +endif() diff --git a/Tests/RunCMake/build_command/RunCMakeTest.cmake b/Tests/RunCMake/build_command/RunCMakeTest.cmake index c3bef4c..030db0b 100644 --- a/Tests/RunCMake/build_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/build_command/RunCMakeTest.cmake @@ -14,3 +14,5 @@ if(RunCMake_GENERATOR MATCHES "Make") else() run_cmake(CMP0061-OLD-other) endif() + +run_cmake(ParallelLevel) diff --git a/Tests/RunCMake/cmake_language/defer_call_ids-stdout.txt b/Tests/RunCMake/cmake_language/defer_call_ids-stdout.txt index 2fd194d..674ff1d 100644 --- a/Tests/RunCMake/cmake_language/defer_call_ids-stdout.txt +++ b/Tests/RunCMake/cmake_language/defer_call_ids-stdout.txt @@ -5,7 +5,7 @@ -- Immediate Message: cancelCall='cmake_language;DEFER;CANCEL_CALL;toBeCancelled' -- Immediate Message: getCallIds2='cmake_language;DEFER;GET_CALL_IDS;ids' -- Immediate Message: messageIds2='cmake_language;EVAL;CODE;message\(STATUS "Deferred Message: ids='\${ids}'"\)' --- Immediate Message: toBeCancelled='message;STATUS;Cancelled Message' +-- Immediate Message: toBeCancelled='message;STATUS;Canceled Message' -- Immediate Message: message3='message;STATUS;Final Deferred Message' -- First Deferred Message -- Deferred Message: ids='messageIds1;cancelCall;getCallIds2;messageIds2;toBeCancelled;message3' diff --git a/Tests/RunCMake/cmake_language/defer_call_ids.cmake b/Tests/RunCMake/cmake_language/defer_call_ids.cmake index 2874894..fd5bc17 100644 --- a/Tests/RunCMake/cmake_language/defer_call_ids.cmake +++ b/Tests/RunCMake/cmake_language/defer_call_ids.cmake @@ -4,7 +4,7 @@ cmake_language(DEFER ID messageIds1 CALL cmake_language EVAL CODE [[message(STAT cmake_language(DEFER ID cancelCall CALL cmake_language DEFER CANCEL_CALL toBeCancelled) cmake_language(DEFER ID getCallIds2 CALL cmake_language DEFER GET_CALL_IDS ids) cmake_language(DEFER ID messageIds2 CALL cmake_language EVAL CODE [[message(STATUS "Deferred Message: ids='${ids}'")]]) -cmake_language(DEFER ID toBeCancelled CALL message STATUS "Cancelled Message") +cmake_language(DEFER ID toBeCancelled CALL message STATUS "Canceled Message") cmake_language(DEFER ID message3 CALL message STATUS "Final Deferred Message") cmake_language(DEFER GET_CALL_IDS ids) message(STATUS "Immediate Message: ids='${ids}'") diff --git a/Tests/RunCMake/configure_file/NoSourcePermissions.cmake b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake index c6ad131..85533c4 100644 --- a/Tests/RunCMake/configure_file/NoSourcePermissions.cmake +++ b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake @@ -1,7 +1,7 @@ configure_file(NoSourcePermissions.sh NoSourcePermissions.sh.out NO_SOURCE_PERMISSIONS) -if (UNIX) +if (UNIX AND NOT MSYS) execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/NoSourcePermissions.sh.out RESULT_VARIABLE result) if (result EQUAL "0") diff --git a/Tests/RunCMake/configure_file/SourcePermissions.cmake b/Tests/RunCMake/configure_file/SourcePermissions.cmake index c4d3d61..f8c506a 100644 --- a/Tests/RunCMake/configure_file/SourcePermissions.cmake +++ b/Tests/RunCMake/configure_file/SourcePermissions.cmake @@ -6,7 +6,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt WORLD_READ ) -if (CMAKE_HOST_UNIX) +if (CMAKE_HOST_UNIX AND NOT MSYS) find_program(STAT_EXECUTABLE NAMES stat) if(NOT STAT_EXECUTABLE) return() diff --git a/Tests/RunCMake/ctest_build/ParallelLevel-check.cmake b/Tests/RunCMake/ctest_build/ParallelLevel-check.cmake new file mode 100644 index 0000000..f45d2a2 --- /dev/null +++ b/Tests/RunCMake/ctest_build/ParallelLevel-check.cmake @@ -0,0 +1,11 @@ +file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml") +if(build_xml_file) + file(STRINGS "${build_xml_file}" build_cmd LIMIT_COUNT 1 REGEX "<BuildCommand>") + if(NOT build_cmd MATCHES [[ --parallel "1"]]) + set(RunCMake_TEST_FAILED + "Build.xml does not have expected build command with --parallel flag" + ) + endif() +else() + set(RunCMake_TEST_FAILED "Build.xml not found") +endif() diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake index 072fbac..511cd71 100644 --- a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake @@ -10,6 +10,7 @@ function(run_ctest_build CASE_NAME) endfunction() run_ctest_build(BuildQuiet QUIET) +run_ctest_build(ParallelLevel PARALLEL_LEVEL 1) function(run_BuildFailure) set(CASE_CMAKELISTS_SUFFIX_CODE [[ diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt index b54220c..acda9e2 100644 --- a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt +++ b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt @@ -1,5 +1,12 @@ -Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-build +Test project [^ +]*/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-build( +[^*][^ +]*)* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt index c221eed..4081f98 100644 --- a/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt +++ b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt @@ -1,5 +1,12 @@ -Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadPass-build +Test project [^ +]*/Tests/RunCMake/ctest_test/CTestTestLoadPass-build( +[^*][^ +]*)* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt index 2af3838..2f4468f 100644 --- a/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt +++ b/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt @@ -1,6 +1,13 @@ -Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadWait-build +Test project [^ +]*/Tests/RunCMake/ctest_test/CTestTestLoadWait-build( +[^*][^ +]*)* \*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 4, Smallest test RunCMakeVersion requires 1\*\*\*\*\* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/OutputJUnit-check.cmake b/Tests/RunCMake/ctest_test/OutputJUnit-check.cmake new file mode 100644 index 0000000..00310a4 --- /dev/null +++ b/Tests/RunCMake/ctest_test/OutputJUnit-check.cmake @@ -0,0 +1,24 @@ +file(GLOB junit_xml_file "${RunCMake_TEST_BINARY_DIR}/junit.xml") +if(junit_xml_file) + file(READ "${junit_xml_file}" junit_xml LIMIT 4096) + if(NOT "${junit_xml}" MATCHES "tests=\"1\"") + set(RunCMake_TEST_FAILED "tests=\"1\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "failures=\"0\"") + set(RunCMake_TEST_FAILED "failures=\"0\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "disabled=\"0\"") + set(RunCMake_TEST_FAILED "disabled=\"0\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "skipped=\"0\"") + set(RunCMake_TEST_FAILED "skipped=\"0\" not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<testcase name=\"RunCMakeVersion\" classname=\"RunCMakeVersion\"") + set(RunCMake_TEST_FAILED "RunCMakeVersion not found when expected") + endif() + if(NOT "${junit_xml}" MATCHES "<system-out>cmake version") + set(RunCMake_TEST_FAILED "<system-out>cmake version not found when expected") + endif() +else() + set(RunCMake_TEST_FAILED "junit.xml not found") +endif() diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index b82335f..b559e89 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake @@ -18,6 +18,7 @@ run_ctest_test(TestQuiet QUIET) # # Spoof a load average value to make these tests more reliable. set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5) +set(RunCTest_VERBOSE_FLAG -VV) # Verify that new tests are started when the load average falls below # our threshold. @@ -53,6 +54,7 @@ run_ctest_test(TestLoadOrder TEST_LOAD "ERR4") unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING}) unset(CASE_CTEST_TEST_LOAD) +unset(RunCTest_VERBOSE_FLAG) function(run_TestChangeId) set(CASE_TEST_PREFIX_CODE [[ @@ -144,3 +146,22 @@ set_property(TEST RunCMakeVersion PROPERTY ENVIRONMENT "ENV1=env1;ENV2=env2") run_ctest(TestEnvironment) endfunction() run_environment() + +# test for OUTPUT_JUNIT +run_ctest_test(OutputJUnit OUTPUT_JUNIT junit.xml REPEAT UNTIL_FAIL:2) + +# Verify that extra measurements get reported. +function(run_measurements) + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +add_test( + NAME double_measurement + COMMAND ${CMAKE_COMMAND} -E + echo <DartMeasurement type="numeric/double" name="my_custom_value">1.4847</DartMeasurement>) +add_test( + NAME img_measurement + COMMAND ${CMAKE_COMMAND} -E + echo <DartMeasurementFile name="TestImage" type="image/png">]] ${IMAGE_DIR}/cmake-logo-16.png [[</DartMeasurementFile>) + ]]) + run_ctest(TestMeasurements) +endfunction() +run_measurements() diff --git a/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt index c4fd35b..8d21f91 100644 --- a/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt +++ b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt @@ -1,5 +1,12 @@ -Test project .*/Tests/RunCMake/ctest_test/TestLoadInvalid-build +Test project [^ +]*/Tests/RunCMake/ctest_test/TestLoadInvalid-build( +[^*][^ +]*)* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt index 22da092..1ef5f5a 100644 --- a/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt +++ b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt @@ -1,5 +1,12 @@ -Test project .*/Tests/RunCMake/ctest_test/TestLoadOrder-build +Test project [^ +]*/Tests/RunCMake/ctest_test/TestLoadOrder-build( +[^*][^ +]*)* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt index e5048f4..f3e7cd1 100644 --- a/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt +++ b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt @@ -1,5 +1,12 @@ -Test project .*/Tests/RunCMake/ctest_test/TestLoadPass-build +Test project [^ +]*/Tests/RunCMake/ctest_test/TestLoadPass-build( +[^*][^ +]*)* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt index 07f4ed3..fc32958 100644 --- a/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt +++ b/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt @@ -1,6 +1,13 @@ -Test project .*/Tests/RunCMake/ctest_test/TestLoadWait-build +Test project [^ +]*/Tests/RunCMake/ctest_test/TestLoadWait-build( +[^*][^ +]*)* \*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test RunCMakeVersion requires 1\*\*\*\*\* +test 1 Start 1: RunCMakeVersion ++( +[^*][^ +]*)* 1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec + 100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake b/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake new file mode 100644 index 0000000..9ff9447 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake @@ -0,0 +1,17 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag) +string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}") +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/Test.xml" _test_contents) + +# Check double measurement. +if(NOT _test_contents MATCHES [[NamedMeasurement type="numeric/double" name="my_custom_value"]]) + string(APPEND RunCMake_TEST_FAILED + "Could not find expected <NamedMeasurement> tag for type='numeric/double' in Test.xml") +endif() +if(NOT _test_contents MATCHES "<Value>1.4847</Value>") + string(APPEND RunCMake_TEST_FAILED "Could not find expected measurement value in Test.xml") +endif() +# Check img measurement. +if(NOT _test_contents MATCHES [[NamedMeasurement name="TestImage" type="image/png" encoding="base64"]]) + string(APPEND RunCMake_TEST_FAILED + "Could not find expected <NamedMeasurement> tag for type='image/png' in Test.xml") +endif() diff --git a/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake index c7bff15..18deb89 100644 --- a/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake +++ b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake @@ -14,6 +14,6 @@ if(UNIX) OUTPUT_STRIP_TRAILING_WHITESPACE) endif() -if(NOT WIN32 AND NOT "${uid}" STREQUAL "0") +if(NOT WIN32 AND NOT MSYS AND NOT "${uid}" STREQUAL "0") run_cmake(CHMOD-write-only) endif() diff --git a/Tests/RunCMake/file/COPY_FILE-arg-missing-result.txt b/Tests/RunCMake/file/COPY_FILE-arg-missing-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-missing-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-arg-missing-stderr.txt b/Tests/RunCMake/file/COPY_FILE-arg-missing-stderr.txt new file mode 100644 index 0000000..2ba38b6 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-missing-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-arg-missing.cmake:1 \(file\): + file COPY_FILE must be called with at least two additional arguments diff --git a/Tests/RunCMake/file/COPY_FILE-arg-missing.cmake b/Tests/RunCMake/file/COPY_FILE-arg-missing.cmake new file mode 100644 index 0000000..0e56c38 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-missing.cmake @@ -0,0 +1 @@ +file(COPY_FILE "old") diff --git a/Tests/RunCMake/file/COPY_FILE-arg-unknown-result.txt b/Tests/RunCMake/file/COPY_FILE-arg-unknown-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-unknown-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-arg-unknown-stderr.txt b/Tests/RunCMake/file/COPY_FILE-arg-unknown-stderr.txt new file mode 100644 index 0000000..e5ccd33 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-unknown-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-arg-unknown.cmake:1 \(file\): + file COPY_FILE unknown argument: + + unknown$ diff --git a/Tests/RunCMake/file/COPY_FILE-arg-unknown.cmake b/Tests/RunCMake/file/COPY_FILE-arg-unknown.cmake new file mode 100644 index 0000000..835f39e --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-arg-unknown.cmake @@ -0,0 +1 @@ +file(COPY_FILE "old" "new" unknown) diff --git a/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture-stdout.txt b/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture-stdout.txt new file mode 100644 index 0000000..45b3d27 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture-stdout.txt @@ -0,0 +1 @@ +^-- file\(COPY_FILE\) failed with result: cannot copy a directory diff --git a/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture.cmake b/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture.cmake new file mode 100644 index 0000000..acec05a --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dir-to-file-capture.cmake @@ -0,0 +1,8 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(MAKE_DIRECTORY "${oldname}") +file(COPY_FILE "${oldname}" "${newname}" RESULT result) +message(STATUS "file(COPY_FILE) failed with result: ${result}") +if(EXISTS "${newname}") + message(FATAL_ERROR "The new name exists:\n ${newname}") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-result.txt b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-stderr.txt b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-stderr.txt new file mode 100644 index 0000000..2fe8bec --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail.cmake:[0-9] \(file\): + file COPY_FILE cannot copy a directory + + [^ +]*/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail-build/input diff --git a/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail.cmake b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail.cmake new file mode 100644 index 0000000..a86ba8d --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dir-to-file-fail.cmake @@ -0,0 +1,4 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(MAKE_DIRECTORY "${oldname}") +file(COPY_FILE "${oldname}" "${newname}") diff --git a/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture-stdout.txt b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture-stdout.txt new file mode 100644 index 0000000..45b3d27 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture-stdout.txt @@ -0,0 +1 @@ +^-- file\(COPY_FILE\) failed with result: cannot copy a directory diff --git a/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture.cmake b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture.cmake new file mode 100644 index 0000000..acec05a --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-capture.cmake @@ -0,0 +1,8 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(MAKE_DIRECTORY "${oldname}") +file(COPY_FILE "${oldname}" "${newname}" RESULT result) +message(STATUS "file(COPY_FILE) failed with result: ${result}") +if(EXISTS "${newname}") + message(FATAL_ERROR "The new name exists:\n ${newname}") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-result.txt b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-stderr.txt b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-stderr.txt new file mode 100644 index 0000000..c58dc2c --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail.cmake:[0-9] \(file\): + file COPY_FILE cannot copy a directory + + [^ +]*/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail-build/input diff --git a/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail.cmake b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail.cmake new file mode 100644 index 0000000..a86ba8d --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-dirlink-to-file-fail.cmake @@ -0,0 +1,4 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(MAKE_DIRECTORY "${oldname}") +file(COPY_FILE "${oldname}" "${newname}") diff --git a/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-capture.cmake b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-capture.cmake new file mode 100644 index 0000000..028220e --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-capture.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(COPY_FILE "${oldname}" "${newname}" RESULT result ONLY_IF_DIFFERENT) +message(STATUS "file(COPY_FILE) failed with result: ${result}") +if(NOT EXISTS "${oldname}") + message(FATAL_ERROR "The old name still does not exist:\n ${oldname}") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-result.txt b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-stderr.txt b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-stderr.txt new file mode 100644 index 0000000..fd5ceee --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail.cmake:[0-9] \(file\): + file COPY_FILE cannot copy to a directory + + [^ +]*/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail-build/output diff --git a/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail.cmake b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail.cmake new file mode 100644 index 0000000..a56b4e7 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-fail.cmake @@ -0,0 +1,5 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(COPY_FILE "${oldname}" "${newname}" ONLY_IF_DIFFERENT) diff --git a/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-no-overwrite.cmake b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-no-overwrite.cmake new file mode 100644 index 0000000..059a308 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-ONLY_IF_DIFFERENT-no-overwrite.cmake @@ -0,0 +1,12 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +execute_process(COMMAND "${CMAKE_COMMAND} -E sleep 1") +file(WRITE "${newname}" "") +file(TIMESTAMP "${newname}" before_copy UTC) +file(COPY_FILE "${oldname}" "${newname}" RESULT result ONLY_IF_DIFFERENT) +file(TIMESTAMP "${newname}" after_copy UTC) +if (NOT before_copy STREQUAL after_copy) + message(FATAL_ERROR + "${newname} was modified even though ONLY_IF_DIFFERENT was specified") +endif () diff --git a/Tests/RunCMake/file/COPY_FILE-file-replace.cmake b/Tests/RunCMake/file/COPY_FILE-file-replace.cmake new file mode 100644 index 0000000..40e4290 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-replace.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "a") +file(WRITE "${newname}" "b") +file(COPY_FILE "${oldname}" "${newname}") +file(READ "${newname}" new) +if(NOT "${new}" STREQUAL "a") + message(FATAL_ERROR "New name:\n ${newname}\ndoes not contain expected content 'a'.") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture-stdout.txt b/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture-stdout.txt new file mode 100644 index 0000000..24f969f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture-stdout.txt @@ -0,0 +1 @@ +^-- file\(COPY_FILE\) failed with result: cannot copy to a directory diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture.cmake b/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture.cmake new file mode 100644 index 0000000..98621c6 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-dir-capture.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(COPY_FILE "${oldname}" "${newname}" RESULT result) +message(STATUS "file(COPY_FILE) failed with result: ${result}") +if(NOT EXISTS "${oldname}") + message(FATAL_ERROR "The old name does not exist:\n ${oldname}") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-result.txt b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-stderr.txt b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-stderr.txt new file mode 100644 index 0000000..ba2a027 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail.cmake:[0-9] \(file\): + file COPY_FILE cannot copy to a directory + + [^ +]*/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail-build/output diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail.cmake b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail.cmake new file mode 100644 index 0000000..c2628dd --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-dir-fail.cmake @@ -0,0 +1,5 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(COPY_FILE "${oldname}" "${newname}") diff --git a/Tests/RunCMake/file/COPY_FILE-file-to-file.cmake b/Tests/RunCMake/file/COPY_FILE-file-to-file.cmake new file mode 100644 index 0000000..26b702a --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-file-to-file.cmake @@ -0,0 +1,10 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(COPY_FILE "${oldname}" "${newname}") +if(NOT EXISTS "${oldname}") + message(FATAL_ERROR "The old name does not exist:\n ${oldname}") +endif() +if(NOT EXISTS "${newname}") + message(FATAL_ERROR "The new name does not exist:\n ${newname}") +endif() diff --git a/Tests/RunCMake/file/COPY_FILE-link-to-file.cmake b/Tests/RunCMake/file/COPY_FILE-link-to-file.cmake new file mode 100644 index 0000000..93a0204 --- /dev/null +++ b/Tests/RunCMake/file/COPY_FILE-link-to-file.cmake @@ -0,0 +1,10 @@ +set(lnkname "${CMAKE_CURRENT_BINARY_DIR}/link") +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${lnkname}" "a") +file(CREATE_LINK "${lnkname}" "${oldname}") +file(COPY_FILE "${oldname}" "${newname}") +file(READ "${newname}" new) +if(NOT "${new}" STREQUAL "a") + message(FATAL_ERROR "New name:\n ${newname}\ndoes not contain expected content 'a'.") +endif() diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake index be25706..0b5d3c0 100644 --- a/Tests/RunCMake/file/REAL_PATH.cmake +++ b/Tests/RunCMake/file/REAL_PATH.cmake @@ -1,14 +1,36 @@ -file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/test.txt") -file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test.sym") -file(CREATE_LINK "test.txt" "${CMAKE_CURRENT_BINARY_DIR}/test.sym" SYMBOLIC) +if (NOT WIN32 OR CYGWIN) + file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/test.txt") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test.sym") + file(CREATE_LINK "test.txt" "${CMAKE_CURRENT_BINARY_DIR}/test.sym" SYMBOLIC) -file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/test.sym" real_path) -if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") - message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") + file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/test.sym" real_path) + if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") + endif() + + file(REAL_PATH "test.sym" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") + endif() +endif() + + +If (WIN32) + cmake_path(SET HOME_DIR "$ENV{USERPROFILE}") + if (NOT HOME_DIR) + cmake_path(SET HOME_DIR "$ENV{HOME}") + endif() +else() + set(HOME_DIR "$ENV{HOME}") +endif() + +file(REAL_PATH "~" real_path EXPAND_TILDE) +if (NOT real_path STREQUAL "${HOME_DIR}") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${HOME_DIR}\"") endif() -file(REAL_PATH "test.sym" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") - message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") +file(REAL_PATH "~/test.txt" real_path EXPAND_TILDE) +if (NOT real_path STREQUAL "${HOME_DIR}/test.txt") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${HOME_DIR}/test.txt\"") endif() diff --git a/Tests/RunCMake/file/RENAME-arg-missing-result.txt b/Tests/RunCMake/file/RENAME-arg-missing-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-missing-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/RENAME-arg-missing-stderr.txt b/Tests/RunCMake/file/RENAME-arg-missing-stderr.txt new file mode 100644 index 0000000..98d2961 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-missing-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/RENAME-arg-missing.cmake:1 \(file\): + file RENAME must be called with at least two additional arguments$ diff --git a/Tests/RunCMake/file/RENAME-arg-missing.cmake b/Tests/RunCMake/file/RENAME-arg-missing.cmake new file mode 100644 index 0000000..2358ce9 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-missing.cmake @@ -0,0 +1 @@ +file(RENAME "old") diff --git a/Tests/RunCMake/file/RENAME-arg-unknown-result.txt b/Tests/RunCMake/file/RENAME-arg-unknown-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-unknown-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/RENAME-arg-unknown-stderr.txt b/Tests/RunCMake/file/RENAME-arg-unknown-stderr.txt new file mode 100644 index 0000000..16edb25 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-unknown-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/RENAME-arg-unknown.cmake:1 \(file\): + file RENAME unknown argument: + + unknown$ diff --git a/Tests/RunCMake/file/RENAME-arg-unknown.cmake b/Tests/RunCMake/file/RENAME-arg-unknown.cmake new file mode 100644 index 0000000..3110f70 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-arg-unknown.cmake @@ -0,0 +1 @@ +file(RENAME "old" "new" unknown) diff --git a/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture-stdout.txt b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture-stdout.txt new file mode 100644 index 0000000..a116330 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture-stdout.txt @@ -0,0 +1 @@ +^-- file\(RENAME\) failed with result: NO_REPLACE$ diff --git a/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture.cmake b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture.cmake new file mode 100644 index 0000000..1ff4178 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-capture.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "a") +file(WRITE "${newname}" "b") +file(RENAME "${oldname}" "${newname}" NO_REPLACE RESULT result) +message(STATUS "file(RENAME) failed with result: ${result}") +if(NOT EXISTS "${oldname}") + message(FATAL_ERROR "The old name does not still exist:\n ${oldname}") +endif() diff --git a/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-result.txt b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-stderr.txt b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-stderr.txt new file mode 100644 index 0000000..dd7294c --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-stderr.txt @@ -0,0 +1,13 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake:[0-9] \(file\): + file RENAME failed to rename + + [^ +]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-build/input + + to + + [^ +]*/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail-build/output + + because: path not replaced$ diff --git a/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake new file mode 100644 index 0000000..c05dd63 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-NO_REPLACE-fail.cmake @@ -0,0 +1,5 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "a") +file(WRITE "${newname}" "b") +file(RENAME "${oldname}" "${newname}" NO_REPLACE) diff --git a/Tests/RunCMake/file/RENAME-file-replace.cmake b/Tests/RunCMake/file/RENAME-file-replace.cmake new file mode 100644 index 0000000..efbfaed --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-replace.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "a") +file(WRITE "${newname}" "b") +file(RENAME "${oldname}" "${newname}") +file(READ "${newname}" new) +if(NOT "${new}" STREQUAL "a") + message(FATAL_ERROR "New name:\n ${newname}\ndoes not contain expected content 'a'.") +endif() diff --git a/Tests/RunCMake/file/RENAME-file-to-dir-capture-stdout.txt b/Tests/RunCMake/file/RENAME-file-to-dir-capture-stdout.txt new file mode 100644 index 0000000..0276a5f --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-dir-capture-stdout.txt @@ -0,0 +1 @@ +^-- file\(RENAME\) failed with result: [A-Za-z] diff --git a/Tests/RunCMake/file/RENAME-file-to-dir-capture.cmake b/Tests/RunCMake/file/RENAME-file-to-dir-capture.cmake new file mode 100644 index 0000000..4f817e8 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-dir-capture.cmake @@ -0,0 +1,9 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(RENAME "${oldname}" "${newname}" RESULT result) +message(STATUS "file(RENAME) failed with result: ${result}") +if(NOT EXISTS "${oldname}") + message(FATAL_ERROR "The old name does not still exist:\n ${oldname}") +endif() diff --git a/Tests/RunCMake/file/RENAME-file-to-dir-fail-result.txt b/Tests/RunCMake/file/RENAME-file-to-dir-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-dir-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/RENAME-file-to-dir-fail-stderr.txt b/Tests/RunCMake/file/RENAME-file-to-dir-fail-stderr.txt new file mode 100644 index 0000000..e4dbc38 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-dir-fail-stderr.txt @@ -0,0 +1,13 @@ +^CMake Error at [^ +]*/Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake:[0-9] \(file\): + file RENAME failed to rename + + [^ +]*/Tests/RunCMake/file/RENAME-file-to-dir-fail-build/input + + to + + [^ +]*/Tests/RunCMake/file/RENAME-file-to-dir-fail-build/output + + because: [A-Za-z] diff --git a/Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake b/Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake new file mode 100644 index 0000000..61fa644 --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-dir-fail.cmake @@ -0,0 +1,5 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(MAKE_DIRECTORY "${newname}") +file(RENAME "${oldname}" "${newname}") diff --git a/Tests/RunCMake/file/RENAME-file-to-file.cmake b/Tests/RunCMake/file/RENAME-file-to-file.cmake new file mode 100644 index 0000000..dbc411be --- /dev/null +++ b/Tests/RunCMake/file/RENAME-file-to-file.cmake @@ -0,0 +1,10 @@ +set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input") +set(newname "${CMAKE_CURRENT_BINARY_DIR}/output") +file(WRITE "${oldname}" "") +file(RENAME "${oldname}" "${newname}") +if(EXISTS "${oldname}") + message(FATAL_ERROR "The old name still exists:\n ${oldname}") +endif() +if(NOT EXISTS "${newname}") + message(FATAL_ERROR "The new name does not exist:\n ${newname}") +endif() diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 22813eb..9efd3f4 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -50,6 +50,30 @@ run_cmake(SIZE-error-does-not-exist) run_cmake(REMOVE-empty) +run_cmake_script(COPY_FILE-file-replace) +run_cmake_script(COPY_FILE-dir-to-file-capture) +run_cmake_script(COPY_FILE-dir-to-file-fail) +run_cmake_script(COPY_FILE-dirlink-to-file-capture) +run_cmake_script(COPY_FILE-dirlink-to-file-fail) +run_cmake_script(COPY_FILE-file-to-file) +run_cmake_script(COPY_FILE-file-to-dir-capture) +run_cmake_script(COPY_FILE-file-to-dir-fail) +run_cmake_script(COPY_FILE-file-ONLY_IF_DIFFERENT-capture) +run_cmake_script(COPY_FILE-file-ONLY_IF_DIFFERENT-fail) +run_cmake_script(COPY_FILE-file-ONLY_IF_DIFFERENT-no-overwrite) +run_cmake_script(COPY_FILE-link-to-file) +run_cmake_script(COPY_FILE-arg-missing) +run_cmake_script(COPY_FILE-arg-unknown) + +run_cmake_script(RENAME-file-replace) +run_cmake_script(RENAME-file-to-file) +run_cmake_script(RENAME-file-to-dir-capture) +run_cmake_script(RENAME-file-to-dir-fail) +run_cmake_script(RENAME-file-NO_REPLACE-capture) +run_cmake_script(RENAME-file-NO_REPLACE-fail) +run_cmake_script(RENAME-arg-missing) +run_cmake_script(RENAME-arg-unknown) + # tests are valid both for GLOB and GLOB_RECURSE run_cmake(GLOB-sort-dedup) run_cmake(GLOB-error-LIST_DIRECTORIES-not-boolean) @@ -63,7 +87,9 @@ run_cmake(GLOB-noexp-RELATIVE) run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake) -if(NOT WIN32 OR CYGWIN) +if(NOT WIN32 + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) run_cmake(CREATE_LINK-SYMBOLIC) run_cmake(CREATE_LINK-SYMBOLIC-noexist) run_cmake(GLOB_RECURSE-cyclic-recursion) @@ -72,11 +98,12 @@ if(NOT WIN32 OR CYGWIN) run_cmake(READ_SYMLINK-noexist) run_cmake(READ_SYMLINK-notsymlink) run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN) - run_cmake(REAL_PATH-unexpected-arg) - run_cmake(REAL_PATH-no-base-dir) - run_cmake(REAL_PATH) endif() +run_cmake(REAL_PATH-unexpected-arg) +run_cmake(REAL_PATH-no-base-dir) +run_cmake(REAL_PATH) + if(RunCMake_GENERATOR MATCHES "Ninja") # Detect ninja version so we know what tests can be supported. execute_process( @@ -137,7 +164,9 @@ else() run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second ${CMAKE_COMMAND} --build .) run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-nowork ${CMAKE_COMMAND} --build .) - if(NOT WIN32 OR CYGWIN) + if(NOT WIN32 + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) message(STATUS "GLOB-CONFIGURE_DEPENDS-CMP0009-RerunCMake: link the first test directory into a new directory...") file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/test2") execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${RunCMake_TEST_BINARY_DIR}/test" "${RunCMake_TEST_BINARY_DIR}/test2/test_folder_symlink") diff --git a/Tests/RunCMake/find_file/FromPATHEnv-stdout-msys.txt b/Tests/RunCMake/find_file/FromPATHEnv-stdout-msys.txt new file mode 100644 index 0000000..6912bdf --- /dev/null +++ b/Tests/RunCMake/find_file/FromPATHEnv-stdout-msys.txt @@ -0,0 +1,9 @@ +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_File='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' +-- PrefixInPATH_File='PrefixInPATH_File-NOTFOUND' diff --git a/Tests/RunCMake/find_file/PrefixInPATH-stdout-msys.txt b/Tests/RunCMake/find_file/PrefixInPATH-stdout-msys.txt new file mode 100644 index 0000000..d73bc1d --- /dev/null +++ b/Tests/RunCMake/find_file/PrefixInPATH-stdout-msys.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' diff --git a/Tests/RunCMake/find_library/FromPATHEnv-stdout-msys.txt b/Tests/RunCMake/find_library/FromPATHEnv-stdout-msys.txt new file mode 100644 index 0000000..01e2720 --- /dev/null +++ b/Tests/RunCMake/find_library/FromPATHEnv-stdout-msys.txt @@ -0,0 +1,6 @@ +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' +-- CREATED_LIBRARY='[^']*/Tests/RunCMake/find_library/FromPATHEnv-build/lib/libcreated.a' +-- CREATED_LIBRARY='[^']*/Tests/RunCMake/find_library/FromPATHEnv-build/lib/libcreated.a' +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' +-- CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' diff --git a/Tests/RunCMake/find_library/PrefixInPATH-stdout-msys.txt b/Tests/RunCMake/find_library/PrefixInPATH-stdout-msys.txt new file mode 100644 index 0000000..1ab884c --- /dev/null +++ b/Tests/RunCMake/find_library/PrefixInPATH-stdout-msys.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_LIBRARY='PrefixInPATH_LIBRARY-NOTFOUND' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index a899f46..72ffcce 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -40,6 +40,8 @@ run_cmake(VersionRangeConfig) run_cmake(VersionRangeConfig2) run_cmake(VersionRangeConfigStd) run_cmake(VersionRangeConfigStd2) -if(UNIX) +if(UNIX + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) run_cmake(SetFoundResolved) endif() diff --git a/Tests/RunCMake/find_path/FromPATHEnv-stdout-msys.txt b/Tests/RunCMake/find_path/FromPATHEnv-stdout-msys.txt new file mode 100644 index 0000000..8f3e7ca --- /dev/null +++ b/Tests/RunCMake/find_path/FromPATHEnv-stdout-msys.txt @@ -0,0 +1,9 @@ +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='.*/Tests/RunCMake/find_path/include' +-- PATH_IN_ENV_PATH='.*/Tests/RunCMake/find_path/include' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' +-- PATH_IN_ENV_PATH='PATH_IN_ENV_PATH-NOTFOUND' diff --git a/Tests/RunCMake/find_path/PrefixInPATH-stdout-msys.txt b/Tests/RunCMake/find_path/PrefixInPATH-stdout-msys.txt new file mode 100644 index 0000000..bb2ceb7 --- /dev/null +++ b/Tests/RunCMake/find_path/PrefixInPATH-stdout-msys.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake index 3e23920..77c021d 100644 --- a/Tests/RunCMake/find_program/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake @@ -6,7 +6,7 @@ run_cmake(NamesPerDir) run_cmake(RelAndAbsPath) run_cmake(Required) -if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$") +if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$") run_cmake(WindowsCom) run_cmake(WindowsExe) else() diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake index d3f7c23..15ca477 100644 --- a/Tests/RunCMake/foreach/RunCMakeTest.cmake +++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake @@ -20,3 +20,5 @@ run_cmake(foreach-RANGE-non-int-test-3-2) run_cmake(foreach-RANGE-non-int-test-3-3) run_cmake(foreach-RANGE-invalid-test) run_cmake(foreach-RANGE-out-of-range-test) +run_cmake(foreach-var-scope-CMP0124-OLD) +run_cmake(foreach-var-scope-CMP0124-NEW) diff --git a/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake new file mode 100644 index 0000000..7e2eee0 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake @@ -0,0 +1,51 @@ + +cmake_policy(SET CMP0124 NEW) + +foreach(VAR a b c) +endforeach() +if (DEFINED VAR) + message(SEND_ERROR "Variable 'VAR' unexpectedly defined.") +endif() + +set(LIST1 a b c) +set(LIST2 x y z) +foreach(VAR1_1 VAR1_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (DEFINED VAR1_1 OR DEFINED VAR1_2) + message(SEND_ERROR "Variables 'VAR1_1' or 'VAR1_2' unexpectedly defined.") +endif() + + +set (VAR2 OLD) +foreach(VAR2 a b c) +endforeach() +if (NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR2' not defined or wrong value.") +endif() + +set (VAR2_2 OLD) +foreach(VAR2_1 VAR2_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (DEFINED VAR2_1 OR NOT DEFINED VAR2_2) + message(SEND_ERROR "Variable 'VAR2_1' unexpectedly defined or variable 'VAR2_2' not defined.") +endif() + + +set (VAR3 OLD CACHE STRING "") +foreach(VAR3 a b c) +endforeach() +# check that only cache variable is defined +set(OLD_VALUE "${VAR3}") +unset(VAR3 CACHE) +if (DEFINED VAR3 OR NOT OLD_VALUE STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3' wrongly defined or wrong value.") +endif() + +set (VAR3_2 OLD CACHE STRING "") +foreach(VAR3_1 VAR3_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +set(OLD_VALUE "${VAR3_2}") +unset(VAR3_2 CACHE) +if (DEFINED VAR3_1 OR DEFINED VAR3_2 OR NOT OLD_VALUE STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3_1' unexpectedly defined or variable 'VAR2_2' wrongly defined or wrong value.") +endif() diff --git a/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake new file mode 100644 index 0000000..f955982 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake @@ -0,0 +1,53 @@ + +cmake_policy(SET CMP0124 OLD) + +foreach(VAR a b c) +endforeach() +if (NOT DEFINED VAR OR NOT VAR STREQUAL "") + message(SEND_ERROR "Variable 'VAR' not defined or wrong value.") +endif() + +set(LIST1 a b c) +set(LIST2 x y z) +foreach(VAR1_1 VAR1_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (NOT DEFINED VAR1_1 OR NOT VAR1_1 STREQUAL "" + OR NOT DEFINED VAR1_2 OR NOT VAR1_2 STREQUAL "") + message(SEND_ERROR "Variables 'VAR1_1' or 'VAR1_2' not defined or wrong value.") +endif() + + +set (VAR2 OLD) +foreach(VAR2 a b c) +endforeach() +if (NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR2' not defined or wrong value.") +endif() + +set (VAR2_2 OLD) +foreach(VAR2_1 VAR2_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (NOT DEFINED VAR2_1 OR NOT VAR2_1 STREQUAL "" + OR NOT DEFINED VAR2_2 OR NOT VAR2_2 STREQUAL "OLD") + message(SEND_ERROR "Variables 'VAR2_1' or 'VAR2_2' not defined or wrong value.") +endif() + + +set (VAR3 OLD CACHE STRING "") +foreach(VAR3 a b c) +endforeach() +# a normal variable is defined, holding cache variable value +unset(VAR3 CACHE) +if (NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3' not defined or wrong value.") +endif() + +set (VAR3_2 OLD CACHE STRING "") +foreach(VAR3_1 VAR3_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +# a normal variable is defined, holding cache variable value +unset(VAR3_2 CACHE) +if (NOT DEFINED VAR3_1 OR NOT VAR3_1 STREQUAL "" + OR NOT DEFINED VAR3_2 OR NOT VAR3_2 STREQUAL "OLD") + message(SEND_ERROR "Variables 'VAR3_1' or 'VAR3_2' not defined or wrong value.") +endif() diff --git a/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake b/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake index 7ed0773..cb0eb18 100644 --- a/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake +++ b/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake @@ -8,4 +8,5 @@ run_cmake(CustomConfig) if(RunCMake_GENERATOR MATCHES "Visual Studio ([^9]|9[0-9])") run_cmake(SkipGetTargetFrameworkProperties) + run_cmake(VSCSharpReference) endif() diff --git a/Tests/RunCMake/include_external_msproject/VSCSharpReference-check.cmake b/Tests/RunCMake/include_external_msproject/VSCSharpReference-check.cmake new file mode 100644 index 0000000..71b8c1f --- /dev/null +++ b/Tests/RunCMake/include_external_msproject/VSCSharpReference-check.cmake @@ -0,0 +1,36 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/internal.vcxproj" all_build) + +string(REGEX MATCH + "<ProjectReference.Include=.external.csproj.>.*</ProjectReference>" + ProjectReference + ${all_build} +) + +if(ProjectReference STREQUAL "") + set(RunCMake_TEST_FAILED "${test} is being set unexpectedly.") +else() + string(REGEX MATCH + "<ReferenceOutputAssembly>.*</ReferenceOutputAssembly>" + ReferenceOutputAssembly + ${ProjectReference} + ) + + if(NOT ReferenceOutputAssembly STREQUAL "") + string(REPLACE + "<ReferenceOutputAssembly>" + "" + ReferenceOutputAssemblyValue + ${ReferenceOutputAssembly} + ) + string(REPLACE + "</ReferenceOutputAssembly>" + "" + ReferenceOutputAssemblyValue + ${ReferenceOutputAssemblyValue} + ) + + if(ReferenceOutputAssemblyValue MATCHES "[Fa][Ll][Ss][Ee]") + set(RunCMake_TEST_FAILED "Referenced C# project with ReferenceOutputAssembly set to false.") + endif() + endif() +endif() diff --git a/Tests/RunCMake/include_external_msproject/VSCSharpReference.cmake b/Tests/RunCMake/include_external_msproject/VSCSharpReference.cmake new file mode 100644 index 0000000..6229e61 --- /dev/null +++ b/Tests/RunCMake/include_external_msproject/VSCSharpReference.cmake @@ -0,0 +1,10 @@ +project(VSCSharpReference) + +include_external_msproject(external external.csproj) + +add_executable(internal + main.cpp +) +add_dependencies(internal + external +) diff --git a/Tests/RunCMake/install/FILES-directory-result.txt b/Tests/RunCMake/install/FILES-directory-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/FILES-directory-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/FILES-directory-stderr.txt b/Tests/RunCMake/install/FILES-directory-stderr.txt new file mode 100644 index 0000000..4699037 --- /dev/null +++ b/Tests/RunCMake/install/FILES-directory-stderr.txt @@ -0,0 +1 @@ +install FILES given directory diff --git a/Tests/RunCMake/install/FILES-directory.cmake b/Tests/RunCMake/install/FILES-directory.cmake new file mode 100644 index 0000000..1199cf7 --- /dev/null +++ b/Tests/RunCMake/install/FILES-directory.cmake @@ -0,0 +1,7 @@ +set(dst "${CMAKE_CURRENT_BINARY_DIR}/dst") +set(src "${CMAKE_CURRENT_BINARY_DIR}/src") + +file(MAKE_DIRECTORY "${dst}") +file(MAKE_DIRECTORY "${src}") + +install(FILES "${src}" DESTINATION "${dst}") diff --git a/Tests/RunCMake/install/FILES-symlink-to-directory.cmake b/Tests/RunCMake/install/FILES-symlink-to-directory.cmake new file mode 100644 index 0000000..ed76470 --- /dev/null +++ b/Tests/RunCMake/install/FILES-symlink-to-directory.cmake @@ -0,0 +1,9 @@ +set(dst "${CMAKE_CURRENT_BINARY_DIR}/dst") +set(src "${CMAKE_CURRENT_BINARY_DIR}/src") +set(lnk "${CMAKE_CURRENT_BINARY_DIR}/lnk") + +file(MAKE_DIRECTORY "${dst}") +file(MAKE_DIRECTORY "${src}") +file(CREATE_LINK "${src}" "${lnk}" SYMBOLIC) + +install(FILES "${lnk}" DESTINATION "${dst}") diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index efd03df..94887a0 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -55,9 +55,9 @@ function(run_cmake_EDIT_RPATH_only case) else() # Sanity check against a platform known to be ELF-based if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - message(FATAL_ERROR "Expected platform Linux to advertize itself as ELF-based, but it did not.") + message(FATAL_ERROR "Expected platform Linux to advertise itself as ELF-based, but it did not.") elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX") - message(FATAL_ERROR "Expected platform AIX to advertize itself as XCOFF-based, but it did not.") + message(FATAL_ERROR "Expected platform AIX to advertise itself as XCOFF-based, but it did not.") else() message(STATUS "${case} - SKIPPED (No ELF-based platform found)") endif() @@ -93,6 +93,10 @@ run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all) run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc) run_cmake(FILES-DESTINATION-TYPE) run_cmake(DIRECTORY-DESTINATION-TYPE) +run_cmake(FILES-directory) +if(NOT WIN32) + run_cmake(FILES-symlink-to-directory) +endif() set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug") run_install_test(FILES-RENAME) @@ -175,3 +179,4 @@ run_install_test(FILES-EXCLUDE_FROM_ALL) run_install_test(TARGETS-EXCLUDE_FROM_ALL) run_install_test(TARGETS-NAMELINK_COMPONENT) run_install_test(SCRIPT-COMPONENT) +run_install_test(SCRIPT-ALL_COMPONENTS) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake new file mode 100644 index 0000000..aa3f9d1 --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake @@ -0,0 +1,5 @@ +install( + SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake" + CODE "write_empty_file(empty2.txt)" + ALL_COMPONENTS + ) diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake index 4a55cd6..d099469 100644 --- a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake +++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake @@ -13,6 +13,21 @@ if(WIN32) [[mylib/(lib)?lib1\.(dll\.a|lib)]] [[mylib/(lib)?lib2\.(a|lib)]] ) +elseif(MSYS) + set(_check_files + [[lib3]] + [[lib3/liblib3\.dll\.a]] + [[lib4]] + [[lib4/msys-lib4\.dll]] + [[mybin]] + [[mybin/exe\.exe]] + [[mybin/msys-lib1\.dll]] + [[myinclude]] + [[myinclude/obj3\.h]] + [[mylib]] + [[mylib/liblib1\.dll\.a]] + [[mylib/liblib2\.a]] + ) elseif(CYGWIN) set(_check_files [[lib3]] diff --git a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake index 30f2266..6e13b84 100644 --- a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake +++ b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake @@ -15,6 +15,23 @@ if(WIN32) [[lib4]] [[lib4/(lib)?lib4\.dll]] ) +elseif(MSYS) + set(_check_files + [[bin]] + [[bin/exe\.exe]] + [[bin/msys-lib1\.dll]] + [[include]] + [[include/obj1\.h]] + [[include/obj2\.h]] + [[include/obj3\.h]] + [[lib]] + [[lib/liblib1\.dll\.a]] + [[lib/liblib2\.a]] + [[lib3]] + [[lib3/liblib3\.dll\.a]] + [[lib4]] + [[lib4/msys-lib4\.dll]] + ) elseif(CYGWIN) set(_check_files [[bin]] diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake index bc9ebd1..e602af9 100644 --- a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake +++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-all-check.cmake @@ -8,6 +8,16 @@ if(WIN32) [[lib/(lib)?namelink-uns-dev\.dll]] [[lib/(lib)?namelink-uns\.dll]] ) +elseif(MSYS) + set(_check_files + [[lib]] + [[lib/msys-namelink-none\.dll]] + [[lib/msys-namelink-same-1\.dll]] + [[lib/msys-namelink-sep-1\.dll]] + [[lib/msys-namelink-skip-1\.dll]] + [[lib/msys-namelink-uns-1\.dll]] + [[lib/msys-namelink-uns-dev-1\.dll]] + ) elseif(CYGWIN) set(_check_files [[lib]] diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake index 3f6be68..cd579eb 100644 --- a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake +++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-lib-check.cmake @@ -6,6 +6,14 @@ if(WIN32) [[lib/(lib)?namelink-sep\.dll]] [[lib/(lib)?namelink-skip\.dll]] ) +elseif(MSYS) + set(_check_files + [[lib]] + [[lib/msys-namelink-none\.dll]] + [[lib/msys-namelink-same-1\.dll]] + [[lib/msys-namelink-sep-1\.dll]] + [[lib/msys-namelink-skip-1\.dll]] + ) elseif(CYGWIN) set(_check_files [[lib]] diff --git a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake index 0033c88..ea68f4a 100644 --- a/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake +++ b/Tests/RunCMake/install/TARGETS-NAMELINK_COMPONENT-uns-check.cmake @@ -4,6 +4,12 @@ if(WIN32) [[lib/(lib)?namelink-uns-dev\.dll]] [[lib/(lib)?namelink-uns\.dll]] ) +elseif(MSYS) + set(_check_files + [[lib]] + [[lib/msys-namelink-uns-1\.dll]] + [[lib/msys-namelink-uns-dev-1\.dll]] + ) elseif(CYGWIN) set(_check_files [[lib]] diff --git a/Tests/RunCMake/install/TARGETS-OUTPUT_NAME-all-check.cmake b/Tests/RunCMake/install/TARGETS-OUTPUT_NAME-all-check.cmake index 5daecc8..91d5ef0 100644 --- a/Tests/RunCMake/install/TARGETS-OUTPUT_NAME-all-check.cmake +++ b/Tests/RunCMake/install/TARGETS-OUTPUT_NAME-all-check.cmake @@ -4,6 +4,8 @@ if(WIN32) set(test45 [[bin/test4\.dll;bin/test4\.lib;bin/test5ar\.lib]]) check_installed("^bin;(${libtest45};${test123})|(${test123};${test45})\$") +elseif(MSYS) + check_installed([[^bin;bin/libtest4\.dll\.a;bin/libtest5ar\.a;bin/msys-test4\.dll;bin/test1out\.exe;bin/test2deb\.exe;bin/test3exc\.exe$]]) elseif(CYGWIN) check_installed([[^bin;bin/cygtest4\.dll;bin/libtest4\.dll\.a;bin/libtest5ar\.a;bin/test1out\.exe;bin/test2deb\.exe;bin/test3exc\.exe$]]) elseif(APPLE) diff --git a/Tests/RunCMake/option/CMP0077-OLD-stderr.txt b/Tests/RunCMake/option/CMP0077-OLD-stderr.txt new file mode 100644 index 0000000..9d963cb --- /dev/null +++ b/Tests/RunCMake/option/CMP0077-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0077-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0077 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/project/ProjectIsTopLevel-stdout.txt b/Tests/RunCMake/project/ProjectIsTopLevel-stdout.txt new file mode 100644 index 0000000..af8abfd --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevel-stdout.txt @@ -0,0 +1,2 @@ +-- PROJECT_IS_TOP_LEVEL=ON +-- ProjectIsTopLevel_IS_TOP_LEVEL=ON diff --git a/Tests/RunCMake/project/ProjectIsTopLevel.cmake b/Tests/RunCMake/project/ProjectIsTopLevel.cmake new file mode 100644 index 0000000..5a0af0a --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevel.cmake @@ -0,0 +1,9 @@ +# no project() call, includer already calls project(${RunCMake_TEST} NONE) +if(NOT DEFINED PROJECT_IS_TOP_LEVEL) + message(FATAL_ERROR "PROJECT_IS_TOP_LEVEL is not defined") +endif() +if(NOT DEFINED "CACHE{${RunCMake_TEST}_IS_TOP_LEVEL}") + message(FATAL_ERROR "IsTopLevel_IS_TOP_LEVEL is not defined") +endif() +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") +message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}") diff --git a/Tests/RunCMake/project/ProjectIsTopLevelMultiple-stdout.txt b/Tests/RunCMake/project/ProjectIsTopLevelMultiple-stdout.txt new file mode 100644 index 0000000..75d787f --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevelMultiple-stdout.txt @@ -0,0 +1,3 @@ +-- PROJECT_IS_TOP_LEVEL=ON +-- ProjectIsTopLevelMultiple_IS_TOP_LEVEL=ON +-- IsTopLevel_IS_TOP_LEVEL=ON diff --git a/Tests/RunCMake/project/ProjectIsTopLevelMultiple.cmake b/Tests/RunCMake/project/ProjectIsTopLevelMultiple.cmake new file mode 100644 index 0000000..98ba55b --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevelMultiple.cmake @@ -0,0 +1,14 @@ +# only one project() call, includer already calls project(${RunCMake_TEST} NONE) +project(IsTopLevel NONE) +if(NOT DEFINED PROJECT_IS_TOP_LEVEL) + message(FATAL_ERROR "PROJECT_IS_TOP_LEVEL is not defined") +endif() +if(NOT DEFINED "CACHE{${RunCMake_TEST}_IS_TOP_LEVEL}") + message(FATAL_ERROR "${RunCMake_TEST}_IS_TOP_LEVEL is not defined") +endif() +if(NOT DEFINED CACHE{IsTopLevel_IS_TOP_LEVEL}) + message(FATAL_ERROR "IsTopLevel_IS_TOP_LEVEL is not defined") +endif() +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") +message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}") +message(STATUS "IsTopLevel_IS_TOP_LEVEL=${IsTopLevel_IS_TOP_LEVEL}") diff --git a/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory-stdout.txt b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory-stdout.txt new file mode 100644 index 0000000..d9e15ff --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory-stdout.txt @@ -0,0 +1,6 @@ +-- PROJECT_IS_TOP_LEVEL=ON +-- PROJECT_IS_TOP_LEVEL=ON +-- PROJECT_IS_TOP_LEVEL=OFF +-- PROJECT_IS_TOP_LEVEL=ON +-- ProjectIsTopLevelSubdirectory_IS_TOP_LEVEL=ON +-- NotTopLevel_IS_TOP_LEVEL=OFF diff --git a/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory.cmake b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory.cmake new file mode 100644 index 0000000..b5df84b --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory.cmake @@ -0,0 +1,8 @@ +# no project() call, includer already calls project(${RunCMake_TEST} NONE) +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") + +add_subdirectory(ProjectIsTopLevelSubdirectory) + +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") +message(STATUS "${RunCMake_TEST}_IS_TOP_LEVEL=${${RunCMake_TEST}_IS_TOP_LEVEL}") +message(STATUS "NotTopLevel_IS_TOP_LEVEL=${NotTopLevel_IS_TOP_LEVEL}") diff --git a/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory/CMakeLists.txt b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory/CMakeLists.txt new file mode 100644 index 0000000..d2f16ea --- /dev/null +++ b/Tests/RunCMake/project/ProjectIsTopLevelSubdirectory/CMakeLists.txt @@ -0,0 +1,5 @@ +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") + +project(NotTopLevel NONE) + +message(STATUS "PROJECT_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}") diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake index 6914699..349e8ac 100644 --- a/Tests/RunCMake/project/RunCMakeTest.cmake +++ b/Tests/RunCMake/project/RunCMakeTest.cmake @@ -15,6 +15,9 @@ run_cmake(ProjectDescriptionNoArg2) run_cmake(ProjectHomepage) run_cmake(ProjectHomepage2) run_cmake(ProjectHomepageNoArg) +run_cmake(ProjectIsTopLevel) +run_cmake(ProjectIsTopLevelMultiple) +run_cmake(ProjectIsTopLevelSubdirectory) run_cmake(ProjectTwice) run_cmake(VersionAndLanguagesEmpty) run_cmake(VersionEmpty) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stderr.txt new file mode 100644 index 0000000..c664505 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at CMP0079-iface-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0079 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt index 0b4c4c6..14f4789 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt @@ -1,4 +1,15 @@ -^CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): +^CMake Deprecation Warning at CMP0079-link-OLD.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0079 will be removed from a future version + of CMake. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) ++ +CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): Attempt to add link library "foo" to target "top" which is not built in this directory. diff --git a/Tests/SetLang/CMakeLists.txt b/Tests/SetLang/CMakeLists.txt index 3eb9185..80348ab 100644 --- a/Tests/SetLang/CMakeLists.txt +++ b/Tests/SetLang/CMakeLists.txt @@ -9,6 +9,10 @@ set_source_files_properties(foo.c bar.c PROPERTIES LANGUAGE CXX) target_link_libraries(SetLang foo) set_target_properties(SetLang PROPERTIES LINKER_LANGUAGE CXX) +# Windows defender blocks SetLang executable (https://cygwin.com/pipermail/cygwin/2021-January/247508.html) +# Coordinate this name with 'Tests/CMakeLists.txt'. +set_target_properties(SetLang PROPERTIES OUTPUT_NAME "SetLangX") + # VS generators historically tolerated target-wide -TP flags added # by project code, so cover that case to preserve the behavior. if(CMAKE_GENERATOR MATCHES "^Visual Studio" AND "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC") diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt index faf3bc9..068fae9 100644 --- a/Tests/StringFileTest/CMakeLists.txt +++ b/Tests/StringFileTest/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(StringFileTest) include_directories(${StringFileTest_BINARY_DIR}) diff --git a/Tests/SubDirSpaces/CMakeLists.txt b/Tests/SubDirSpaces/CMakeLists.txt index 0d45db8..ecd4353 100644 --- a/Tests/SubDirSpaces/CMakeLists.txt +++ b/Tests/SubDirSpaces/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(SUBDIR) # Some systems do not seem to support rpath with spaces. diff --git a/Tests/TargetName/CMakeLists.txt b/Tests/TargetName/CMakeLists.txt index 9729d21..21752b7 100644 --- a/Tests/TargetName/CMakeLists.txt +++ b/Tests/TargetName/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(TargetName) add_subdirectory(executables) diff --git a/Tests/TestDriver/CMakeLists.txt b/Tests/TestDriver/CMakeLists.txt index 663ecab..3cc69c0 100644 --- a/Tests/TestDriver/CMakeLists.txt +++ b/Tests/TestDriver/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(TestDriverTest) set(Extra_SRCS testExtraStuff.cxx testExtraStuff2.cxx ) diff --git a/Tests/TestsWorkingDirectory/CMakeLists.txt b/Tests/TestsWorkingDirectory/CMakeLists.txt index 6a6e9b6..2a0b015 100644 --- a/Tests/TestsWorkingDirectory/CMakeLists.txt +++ b/Tests/TestsWorkingDirectory/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(TestsWorkingDirectoryProj) add_executable(WorkingDirectory main.c) diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt index 0c6b938..fa0549f 100644 --- a/Tests/TryCompile/CMakeLists.txt +++ b/Tests/TryCompile/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(TryCompile) macro(TEST_ASSERT value msg) diff --git a/Tests/TryCompile/Inner/CMakeLists.txt b/Tests/TryCompile/Inner/CMakeLists.txt index d62bcc4..d8c22d0 100644 --- a/Tests/TryCompile/Inner/CMakeLists.txt +++ b/Tests/TryCompile/Inner/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.12) project(TryCompileInner C) try_compile(SHOULD_PASS diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt index d08c59c..f1b2f32 100644 --- a/Tests/UseSWIG/CMakeLists.txt +++ b/Tests/UseSWIG/CMakeLists.txt @@ -66,7 +66,8 @@ add_test(NAME UseSWIG.BasicPerl COMMAND --build-options ${build_options} --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) -if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2") +if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2" + AND CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode") add_test(NAME UseSWIG.Depfile.BasicPython COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --build-and-test diff --git a/Tests/VSExternalInclude/CMakeLists.txt b/Tests/VSExternalInclude/CMakeLists.txt index 8ca7252..e38df8e 100644 --- a/Tests/VSExternalInclude/CMakeLists.txt +++ b/Tests/VSExternalInclude/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.12) project(VSExternalInclude) if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012456]") diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt index abd0628..950ec25 100644 --- a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt +++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt @@ -43,4 +43,9 @@ if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) target_link_libraries(hello PRIVATE sunquad) endif() endif() +elseif(CMAKE_Fortran_COMPILER_ID MATCHES Fujitsu) + # Fujitsu Fortran doesn't automatically link its runtime libraries into + # SOs + target_link_libraries(world PRIVATE fj90i fj90f fjsrcinfo) + target_link_libraries(hello PRIVATE fj90i fj90f fjsrcinfo) endif() diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt index a880f7a..0ccb721 100644 --- a/Utilities/Doxygen/CMakeLists.txt +++ b/Utilities/Doxygen/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeDeveloperReference_STANDALONE 1) - cmake_minimum_required(VERSION 3.1...3.18 FATAL_ERROR) + cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index c2aced5..f1bdcc4 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -21,6 +21,7 @@ { include: [ "<wctype.h>", public, "<cwctype>", public ] }, # HACK: check whether this can be removed with next iwyu release. + { include: [ "<bits/cxxabi_forced.h>", private, "<ctime>", public ] }, { include: [ "<bits/shared_ptr.h>", private, "<memory>", public ] }, { include: [ "<bits/std_function.h>", private, "<functional>", public ] }, { include: [ "<bits/refwrap.h>", private, "<functional>", public ] }, @@ -96,6 +97,7 @@ { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] }, { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<60, 1> > >::type", private, "\"cmConfigure.h\"", public ] }, { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1000> > >::type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "__gnu_cxx::__enable_if<true, bool>::__type", private, "\"cmConfigure.h\"", public ] }, # Wrappers for 3rd-party libraries { include: [ "@<.*curl/curlver.h>", private, "<cm3p/curl/curl.h>", public ] }, diff --git a/Utilities/Scripts/BoostScanDeps.cmake b/Utilities/Scripts/BoostScanDeps.cmake index 5794d03..14c7f3c 100644 --- a/Utilities/Scripts/BoostScanDeps.cmake +++ b/Utilities/Scripts/BoostScanDeps.cmake @@ -20,7 +20,7 @@ # "component". For each component, all the headers will be scanned to # determine the components it depends upon by following all the # possible includes from this component. This is to match the -# behaviour of autolinking. +# behavior of autolinking. # Written by Roger Leigh <rleigh@codelibre.net> @@ -86,7 +86,7 @@ function(_Boost_FIND_COMPONENT_DEPENDENCIES component includedir _ret_libs) set(library_component TRUE) set(_boost_unprocessed_headers "${BOOST_DIR}/test/test_exec_monitor.hpp") else() - # Default behaviour where header directory is the same as the library name. + # Default behavior where header directory is the same as the library name. file(GLOB_RECURSE _boost_unprocessed_headers RELATIVE "${includedir}" "${includedir}/boost/${component}/*") diff --git a/Utilities/Scripts/update-liblzma.bash b/Utilities/Scripts/update-liblzma.bash index fdf66b3..a5a7175 100755 --- a/Utilities/Scripts/update-liblzma.bash +++ b/Utilities/Scripts/update-liblzma.bash @@ -8,12 +8,17 @@ readonly name="liblzma" readonly ownership="liblzma upstream <xz-devel@tukaani.org>" readonly subtree="Utilities/cmliblzma" readonly repo="https://git.tukaani.org/xz.git" -readonly tag="v5.2.4" +readonly tag="v5.2.5" readonly shortlog=false readonly paths=" COPYING src/common/common_w32res.rc + src/common/mythread.h src/common/sysdefs.h + src/common/tuklib_common.h + src/common/tuklib_config.h + src/common/tuklib_cpucores.c + src/common/tuklib_cpucores.h src/common/tuklib_integer.h src/liblzma/ " diff --git a/Utilities/Scripts/update-third-party.bash b/Utilities/Scripts/update-third-party.bash index fcab871..0d0a667 100644 --- a/Utilities/Scripts/update-third-party.bash +++ b/Utilities/Scripts/update-third-party.bash @@ -89,7 +89,7 @@ readonly basehash_regex="$name $regex_date ([0-9a-f]*)" # Check for an empty destination directory on disk. By checking on disk and # not in the repo it allows a library to be freshly re-inialized in a single # commit rather than first deleting the old copy in one commit and adding the -# new copy in a seperate commit. +# new copy in a separate commit. if [ ! -d "$(git rev-parse --show-toplevel)/$subtree" ]; then readonly basehash="" else diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index f989907..32efd48 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT CMake_SOURCE_DIR) set(CMakeHelp_STANDALONE 1) - cmake_minimum_required(VERSION 3.1...3.18 FATAL_ERROR) + cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) @@ -22,6 +22,7 @@ option(SPHINX_MAN "Build man pages with Sphinx" OFF) option(SPHINX_HTML "Build html help with Sphinx" OFF) option(SPHINX_SINGLEHTML "Build html single page help with Sphinx" OFF) option(SPHINX_QTHELP "Build Qt help with Sphinx" OFF) +option(SPHINX_LATEXPDF "Build PDF help with Sphinx using LaTeX" OFF) option(SPHINX_TEXT "Build text help with Sphinx (not installed)" OFF) find_program(SPHINX_EXECUTABLE NAMES sphinx-build @@ -33,7 +34,7 @@ separate_arguments(sphinx_flags UNIX_COMMAND "${SPHINX_FLAGS}") mark_as_advanced(SPHINX_TEXT) mark_as_advanced(SPHINX_FLAGS) -if(NOT SPHINX_INFO AND NOT SPHINX_MAN AND NOT SPHINX_HTML AND NOT SPHINX_SINGLEHTML AND NOT SPHINX_QTHELP AND NOT SPHINX_TEXT) +if(NOT SPHINX_INFO AND NOT SPHINX_MAN AND NOT SPHINX_HTML AND NOT SPHINX_SINGLEHTML AND NOT SPHINX_QTHELP AND NOT SPHINX_TEXT AND NOT SPHINX_LATEXPDF) return() elseif(NOT SPHINX_EXECUTABLE) message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!") @@ -117,28 +118,51 @@ if(SPHINX_QTHELP) ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake.qhcp ) endif() - +if(SPHINX_LATEXPDF) + list(APPEND doc_formats latexpdf) +endif() set(doc_format_outputs "") set(doc_format_last "") foreach(format ${doc_formats}) set(doc_format_output "doc_format_${format}") set(doc_format_log "build-${format}.log") - add_custom_command( - OUTPUT ${doc_format_output} - COMMAND ${SPHINX_EXECUTABLE} - -c ${CMAKE_CURRENT_BINARY_DIR} - -d ${CMAKE_CURRENT_BINARY_DIR}/doctrees - -b ${format} - ${sphinx_flags} - ${CMake_SOURCE_DIR}/Help - ${CMAKE_CURRENT_BINARY_DIR}/${format} - > ${doc_format_log} # log stdout, pass stderr - ${${format}_extra_commands} - DEPENDS ${doc_format_last} - COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}" - VERBATIM - ) + if(format STREQUAL "latexpdf") + # This format does not use builder (-b) but make_mode (-M) which expects + # arguments in peculiar order + add_custom_command( + OUTPUT ${doc_format_output} + COMMAND ${SPHINX_EXECUTABLE} + -M ${format} + ${CMake_SOURCE_DIR}/Help + ${CMAKE_CURRENT_BINARY_DIR}/${format} + -c ${CMAKE_CURRENT_BINARY_DIR} + -d ${CMAKE_CURRENT_BINARY_DIR}/doctrees + ${sphinx_flags} + > ${doc_format_log} # log stdout, pass stderr + ${${format}_extra_commands} + DEPENDS ${doc_format_last} + COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}" + VERBATIM + ) + else() + # other formats use standard builder (-b) mode + add_custom_command( + OUTPUT ${doc_format_output} + COMMAND ${SPHINX_EXECUTABLE} + -c ${CMAKE_CURRENT_BINARY_DIR} + -d ${CMAKE_CURRENT_BINARY_DIR}/doctrees + -b ${format} + ${sphinx_flags} + ${CMake_SOURCE_DIR}/Help + ${CMAKE_CURRENT_BINARY_DIR}/${format} + > ${doc_format_log} # log stdout, pass stderr + ${${format}_extra_commands} + DEPENDS ${doc_format_last} + COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}" + VERBATIM + ) + endif() set_property(SOURCE ${doc_format_output} PROPERTY SYMBOLIC 1) list(APPEND doc_format_outputs ${doc_format_output}) set(doc_format_last ${doc_format_output}) @@ -219,3 +243,10 @@ if(SPHINX_QTHELP) DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT} ) endif() + +if(SPHINX_LATEXPDF) + CMake_OPTIONAL_COMPONENT(sphinx-latexpdf) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/latexpdf/latex/CMake.pdf + DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT} + ) +endif() diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index ece4bf5..9fa56cd 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -20,7 +20,7 @@ from pygments.lexer import bygroups # - [\.\+-] are needed for string constants like gtk+-2.0 # - Unix paths are recognized by '/'; support for Windows paths may be added if needed # - (\\.) allows for \-escapes (used in manual/cmake-language.7) -# - $<..$<..$>..> nested occurence in cmake-buildsystem +# - $<..$<..$>..> nested occurrence in cmake-buildsystem # - Nested variable evaluations are only supported in a limited capacity. Only # one level of nesting is supported and at most one nested variable can be present. diff --git a/Utilities/cmbzip2/CMakeLists.txt b/Utilities/cmbzip2/CMakeLists.txt index 9b53b0f..ff90bb6 100644 --- a/Utilities/cmbzip2/CMakeLists.txt +++ b/Utilities/cmbzip2/CMakeLists.txt @@ -2,7 +2,7 @@ project(bzip2) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 4fb9361..57860a9 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -97,7 +97,7 @@ endif(APPLE) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmexpat/CMakeLists.txt b/Utilities/cmexpat/CMakeLists.txt index b8dc4e8..9048096 100644 --- a/Utilities/cmexpat/CMakeLists.txt +++ b/Utilities/cmexpat/CMakeLists.txt @@ -1,6 +1,6 @@ # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmjsoncpp/CMakeLists.txt b/Utilities/cmjsoncpp/CMakeLists.txt index 74e9988..029ae86 100644 --- a/Utilities/cmjsoncpp/CMakeLists.txt +++ b/Utilities/cmjsoncpp/CMakeLists.txt @@ -2,7 +2,7 @@ project(JsonCpp CXX) # Disable warnings to avoid changing 3rd party code. if(CMAKE_CXX_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "PathScale") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -woffall") diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt index 689d98a..79452ff 100644 --- a/Utilities/cmlibarchive/CMakeLists.txt +++ b/Utilities/cmlibarchive/CMakeLists.txt @@ -94,7 +94,7 @@ SET(CMAKE_REQUIRED_FLAGS) # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt index 32a14dc..4820a8f 100644 --- a/Utilities/cmliblzma/CMakeLists.txt +++ b/Utilities/cmliblzma/CMakeLists.txt @@ -6,6 +6,12 @@ include(CheckSymbolExists) include(CheckTypeSize) include(TestBigEndian) +if(WIN32) + add_definitions(-DMYTHREAD_VISTA) +else() + add_definitions(-DMYTHREAD_POSIX) +endif() + CHECK_INCLUDE_FILE(byteswap.h HAVE_BYTESWAP_H) CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H) CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H) @@ -60,7 +66,10 @@ set(HAVE_MF_HC3 1) set(HAVE_MF_HC4 1) SET(LZMA_SRCS + common/mythread.h common/sysdefs.h + common/tuklib_cpucores.c + common/tuklib_cpucores.h common/tuklib_integer.h liblzma/check/check.c liblzma/check/crc32_fast.c @@ -91,14 +100,17 @@ SET(LZMA_SRCS liblzma/common/filter_encoder.c liblzma/common/filter_flags_decoder.c liblzma/common/filter_flags_encoder.c + liblzma/common/hardware_cputhreads.c liblzma/common/index.c liblzma/common/index_decoder.c liblzma/common/index_encoder.c liblzma/common/index_hash.c + liblzma/common/outqueue.c liblzma/common/stream_buffer_decoder.c liblzma/common/stream_buffer_encoder.c liblzma/common/stream_decoder.c liblzma/common/stream_encoder.c + liblzma/common/stream_encoder_mt.c liblzma/common/stream_flags_common.c liblzma/common/stream_flags_decoder.c liblzma/common/stream_flags_encoder.c @@ -148,7 +160,7 @@ INCLUDE_DIRECTORIES( # Disable warnings to avoid changing 3rd party code. IF(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmliblzma/common/mythread.h b/Utilities/cmliblzma/common/mythread.h new file mode 100644 index 0000000..be22654 --- /dev/null +++ b/Utilities/cmliblzma/common/mythread.h @@ -0,0 +1,521 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file mythread.h +/// \brief Some threading related helper macros and functions +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef MYTHREAD_H +#define MYTHREAD_H + +#include "sysdefs.h" + +// If any type of threading is enabled, #define MYTHREAD_ENABLED. +#if defined(MYTHREAD_POSIX) || defined(MYTHREAD_WIN95) \ + || defined(MYTHREAD_VISTA) +# define MYTHREAD_ENABLED 1 +#endif + + +#ifdef MYTHREAD_ENABLED + +//////////////////////////////////////// +// Shared between all threading types // +//////////////////////////////////////// + +// Locks a mutex for a duration of a block. +// +// Perform mythread_mutex_lock(&mutex) in the beginning of a block +// and mythread_mutex_unlock(&mutex) at the end of the block. "break" +// may be used to unlock the mutex and jump out of the block. +// mythread_sync blocks may be nested. +// +// Example: +// +// mythread_sync(mutex) { +// foo(); +// if (some_error) +// break; // Skips bar() +// bar(); +// } +// +// At least GCC optimizes the loops completely away so it doesn't slow +// things down at all compared to plain mythread_mutex_lock(&mutex) +// and mythread_mutex_unlock(&mutex) calls. +// +#define mythread_sync(mutex) mythread_sync_helper1(mutex, __LINE__) +#define mythread_sync_helper1(mutex, line) mythread_sync_helper2(mutex, line) +#define mythread_sync_helper2(mutex, line) \ + for (unsigned int mythread_i_ ## line = 0; \ + mythread_i_ ## line \ + ? (mythread_mutex_unlock(&(mutex)), 0) \ + : (mythread_mutex_lock(&(mutex)), 1); \ + mythread_i_ ## line = 1) \ + for (unsigned int mythread_j_ ## line = 0; \ + !mythread_j_ ## line; \ + mythread_j_ ## line = 1) +#endif + + +#if !defined(MYTHREAD_ENABLED) + +////////////////// +// No threading // +////////////////// + +// Calls the given function once. This isn't thread safe. +#define mythread_once(func) \ +do { \ + static bool once_ = false; \ + if (!once_) { \ + func(); \ + once_ = true; \ + } \ +} while (0) + + +#if !(defined(_WIN32) && !defined(__CYGWIN__)) +// Use sigprocmask() to set the signal mask in single-threaded programs. +#include <signal.h> + +static inline void +mythread_sigmask(int how, const sigset_t *restrict set, + sigset_t *restrict oset) +{ + int ret = sigprocmask(how, set, oset); + assert(ret == 0); + (void)ret; +} +#endif + + +#elif defined(MYTHREAD_POSIX) + +//////////////////// +// Using pthreads // +//////////////////// + +#include <sys/time.h> +#include <pthread.h> +#include <signal.h> +#include <time.h> +#include <errno.h> + +#define MYTHREAD_RET_TYPE void * +#define MYTHREAD_RET_VALUE NULL + +typedef pthread_t mythread; +typedef pthread_mutex_t mythread_mutex; + +typedef struct { + pthread_cond_t cond; +#ifdef HAVE_CLOCK_GETTIME + // Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with + // the condition variable. + clockid_t clk_id; +#endif +} mythread_cond; + +typedef struct timespec mythread_condtime; + + +// Calls the given function once in a thread-safe way. +#define mythread_once(func) \ + do { \ + static pthread_once_t once_ = PTHREAD_ONCE_INIT; \ + pthread_once(&once_, &func); \ + } while (0) + + +// Use pthread_sigmask() to set the signal mask in multi-threaded programs. +// Do nothing on OpenVMS since it lacks pthread_sigmask(). +static inline void +mythread_sigmask(int how, const sigset_t *restrict set, + sigset_t *restrict oset) +{ +#ifdef __VMS + (void)how; + (void)set; + (void)oset; +#else + int ret = pthread_sigmask(how, set, oset); + assert(ret == 0); + (void)ret; +#endif +} + + +// Creates a new thread with all signals blocked. Returns zero on success +// and non-zero on error. +static inline int +mythread_create(mythread *thread, void *(*func)(void *arg), void *arg) +{ + sigset_t old; + sigset_t all; + sigfillset(&all); + + mythread_sigmask(SIG_SETMASK, &all, &old); + const int ret = pthread_create(thread, NULL, func, arg); + mythread_sigmask(SIG_SETMASK, &old, NULL); + + return ret; +} + +// Joins a thread. Returns zero on success and non-zero on error. +static inline int +mythread_join(mythread thread) +{ + return pthread_join(thread, NULL); +} + + +// Initiatlizes a mutex. Returns zero on success and non-zero on error. +static inline int +mythread_mutex_init(mythread_mutex *mutex) +{ + return pthread_mutex_init(mutex, NULL); +} + +static inline void +mythread_mutex_destroy(mythread_mutex *mutex) +{ + int ret = pthread_mutex_destroy(mutex); + assert(ret == 0); + (void)ret; +} + +static inline void +mythread_mutex_lock(mythread_mutex *mutex) +{ + int ret = pthread_mutex_lock(mutex); + assert(ret == 0); + (void)ret; +} + +static inline void +mythread_mutex_unlock(mythread_mutex *mutex) +{ + int ret = pthread_mutex_unlock(mutex); + assert(ret == 0); + (void)ret; +} + + +// Initializes a condition variable. +// +// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the +// timeout in pthread_cond_timedwait() work correctly also if system time +// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available +// everywhere while the default CLOCK_REALTIME is, so the default is +// used if CLOCK_MONOTONIC isn't available. +// +// If clock_gettime() isn't available at all, gettimeofday() will be used. +static inline int +mythread_cond_init(mythread_cond *mycond) +{ +#ifdef HAVE_CLOCK_GETTIME + // NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1. +# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && HAVE_DECL_CLOCK_MONOTONIC + struct timespec ts; + pthread_condattr_t condattr; + + // POSIX doesn't seem to *require* that pthread_condattr_setclock() + // will fail if given an unsupported clock ID. Test that + // CLOCK_MONOTONIC really is supported using clock_gettime(). + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0 + && pthread_condattr_init(&condattr) == 0) { + int ret = pthread_condattr_setclock( + &condattr, CLOCK_MONOTONIC); + if (ret == 0) + ret = pthread_cond_init(&mycond->cond, &condattr); + + pthread_condattr_destroy(&condattr); + + if (ret == 0) { + mycond->clk_id = CLOCK_MONOTONIC; + return 0; + } + } + + // If anything above fails, fall back to the default CLOCK_REALTIME. + // POSIX requires that all implementations of clock_gettime() must + // support at least CLOCK_REALTIME. +# endif + + mycond->clk_id = CLOCK_REALTIME; +#endif + + return pthread_cond_init(&mycond->cond, NULL); +} + +static inline void +mythread_cond_destroy(mythread_cond *cond) +{ + int ret = pthread_cond_destroy(&cond->cond); + assert(ret == 0); + (void)ret; +} + +static inline void +mythread_cond_signal(mythread_cond *cond) +{ + int ret = pthread_cond_signal(&cond->cond); + assert(ret == 0); + (void)ret; +} + +static inline void +mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex) +{ + int ret = pthread_cond_wait(&cond->cond, mutex); + assert(ret == 0); + (void)ret; +} + +// Waits on a condition or until a timeout expires. If the timeout expires, +// non-zero is returned, otherwise zero is returned. +static inline int +mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex, + const mythread_condtime *condtime) +{ + int ret = pthread_cond_timedwait(&cond->cond, mutex, condtime); + assert(ret == 0 || ret == ETIMEDOUT); + return ret; +} + +// Sets condtime to the absolute time that is timeout_ms milliseconds +// in the future. The type of the clock to use is taken from cond. +static inline void +mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond, + uint32_t timeout_ms) +{ + condtime->tv_sec = timeout_ms / 1000; + condtime->tv_nsec = (timeout_ms % 1000) * 1000000; + +#ifdef HAVE_CLOCK_GETTIME + struct timespec now; + int ret = clock_gettime(cond->clk_id, &now); + assert(ret == 0); + (void)ret; + + condtime->tv_sec += now.tv_sec; + condtime->tv_nsec += now.tv_nsec; +#else + (void)cond; + + struct timeval now; + gettimeofday(&now, NULL); + + condtime->tv_sec += now.tv_sec; + condtime->tv_nsec += now.tv_usec * 1000L; +#endif + + // tv_nsec must stay in the range [0, 999_999_999]. + if (condtime->tv_nsec >= 1000000000L) { + condtime->tv_nsec -= 1000000000L; + ++condtime->tv_sec; + } +} + + +#elif defined(MYTHREAD_WIN95) || defined(MYTHREAD_VISTA) + +///////////////////// +// Windows threads // +///////////////////// + +#define WIN32_LEAN_AND_MEAN +#ifdef MYTHREAD_VISTA +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +#endif +#include <windows.h> +#include <process.h> + +#define MYTHREAD_RET_TYPE unsigned int __stdcall +#define MYTHREAD_RET_VALUE 0 + +typedef HANDLE mythread; +typedef CRITICAL_SECTION mythread_mutex; + +#ifdef MYTHREAD_WIN95 +typedef HANDLE mythread_cond; +#else +typedef CONDITION_VARIABLE mythread_cond; +#endif + +typedef struct { + // Tick count (milliseconds) in the beginning of the timeout. + // NOTE: This is 32 bits so it wraps around after 49.7 days. + // Multi-day timeouts may not work as expected. + DWORD start; + + // Length of the timeout in milliseconds. The timeout expires + // when the current tick count minus "start" is equal or greater + // than "timeout". + DWORD timeout; +} mythread_condtime; + + +// mythread_once() is only available with Vista threads. +#ifdef MYTHREAD_VISTA +#define mythread_once(func) \ + do { \ + static INIT_ONCE once_ = INIT_ONCE_STATIC_INIT; \ + BOOL pending_; \ + if (!InitOnceBeginInitialize(&once_, 0, &pending_, NULL)) \ + abort(); \ + if (pending_) \ + func(); \ + if (!InitOnceComplete(&once, 0, NULL)) \ + abort(); \ + } while (0) +#endif + + +// mythread_sigmask() isn't available on Windows. Even a dummy version would +// make no sense because the other POSIX signal functions are missing anyway. + + +static inline int +mythread_create(mythread *thread, + unsigned int (__stdcall *func)(void *arg), void *arg) +{ + uintptr_t ret = _beginthreadex(NULL, 0, func, arg, 0, NULL); + if (ret == 0) + return -1; + + *thread = (HANDLE)ret; + return 0; +} + +static inline int +mythread_join(mythread thread) +{ + int ret = 0; + + if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) + ret = -1; + + if (!CloseHandle(thread)) + ret = -1; + + return ret; +} + + +static inline int +mythread_mutex_init(mythread_mutex *mutex) +{ + InitializeCriticalSection(mutex); + return 0; +} + +static inline void +mythread_mutex_destroy(mythread_mutex *mutex) +{ + DeleteCriticalSection(mutex); +} + +static inline void +mythread_mutex_lock(mythread_mutex *mutex) +{ + EnterCriticalSection(mutex); +} + +static inline void +mythread_mutex_unlock(mythread_mutex *mutex) +{ + LeaveCriticalSection(mutex); +} + + +static inline int +mythread_cond_init(mythread_cond *cond) +{ +#ifdef MYTHREAD_WIN95 + *cond = CreateEvent(NULL, FALSE, FALSE, NULL); + return *cond == NULL ? -1 : 0; +#else + InitializeConditionVariable(cond); + return 0; +#endif +} + +static inline void +mythread_cond_destroy(mythread_cond *cond) +{ +#ifdef MYTHREAD_WIN95 + CloseHandle(*cond); +#else + (void)cond; +#endif +} + +static inline void +mythread_cond_signal(mythread_cond *cond) +{ +#ifdef MYTHREAD_WIN95 + SetEvent(*cond); +#else + WakeConditionVariable(cond); +#endif +} + +static inline void +mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex) +{ +#ifdef MYTHREAD_WIN95 + LeaveCriticalSection(mutex); + WaitForSingleObject(*cond, INFINITE); + EnterCriticalSection(mutex); +#else + BOOL ret = SleepConditionVariableCS(cond, mutex, INFINITE); + assert(ret); + (void)ret; +#endif +} + +static inline int +mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex, + const mythread_condtime *condtime) +{ +#ifdef MYTHREAD_WIN95 + LeaveCriticalSection(mutex); +#endif + + DWORD elapsed = GetTickCount() - condtime->start; + DWORD timeout = elapsed >= condtime->timeout + ? 0 : condtime->timeout - elapsed; + +#ifdef MYTHREAD_WIN95 + DWORD ret = WaitForSingleObject(*cond, timeout); + assert(ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT); + + EnterCriticalSection(mutex); + + return ret == WAIT_TIMEOUT; +#else + BOOL ret = SleepConditionVariableCS(cond, mutex, timeout); + assert(ret || GetLastError() == ERROR_TIMEOUT); + return !ret; +#endif +} + +static inline void +mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond, + uint32_t timeout) +{ + (void)cond; + condtime->start = GetTickCount(); + condtime->timeout = timeout; +} + +#endif + +#endif diff --git a/Utilities/cmliblzma/common/sysdefs.h b/Utilities/cmliblzma/common/sysdefs.h index 22f487b..86c5da0 100644 --- a/Utilities/cmliblzma/common/sysdefs.h +++ b/Utilities/cmliblzma/common/sysdefs.h @@ -49,9 +49,7 @@ // Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The // limits are also used to figure out some macros missing from pre-C99 systems. -#ifdef HAVE_LIMITS_H -# include <limits.h> -#endif +#include <limits.h> #if defined(_MSC_VER) && (_MSC_VER < 1310) @@ -164,9 +162,7 @@ typedef unsigned char _Bool; // string.h should be enough but let's include strings.h and memory.h too if // they exists, since that shouldn't do any harm, but may improve portability. -#ifdef HAVE_STRING_H -# include <string.h> -#endif +#include <string.h> #ifdef HAVE_STRINGS_H # include <strings.h> @@ -204,7 +200,8 @@ typedef unsigned char _Bool; # define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 +#if defined(__GNUC__) \ + && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) # define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x))) #else # define lzma_attr_alloc_size(x) diff --git a/Utilities/cmliblzma/common/tuklib_common.h b/Utilities/cmliblzma/common/tuklib_common.h new file mode 100644 index 0000000..31fbab5 --- /dev/null +++ b/Utilities/cmliblzma/common/tuklib_common.h @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file tuklib_common.h +/// \brief Common definitions for tuklib modules +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TUKLIB_COMMON_H +#define TUKLIB_COMMON_H + +// The config file may be replaced by a package-specific file. +// It should include at least stddef.h, inttypes.h, and limits.h. +#include "tuklib_config.h" + +// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by +// the tuklib modules. If you use a tuklib module in a library, +// you should use TUKLIB_SYMBOL_PREFIX to make sure that there +// are no symbol conflicts in case someone links your library +// into application that also uses the same tuklib module. +#ifndef TUKLIB_SYMBOL_PREFIX +# define TUKLIB_SYMBOL_PREFIX +#endif + +#define TUKLIB_CAT_X(a, b) a ## b +#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b) + +#ifndef TUKLIB_SYMBOL +# define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym) +#endif + +#ifndef TUKLIB_DECLS_BEGIN +# ifdef __cplusplus +# define TUKLIB_DECLS_BEGIN extern "C" { +# else +# define TUKLIB_DECLS_BEGIN +# endif +#endif + +#ifndef TUKLIB_DECLS_END +# ifdef __cplusplus +# define TUKLIB_DECLS_END } +# else +# define TUKLIB_DECLS_END +# endif +#endif + +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define TUKLIB_GNUC_REQ(major, minor) \ + ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \ + || __GNUC__ > (major)) +#else +# define TUKLIB_GNUC_REQ(major, minor) 0 +#endif + +#if TUKLIB_GNUC_REQ(2, 5) +# define tuklib_attr_noreturn __attribute__((__noreturn__)) +#else +# define tuklib_attr_noreturn +#endif + +#if (defined(_WIN32) && !defined(__CYGWIN__)) \ + || defined(__OS2__) || defined(__MSDOS__) +# define TUKLIB_DOSLIKE 1 +#endif + +#endif diff --git a/Utilities/cmliblzma/common/tuklib_config.h b/Utilities/cmliblzma/common/tuklib_config.h new file mode 100644 index 0000000..549cb24 --- /dev/null +++ b/Utilities/cmliblzma/common/tuklib_config.h @@ -0,0 +1,7 @@ +#ifdef HAVE_CONFIG_H +# include "sysdefs.h" +#else +# include <stddef.h> +# include <inttypes.h> +# include <limits.h> +#endif diff --git a/Utilities/cmliblzma/common/tuklib_cpucores.c b/Utilities/cmliblzma/common/tuklib_cpucores.c new file mode 100644 index 0000000..cc968dd --- /dev/null +++ b/Utilities/cmliblzma/common/tuklib_cpucores.c @@ -0,0 +1,100 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file tuklib_cpucores.c +/// \brief Get the number of CPU cores online +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "tuklib_cpucores.h" + +#if defined(_WIN32) || defined(__CYGWIN__) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 +# endif +# include <windows.h> + +// glibc >= 2.9 +#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) +# include <sched.h> + +// FreeBSD +#elif defined(TUKLIB_CPUCORES_CPUSET) +# include <sys/param.h> +# include <sys/cpuset.h> + +#elif defined(TUKLIB_CPUCORES_SYSCTL) +# ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +# endif +# include <sys/sysctl.h> + +#elif defined(TUKLIB_CPUCORES_SYSCONF) +# include <unistd.h> + +// HP-UX +#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC) +# include <sys/param.h> +# include <sys/pstat.h> +#endif + + +extern uint32_t +tuklib_cpucores(void) +{ + uint32_t ret = 0; + +#if defined(_WIN32) || defined(__CYGWIN__) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + ret = sysinfo.dwNumberOfProcessors; + +#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) + cpu_set_t cpu_mask; + if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0) + ret = (uint32_t)CPU_COUNT(&cpu_mask); + +#elif defined(TUKLIB_CPUCORES_CPUSET) + cpuset_t set; + if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, + sizeof(set), &set) == 0) { +# ifdef CPU_COUNT + ret = (uint32_t)CPU_COUNT(&set); +# else + for (unsigned i = 0; i < CPU_SETSIZE; ++i) + if (CPU_ISSET(i, &set)) + ++ret; +# endif + } + +#elif defined(TUKLIB_CPUCORES_SYSCTL) + int name[2] = { CTL_HW, HW_NCPU }; + int cpus; + size_t cpus_size = sizeof(cpus); + if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1 + && cpus_size == sizeof(cpus) && cpus > 0) + ret = (uint32_t)cpus; + +#elif defined(TUKLIB_CPUCORES_SYSCONF) +# ifdef _SC_NPROCESSORS_ONLN + // Most systems + const long cpus = sysconf(_SC_NPROCESSORS_ONLN); +# else + // IRIX + const long cpus = sysconf(_SC_NPROC_ONLN); +# endif + if (cpus > 0) + ret = (uint32_t)cpus; + +#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC) + struct pst_dynamic pst; + if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1) + ret = (uint32_t)pst.psd_proc_cnt; +#endif + + return ret; +} diff --git a/Utilities/cmliblzma/common/tuklib_cpucores.h b/Utilities/cmliblzma/common/tuklib_cpucores.h new file mode 100644 index 0000000..be1ce1c --- /dev/null +++ b/Utilities/cmliblzma/common/tuklib_cpucores.h @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file tuklib_cpucores.h +/// \brief Get the number of CPU cores online +// +// Author: Lasse Collin +// +// This file has been put into the public domain. +// You can do whatever you want with this file. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TUKLIB_CPUCORES_H +#define TUKLIB_CPUCORES_H + +#include "tuklib_common.h" +TUKLIB_DECLS_BEGIN + +#define tuklib_cpucores TUKLIB_SYMBOL(tuklib_cpucores) +extern uint32_t tuklib_cpucores(void); + +TUKLIB_DECLS_END +#endif diff --git a/Utilities/cmliblzma/common/tuklib_integer.h b/Utilities/cmliblzma/common/tuklib_integer.h index 5d82685..4e61357 100644 --- a/Utilities/cmliblzma/common/tuklib_integer.h +++ b/Utilities/cmliblzma/common/tuklib_integer.h @@ -6,22 +6,26 @@ /// This file provides macros or functions to do some basic integer and bit /// operations. /// -/// Endianness related integer operations (XX = 16, 32, or 64; Y = b or l): -/// - Byte swapping: bswapXX(num) -/// - Byte order conversions to/from native: convXXYe(num) -/// - Aligned reads: readXXYe(ptr) -/// - Aligned writes: writeXXYe(ptr, num) -/// - Unaligned reads (16/32-bit only): unaligned_readXXYe(ptr) -/// - Unaligned writes (16/32-bit only): unaligned_writeXXYe(ptr, num) +/// Native endian inline functions (XX = 16, 32, or 64): +/// - Unaligned native endian reads: readXXne(ptr) +/// - Unaligned native endian writes: writeXXne(ptr, num) +/// - Aligned native endian reads: aligned_readXXne(ptr) +/// - Aligned native endian writes: aligned_writeXXne(ptr, num) /// -/// Since they can macros, the arguments should have no side effects since -/// they may be evaluated more than once. +/// Endianness-converting integer operations (these can be macros!) +/// (XX = 16, 32, or 64; Y = b or l): +/// - Byte swapping: bswapXX(num) +/// - Byte order conversions to/from native (byteswaps if Y isn't +/// the native endianness): convXXYe(num) +/// - Unaligned reads (16/32-bit only): readXXYe(ptr) +/// - Unaligned writes (16/32-bit only): writeXXYe(ptr, num) +/// - Aligned reads: aligned_readXXYe(ptr) +/// - Aligned writes: aligned_writeXXYe(ptr, num) /// -/// \todo PowerPC and possibly some other architectures support -/// byte swapping load and store instructions. This file -/// doesn't take advantage of those instructions. +/// Since the above can macros, the arguments should have no side effects +/// because they may be evaluated more than once. /// -/// Bit scan operations for non-zero 32-bit integers: +/// Bit scan operations for non-zero 32-bit integers (inline functions): /// - Bit scan reverse (find highest non-zero bit): bsr32(num) /// - Count leading zeros: clz32(num) /// - Count trailing zeros: ctz32(num) @@ -41,22 +45,27 @@ #ifndef TUKLIB_INTEGER_H #define TUKLIB_INTEGER_H -#include "sysdefs.h" +#include "tuklib_common.h" +#include <string.h> -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define TUKLIB_GNUC_REQ(major, minor) \ - ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \ - || __GNUC__ > (major)) -#else -# define TUKLIB_GNUC_REQ(major, minor) 0 +// Newer Intel C compilers require immintrin.h for _bit_scan_reverse() +// and such functions. +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) +# include <immintrin.h> #endif -//////////////////////////////////////// -// Operating system specific features // -//////////////////////////////////////// +/////////////////// +// Byte swapping // +/////////////////// + +#if defined(HAVE___BUILTIN_BSWAPXX) + // GCC >= 4.8 and Clang +# define bswap16(n) __builtin_bswap16(n) +# define bswap32(n) __builtin_bswap32(n) +# define bswap64(n) __builtin_bswap64(n) -#if defined(HAVE_BYTESWAP_H) +#elif defined(HAVE_BYTESWAP_H) // glibc, uClibc, dietlibc # include <byteswap.h> # ifdef HAVE_BSWAP_16 @@ -105,45 +114,33 @@ # endif #endif - -//////////////////////////////// -// Compiler-specific features // -//////////////////////////////// - -// Newer Intel C compilers require immintrin.h for _bit_scan_reverse() -// and such functions. -#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) -# include <immintrin.h> -#endif - - -/////////////////// -// Byte swapping // -/////////////////// - #ifndef bswap16 -# define bswap16(num) \ - (((uint16_t)(num) << 8) | ((uint16_t)(num) >> 8)) +# define bswap16(n) (uint16_t)( \ + (((n) & 0x00FFU) << 8) \ + | (((n) & 0xFF00U) >> 8) \ + ) #endif #ifndef bswap32 -# define bswap32(num) \ - ( (((uint32_t)(num) << 24) ) \ - | (((uint32_t)(num) << 8) & UINT32_C(0x00FF0000)) \ - | (((uint32_t)(num) >> 8) & UINT32_C(0x0000FF00)) \ - | (((uint32_t)(num) >> 24) ) ) +# define bswap32(n) (uint32_t)( \ + (((n) & UINT32_C(0x000000FF)) << 24) \ + | (((n) & UINT32_C(0x0000FF00)) << 8) \ + | (((n) & UINT32_C(0x00FF0000)) >> 8) \ + | (((n) & UINT32_C(0xFF000000)) >> 24) \ + ) #endif #ifndef bswap64 -# define bswap64(num) \ - ( (((uint64_t)(num) << 56) ) \ - | (((uint64_t)(num) << 40) & UINT64_C(0x00FF000000000000)) \ - | (((uint64_t)(num) << 24) & UINT64_C(0x0000FF0000000000)) \ - | (((uint64_t)(num) << 8) & UINT64_C(0x000000FF00000000)) \ - | (((uint64_t)(num) >> 8) & UINT64_C(0x00000000FF000000)) \ - | (((uint64_t)(num) >> 24) & UINT64_C(0x0000000000FF0000)) \ - | (((uint64_t)(num) >> 40) & UINT64_C(0x000000000000FF00)) \ - | (((uint64_t)(num) >> 56) ) ) +# define bswap64(n) (uint64_t)( \ + (((n) & UINT64_C(0x00000000000000FF)) << 56) \ + | (((n) & UINT64_C(0x000000000000FF00)) << 40) \ + | (((n) & UINT64_C(0x0000000000FF0000)) << 24) \ + | (((n) & UINT64_C(0x00000000FF000000)) << 8) \ + | (((n) & UINT64_C(0x000000FF00000000)) >> 8) \ + | (((n) & UINT64_C(0x0000FF0000000000)) >> 24) \ + | (((n) & UINT64_C(0x00FF000000000000)) >> 40) \ + | (((n) & UINT64_C(0xFF00000000000000)) >> 56) \ + ) #endif // Define conversion macros using the basic byte swapping macros. @@ -188,76 +185,76 @@ #endif -////////////////////////////// -// Aligned reads and writes // -////////////////////////////// - -static inline uint16_t -read16be(const uint8_t *buf) -{ - uint16_t num = *(const uint16_t *)buf; - return conv16be(num); -} +//////////////////////////////// +// Unaligned reads and writes // +//////////////////////////////// +// The traditional way of casting e.g. *(const uint16_t *)uint8_pointer +// is bad even if the uint8_pointer is properly aligned because this kind +// of casts break strict aliasing rules and result in undefined behavior. +// With unaligned pointers it's even worse: compilers may emit vector +// instructions that require aligned pointers even if non-vector +// instructions work with unaligned pointers. +// +// Using memcpy() is the standard compliant way to do unaligned access. +// Many modern compilers inline it so there is no function call overhead. +// For those compilers that don't handle the memcpy() method well, the +// old casting method (that violates strict aliasing) can be requested at +// build time. A third method, casting to a packed struct, would also be +// an option but isn't provided to keep things simpler (it's already a mess). +// Hopefully this is flexible enough in practice. static inline uint16_t -read16le(const uint8_t *buf) +read16ne(const uint8_t *buf) { - uint16_t num = *(const uint16_t *)buf; - return conv16le(num); -} - - -static inline uint32_t -read32be(const uint8_t *buf) -{ - uint32_t num = *(const uint32_t *)buf; - return conv32be(num); +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) + return *(const uint16_t *)buf; +#else + uint16_t num; + memcpy(&num, buf, sizeof(num)); + return num; +#endif } static inline uint32_t -read32le(const uint8_t *buf) -{ - uint32_t num = *(const uint32_t *)buf; - return conv32le(num); -} - - -static inline uint64_t -read64be(const uint8_t *buf) +read32ne(const uint8_t *buf) { - uint64_t num = *(const uint64_t *)buf; - return conv64be(num); +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) + return *(const uint32_t *)buf; +#else + uint32_t num; + memcpy(&num, buf, sizeof(num)); + return num; +#endif } static inline uint64_t -read64le(const uint8_t *buf) +read64ne(const uint8_t *buf) { - uint64_t num = *(const uint64_t *)buf; - return conv64le(num); +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) + return *(const uint64_t *)buf; +#else + uint64_t num; + memcpy(&num, buf, sizeof(num)); + return num; +#endif } -// NOTE: Possible byte swapping must be done in a macro to allow GCC -// to optimize byte swapping of constants when using glibc's or *BSD's -// byte swapping macros. The actual write is done in an inline function -// to make type checking of the buf pointer possible similarly to readXXYe() -// functions. - -#define write16be(buf, num) write16ne((buf), conv16be(num)) -#define write16le(buf, num) write16ne((buf), conv16le(num)) -#define write32be(buf, num) write32ne((buf), conv32be(num)) -#define write32le(buf, num) write32ne((buf), conv32le(num)) -#define write64be(buf, num) write64ne((buf), conv64be(num)) -#define write64le(buf, num) write64ne((buf), conv64le(num)) - - static inline void write16ne(uint8_t *buf, uint16_t num) { +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) *(uint16_t *)buf = num; +#else + memcpy(buf, &num, sizeof(num)); +#endif return; } @@ -265,7 +262,12 @@ write16ne(uint8_t *buf, uint16_t num) static inline void write32ne(uint8_t *buf, uint32_t num) { +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) *(uint32_t *)buf = num; +#else + memcpy(buf, &num, sizeof(num)); +#endif return; } @@ -273,90 +275,114 @@ write32ne(uint8_t *buf, uint32_t num) static inline void write64ne(uint8_t *buf, uint64_t num) { +#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ + && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) *(uint64_t *)buf = num; +#else + memcpy(buf, &num, sizeof(num)); +#endif return; } -//////////////////////////////// -// Unaligned reads and writes // -//////////////////////////////// - -// NOTE: TUKLIB_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and -// 32-bit unaligned integer loads and stores. It's possible that 64-bit -// unaligned access doesn't work or is slower than byte-by-byte access. -// Since unaligned 64-bit is probably not needed as often as 16-bit or -// 32-bit, we simply don't support 64-bit unaligned access for now. -#ifdef TUKLIB_FAST_UNALIGNED_ACCESS -# define unaligned_read16be read16be -# define unaligned_read16le read16le -# define unaligned_read32be read32be -# define unaligned_read32le read32le -# define unaligned_write16be write16be -# define unaligned_write16le write16le -# define unaligned_write32be write32be -# define unaligned_write32le write32le - -#else - static inline uint16_t -unaligned_read16be(const uint8_t *buf) +read16be(const uint8_t *buf) { +#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) + uint16_t num = read16ne(buf); + return conv16be(num); +#else uint16_t num = ((uint16_t)buf[0] << 8) | (uint16_t)buf[1]; return num; +#endif } static inline uint16_t -unaligned_read16le(const uint8_t *buf) +read16le(const uint8_t *buf) { +#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) + uint16_t num = read16ne(buf); + return conv16le(num); +#else uint16_t num = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8); return num; +#endif } static inline uint32_t -unaligned_read32be(const uint8_t *buf) +read32be(const uint8_t *buf) { +#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) + uint32_t num = read32ne(buf); + return conv32be(num); +#else uint32_t num = (uint32_t)buf[0] << 24; num |= (uint32_t)buf[1] << 16; num |= (uint32_t)buf[2] << 8; num |= (uint32_t)buf[3]; return num; +#endif } static inline uint32_t -unaligned_read32le(const uint8_t *buf) +read32le(const uint8_t *buf) { +#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) + uint32_t num = read32ne(buf); + return conv32le(num); +#else uint32_t num = (uint32_t)buf[0]; num |= (uint32_t)buf[1] << 8; num |= (uint32_t)buf[2] << 16; num |= (uint32_t)buf[3] << 24; return num; +#endif } +// NOTE: Possible byte swapping must be done in a macro to allow the compiler +// to optimize byte swapping of constants when using glibc's or *BSD's +// byte swapping macros. The actual write is done in an inline function +// to make type checking of the buf pointer possible. +#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) +# define write16be(buf, num) write16ne(buf, conv16be(num)) +# define write32be(buf, num) write32ne(buf, conv32be(num)) +#endif + +#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS) +# define write16le(buf, num) write16ne(buf, conv16le(num)) +# define write32le(buf, num) write32ne(buf, conv32le(num)) +#endif + + +#ifndef write16be static inline void -unaligned_write16be(uint8_t *buf, uint16_t num) +write16be(uint8_t *buf, uint16_t num) { buf[0] = (uint8_t)(num >> 8); buf[1] = (uint8_t)num; return; } +#endif +#ifndef write16le static inline void -unaligned_write16le(uint8_t *buf, uint16_t num) +write16le(uint8_t *buf, uint16_t num) { buf[0] = (uint8_t)num; buf[1] = (uint8_t)(num >> 8); return; } +#endif +#ifndef write32be static inline void -unaligned_write32be(uint8_t *buf, uint32_t num) +write32be(uint8_t *buf, uint32_t num) { buf[0] = (uint8_t)(num >> 24); buf[1] = (uint8_t)(num >> 16); @@ -364,10 +390,12 @@ unaligned_write32be(uint8_t *buf, uint32_t num) buf[3] = (uint8_t)num; return; } +#endif +#ifndef write32le static inline void -unaligned_write32le(uint8_t *buf, uint32_t num) +write32le(uint8_t *buf, uint32_t num) { buf[0] = (uint8_t)num; buf[1] = (uint8_t)(num >> 8); @@ -375,10 +403,184 @@ unaligned_write32le(uint8_t *buf, uint32_t num) buf[3] = (uint8_t)(num >> 24); return; } +#endif + + +////////////////////////////// +// Aligned reads and writes // +////////////////////////////// +// Separate functions for aligned reads and writes are provided since on +// strict-align archs aligned access is much faster than unaligned access. +// +// Just like in the unaligned case, memcpy() is needed to avoid +// strict aliasing violations. However, on archs that don't support +// unaligned access the compiler cannot know that the pointers given +// to memcpy() are aligned which results in slow code. As of C11 there is +// no standard way to tell the compiler that we know that the address is +// aligned but some compilers have language extensions to do that. With +// such language extensions the memcpy() method gives excellent results. +// +// What to do on a strict-align system when no known language extentensions +// are available? Falling back to byte-by-byte access would be safe but ruin +// optimizations that have been made specifically with aligned access in mind. +// As a compromise, aligned reads will fall back to non-compliant type punning +// but aligned writes will be byte-by-byte, that is, fast reads are preferred +// over fast writes. This obviously isn't great but hopefully it's a working +// compromise for now. +// +// __builtin_assume_aligned is support by GCC >= 4.7 and clang >= 3.6. +#ifdef HAVE___BUILTIN_ASSUME_ALIGNED +# define tuklib_memcpy_aligned(dest, src, size) \ + memcpy(dest, __builtin_assume_aligned(src, size), size) +#else +# define tuklib_memcpy_aligned(dest, src, size) \ + memcpy(dest, src, size) +# ifndef TUKLIB_FAST_UNALIGNED_ACCESS +# define TUKLIB_USE_UNSAFE_ALIGNED_READS 1 +# endif #endif +static inline uint16_t +aligned_read16ne(const uint8_t *buf) +{ +#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \ + || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS) + return *(const uint16_t *)buf; +#else + uint16_t num; + tuklib_memcpy_aligned(&num, buf, sizeof(num)); + return num; +#endif +} + + +static inline uint32_t +aligned_read32ne(const uint8_t *buf) +{ +#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \ + || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS) + return *(const uint32_t *)buf; +#else + uint32_t num; + tuklib_memcpy_aligned(&num, buf, sizeof(num)); + return num; +#endif +} + + +static inline uint64_t +aligned_read64ne(const uint8_t *buf) +{ +#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \ + || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS) + return *(const uint64_t *)buf; +#else + uint64_t num; + tuklib_memcpy_aligned(&num, buf, sizeof(num)); + return num; +#endif +} + + +static inline void +aligned_write16ne(uint8_t *buf, uint16_t num) +{ +#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING + *(uint16_t *)buf = num; +#else + tuklib_memcpy_aligned(buf, &num, sizeof(num)); +#endif + return; +} + + +static inline void +aligned_write32ne(uint8_t *buf, uint32_t num) +{ +#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING + *(uint32_t *)buf = num; +#else + tuklib_memcpy_aligned(buf, &num, sizeof(num)); +#endif + return; +} + + +static inline void +aligned_write64ne(uint8_t *buf, uint64_t num) +{ +#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING + *(uint64_t *)buf = num; +#else + tuklib_memcpy_aligned(buf, &num, sizeof(num)); +#endif + return; +} + + +static inline uint16_t +aligned_read16be(const uint8_t *buf) +{ + uint16_t num = aligned_read16ne(buf); + return conv16be(num); +} + + +static inline uint16_t +aligned_read16le(const uint8_t *buf) +{ + uint16_t num = aligned_read16ne(buf); + return conv16le(num); +} + + +static inline uint32_t +aligned_read32be(const uint8_t *buf) +{ + uint32_t num = aligned_read32ne(buf); + return conv32be(num); +} + + +static inline uint32_t +aligned_read32le(const uint8_t *buf) +{ + uint32_t num = aligned_read32ne(buf); + return conv32le(num); +} + + +static inline uint64_t +aligned_read64be(const uint8_t *buf) +{ + uint64_t num = aligned_read64ne(buf); + return conv64be(num); +} + + +static inline uint64_t +aligned_read64le(const uint8_t *buf) +{ + uint64_t num = aligned_read64ne(buf); + return conv64le(num); +} + + +// These need to be macros like in the unaligned case. +#define aligned_write16be(buf, num) aligned_write16ne((buf), conv16be(num)) +#define aligned_write16le(buf, num) aligned_write16ne((buf), conv16le(num)) +#define aligned_write32be(buf, num) aligned_write32ne((buf), conv32be(num)) +#define aligned_write32le(buf, num) aligned_write32ne((buf), conv32le(num)) +#define aligned_write64be(buf, num) aligned_write64ne((buf), conv64be(num)) +#define aligned_write64le(buf, num) aligned_write64ne((buf), conv64le(num)) + + +//////////////////// +// Bit operations // +//////////////////// + static inline uint32_t bsr32(uint32_t n) { @@ -391,7 +593,7 @@ bsr32(uint32_t n) // multiple architectures. On x86, __builtin_clz() ^ 31U becomes // either plain BSR (so the XOR gets optimized away) or LZCNT and // XOR (if -march indicates that SSE4a instructions are supported). - return __builtin_clz(n) ^ 31U; + return (uint32_t)__builtin_clz(n) ^ 31U; #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) uint32_t i; @@ -401,27 +603,27 @@ bsr32(uint32_t n) #else uint32_t i = 31; - if ((n & UINT32_C(0xFFFF0000)) == 0) { + if ((n & 0xFFFF0000) == 0) { n <<= 16; i = 15; } - if ((n & UINT32_C(0xFF000000)) == 0) { + if ((n & 0xFF000000) == 0) { n <<= 8; i -= 8; } - if ((n & UINT32_C(0xF0000000)) == 0) { + if ((n & 0xF0000000) == 0) { n <<= 4; i -= 4; } - if ((n & UINT32_C(0xC0000000)) == 0) { + if ((n & 0xC0000000) == 0) { n <<= 2; i -= 2; } - if ((n & UINT32_C(0x80000000)) == 0) + if ((n & 0x80000000) == 0) --i; return i; @@ -436,7 +638,7 @@ clz32(uint32_t n) return _bit_scan_reverse(n) ^ 31U; #elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX - return __builtin_clz(n); + return (uint32_t)__builtin_clz(n); #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) uint32_t i; @@ -448,27 +650,27 @@ clz32(uint32_t n) #else uint32_t i = 0; - if ((n & UINT32_C(0xFFFF0000)) == 0) { + if ((n & 0xFFFF0000) == 0) { n <<= 16; i = 16; } - if ((n & UINT32_C(0xFF000000)) == 0) { + if ((n & 0xFF000000) == 0) { n <<= 8; i += 8; } - if ((n & UINT32_C(0xF0000000)) == 0) { + if ((n & 0xF0000000) == 0) { n <<= 4; i += 4; } - if ((n & UINT32_C(0xC0000000)) == 0) { + if ((n & 0xC0000000) == 0) { n <<= 2; i += 2; } - if ((n & UINT32_C(0x80000000)) == 0) + if ((n & 0x80000000) == 0) ++i; return i; @@ -483,7 +685,7 @@ ctz32(uint32_t n) return _bit_scan_forward(n); #elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX - return __builtin_ctz(n); + return (uint32_t)__builtin_ctz(n); #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) uint32_t i; @@ -493,27 +695,27 @@ ctz32(uint32_t n) #else uint32_t i = 0; - if ((n & UINT32_C(0x0000FFFF)) == 0) { + if ((n & 0x0000FFFF) == 0) { n >>= 16; i = 16; } - if ((n & UINT32_C(0x000000FF)) == 0) { + if ((n & 0x000000FF) == 0) { n >>= 8; i += 8; } - if ((n & UINT32_C(0x0000000F)) == 0) { + if ((n & 0x0000000F) == 0) { n >>= 4; i += 4; } - if ((n & UINT32_C(0x00000003)) == 0) { + if ((n & 0x00000003) == 0) { n >>= 2; i += 2; } - if ((n & UINT32_C(0x00000001)) == 0) + if ((n & 0x00000001) == 0) ++i; return i; diff --git a/Utilities/cmliblzma/liblzma/api/lzma.h b/Utilities/cmliblzma/liblzma/api/lzma.h index aa88e42..122dab8 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma.h +++ b/Utilities/cmliblzma/liblzma/api/lzma.h @@ -224,7 +224,8 @@ # else # define lzma_nothrow throw() # endif -# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +# elif defined(__GNUC__) && (__GNUC__ > 3 \ + || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) # define lzma_nothrow __attribute__((__nothrow__)) # else # define lzma_nothrow @@ -241,7 +242,7 @@ * break anything if these are sometimes enabled and sometimes not, only * affects warnings and optimizations. */ -#if __GNUC__ >= 3 +#if defined(__GNUC__) && __GNUC__ >= 3 # ifndef lzma_attribute # define lzma_attribute(attr) __attribute__(attr) # endif diff --git a/Utilities/cmliblzma/liblzma/api/lzma/block.h b/Utilities/cmliblzma/liblzma/api/lzma/block.h index 7bdcfd7..962f387 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/block.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/block.h @@ -448,7 +448,7 @@ extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block) * - LZMA_MEM_ERROR * - LZMA_OPTIONS_ERROR * - LZMA_UNSUPPORTED_CHECK: block->check specifies a Check ID - * that is not supported by this buid of liblzma. Initializing + * that is not supported by this build of liblzma. Initializing * the encoder failed. * - LZMA_PROG_ERROR */ diff --git a/Utilities/cmliblzma/liblzma/api/lzma/filter.h b/Utilities/cmliblzma/liblzma/api/lzma/filter.h index 4e78752..8c85931 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/filter.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/filter.h @@ -341,9 +341,10 @@ extern LZMA_API(lzma_ret) lzma_properties_encode( * \param filter filter->id must have been set to the correct * Filter ID. filter->options doesn't need to be * initialized (it's not freed by this function). The - * decoded options will be stored to filter->options. - * filter->options is set to NULL if there are no - * properties or if an error occurs. + * decoded options will be stored in filter->options; + * it's application's responsibility to free it when + * appropriate. filter->options is set to NULL if + * there are no properties or if an error occurs. * \param allocator Custom memory allocator used to allocate the * options. Set to NULL to use the default malloc(), * and in case of an error, also free(). diff --git a/Utilities/cmliblzma/liblzma/api/lzma/hardware.h b/Utilities/cmliblzma/liblzma/api/lzma/hardware.h index 5321d9a..47481f2 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/hardware.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/hardware.h @@ -6,7 +6,7 @@ * ways to limit the resource usage. Applications linking against liblzma * need to do the actual decisions how much resources to let liblzma to use. * To ease making these decisions, liblzma provides functions to find out - * the relevant capabilities of the underlaying hardware. Currently there + * the relevant capabilities of the underlying hardware. Currently there * is only a function to find out the amount of RAM, but in the future there * will be also a function to detect how many concurrent threads the system * can run. diff --git a/Utilities/cmliblzma/liblzma/api/lzma/lzma12.h b/Utilities/cmliblzma/liblzma/api/lzma/lzma12.h index 4e32fa3..df5f23b 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/lzma12.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/lzma12.h @@ -301,7 +301,7 @@ typedef struct { * (2^ pb =2^2=4), which is often a good choice when there's * no better guess. * - * When the aligment is known, setting pb accordingly may reduce + * When the alignment is known, setting pb accordingly may reduce * the file size a little. E.g. with text files having one-byte * alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can * improve compression slightly. For UTF-16 text, pb=1 is a good diff --git a/Utilities/cmliblzma/liblzma/api/lzma/version.h b/Utilities/cmliblzma/liblzma/api/lzma/version.h index 143c7de..2bf3eae 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/version.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/version.h @@ -22,7 +22,7 @@ */ #define LZMA_VERSION_MAJOR 5 #define LZMA_VERSION_MINOR 2 -#define LZMA_VERSION_PATCH 4 +#define LZMA_VERSION_PATCH 5 #define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE #ifndef LZMA_VERSION_COMMIT diff --git a/Utilities/cmliblzma/liblzma/api/lzma/vli.h b/Utilities/cmliblzma/liblzma/api/lzma/vli.h index 9ad13f2..1b7a952 100644 --- a/Utilities/cmliblzma/liblzma/api/lzma/vli.h +++ b/Utilities/cmliblzma/liblzma/api/lzma/vli.h @@ -54,7 +54,7 @@ * * Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is * indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the - * underlaying integer type. + * underlying integer type. * * lzma_vli will be uint64_t for the foreseeable future. If a bigger size * is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will diff --git a/Utilities/cmliblzma/liblzma/check/crc32_fast.c b/Utilities/cmliblzma/liblzma/check/crc32_fast.c index 3de0263..eed7350 100644 --- a/Utilities/cmliblzma/liblzma/check/crc32_fast.c +++ b/Utilities/cmliblzma/liblzma/check/crc32_fast.c @@ -49,7 +49,7 @@ lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc) // Calculate the CRC32 using the slice-by-eight algorithm. while (buf < limit) { - crc ^= *(const uint32_t *)(buf); + crc ^= aligned_read32ne(buf); buf += 4; crc = lzma_crc32_table[7][A(crc)] @@ -57,7 +57,7 @@ lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc) ^ lzma_crc32_table[5][C(crc)] ^ lzma_crc32_table[4][D(crc)]; - const uint32_t tmp = *(const uint32_t *)(buf); + const uint32_t tmp = aligned_read32ne(buf); buf += 4; // At least with some compilers, it is critical for diff --git a/Utilities/cmliblzma/liblzma/check/crc32_table.c b/Utilities/cmliblzma/liblzma/check/crc32_table.c index 368874e..b11762a 100644 --- a/Utilities/cmliblzma/liblzma/check/crc32_table.c +++ b/Utilities/cmliblzma/liblzma/check/crc32_table.c @@ -12,6 +12,9 @@ #include "common.h" +// Having the declaration here silences clang -Wmissing-variable-declarations. +extern const uint32_t lzma_crc32_table[8][256]; + #ifdef WORDS_BIGENDIAN # include "crc32_table_be.h" #else diff --git a/Utilities/cmliblzma/liblzma/check/crc64_fast.c b/Utilities/cmliblzma/liblzma/check/crc64_fast.c index 52af29e..8af54cd 100644 --- a/Utilities/cmliblzma/liblzma/check/crc64_fast.c +++ b/Utilities/cmliblzma/liblzma/check/crc64_fast.c @@ -47,9 +47,9 @@ lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc) while (buf < limit) { #ifdef WORDS_BIGENDIAN const uint32_t tmp = (crc >> 32) - ^ *(const uint32_t *)(buf); + ^ aligned_read32ne(buf); #else - const uint32_t tmp = crc ^ *(const uint32_t *)(buf); + const uint32_t tmp = crc ^ aligned_read32ne(buf); #endif buf += 4; diff --git a/Utilities/cmliblzma/liblzma/check/crc64_table.c b/Utilities/cmliblzma/liblzma/check/crc64_table.c index 1fbcd94..7560eb0 100644 --- a/Utilities/cmliblzma/liblzma/check/crc64_table.c +++ b/Utilities/cmliblzma/liblzma/check/crc64_table.c @@ -12,6 +12,9 @@ #include "common.h" +// Having the declaration here silences clang -Wmissing-variable-declarations. +extern const uint64_t lzma_crc64_table[4][256]; + #ifdef WORDS_BIGENDIAN # include "crc64_table_be.h" #else diff --git a/Utilities/cmliblzma/liblzma/common/alone_decoder.c b/Utilities/cmliblzma/liblzma/common/alone_decoder.c index 77d0a9b..239b230 100644 --- a/Utilities/cmliblzma/liblzma/common/alone_decoder.c +++ b/Utilities/cmliblzma/liblzma/common/alone_decoder.c @@ -50,8 +50,7 @@ typedef struct { static lzma_ret -alone_decode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), +alone_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, diff --git a/Utilities/cmliblzma/liblzma/common/alone_encoder.c b/Utilities/cmliblzma/liblzma/common/alone_encoder.c index 4853cfd..96c1db7 100644 --- a/Utilities/cmliblzma/liblzma/common/alone_encoder.c +++ b/Utilities/cmliblzma/liblzma/common/alone_encoder.c @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////// // -/// \file alone_decoder.c -/// \brief Decoder for LZMA_Alone files +/// \file alone_encoder.c +/// \brief Encoder for LZMA_Alone files // // Author: Lasse Collin // @@ -31,8 +31,7 @@ typedef struct { static lzma_ret -alone_encode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), +alone_encode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, @@ -122,7 +121,7 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (d != UINT32_MAX) ++d; - unaligned_write32le(coder->header + 1, d); + write32le(coder->header + 1, d); // - Uncompressed size (always unknown and using EOPM) memset(coder->header + 1 + 4, 0xFF, 8); diff --git a/Utilities/cmliblzma/liblzma/common/block_header_decoder.c b/Utilities/cmliblzma/liblzma/common/block_header_decoder.c index 1dd982f..2e1135d 100644 --- a/Utilities/cmliblzma/liblzma/common/block_header_decoder.c +++ b/Utilities/cmliblzma/liblzma/common/block_header_decoder.c @@ -67,7 +67,7 @@ lzma_block_header_decode(lzma_block *block, const size_t in_size = block->header_size - 4; // Verify CRC32 - if (lzma_crc32(in, in_size, 0) != unaligned_read32le(in + in_size)) + if (lzma_crc32(in, in_size, 0) != read32le(in + in_size)) return LZMA_DATA_ERROR; // Check for unsupported flags. @@ -98,7 +98,7 @@ lzma_block_header_decode(lzma_block *block, block->uncompressed_size = LZMA_VLI_UNKNOWN; // Filter Flags - const size_t filter_count = (in[1] & 3) + 1; + const size_t filter_count = (in[1] & 3U) + 1; for (size_t i = 0; i < filter_count; ++i) { const lzma_ret ret = lzma_filter_flags_decode( &block->filters[i], allocator, diff --git a/Utilities/cmliblzma/liblzma/common/block_header_encoder.c b/Utilities/cmliblzma/liblzma/common/block_header_encoder.c index 5c5f542..160425d 100644 --- a/Utilities/cmliblzma/liblzma/common/block_header_encoder.c +++ b/Utilities/cmliblzma/liblzma/common/block_header_encoder.c @@ -126,7 +126,7 @@ lzma_block_header_encode(const lzma_block *block, uint8_t *out) memzero(out + out_pos, out_size - out_pos); // CRC32 - unaligned_write32le(out + out_size, lzma_crc32(out, out_size, 0)); + write32le(out + out_size, lzma_crc32(out, out_size, 0)); return LZMA_OK; } diff --git a/Utilities/cmliblzma/liblzma/common/block_util.c b/Utilities/cmliblzma/liblzma/common/block_util.c index 00c7fe8..acb3111 100644 --- a/Utilities/cmliblzma/liblzma/common/block_util.c +++ b/Utilities/cmliblzma/liblzma/common/block_util.c @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -/// \file block_header.c +/// \file block_util.c /// \brief Utility functions to handle lzma_block // // Author: Lasse Collin diff --git a/Utilities/cmliblzma/liblzma/common/common.c b/Utilities/cmliblzma/liblzma/common/common.c index 57e3f8e..cf714e5 100644 --- a/Utilities/cmliblzma/liblzma/common/common.c +++ b/Utilities/cmliblzma/liblzma/common/common.c @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -/// \file common.h +/// \file common.c /// \brief Common functions needed in many places in liblzma // // Author: Lasse Collin @@ -99,7 +99,11 @@ lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, const size_t out_avail = out_size - *out_pos; const size_t copy_size = my_min(in_avail, out_avail); - memcpy(out + *out_pos, in + *in_pos, copy_size); + // Call memcpy() only if there is something to copy. If there is + // nothing to copy, in or out might be NULL and then the memcpy() + // call would trigger undefined behavior. + if (copy_size > 0) + memcpy(out + *out_pos, in + *in_pos, copy_size); *in_pos += copy_size; *out_pos += copy_size; diff --git a/Utilities/cmliblzma/liblzma/common/common.h b/Utilities/cmliblzma/liblzma/common/common.h index dde3ae0..b3d3b7a 100644 --- a/Utilities/cmliblzma/liblzma/common/common.h +++ b/Utilities/cmliblzma/liblzma/common/common.h @@ -14,6 +14,7 @@ #define LZMA_COMMON_H #include "sysdefs.h" +#include "mythread.h" #include "tuklib_integer.h" #if defined(_WIN32) || defined(__CYGWIN__) diff --git a/Utilities/cmliblzma/liblzma/common/filter_common.h b/Utilities/cmliblzma/liblzma/common/filter_common.h index 42a26a2..9390305 100644 --- a/Utilities/cmliblzma/liblzma/common/filter_common.h +++ b/Utilities/cmliblzma/liblzma/common/filter_common.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -/// \file filter_common.c +/// \file filter_common.h /// \brief Filter-specific stuff common for both encoder and decoder // // Author: Lasse Collin diff --git a/Utilities/cmliblzma/liblzma/common/filter_decoder.h b/Utilities/cmliblzma/liblzma/common/filter_decoder.h index a2e255f..2dac602 100644 --- a/Utilities/cmliblzma/liblzma/common/filter_decoder.h +++ b/Utilities/cmliblzma/liblzma/common/filter_decoder.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -/// \file filter_decoder.c +/// \file filter_decoder.h /// \brief Filter ID mapping to filter-specific functions // // Author: Lasse Collin diff --git a/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c b/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c index d110566..b57b9fd 100644 --- a/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c +++ b/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////// // /// \file filter_flags_encoder.c -/// \brief Decodes a Filter Flags field +/// \brief Encodes a Filter Flags field // // Author: Lasse Collin // diff --git a/Utilities/cmliblzma/liblzma/common/hardware_physmem.c b/Utilities/cmliblzma/liblzma/common/hardware_physmem.c index 7405b65..a2bbbe2 100644 --- a/Utilities/cmliblzma/liblzma/common/hardware_physmem.c +++ b/Utilities/cmliblzma/liblzma/common/hardware_physmem.c @@ -19,7 +19,7 @@ extern LZMA_API(uint64_t) lzma_physmem(void) { // It is simpler to make lzma_physmem() a wrapper for - // tuklib_physmem() than to hack appropriate symbol visiblity + // tuklib_physmem() than to hack appropriate symbol visibility // support for the tuklib modules. return tuklib_physmem(); } diff --git a/Utilities/cmliblzma/liblzma/common/index.c b/Utilities/cmliblzma/liblzma/common/index.c index 26e4e51..a41e8f3 100644 --- a/Utilities/cmliblzma/liblzma/common/index.c +++ b/Utilities/cmliblzma/liblzma/common/index.c @@ -105,7 +105,7 @@ typedef struct { typedef struct { - /// Every index_stream is a node in the tree of Sreams. + /// Every index_stream is a node in the tree of Streams. index_tree_node node; /// Number of this Stream (first one is 1) @@ -166,7 +166,7 @@ struct lzma_index_s { lzma_vli index_list_size; /// How many Records to allocate at once in lzma_index_append(). - /// This defaults to INDEX_GROUP_SIZE but can be overriden with + /// This defaults to INDEX_GROUP_SIZE but can be overridden with /// lzma_index_prealloc(). size_t prealloc; @@ -825,8 +825,8 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src, s->groups.root = &newg->node; } - if (s->groups.rightmost == &g->node) - s->groups.rightmost = &newg->node; + assert(s->groups.rightmost == &g->node); + s->groups.rightmost = &newg->node; lzma_free(g, allocator); diff --git a/Utilities/cmliblzma/liblzma/common/memcmplen.h b/Utilities/cmliblzma/liblzma/common/memcmplen.h index c1efc9e..dcfd8d6 100644 --- a/Utilities/cmliblzma/liblzma/common/memcmplen.h +++ b/Utilities/cmliblzma/liblzma/common/memcmplen.h @@ -61,8 +61,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, // to __builtin_clzll(). #define LZMA_MEMCMPLEN_EXTRA 8 while (len < limit) { - const uint64_t x = *(const uint64_t *)(buf1 + len) - - *(const uint64_t *)(buf2 + len); + const uint64_t x = read64ne(buf1 + len) - read64ne(buf2 + len); if (x != 0) { # if defined(_M_X64) // MSVC or Intel C compiler on Windows unsigned long tmp; @@ -99,15 +98,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, _mm_loadu_si128((const __m128i *)(buf2 + len)))); if (x != 0) { -# if defined(__INTEL_COMPILER) - len += _bit_scan_forward(x); -# elif defined(_MSC_VER) - unsigned long tmp; - _BitScanForward(&tmp, x); - len += tmp; -# else - len += __builtin_ctz(x); -# endif + len += ctz32(x); return my_min(len, limit); } @@ -120,8 +111,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, // Generic 32-bit little endian method # define LZMA_MEMCMPLEN_EXTRA 4 while (len < limit) { - uint32_t x = *(const uint32_t *)(buf1 + len) - - *(const uint32_t *)(buf2 + len); + uint32_t x = read32ne(buf1 + len) - read32ne(buf2 + len); if (x != 0) { if ((x & 0xFFFF) == 0) { len += 2; @@ -143,8 +133,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, // Generic 32-bit big endian method # define LZMA_MEMCMPLEN_EXTRA 4 while (len < limit) { - uint32_t x = *(const uint32_t *)(buf1 + len) - ^ *(const uint32_t *)(buf2 + len); + uint32_t x = read32ne(buf1 + len) ^ read32ne(buf2 + len); if (x != 0) { if ((x & 0xFFFF0000) == 0) { len += 2; diff --git a/Utilities/cmliblzma/liblzma/common/stream_encoder_mt.c b/Utilities/cmliblzma/liblzma/common/stream_encoder_mt.c index 2efe44c..01e4033 100644 --- a/Utilities/cmliblzma/liblzma/common/stream_encoder_mt.c +++ b/Utilities/cmliblzma/liblzma/common/stream_encoder_mt.c @@ -700,7 +700,7 @@ stream_encode_mt(void *coder_ptr, const lzma_allocator *allocator, ret = coder->thread_error; if (ret != LZMA_OK) { assert(ret != LZMA_STREAM_END); - break; + break; // Break out of mythread_sync. } // Try to read compressed data to out[]. @@ -958,7 +958,7 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator, // Validate the filter chain so that we can give an error in this // function instead of delaying it to the first call to lzma_code(). // The memory usage calculation verifies the filter chain as - // a side effect so we take advatange of that. + // a side effect so we take advantage of that. if (lzma_raw_encoder_memusage(filters) == UINT64_MAX) return LZMA_OPTIONS_ERROR; diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c b/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c index 1bc2f97..4e43e35 100644 --- a/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c +++ b/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c @@ -38,7 +38,7 @@ lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in) // and unsupported files. const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic), LZMA_STREAM_FLAGS_SIZE, 0); - if (crc != unaligned_read32le(in + sizeof(lzma_header_magic) + if (crc != read32le(in + sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE)) return LZMA_DATA_ERROR; @@ -67,7 +67,7 @@ lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in) // CRC32 const uint32_t crc = lzma_crc32(in + sizeof(uint32_t), sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0); - if (crc != unaligned_read32le(in)) + if (crc != read32le(in)) return LZMA_DATA_ERROR; // Stream Flags @@ -75,7 +75,7 @@ lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in) return LZMA_OPTIONS_ERROR; // Backward Size - options->backward_size = unaligned_read32le(in + sizeof(uint32_t)); + options->backward_size = read32le(in + sizeof(uint32_t)); options->backward_size = (options->backward_size + 1) * 4; return LZMA_OK; diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c b/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c index 4e71715..b98ab17 100644 --- a/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c +++ b/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c @@ -46,8 +46,8 @@ lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out) const uint32_t crc = lzma_crc32(out + sizeof(lzma_header_magic), LZMA_STREAM_FLAGS_SIZE, 0); - unaligned_write32le(out + sizeof(lzma_header_magic) - + LZMA_STREAM_FLAGS_SIZE, crc); + write32le(out + sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE, + crc); return LZMA_OK; } @@ -66,7 +66,7 @@ lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out) if (!is_backward_size_valid(options)) return LZMA_PROG_ERROR; - unaligned_write32le(out + 4, options->backward_size / 4 - 1); + write32le(out + 4, options->backward_size / 4 - 1); // Stream Flags if (stream_flags_encode(options, out + 2 * 4)) @@ -76,7 +76,7 @@ lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out) const uint32_t crc = lzma_crc32( out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0); - unaligned_write32le(out, crc); + write32le(out, crc); // Magic memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE, diff --git a/Utilities/cmliblzma/liblzma/common/vli_decoder.c b/Utilities/cmliblzma/liblzma/common/vli_decoder.c index c181828..af2799d 100644 --- a/Utilities/cmliblzma/liblzma/common/vli_decoder.c +++ b/Utilities/cmliblzma/liblzma/common/vli_decoder.c @@ -72,7 +72,7 @@ lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos, // corrupt. // // If we need bigger integers in future, old versions liblzma - // will confusingly indicate the file being corrupt istead of + // will confusingly indicate the file being corrupt instead of // unsupported. I suppose it's still better this way, because // in the foreseeable future (writing this in 2008) the only // reason why files would appear having over 63-bit integers diff --git a/Utilities/cmliblzma/liblzma/delta/delta_decoder.c b/Utilities/cmliblzma/liblzma/delta/delta_decoder.c index 6859afa..13d8a28 100644 --- a/Utilities/cmliblzma/liblzma/delta/delta_decoder.c +++ b/Utilities/cmliblzma/liblzma/delta/delta_decoder.c @@ -70,7 +70,7 @@ lzma_delta_props_decode(void **options, const lzma_allocator *allocator, return LZMA_MEM_ERROR; opt->type = LZMA_DELTA_TYPE_BYTE; - opt->dist = props[0] + 1; + opt->dist = props[0] + 1U; *options = opt; diff --git a/Utilities/cmliblzma/liblzma/lz/lz_decoder.c b/Utilities/cmliblzma/liblzma/lz/lz_decoder.c index c708644..09b5743 100644 --- a/Utilities/cmliblzma/liblzma/lz/lz_decoder.c +++ b/Utilities/cmliblzma/liblzma/lz/lz_decoder.c @@ -91,11 +91,17 @@ decode_buffer(lzma_coder *coder, in, in_pos, in_size); // Copy the decoded data from the dictionary to the out[] - // buffer. + // buffer. Do it conditionally because out can be NULL + // (in which case copy_size is always 0). Calling memcpy() + // with a null-pointer is undefined even if the third + // argument is 0. const size_t copy_size = coder->dict.pos - dict_start; assert(copy_size <= out_size - *out_pos); - memcpy(out + *out_pos, coder->dict.buf + dict_start, - copy_size); + + if (copy_size > 0) + memcpy(out + *out_pos, coder->dict.buf + dict_start, + copy_size); + *out_pos += copy_size; // Reset the dictionary if so requested by coder->lz.code(). @@ -125,8 +131,7 @@ decode_buffer(lzma_coder *coder, static lzma_ret -lz_decode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), +lz_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, @@ -241,7 +246,7 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, if (lz_options.dict_size < 4096) lz_options.dict_size = 4096; - // Make dictionary size a multipe of 16. Some LZ-based decoders like + // Make dictionary size a multiple of 16. Some LZ-based decoders like // LZMA use the lowest bits lzma_dict.pos to know the alignment of the // data. Aligned buffer is also good when memcpying from the // dictionary to the output buffer, since applications are diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h index 342a333..fb15c58 100644 --- a/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h +++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h @@ -39,7 +39,7 @@ // Endianness doesn't matter in hash_2_calc() (no effect on the output). #ifdef TUKLIB_FAST_UNALIGNED_ACCESS # define hash_2_calc() \ - const uint32_t hash_value = *(const uint16_t *)(cur) + const uint32_t hash_value = read16ne(cur) #else # define hash_2_calc() \ const uint32_t hash_value \ diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c b/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c index 7852077..d03657a 100644 --- a/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c +++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c @@ -113,7 +113,7 @@ normalize(lzma_mf *mf) // may be match finders that use larger resolution than one byte. const uint32_t subvalue = (MUST_NORMALIZE_POS - mf->cyclic_size); - // & (~(UINT32_C(1) << 10) - 1); + // & ~((UINT32_C(1) << 10) - 1); for (uint32_t i = 0; i < mf->hash_count; ++i) { // If the distance is greater than the dictionary size, diff --git a/Utilities/cmliblzma/liblzma/lzma/fastpos.h b/Utilities/cmliblzma/liblzma/lzma/fastpos.h index a3feea5..cba442c 100644 --- a/Utilities/cmliblzma/liblzma/lzma/fastpos.h +++ b/Utilities/cmliblzma/liblzma/lzma/fastpos.h @@ -101,7 +101,7 @@ extern const uint8_t lzma_fastpos[1 << FASTPOS_BITS]; (UINT32_C(1) << (FASTPOS_BITS + fastpos_shift(extra, n))) #define fastpos_result(dist, extra, n) \ - lzma_fastpos[(dist) >> fastpos_shift(extra, n)] \ + (uint32_t)(lzma_fastpos[(dist) >> fastpos_shift(extra, n)]) \ + 2 * fastpos_shift(extra, n) diff --git a/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c b/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c index c97e6f4..d4484c8 100644 --- a/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c +++ b/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c @@ -11,7 +11,6 @@ // /////////////////////////////////////////////////////////////////////////////// -#include <sys/types.h> #include <inttypes.h> #include <stdio.h> #include "fastpos.h" diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c index 878c870..cf1b511 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c +++ b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c @@ -136,7 +136,7 @@ lzma2_decode(void *coder_ptr, lzma_dict *restrict dict, break; case SEQ_UNCOMPRESSED_2: - coder->uncompressed_size += in[(*in_pos)++] + 1; + coder->uncompressed_size += in[(*in_pos)++] + 1U; coder->sequence = SEQ_COMPRESSED_0; coder->lzma.set_uncompressed(coder->lzma.coder, coder->uncompressed_size); @@ -148,7 +148,7 @@ lzma2_decode(void *coder_ptr, lzma_dict *restrict dict, break; case SEQ_COMPRESSED_1: - coder->compressed_size += in[(*in_pos)++] + 1; + coder->compressed_size += in[(*in_pos)++] + 1U; coder->sequence = coder->next_sequence; break; @@ -297,8 +297,8 @@ lzma_lzma2_props_decode(void **options, const lzma_allocator *allocator, if (props[0] == 40) { opt->dict_size = UINT32_MAX; } else { - opt->dict_size = 2 | (props[0] & 1); - opt->dict_size <<= props[0] / 2 + 11; + opt->dict_size = 2 | (props[0] & 1U); + opt->dict_size <<= props[0] / 2U + 11; } opt->preset_dict = NULL; diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_common.h b/Utilities/cmliblzma/liblzma/lzma/lzma_common.h index 09efd38..9d040d9 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma_common.h +++ b/Utilities/cmliblzma/liblzma/lzma/lzma_common.h @@ -122,7 +122,8 @@ typedef enum { /// byte; and /// - the highest literal_context_bits bits of the previous byte. #define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \ - ((probs)[(((pos) & lp_mask) << lc) + ((prev_byte) >> (8 - lc))]) + ((probs)[(((pos) & (lp_mask)) << (lc)) \ + + ((uint32_t)(prev_byte) >> (8U - (lc)))]) static inline void diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c index d0f29b7..e605a0a 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c +++ b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c @@ -398,7 +398,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, // ("match byte") to "len" to minimize the // number of variables we need to store // between decoder calls. - len = dict_get(&dict, rep0) << 1; + len = (uint32_t)(dict_get(&dict, rep0)) << 1; // The usage of "offset" allows omitting some // branches, which should give tiny speed @@ -569,7 +569,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, #ifdef HAVE_SMALL do { rc_bit(probs[symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_DIST_MODEL); } while (++offset < limit); #else @@ -577,25 +577,25 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, case 5: assert(offset == 0); rc_bit(probs[symbol], , - rep0 += 1, + rep0 += 1U, SEQ_DIST_MODEL); ++offset; --limit; case 4: rc_bit(probs[symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_DIST_MODEL); ++offset; --limit; case 3: rc_bit(probs[symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_DIST_MODEL); ++offset; --limit; case 2: rc_bit(probs[symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_DIST_MODEL); ++offset; --limit; @@ -607,7 +607,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, // the unneeded updating of // "symbol". rc_bit_last(probs[symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_DIST_MODEL); } #endif @@ -635,7 +635,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, do { rc_bit(coder->pos_align[ symbol], , - rep0 += 1 << offset, + rep0 += 1U << offset, SEQ_ALIGN); } while (++offset < ALIGN_BITS); #else @@ -1049,7 +1049,7 @@ lzma_lzma_props_decode(void **options, const lzma_allocator *allocator, // All dictionary sizes are accepted, including zero. LZ decoder // will automatically use a dictionary at least a few KiB even if // a smaller dictionary is requested. - opt->dict_size = unaligned_read32le(props + 1); + opt->dict_size = read32le(props + 1); opt->preset_dict = NULL; opt->preset_dict_size = 0; diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c index ba9ce69..07d2b87 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c +++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c @@ -663,7 +663,7 @@ lzma_lzma_props_encode(const void *options, uint8_t *out) if (lzma_lzma_lclppb_encode(opt, out)) return LZMA_PROG_ERROR; - unaligned_write32le(out + 1, opt->dict_size); + write32le(out + 1, opt->dict_size); return LZMA_OK; } diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c index 59f7734..101c8d4 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c +++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c @@ -636,9 +636,10 @@ helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf, uint32_t len_test_2 = len_test + 1; const uint32_t limit = my_min(buf_avail_full, len_test_2 + nice_len); - for (; len_test_2 < limit - && buf[len_test_2] == buf_back[len_test_2]; - ++len_test_2) ; + // NOTE: len_test_2 may be greater than limit so the call to + // lzma_memcmplen() must be done conditionally. + if (len_test_2 < limit) + len_test_2 = lzma_memcmplen(buf, buf_back, len_test_2, limit); len_test_2 -= len_test + 1; @@ -732,9 +733,12 @@ helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf, const uint32_t limit = my_min(buf_avail_full, len_test_2 + nice_len); - for (; len_test_2 < limit && - buf[len_test_2] == buf_back[len_test_2]; - ++len_test_2) ; + // NOTE: len_test_2 may be greater than limit + // so the call to lzma_memcmplen() must be + // done conditionally. + if (len_test_2 < limit) + len_test_2 = lzma_memcmplen(buf, buf_back, + len_test_2, limit); len_test_2 -= len_test + 1; diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h index a2da969..2e34aac 100644 --- a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h +++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h @@ -25,8 +25,7 @@ // MATCH_LEN_MIN bytes. Unaligned access gives tiny gain so there's no // reason to not use it when it is supported. #ifdef TUKLIB_FAST_UNALIGNED_ACCESS -# define not_equal_16(a, b) \ - (*(const uint16_t *)(a) != *(const uint16_t *)(b)) +# define not_equal_16(a, b) (read16ne(a) != read16ne(b)) #else # define not_equal_16(a, b) \ ((a)[0] != (b)[0] || (a)[1] != (b)[1]) diff --git a/Utilities/cmliblzma/liblzma/simple/arm.c b/Utilities/cmliblzma/liblzma/simple/arm.c index 181d0e3..ff5073a 100644 --- a/Utilities/cmliblzma/liblzma/simple/arm.c +++ b/Utilities/cmliblzma/liblzma/simple/arm.c @@ -22,9 +22,9 @@ arm_code(void *simple lzma_attribute((__unused__)), size_t i; for (i = 0; i + 4 <= size; i += 4) { if (buffer[i + 3] == 0xEB) { - uint32_t src = (buffer[i + 2] << 16) - | (buffer[i + 1] << 8) - | (buffer[i + 0]); + uint32_t src = ((uint32_t)(buffer[i + 2]) << 16) + | ((uint32_t)(buffer[i + 1]) << 8) + | (uint32_t)(buffer[i + 0]); src <<= 2; uint32_t dest; diff --git a/Utilities/cmliblzma/liblzma/simple/armthumb.c b/Utilities/cmliblzma/liblzma/simple/armthumb.c index eab4862..a8da334 100644 --- a/Utilities/cmliblzma/liblzma/simple/armthumb.c +++ b/Utilities/cmliblzma/liblzma/simple/armthumb.c @@ -23,10 +23,10 @@ armthumb_code(void *simple lzma_attribute((__unused__)), for (i = 0; i + 4 <= size; i += 2) { if ((buffer[i + 1] & 0xF8) == 0xF0 && (buffer[i + 3] & 0xF8) == 0xF8) { - uint32_t src = ((buffer[i + 1] & 0x7) << 19) - | (buffer[i + 0] << 11) - | ((buffer[i + 3] & 0x7) << 8) - | (buffer[i + 2]); + uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19) + | ((uint32_t)(buffer[i + 0]) << 11) + | (((uint32_t)(buffer[i + 3]) & 7) << 8) + | (uint32_t)(buffer[i + 2]); src <<= 1; diff --git a/Utilities/cmliblzma/liblzma/simple/ia64.c b/Utilities/cmliblzma/liblzma/simple/ia64.c index 580529e..6492d0a 100644 --- a/Utilities/cmliblzma/liblzma/simple/ia64.c +++ b/Utilities/cmliblzma/liblzma/simple/ia64.c @@ -70,7 +70,7 @@ ia64_code(void *simple lzma_attribute((__unused__)), inst_norm |= (uint64_t)(dest & 0x100000) << (36 - 20); - instruction &= (1 << bit_res) - 1; + instruction &= (1U << bit_res) - 1; instruction |= (inst_norm << bit_res); for (size_t j = 0; j < 6; j++) diff --git a/Utilities/cmliblzma/liblzma/simple/powerpc.c b/Utilities/cmliblzma/liblzma/simple/powerpc.c index 54dfbf1..0b60e9b 100644 --- a/Utilities/cmliblzma/liblzma/simple/powerpc.c +++ b/Utilities/cmliblzma/liblzma/simple/powerpc.c @@ -25,10 +25,11 @@ powerpc_code(void *simple lzma_attribute((__unused__)), if ((buffer[i] >> 2) == 0x12 && ((buffer[i + 3] & 3) == 1)) { - const uint32_t src = ((buffer[i + 0] & 3) << 24) - | (buffer[i + 1] << 16) - | (buffer[i + 2] << 8) - | (buffer[i + 3] & (~3)); + const uint32_t src + = (((uint32_t)(buffer[i + 0]) & 3) << 24) + | ((uint32_t)(buffer[i + 1]) << 16) + | ((uint32_t)(buffer[i + 2]) << 8) + | ((uint32_t)(buffer[i + 3]) & ~UINT32_C(3)); uint32_t dest; if (is_encoder) diff --git a/Utilities/cmliblzma/liblzma/simple/simple_coder.c b/Utilities/cmliblzma/liblzma/simple/simple_coder.c index 13ebabc..4f499be 100644 --- a/Utilities/cmliblzma/liblzma/simple/simple_coder.c +++ b/Utilities/cmliblzma/liblzma/simple/simple_coder.c @@ -118,7 +118,15 @@ simple_code(void *coder_ptr, const lzma_allocator *allocator, // coder->pos and coder->size yet. This way the coder can be // restarted if the next filter in the chain returns e.g. // LZMA_MEM_ERROR. - memcpy(out + *out_pos, coder->buffer + coder->pos, buf_avail); + // + // Do the memcpy() conditionally because out can be NULL + // (in which case buf_avail is always 0). Calling memcpy() + // with a null-pointer is undefined even if the third + // argument is 0. + if (buf_avail > 0) + memcpy(out + *out_pos, coder->buffer + coder->pos, + buf_avail); + *out_pos += buf_avail; // Copy/Encode/Decode more data to out[]. diff --git a/Utilities/cmliblzma/liblzma/simple/simple_decoder.c b/Utilities/cmliblzma/liblzma/simple/simple_decoder.c index 1d864f2..dc4d241 100644 --- a/Utilities/cmliblzma/liblzma/simple/simple_decoder.c +++ b/Utilities/cmliblzma/liblzma/simple/simple_decoder.c @@ -28,7 +28,7 @@ lzma_simple_props_decode(void **options, const lzma_allocator *allocator, if (opt == NULL) return LZMA_MEM_ERROR; - opt->start_offset = unaligned_read32le(props); + opt->start_offset = read32le(props); // Don't leave an options structure allocated if start_offset is zero. if (opt->start_offset == 0) diff --git a/Utilities/cmliblzma/liblzma/simple/simple_encoder.c b/Utilities/cmliblzma/liblzma/simple/simple_encoder.c index 8aa463b..d2cc03e 100644 --- a/Utilities/cmliblzma/liblzma/simple/simple_encoder.c +++ b/Utilities/cmliblzma/liblzma/simple/simple_encoder.c @@ -32,7 +32,7 @@ lzma_simple_props_encode(const void *options, uint8_t *out) if (opt == NULL || opt->start_offset == 0) return LZMA_OK; - unaligned_write32le(out, opt->start_offset); + write32le(out, opt->start_offset); return LZMA_OK; } diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt index 37e2399..1a01165 100644 --- a/Utilities/cmlibrhash/CMakeLists.txt +++ b/Utilities/cmlibrhash/CMakeLists.txt @@ -2,7 +2,7 @@ project(librhash C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index f8b47af..086345c 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -2,7 +2,7 @@ project(libuv C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") @@ -156,7 +156,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS400") ) endif() -if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN") +if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN" OR CMAKE_SYSTEM_NAME MATCHES "MSYS") list(APPEND uv_libraries ) list(APPEND uv_headers diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt index 17cc6dd..3bc2778 100644 --- a/Utilities/cmnghttp2/CMakeLists.txt +++ b/Utilities/cmnghttp2/CMakeLists.txt @@ -1,6 +1,6 @@ # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt index d266af9..d57cb29 100644 --- a/Utilities/cmzlib/CMakeLists.txt +++ b/Utilities/cmzlib/CMakeLists.txt @@ -2,7 +2,7 @@ PROJECT(CMZLIB) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/cmzstd/CMakeLists.txt b/Utilities/cmzstd/CMakeLists.txt index 323151c..1997195 100644 --- a/Utilities/cmzstd/CMakeLists.txt +++ b/Utilities/cmzstd/CMakeLists.txt @@ -2,7 +2,7 @@ project(zstd C) # Disable warnings to avoid changing 3rd party code. if(CMAKE_C_COMPILER_ID MATCHES - "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM)$") + "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel|IntelLLVM|NVHPC)$") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") diff --git a/Utilities/std/cm/filesystem b/Utilities/std/cm/filesystem index 6cbdea9..ce52fbf 100644 --- a/Utilities/std/cm/filesystem +++ b/Utilities/std/cm/filesystem @@ -809,6 +809,10 @@ public: path& remove_filename() { +# if defined(__CYGWIN__) + // FIXME: Avoid crash due to CYGWIN/MSYS bug(?). See CMake Issue 22090. + static_cast<void>(this->path_.data()); +# endif auto fname = this->get_filename(); if (!fname.empty()) { this->path_.erase(fname.data() - this->path_.data()); @@ -825,6 +829,10 @@ public: path& replace_extension(const path& replacement = path()) { +# if defined(__CYGWIN__) + // FIXME: Avoid crash due to CYGWIN/MSYS bug(?). See CMake Issue 22090. + static_cast<void>(this->path_.data()); +# endif auto ext = this->get_filename_fragment(filename_fragment::extension); if (!ext.empty()) { this->path_.erase(ext.data() - this->path_.data()); @@ -84,6 +84,7 @@ cmake_sphinx_info="" cmake_sphinx_man="" cmake_sphinx_html="" cmake_sphinx_qthelp="" +cmake_sphinx_latexpdf="" cmake_sphinx_build="" cmake_sphinx_flags="" @@ -96,8 +97,17 @@ else cmake_system_cygwin=false fi +# Determine whether this is a MSYS environment. +if echo "${cmake_system}" | grep MSYS >/dev/null 2>&1; then + cmake_system_msys=true + cmake_doc_dir_keyword="MSYS" + cmake_man_dir_keyword="MSYS" +else + cmake_system_msys=false +fi + # Determine whether this is a MinGW environment. -if echo "${cmake_system}" | grep 'MINGW\|MSYS' >/dev/null 2>&1; then +if echo "${cmake_system}" | grep 'MINGW' >/dev/null 2>&1; then cmake_system_mingw=true else cmake_system_mingw=false @@ -524,6 +534,7 @@ KWSYS_CXX_SOURCES="\ FStream \ Glob \ RegularExpression \ + Status \ SystemTools" KWSYS_FILES="\ @@ -534,6 +545,7 @@ KWSYS_FILES="\ Glob.hxx \ Process.h \ RegularExpression.hxx \ + Status.hxx \ String.h \ String.hxx \ System.h \ @@ -662,6 +674,7 @@ Configuration: --sphinx-man build man pages with Sphinx --sphinx-html build html help with Sphinx --sphinx-qthelp build qch help with Sphinx + --sphinx-latexpdf build PDF with Sphinx using LaTeX --sphinx-build=<sb> use <sb> as the sphinx-build executable --sphinx-flags=<flags> pass <flags> to sphinx-build executable @@ -926,6 +939,7 @@ while test $# != 0; do --sphinx-man) cmake_sphinx_man="1" ;; --sphinx-html) cmake_sphinx_html="1" ;; --sphinx-qthelp) cmake_sphinx_qthelp="1" ;; + --sphinx-latexpdf) cmake_sphinx_latexpdf="1" ;; --sphinx-build=*) cmake_sphinx_build=`cmake_arg "$1"` ;; --sphinx-flags=*) cmake_sphinx_flags=`cmake_arg "$1"` ;; --help) cmake_usage ;; @@ -1066,7 +1080,7 @@ else fi # Add Cygwin-specific flags -if ${cmake_system_cygwin}; then +if ${cmake_system_cygwin} || ${cmake_system_msys}; then cmake_ld_flags="${LDFLAGS} -Wl,--enable-auto-import" fi @@ -1091,6 +1105,7 @@ cmake_toolchains='' case "${cmake_system}" in *AIX*) cmake_toolchains='XL GNU' ;; *CYGWIN*) cmake_toolchains='GNU' ;; + *MSYS*) cmake_toolchains='GNU' ;; *Darwin*) cmake_toolchains='Clang GNU' ;; *Linux*) cmake_toolchains='GNU Clang XL PGI PathScale' ;; *MINGW*) cmake_toolchains='GNU' ;; @@ -1917,6 +1932,11 @@ if test "x${cmake_sphinx_qthelp}" != "x"; then set (SPHINX_QTHELP "'"${cmake_sphinx_qthelp}"'" CACHE BOOL "Build qch help with Sphinx" FORCE) ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake" fi +if test "x${cmake_sphinx_latexpdf}" != "x"; then + echo ' +set (SPHINX_LATEXPDF "'"${cmake_sphinx_latexpdf}"'" CACHE BOOL "Build PDF help with Sphinx using LaTeX" FORCE) +' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake" +fi if test "x${cmake_sphinx_build}" != "x"; then echo ' set (SPHINX_EXECUTABLE "'"${cmake_sphinx_build}"'" CACHE FILEPATH "Location of Qt sphinx-build" FORCE) |