summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy12
-rw-r--r--.gitlab-ci.yml139
-rw-r--r--.gitlab/.gitignore2
-rwxr-xr-x.gitlab/ci/cmake.ps114
-rw-r--r--.gitlab/ci/configure_fedora36_clang_analyzer.cmake1
-rw-r--r--.gitlab/ci/configure_fedora36_tidy.cmake3
-rw-r--r--.gitlab/ci/configure_fedora37_asan.cmake (renamed from .gitlab/ci/configure_fedora36_asan.cmake)2
-rw-r--r--.gitlab/ci/configure_fedora37_clang_analyzer.cmake1
-rw-r--r--.gitlab/ci/configure_fedora37_common.cmake (renamed from .gitlab/ci/configure_fedora36_common.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_extdeps.cmake (renamed from .gitlab/ci/configure_fedora36_extdeps.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_makefiles.cmake (renamed from .gitlab/ci/configure_fedora36_makefiles.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_ninja.cmake (renamed from .gitlab/ci/configure_fedora36_ninja.cmake)2
-rw-r--r--.gitlab/ci/configure_fedora37_ninja_multi.cmake (renamed from .gitlab/ci/configure_fedora36_ninja_multi.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_sphinx.cmake (renamed from .gitlab/ci/configure_fedora36_sphinx.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_sphinx_package.cmake (renamed from .gitlab/ci/configure_fedora36_sphinx_package.cmake)0
-rw-r--r--.gitlab/ci/configure_fedora37_tidy.cmake5
-rw-r--r--.gitlab/ci/configure_macos_arm64_ninja.cmake3
-rw-r--r--.gitlab/ci/configure_macos_x86_64_makefiles.cmake3
-rw-r--r--.gitlab/ci/configure_macos_x86_64_ninja.cmake3
-rw-r--r--.gitlab/ci/configure_mingw_osdn_io_common.cmake5
-rw-r--r--.gitlab/ci/configure_mingw_osdn_io_mingw_makefiles.cmake1
-rw-r--r--.gitlab/ci/configure_mingw_osdn_io_msys_makefiles.cmake1
-rw-r--r--.gitlab/ci/configure_windows_arm64_vs2022.cmake1
-rw-r--r--.gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake7
-rw-r--r--.gitlab/ci/ctest_memcheck_fedora37_asan.lsan.supp (renamed from .gitlab/ci/ctest_memcheck_fedora36_asan.lsan.supp)0
-rw-r--r--.gitlab/ci/docker/fedora37/Dockerfile (renamed from .gitlab/ci/docker/fedora36/Dockerfile)8
-rwxr-xr-x.gitlab/ci/docker/fedora37/install_clang_tidy_headers.sh (renamed from .gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh)0
-rwxr-xr-x.gitlab/ci/docker/fedora37/install_deps.sh (renamed from .gitlab/ci/docker/fedora36/install_deps.sh)3
-rwxr-xr-x.gitlab/ci/docker/fedora37/install_iwyu.sh (renamed from .gitlab/ci/docker/fedora36/install_iwyu.sh)0
-rwxr-xr-x.gitlab/ci/docker/fedora37/install_rvm.sh (renamed from .gitlab/ci/docker/fedora36/install_rvm.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_asan.sh (renamed from .gitlab/ci/env_fedora36_asan.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_clang_analyzer.sh (renamed from .gitlab/ci/env_fedora36_clang_analyzer.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_extdeps.sh (renamed from .gitlab/ci/env_fedora36_extdeps.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_makefiles.cmake (renamed from .gitlab/ci/env_fedora36_makefiles.cmake)0
-rw-r--r--.gitlab/ci/env_fedora37_makefiles.sh (renamed from .gitlab/ci/env_fedora36_ninja_multi.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_ninja.sh (renamed from .gitlab/ci/env_fedora36_ninja.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_ninja_multi.sh (renamed from .gitlab/ci/env_fedora36_makefiles.sh)0
-rw-r--r--.gitlab/ci/env_fedora37_tidy.sh7
-rw-r--r--.gitlab/ci/env_macos_arm64_ninja.sh1
-rw-r--r--.gitlab/ci/env_macos_x86_64_makefiles.sh1
-rw-r--r--.gitlab/ci/env_macos_x86_64_ninja.sh1
-rwxr-xr-x.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps13
-rwxr-xr-x.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps15
-rwxr-xr-x.gitlab/ci/mingw.ps125
-rw-r--r--.gitlab/ci/openmp-env.sh3
-rwxr-xr-x.gitlab/ci/openmp.sh32
-rwxr-xr-x.gitlab/ci/python-env.ps14
-rwxr-xr-x.gitlab/ci/qt-env.ps110
-rw-r--r--.gitlab/os-linux.yml64
-rw-r--r--.gitlab/os-macos.yml2
-rw-r--r--.gitlab/os-windows.yml72
-rw-r--r--.gitlab/upload.yml4
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--CMakeLists.txt41
-rw-r--r--CompileFlags.cmake5
-rw-r--r--Help/command/DEVICE_LINK_OPTIONS.txt8
-rw-r--r--Help/command/GENEX_NOTE.txt6
-rw-r--r--Help/command/add_compile_definitions.rst11
-rw-r--r--Help/command/add_compile_options.rst20
-rw-r--r--Help/command/add_custom_command.rst5
-rw-r--r--Help/command/add_custom_target.rst5
-rw-r--r--Help/command/add_definitions.rst9
-rw-r--r--Help/command/add_dependencies.rst13
-rw-r--r--Help/command/add_executable.rst5
-rw-r--r--Help/command/add_library.rst11
-rw-r--r--Help/command/add_link_options.rst13
-rw-r--r--Help/command/block.rst6
-rw-r--r--Help/command/build_name.rst2
-rw-r--r--Help/command/cmake_host_system_information.rst2
-rw-r--r--Help/command/cmake_minimum_required.rst5
-rw-r--r--Help/command/cmake_parse_arguments.rst6
-rw-r--r--Help/command/cmake_path.rst40
-rw-r--r--Help/command/cmake_policy.rst5
-rw-r--r--Help/command/configure_file.rst5
-rw-r--r--Help/command/ctest_build.rst2
-rw-r--r--Help/command/ctest_configure.rst2
-rw-r--r--Help/command/ctest_coverage.rst2
-rw-r--r--Help/command/ctest_empty_binary_directory.rst4
-rw-r--r--Help/command/ctest_memcheck.rst2
-rw-r--r--Help/command/ctest_read_custom_files.rst4
-rw-r--r--Help/command/ctest_run_script.rst2
-rw-r--r--Help/command/ctest_sleep.rst4
-rw-r--r--Help/command/ctest_start.rst2
-rw-r--r--Help/command/ctest_submit.rst4
-rw-r--r--Help/command/ctest_test.rst4
-rw-r--r--Help/command/ctest_update.rst2
-rw-r--r--Help/command/ctest_upload.rst2
-rw-r--r--Help/command/define_property.rst6
-rw-r--r--Help/command/exec_program.rst2
-rw-r--r--Help/command/export_library_dependencies.rst2
-rw-r--r--Help/command/file.rst16
-rw-r--r--Help/command/foreach.rst6
-rw-r--r--Help/command/function.rst1
-rw-r--r--Help/command/get_cmake_property.rst7
-rw-r--r--Help/command/get_directory_property.rst7
-rw-r--r--Help/command/get_filename_component.rst5
-rw-r--r--Help/command/get_property.rst6
-rw-r--r--Help/command/get_source_file_property.rst9
-rw-r--r--Help/command/get_target_property.rst8
-rw-r--r--Help/command/get_test_property.rst6
-rw-r--r--Help/command/if.rst6
-rw-r--r--Help/command/include_directories.rst11
-rw-r--r--Help/command/install.rst2
-rw-r--r--Help/command/install_files.rst6
-rw-r--r--Help/command/install_programs.rst4
-rw-r--r--Help/command/install_targets.rst2
-rw-r--r--Help/command/link_directories.rst6
-rw-r--r--Help/command/load_command.rst4
-rw-r--r--Help/command/macro.rst6
-rw-r--r--Help/command/make_directory.rst2
-rw-r--r--Help/command/message.rst5
-rw-r--r--Help/command/output_required_files.rst2
-rw-r--r--Help/command/project.rst3
-rw-r--r--Help/command/remove.rst2
-rw-r--r--Help/command/return.rst3
-rw-r--r--Help/command/set.rst5
-rw-r--r--Help/command/set_directory_properties.rst7
-rw-r--r--Help/command/set_property.rst11
-rw-r--r--Help/command/set_source_files_properties.rst11
-rw-r--r--Help/command/set_target_properties.rst8
-rw-r--r--Help/command/set_tests_properties.rst8
-rw-r--r--Help/command/string.rst11
-rw-r--r--Help/command/subdir_depends.rst2
-rw-r--r--Help/command/subdirs.rst2
-rw-r--r--Help/command/target_compile_definitions.rst19
-rw-r--r--Help/command/target_compile_features.rst22
-rw-r--r--Help/command/target_compile_options.rst25
-rw-r--r--Help/command/target_include_directories.rst19
-rw-r--r--Help/command/target_link_directories.rst19
-rw-r--r--Help/command/target_link_libraries.rst16
-rw-r--r--Help/command/target_link_options.rst18
-rw-r--r--Help/command/target_precompile_headers.rst38
-rw-r--r--Help/command/target_sources.rst14
-rw-r--r--Help/command/try_compile.rst11
-rw-r--r--Help/command/unset.rst5
-rw-r--r--Help/command/use_mangled_mesa.rst2
-rw-r--r--Help/command/utility_source.rst2
-rw-r--r--Help/command/variable_requires.rst2
-rw-r--r--Help/command/while.rst8
-rw-r--r--Help/command/write_file.rst2
-rw-r--r--Help/envvar/ASM_DIALECT.rst10
-rw-r--r--Help/envvar/ASM_DIALECTFLAGS.rst1
-rw-r--r--Help/generator/Ninja Multi-Config.rst6
-rw-r--r--Help/guide/importing-exporting/index.rst3
-rw-r--r--Help/guide/tutorial/Adding Support for a Testing Dashboard.rst95
-rw-r--r--Help/guide/tutorial/Adding System Introspection.rst153
-rw-r--r--Help/guide/tutorial/Installing and Testing.rst4
-rw-r--r--Help/guide/tutorial/Step6/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt20
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx10
-rw-r--r--Help/manual/ccmake.1.rst2
-rw-r--r--Help/manual/cmake-buildsystem.7.rst8
-rw-r--r--Help/manual/cmake-developer.7.rst2
-rw-r--r--Help/manual/cmake-file-api.7.rst34
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst4
-rw-r--r--Help/manual/cmake-gui.1.rst2
-rw-r--r--Help/manual/cmake-language.7.rst22
-rw-r--r--Help/manual/cmake-policies.7.rst7
-rw-r--r--Help/manual/cmake.1.rst34
-rw-r--r--Help/manual/cpack.1.rst22
-rw-r--r--Help/manual/ctest.1.rst18
-rw-r--r--Help/policy/CMP0143.rst30
-rw-r--r--Help/prop_gbl/USE_FOLDERS.rst15
-rw-r--r--Help/prop_test/LABELS.rst2
-rw-r--r--Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst27
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst1
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst1
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst1
-rw-r--r--Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst1
-rw-r--r--Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst1
-rw-r--r--Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst1
-rw-r--r--Help/prop_tgt/LINK_OPTIONS.rst4
-rw-r--r--Help/release/3.15.rst50
-rw-r--r--Help/release/3.17.rst2
-rw-r--r--Help/release/3.18.rst9
-rw-r--r--Help/release/3.20.rst4
-rw-r--r--Help/release/3.23.rst4
-rw-r--r--Help/release/3.9.rst6
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst6
-rw-r--r--Help/release/dev/UseSWIG-perl5.rst4
-rw-r--r--Help/release/dev/cmake-E-copy-t-arg.rst4
-rw-r--r--Help/release/dev/compile-commands-output-field.rst7
-rw-r--r--Help/release/dev/file-api-file-sets.rst9
-rw-r--r--Help/release/dev/marmasm-language.rst4
-rw-r--r--Help/release/dev/timestamp-timezone.rst5
-rw-r--r--Help/release/dev/top-level-command-order.rst6
-rw-r--r--Help/release/dev/trace-try_compile.rst5
-rw-r--r--Help/release/dev/use-folder-on-by-default.rst5
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/CMAKE_DEPENDS_USE_COMPILER.rst2
-rw-r--r--Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt4
-rw-r--r--Modules/CMakeASM_MARMASMInformation.cmake20
-rw-r--r--Modules/CMakeDetermineASM_MARMASMCompiler.cmake18
-rw-r--r--Modules/CMakeDetermineSystem.cmake52
-rw-r--r--Modules/CMakeGenericSystem.cmake12
-rw-r--r--Modules/CMakeSwiftInformation.cmake26
-rw-r--r--Modules/CMakeTestASM_MARMASMCompiler.cmake13
-rw-r--r--Modules/CPack.cmake2
-rw-r--r--Modules/Compiler/Clang.cmake2
-rw-r--r--Modules/Compiler/GNU.cmake14
-rw-r--r--Modules/Compiler/IBMClang.cmake6
-rw-r--r--Modules/Compiler/Intel.cmake14
-rw-r--r--Modules/Compiler/IntelLLVM.cmake20
-rw-r--r--Modules/Compiler/LCC.cmake14
-rw-r--r--Modules/Compiler/NVIDIA-CUDA.cmake2
-rw-r--r--Modules/Compiler/QCC.cmake14
-rw-r--r--Modules/Compiler/Tasking.cmake14
-rw-r--r--Modules/ExternalProject.cmake46
-rw-r--r--Modules/FetchContent.cmake12
-rw-r--r--Modules/FindBZip2.cmake21
-rw-r--r--Modules/FindCUDAToolkit.cmake4
-rw-r--r--Modules/FindLibLZMA.cmake18
-rw-r--r--Modules/FindPython.cmake15
-rw-r--r--Modules/FindPython/Support.cmake39
-rw-r--r--Modules/FindPython2.cmake4
-rw-r--r--Modules/FindPython3.cmake13
-rw-r--r--Modules/FindZLIB.cmake75
-rw-r--r--Modules/GoogleTest.cmake8
-rw-r--r--Modules/Internal/CheckFlagCommonConfig.cmake2
-rw-r--r--Modules/Internal/CheckSourceCompiles.cmake11
-rw-r--r--Modules/Platform/Android-Clang.cmake4
-rw-r--r--Modules/UseJava.cmake2
-rw-r--r--Modules/UseSWIG.cmake7
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx7
-rw-r--r--Source/CursesDialog/ccmake.cxx2
-rw-r--r--Source/QtDialog/CMakeSetup.cxx2
-rw-r--r--Source/cmCommandLineArgument.h11
-rw-r--r--Source/cmCustomCommandGenerator.cxx5
-rw-r--r--Source/cmExportFileGenerator.cxx6
-rw-r--r--Source/cmExportInstallFileGenerator.cxx4
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx2
-rw-r--r--Source/cmFileAPI.cxx2
-rw-r--r--Source/cmFileAPICodemodel.cxx111
-rw-r--r--Source/cmFileCommand.cxx43
-rw-r--r--Source/cmFileSet.cxx9
-rw-r--r--Source/cmFileSet.h4
-rw-r--r--Source/cmFindPackageCommand.cxx7
-rw-r--r--Source/cmGeneratedFileStream.cxx11
-rw-r--r--Source/cmGeneratorExpression.cxx26
-rw-r--r--Source/cmGeneratorExpression.h13
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx2
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx31
-rw-r--r--Source/cmGeneratorExpressionNode.cxx2
-rw-r--r--Source/cmGeneratorTarget.cxx70
-rw-r--r--Source/cmGlobalGenerator.cxx16
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx7
-rw-r--r--Source/cmGlobalNinjaGenerator.h3
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx10
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx12
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx1
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx8
-rw-r--r--Source/cmInstalledFile.cxx4
-rw-r--r--Source/cmLocalGenerator.cxx2
-rw-r--r--Source/cmLocalNinjaGenerator.cxx2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx33
-rw-r--r--Source/cmMakefile.cxx33
-rw-r--r--Source/cmMakefileProfilingData.cxx57
-rw-r--r--Source/cmMakefileProfilingData.h30
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx8
-rw-r--r--Source/cmNinjaTargetGenerator.cxx57
-rw-r--r--Source/cmNinjaTargetGenerator.h3
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Source/cmProjectCommand.cxx9
-rw-r--r--Source/cmQtAutoGenInitializer.cxx2
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h2
-rw-r--r--Source/cmState.cxx2
-rw-r--r--Source/cmState.h1
-rw-r--r--Source/cmSystemTools.cxx18
-rw-r--r--Source/cmTarget.cxx5
-rw-r--r--Source/cmTestGenerator.cxx3
-rw-r--r--Source/cmTimestamp.cxx63
-rw-r--r--Source/cmTimestamp.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx90
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h4
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h1
-rw-r--r--Source/cmake.cxx21
-rw-r--r--Source/cmake.h34
-rw-r--r--Source/cmakemain.cxx28
-rw-r--r--Source/cmcmd.cxx57
-rw-r--r--Source/kwsys/ProcessUNIX.c13
-rw-r--r--Source/kwsys/Status.hxx.in10
-rw-r--r--Source/kwsys/SystemInformation.cxx6
-rw-r--r--Source/kwsys/SystemTools.cxx100
-rw-r--r--Source/kwsys/SystemTools.hxx.in44
-rw-r--r--Templates/MSBuild/FlagTables/v10_MARMASM.json149
-rw-r--r--Templates/MSBuild/FlagTables/v142_CL.json7
-rw-r--r--Templates/MSBuild/FlagTables/v143_CL.json7
-rw-r--r--Tests/CMakeLists.txt64
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt4
-rw-r--r--Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake22
-rw-r--r--Tests/CMakeTests/StringTest.cmake.in3
-rw-r--r--Tests/CTestUpdateGIT.cmake.in2
-rw-r--r--Tests/CheckSourceTree/check.cmake9
-rw-r--r--Tests/CustomCommandByproducts/CMakeLists.txt35
-rw-r--r--Tests/CustomCommandByproducts/ExternalLibraryByproducts.c5
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt15
-rw-r--r--Tests/GeneratorExpression/check-part4.cmake9
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExport.cmake4
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMakeLists.txt73
-rw-r--r--Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular-build-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt1
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt15
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm6
-rw-r--r--Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm6
-rw-r--r--Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt39
-rw-r--r--Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx11
-rw-r--r--Tests/RunCMake/CXXModules/examples/duplicate/main.cxx6
-rw-r--r--Tests/RunCMake/CheckCompilerFlag/CheckCompilerFlagSwift.cmake21
-rw-r--r--Tests/RunCMake/CheckCompilerFlag/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake15
-rw-r--r--Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E_capabilities-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt)0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir2-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt)0
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/compare_files/.gitattributes4
-rw-r--r--Tests/RunCMake/CommandLine/compare_files/crlf2
-rw-r--r--Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake13
-rw-r--r--Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLine/trace-try_compile.cmake2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py31
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_1.json31
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_2.json9
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json5
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json6
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json3
-rw-r--r--Tests/RunCMake/File_Archive/argument-validation-compression-level-1-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Archive/argument-validation-compression-level-2-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Archive/pax-zstd-compression-level.cmake3
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake40
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_VERSION_OPERATORS.cmake21
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL-check.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName.cmake)4
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName1/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName2/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName3/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName4/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName5/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName6/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName7/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName8/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt)2
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget.cmake9
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference.cmake)4
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference1/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference2/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference3/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference4/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference5/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference6/CMakeLists.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6/CMakeLists.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES-check.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION-stderr.txt (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3-result.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-stderr.txt (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake)5
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake)8
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES-check.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES-check.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES.cmake (renamed from Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES.cmake)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.c (renamed from Tests/RunCMake/GeneratorExpression/empty3.c)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.cpp (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.c (renamed from Tests/RunCMake/GeneratorExpression/empty2.c)0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.c0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/main.cpp (renamed from Tests/RunCMake/TargetPropertyGeneratorExpressions/main.cpp)0
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake4
-rw-r--r--Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-skip-test-stdout.txt5
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest.cmake4
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/GoogleTest/skip_test.cpp7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake6
-rw-r--r--Tests/RunCMake/RunCMake.cmake1
-rw-r--r--Tests/RunCMake/RunCTest.cmake4
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget.cmake7
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/VS10Project/VsCLREmpty-check.cmake24
-rw-r--r--Tests/RunCMake/VS10Project/VsCLREmpty.cmake6
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRNetcore-check.cmake24
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRNetcore.cmake6
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRPure-check.cmake24
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRPure.cmake6
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRSafe-check.cmake24
-rw-r--r--Tests/RunCMake/VS10Project/VsCLRSafe.cmake6
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake6
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-NEW.cmake1
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake6
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-OLD.cmake1
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake6
-rw-r--r--Tests/RunCMake/VSSolution/CMP0143-WARN.cmake1
-rw-r--r--Tests/RunCMake/VSSolution/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/ctest_environment/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/file/COPY_FILE-input-missing-result.txt1
-rw-r--r--Tests/RunCMake/file/COPY_FILE-input-missing-stderr.txt14
-rw-r--r--Tests/RunCMake/file/COPY_FILE-input-missing.cmake3
-rw-r--r--Tests/RunCMake/file/COPY_FILE-output-missing-result.txt1
-rw-r--r--Tests/RunCMake/file/COPY_FILE-output-missing-stderr.txt14
-rw-r--r--Tests/RunCMake/file/COPY_FILE-output-missing.cmake4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt1
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMP0048-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/project/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/project/LanguagesTwice-stderr.txt2
-rw-r--r--Tests/RunCMake/project/NoMinimumRequired-stderr.txt5
-rw-r--r--Tests/RunCMake/project/NoMinimumRequired.cmake0
-rw-r--r--Tests/RunCMake/project/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/project/VersionInvalid-stderr.txt2
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages-stderr.txt2
-rw-r--r--Tests/RunCMake/project/VersionTwice-stderr.txt2
-rw-r--r--Tests/RunCMake/project_injected/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/string/Timestamp-stderr.txt2
-rw-r--r--Tests/RunCMake/string/Timestamp.cmake2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt10
-rw-r--r--Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/try_compile/Inspect.cmake27
-rw-r--r--Tests/RunCMake/try_compile/RunCMakeTest.cmake21
-rw-r--r--Tests/SwiftMixLib/CMakeLists.txt3
-rw-r--r--Tests/SwiftMixLib/main.c3
-rw-r--r--Tests/UseSWIG/BasicPerl/CMakeLists.txt4
-rw-r--r--Tests/UseSWIG/CMakeLists.txt30
-rw-r--r--Tests/UseSWIG/LegacyPerl/CMakeLists.txt4
-rw-r--r--Tests/VSMARMASM/CMakeLists.txt3
-rw-r--r--Tests/VSMARMASM/foo.asm10
-rw-r--r--Tests/VSMARMASM/main.c5
-rw-r--r--Utilities/ClangTidyModule/CMakeLists.txt33
-rw-r--r--Utilities/ClangTidyModule/Module.cxx33
-rw-r--r--Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx52
-rw-r--r--Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h21
-rw-r--r--Utilities/ClangTidyModule/Tests/CMakeLists.txt16
-rw-r--r--Utilities/ClangTidyModule/Tests/RunClangTidy.cmake63
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt6
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx10
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class-stdout.txt18
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class.cxx63
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx37
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt20
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx37
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx81
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt155
-rw-r--r--Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx81
-rw-r--r--Utilities/ClangTidyModule/UseBespokeEnumClassCheck.cxx35
-rw-r--r--Utilities/ClangTidyModule/UseBespokeEnumClassCheck.h21
-rw-r--r--Utilities/ClangTidyModule/UseCmstrlenCheck.cxx34
-rw-r--r--Utilities/ClangTidyModule/UseCmstrlenCheck.h21
-rw-r--r--Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx101
-rw-r--r--Utilities/ClangTidyModule/UseCmsysFstreamCheck.h24
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rwxr-xr-xUtilities/Scripts/update-nghttp2.bash2
-rw-r--r--Utilities/Sphinx/CMakeLists.txt110
-rw-r--r--Utilities/Sphinx/cmake.py1
-rw-r--r--Utilities/Sphinx/conf.py.in2
-rw-r--r--Utilities/cmnghttp2/CMakeLists.txt1
-rw-r--r--Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h1144
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_buf.c6
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_buf.h2
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_extpri.c35
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_extpri.h65
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_frame.c111
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_frame.h49
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd.c14
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd.h1
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_helper.c176
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_http.c813
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_http.h51
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_map.c280
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_map.h70
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_net.h6
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_option.c22
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_option.h15
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_outbound_item.c3
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_outbound_item.h2
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_pq.c3
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_pq.h10
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_session.c840
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_session.h77
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_stream.c21
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_stream.h26
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_submit.c102
579 files changed, 8185 insertions, 1822 deletions
diff --git a/.clang-tidy b/.clang-tidy
index a86f39a..9ce5f42 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,24 +1,31 @@
---
Checks: "-*,\
bugprone-*,\
+-bugprone-assignment-in-if-condition,\
-bugprone-easily-swappable-parameters,\
-bugprone-implicit-widening-of-multiplication-result,\
-bugprone-macro-parentheses,\
-bugprone-misplaced-widening-cast,\
-bugprone-narrowing-conversions,\
-bugprone-too-small-loop-variable,\
+-bugprone-unchecked-optional-access,\
misc-*,\
+-misc-confusable-identifiers,\
+-misc-const-correctness,\
-misc-no-recursion,\
-misc-non-private-member-variables-in-classes,\
-misc-static-assert,\
modernize-*,\
-modernize-avoid-c-arrays,\
+-modernize-macro-to-enum,\
-modernize-return-braced-init-list,\
+-modernize-use-emplace,\
-modernize-use-nodiscard,\
-modernize-use-noexcept,\
-modernize-use-trailing-return-type,\
-modernize-use-transparent-functors,\
performance-*,\
+-performance-inefficient-vector-operation,\
readability-*,\
-readability-convert-member-functions-to-static,\
-readability-function-cognitive-complexity,\
@@ -28,11 +35,16 @@ readability-*,\
-readability-implicit-bool-conversion,\
-readability-inconsistent-declaration-parameter-name,\
-readability-magic-numbers,\
+-readability-make-member-function-const,\
-readability-named-parameter,\
-readability-redundant-declaration,\
-readability-redundant-member-init,\
+-readability-simplify-boolean-expr,\
-readability-suspicious-call-argument,\
-readability-uppercase-literal-suffix,\
+cmake-*,\
+-cmake-ostringstream-use-cmstrcat,\
+-cmake-use-bespoke-enum-class,\
"
HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$'
CheckOptions:
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 712ebd1..4c44b07 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -57,7 +57,7 @@ p:source-package:
p:doc-package:
extends:
- - .fedora36_sphinx_package
+ - .fedora37_sphinx_package
- .cmake_prep_doc_linux
- .linux_builder_tags_qt
- .cmake_doc_artifacts
@@ -105,16 +105,16 @@ l:iwyu-debian10:
- .linux_builder_tags
- .run_automatically
-l:tidy-fedora36:
+l:tidy-fedora37:
extends:
- - .fedora36_tidy
+ - .fedora37_tidy
- .cmake_build_linux
- .linux_builder_tags_qt
- .run_automatically
-l:sphinx-fedora36:
+l:sphinx-fedora37:
extends:
- - .fedora36_sphinx
+ - .fedora37_sphinx
- .cmake_build_linux
- .linux_builder_tags_qt
- .run_automatically
@@ -122,9 +122,9 @@ l:sphinx-fedora36:
CMAKE_CI_JOB_CONTINUOUS: "true"
CMAKE_CI_JOB_HELP: "true"
-l:clang-analyzer-fedora36:
+l:clang-analyzer-fedora37:
extends:
- - .fedora36_clang_analyzer
+ - .fedora37_clang_analyzer
- .cmake_build_linux
- .linux_builder_tags_qt
- .run_automatically
@@ -181,7 +181,7 @@ t:debian10-ninja-clang:
- .debian10_ninja_clang
- .cmake_test_linux_release
- .linux_builder_tags_qt
- - .run_manually
+ - .run_dependent
- .needs_centos6_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -191,22 +191,22 @@ t:debian10-makefiles-clang:
- .debian10_makefiles_clang
- .cmake_test_linux_release
- .linux_builder_tags_qt
- - .run_manually
+ - .run_dependent
- .needs_centos6_x86_64
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:fedora36-makefiles:
+t:fedora37-makefiles:
extends:
- - .fedora36_makefiles
+ - .fedora37_makefiles
- .cmake_test_linux_release
- .linux_builder_tags_qt
- .run_dependent
- .needs_centos6_x86_64
-t:fedora36-makefiles-nospace:
+t:fedora37-makefiles-nospace:
extends:
- - .fedora36_makefiles
+ - .fedora37_makefiles
- .cmake_test_linux_release
- .linux_builder_tags_qt
- .cmake_junit_artifacts
@@ -214,7 +214,7 @@ t:fedora36-makefiles-nospace:
- .needs_centos6_x86_64
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
- CMAKE_CI_BUILD_NAME: fedora36_makefiles_nospace
+ CMAKE_CI_BUILD_NAME: fedora37_makefiles_nospace
CMAKE_CI_JOB_NIGHTLY: "true"
t:cuda9.2-nvidia:
@@ -295,9 +295,9 @@ t:linux-gcc-cxx-modules-ninja-multi:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-b:fedora36-ninja:
+b:fedora37-ninja:
extends:
- - .fedora36_ninja
+ - .fedora37_ninja
- .cmake_build_linux
- .cmake_build_artifacts
- .linux_builder_tags_qt
@@ -332,40 +332,40 @@ b:debian10-aarch64-extdeps:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-b:fedora36-extdeps:
+b:fedora37-extdeps:
extends:
- - .fedora36_extdeps
+ - .fedora37_extdeps
- .cmake_build_linux_standalone
- .linux_builder_tags
- .run_manually
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:fedora36-ninja:
+t:fedora37-ninja:
extends:
- - .fedora36_ninja
+ - .fedora37_ninja
- .cmake_test_linux
- .linux_builder_tags_x11
- .cmake_test_artifacts
- .run_dependent
dependencies:
- - b:fedora36-ninja
+ - b:fedora37-ninja
needs:
- - b:fedora36-ninja
+ - b:fedora37-ninja
variables:
CMAKE_CI_JOB_CONTINUOUS: "true"
-t:fedora36-ninja-multi:
+t:fedora37-ninja-multi:
extends:
- - .fedora36_ninja_multi
+ - .fedora37_ninja_multi
- .cmake_test_linux_external
- .linux_builder_tags_qt
- .cmake_junit_artifacts
- .run_dependent
dependencies:
- - t:fedora36-ninja
+ - t:fedora37-ninja
needs:
- - t:fedora36-ninja
+ - t:fedora37-ninja
t:intel2016-makefiles:
extends:
@@ -704,9 +704,9 @@ u:linux-aarch64-package:
## Sanitizer builds
-b:fedora36-asan:
+b:fedora37-asan:
extends:
- - .fedora36_asan
+ - .fedora37_asan
- .cmake_build_linux
- .cmake_build_artifacts
- .linux_builder_tags_qt
@@ -714,16 +714,16 @@ b:fedora36-asan:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:fedora36-asan:
+t:fedora37-asan:
extends:
- - .fedora36_asan
+ - .fedora37_asan
- .cmake_memcheck_linux
- .linux_builder_tags_qt
- .run_dependent
dependencies:
- - b:fedora36-asan
+ - b:fedora37-asan
needs:
- - b:fedora36-asan
+ - b:fedora37-asan
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
@@ -736,6 +736,8 @@ b:macos-x86_64-ninja:
- .cmake_build_artifacts
- .macos_x86_64_builder_tags
- .run_manually
+ variables:
+ CMAKE_CI_JOB_CONTINUOUS: "true"
b:macos-arm64-ninja:
extends:
@@ -759,6 +761,7 @@ t:macos-x86_64-ninja:
needs:
- b:macos-x86_64-ninja
variables:
+ CMAKE_CI_JOB_CONTINUOUS: "true"
CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
t:macos-arm64-ninja:
@@ -880,7 +883,7 @@ u:macos10.10-package:
needs:
- b:macos10.10-package
-# Windows builds
+# Windows x86_64 jobs
b:windows-vs2022-x64-ninja:
extends:
@@ -1060,6 +1063,34 @@ t:windows-clang15.0-gnu-nmake:
CMAKE_CI_BUILD_NAME: windows_clang15.0_gnu_nmake
CMAKE_CI_JOB_NIGHTLY: "true"
+t:mingw_osdn_io-mingw_makefiles:
+ extends:
+ - .mingw_osdn_io_mingw_makefiles
+ - .cmake_test_windows_external
+ - .windows_tags_concurrent
+ - .cmake_junit_artifacts
+ - .run_dependent
+ dependencies:
+ - t:windows-vs2022-x64-ninja
+ needs:
+ - t:windows-vs2022-x64-ninja
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:mingw_osdn_io-msys_makefiles:
+ extends:
+ - .mingw_osdn_io_msys_makefiles
+ - .cmake_test_windows_external
+ - .windows_tags_concurrent
+ - .cmake_junit_artifacts
+ - .run_dependent
+ dependencies:
+ - t:windows-vs2022-x64-ninja
+ needs:
+ - t:windows-vs2022-x64-ninja
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:windows-msvc-v71-nmake:
extends:
- .windows_msvc_v71_nmake
@@ -1088,6 +1119,48 @@ t:windows-openwatcom1.9:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
+# Windows arm64 jobs
+
+b:windows-arm64-vs2022-ninja:
+ extends:
+ - .windows_arm64_vs2022_ninja
+ - .cmake_build_windows
+ - .cmake_build_artifacts
+ - .windows_arm64_tags_nonconcurrent_vs2022
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-arm64-vs2022-ninja:
+ extends:
+ - .windows_arm64_vs2022_ninja
+ - .cmake_test_windows
+ - .windows_arm64_tags_nonconcurrent_vs2022
+ - .cmake_test_artifacts
+ - .run_dependent
+ dependencies:
+ - b:windows-arm64-vs2022-ninja
+ needs:
+ - b:windows-arm64-vs2022-ninja
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-arm64-vs2022:
+ extends:
+ - .windows_arm64_vs2022
+ - .cmake_test_windows_external
+ - .windows_arm64_tags_concurrent_vs2022
+ - .cmake_junit_artifacts
+ - .run_dependent
+ dependencies:
+ - t:windows-arm64-vs2022-ninja
+ needs:
+ - t:windows-arm64-vs2022-ninja
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+# Windows package jobs
+
b:windows-x86_64-package:
extends:
- .windows_x86_64_package
diff --git a/.gitlab/.gitignore b/.gitlab/.gitignore
index d62e477..10d03ca 100644
--- a/.gitlab/.gitignore
+++ b/.gitlab/.gitignore
@@ -5,8 +5,10 @@
/ispc*
/jom
/llvm*
+/mingw
/msvc*
/ninja*
+/openmp
/open-watcom*
/python*
/qt*
diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1
index 98aeae3..3efb67a 100755
--- a/.gitlab/ci/cmake.ps1
+++ b/.gitlab/ci/cmake.ps1
@@ -1,8 +1,18 @@
$erroractionpreference = "stop"
$version = "3.24.1"
-$sha256sum = "C1B17431A16337D517F7BA78C7067B6F143A12686CB8087F3DD32F3FA45F5AAE"
-$filename = "cmake-$version-windows-x86_64"
+
+if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
+ $sha256sum = "C1B17431A16337D517F7BA78C7067B6F143A12686CB8087F3DD32F3FA45F5AAE"
+ $platform = "windows-x86_64"
+} elseif ("$env:PROCESSOR_ARCHITECTURE" -eq "ARM64") {
+ $sha256sum = "D94683F3B0E63F6EF194C621194F6E26F3735EDA70750395E0F2BBEE4023FB95"
+ $platform = "windows-arm64"
+} else {
+ throw ('unknown PROCESSOR_ARCHITECTURE: ' + "$env:PROCESSOR_ARCHITECTURE")
+}
+
+$filename = "cmake-$version-$platform"
$tarball = "$filename.zip"
$outdir = $pwd.Path
diff --git a/.gitlab/ci/configure_fedora36_clang_analyzer.cmake b/.gitlab/ci/configure_fedora36_clang_analyzer.cmake
deleted file mode 100644
index 456936b..0000000
--- a/.gitlab/ci/configure_fedora36_clang_analyzer.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_tidy.cmake b/.gitlab/ci/configure_fedora36_tidy.cmake
deleted file mode 100644
index 38414d3..0000000
--- a/.gitlab/ci/configure_fedora36_tidy.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_asan.cmake b/.gitlab/ci/configure_fedora37_asan.cmake
index 51977d9..363e953 100644
--- a/.gitlab/ci/configure_fedora36_asan.cmake
+++ b/.gitlab/ci/configure_fedora37_asan.cmake
@@ -1,4 +1,4 @@
set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "")
set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common.cmake")
diff --git a/.gitlab/ci/configure_fedora37_clang_analyzer.cmake b/.gitlab/ci/configure_fedora37_clang_analyzer.cmake
new file mode 100644
index 0000000..f4c4cdd
--- /dev/null
+++ b/.gitlab/ci/configure_fedora37_clang_analyzer.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_common.cmake b/.gitlab/ci/configure_fedora37_common.cmake
index 4484e26..4484e26 100644
--- a/.gitlab/ci/configure_fedora36_common.cmake
+++ b/.gitlab/ci/configure_fedora37_common.cmake
diff --git a/.gitlab/ci/configure_fedora36_extdeps.cmake b/.gitlab/ci/configure_fedora37_extdeps.cmake
index 8e545f5..8e545f5 100644
--- a/.gitlab/ci/configure_fedora36_extdeps.cmake
+++ b/.gitlab/ci/configure_fedora37_extdeps.cmake
diff --git a/.gitlab/ci/configure_fedora36_makefiles.cmake b/.gitlab/ci/configure_fedora37_makefiles.cmake
index 11d1a08..11d1a08 100644
--- a/.gitlab/ci/configure_fedora36_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora37_makefiles.cmake
diff --git a/.gitlab/ci/configure_fedora36_ninja.cmake b/.gitlab/ci/configure_fedora37_ninja.cmake
index 45d9192..3defa5a 100644
--- a/.gitlab/ci/configure_fedora36_ninja.cmake
+++ b/.gitlab/ci/configure_fedora37_ninja.cmake
@@ -10,4 +10,4 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "")
# Cover compilation with C++11 only and not higher standards.
set(CMAKE_CXX_STANDARD "11" CACHE STRING "")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_ninja_multi.cmake b/.gitlab/ci/configure_fedora37_ninja_multi.cmake
index 94af721..94af721 100644
--- a/.gitlab/ci/configure_fedora36_ninja_multi.cmake
+++ b/.gitlab/ci/configure_fedora37_ninja_multi.cmake
diff --git a/.gitlab/ci/configure_fedora36_sphinx.cmake b/.gitlab/ci/configure_fedora37_sphinx.cmake
index 90d159b..90d159b 100644
--- a/.gitlab/ci/configure_fedora36_sphinx.cmake
+++ b/.gitlab/ci/configure_fedora37_sphinx.cmake
diff --git a/.gitlab/ci/configure_fedora36_sphinx_package.cmake b/.gitlab/ci/configure_fedora37_sphinx_package.cmake
index e839de8..e839de8 100644
--- a/.gitlab/ci/configure_fedora36_sphinx_package.cmake
+++ b/.gitlab/ci/configure_fedora37_sphinx_package.cmake
diff --git a/.gitlab/ci/configure_fedora37_tidy.cmake b/.gitlab/ci/configure_fedora37_tidy.cmake
new file mode 100644
index 0000000..f8eb9ab
--- /dev/null
+++ b/.gitlab/ci/configure_fedora37_tidy.cmake
@@ -0,0 +1,5 @@
+set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
+set(CMake_USE_CLANG_TIDY_MODULE ON CACHE BOOL "")
+set(CMake_CLANG_TIDY_MODULE "$ENV{CI_PROJECT_DIR}/Utilities/ClangTidyModule/build/libcmake-clang-tidy-module.so" CACHE FILEPATH "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora37_common.cmake")
diff --git a/.gitlab/ci/configure_macos_arm64_ninja.cmake b/.gitlab/ci/configure_macos_arm64_ninja.cmake
index f657d98..1a41bc3 100644
--- a/.gitlab/ci/configure_macos_arm64_ninja.cmake
+++ b/.gitlab/ci/configure_macos_arm64_ninja.cmake
@@ -1,3 +1,6 @@
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_GUI "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_macos_x86_64_makefiles.cmake b/.gitlab/ci/configure_macos_x86_64_makefiles.cmake
index d3ef93f..113fe56 100644
--- a/.gitlab/ci/configure_macos_x86_64_makefiles.cmake
+++ b/.gitlab/ci/configure_macos_x86_64_makefiles.cmake
@@ -1,3 +1,6 @@
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_GUI "ON" CACHE BOOL "")
if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
diff --git a/.gitlab/ci/configure_macos_x86_64_ninja.cmake b/.gitlab/ci/configure_macos_x86_64_ninja.cmake
index d3ef93f..113fe56 100644
--- a/.gitlab/ci/configure_macos_x86_64_ninja.cmake
+++ b/.gitlab/ci/configure_macos_x86_64_ninja.cmake
@@ -1,3 +1,6 @@
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_GUI "ON" CACHE BOOL "")
if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
diff --git a/.gitlab/ci/configure_mingw_osdn_io_common.cmake b/.gitlab/ci/configure_mingw_osdn_io_common.cmake
new file mode 100644
index 0000000..55dce1d
--- /dev/null
+++ b/.gitlab/ci/configure_mingw_osdn_io_common.cmake
@@ -0,0 +1,5 @@
+set(CMake_TEST_Java OFF CACHE BOOL "")
+
+set(configure_no_sccache 1)
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_mingw_osdn_io_mingw_makefiles.cmake b/.gitlab/ci/configure_mingw_osdn_io_mingw_makefiles.cmake
new file mode 100644
index 0000000..5ddd410
--- /dev/null
+++ b/.gitlab/ci/configure_mingw_osdn_io_mingw_makefiles.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_mingw_osdn_io_common.cmake")
diff --git a/.gitlab/ci/configure_mingw_osdn_io_msys_makefiles.cmake b/.gitlab/ci/configure_mingw_osdn_io_msys_makefiles.cmake
new file mode 100644
index 0000000..5ddd410
--- /dev/null
+++ b/.gitlab/ci/configure_mingw_osdn_io_msys_makefiles.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_mingw_osdn_io_common.cmake")
diff --git a/.gitlab/ci/configure_windows_arm64_vs2022.cmake b/.gitlab/ci/configure_windows_arm64_vs2022.cmake
new file mode 100644
index 0000000..c7d41ea
--- /dev/null
+++ b/.gitlab/ci/configure_windows_arm64_vs2022.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common.cmake")
diff --git a/.gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake b/.gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake
new file mode 100644
index 0000000..722e009
--- /dev/null
+++ b/.gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake
@@ -0,0 +1,7 @@
+# Qt host tools are not yet available natively on windows-arm64.
+set(CMake_TEST_GUI "OFF" CACHE BOOL "")
+set(BUILD_QtDialog "OFF" CACHE BOOL "")
+set(CMAKE_PREFIX_PATH "" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common_ninja.cmake")
diff --git a/.gitlab/ci/ctest_memcheck_fedora36_asan.lsan.supp b/.gitlab/ci/ctest_memcheck_fedora37_asan.lsan.supp
index 8ec1a03..8ec1a03 100644
--- a/.gitlab/ci/ctest_memcheck_fedora36_asan.lsan.supp
+++ b/.gitlab/ci/ctest_memcheck_fedora37_asan.lsan.supp
diff --git a/.gitlab/ci/docker/fedora36/Dockerfile b/.gitlab/ci/docker/fedora37/Dockerfile
index ea42561..13ef9aa 100644
--- a/.gitlab/ci/docker/fedora36/Dockerfile
+++ b/.gitlab/ci/docker/fedora37/Dockerfile
@@ -1,22 +1,22 @@
-FROM fedora:36 as rvm-build
+FROM fedora:37 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:36 AS clang-tidy-headers
+FROM fedora:37 AS clang-tidy-headers
MAINTAINER Kyle Edwards <kyle.edwards@kitware.com>
COPY install_clang_tidy_headers.sh /root/install_clang_tidy_headers.sh
RUN sh /root/install_clang_tidy_headers.sh
-FROM fedora:36 AS iwyu
+FROM fedora:37 AS iwyu
MAINTAINER Kyle Edwards <kyle.edwards@kitware.com>
COPY install_iwyu.sh /root/install_iwyu.sh
RUN sh /root/install_iwyu.sh
-FROM fedora:36
+FROM fedora:37
MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
COPY install_deps.sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh b/.gitlab/ci/docker/fedora37/install_clang_tidy_headers.sh
index b9883f4..b9883f4 100755
--- a/.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh
+++ b/.gitlab/ci/docker/fedora37/install_clang_tidy_headers.sh
diff --git a/.gitlab/ci/docker/fedora36/install_deps.sh b/.gitlab/ci/docker/fedora37/install_deps.sh
index f117888..afb8560 100755
--- a/.gitlab/ci/docker/fedora36/install_deps.sh
+++ b/.gitlab/ci/docker/fedora37/install_deps.sh
@@ -11,8 +11,11 @@ dnf install --setopt=install_weak_deps=False -y \
# Install development tools.
dnf install --setopt=install_weak_deps=False -y \
+ clang \
clang-tools-extra \
compiler-rt \
+ flang \
+ flang-devel \
gcc-c++ \
git-core \
make
diff --git a/.gitlab/ci/docker/fedora36/install_iwyu.sh b/.gitlab/ci/docker/fedora37/install_iwyu.sh
index 714bcc0..714bcc0 100755
--- a/.gitlab/ci/docker/fedora36/install_iwyu.sh
+++ b/.gitlab/ci/docker/fedora37/install_iwyu.sh
diff --git a/.gitlab/ci/docker/fedora36/install_rvm.sh b/.gitlab/ci/docker/fedora37/install_rvm.sh
index 0011f87..0011f87 100755
--- a/.gitlab/ci/docker/fedora36/install_rvm.sh
+++ b/.gitlab/ci/docker/fedora37/install_rvm.sh
diff --git a/.gitlab/ci/env_fedora36_asan.sh b/.gitlab/ci/env_fedora37_asan.sh
index e976486..e976486 100644
--- a/.gitlab/ci/env_fedora36_asan.sh
+++ b/.gitlab/ci/env_fedora37_asan.sh
diff --git a/.gitlab/ci/env_fedora36_clang_analyzer.sh b/.gitlab/ci/env_fedora37_clang_analyzer.sh
index d732c0b..d732c0b 100644
--- a/.gitlab/ci/env_fedora36_clang_analyzer.sh
+++ b/.gitlab/ci/env_fedora37_clang_analyzer.sh
diff --git a/.gitlab/ci/env_fedora36_extdeps.sh b/.gitlab/ci/env_fedora37_extdeps.sh
index 7076e18..7076e18 100644
--- a/.gitlab/ci/env_fedora36_extdeps.sh
+++ b/.gitlab/ci/env_fedora37_extdeps.sh
diff --git a/.gitlab/ci/env_fedora36_makefiles.cmake b/.gitlab/ci/env_fedora37_makefiles.cmake
index 2bcb6d0..2bcb6d0 100644
--- a/.gitlab/ci/env_fedora36_makefiles.cmake
+++ b/.gitlab/ci/env_fedora37_makefiles.cmake
diff --git a/.gitlab/ci/env_fedora36_ninja_multi.sh b/.gitlab/ci/env_fedora37_makefiles.sh
index 217ff30..217ff30 100644
--- a/.gitlab/ci/env_fedora36_ninja_multi.sh
+++ b/.gitlab/ci/env_fedora37_makefiles.sh
diff --git a/.gitlab/ci/env_fedora36_ninja.sh b/.gitlab/ci/env_fedora37_ninja.sh
index 217ff30..217ff30 100644
--- a/.gitlab/ci/env_fedora36_ninja.sh
+++ b/.gitlab/ci/env_fedora37_ninja.sh
diff --git a/.gitlab/ci/env_fedora36_makefiles.sh b/.gitlab/ci/env_fedora37_ninja_multi.sh
index 217ff30..217ff30 100644
--- a/.gitlab/ci/env_fedora36_makefiles.sh
+++ b/.gitlab/ci/env_fedora37_ninja_multi.sh
diff --git a/.gitlab/ci/env_fedora37_tidy.sh b/.gitlab/ci/env_fedora37_tidy.sh
new file mode 100644
index 0000000..f9f08a3
--- /dev/null
+++ b/.gitlab/ci/env_fedora37_tidy.sh
@@ -0,0 +1,7 @@
+cmake \
+ -S Utilities/ClangTidyModule \
+ -B Utilities/ClangTidyModule/build \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DRUN_TESTS=ON
+cmake --build Utilities/ClangTidyModule/build
+ctest --test-dir Utilities/ClangTidyModule/build --output-on-failure
diff --git a/.gitlab/ci/env_macos_arm64_ninja.sh b/.gitlab/ci/env_macos_arm64_ninja.sh
new file mode 100644
index 0000000..f8d459b
--- /dev/null
+++ b/.gitlab/ci/env_macos_arm64_ninja.sh
@@ -0,0 +1 @@
+. .gitlab/ci/openmp-env.sh
diff --git a/.gitlab/ci/env_macos_x86_64_makefiles.sh b/.gitlab/ci/env_macos_x86_64_makefiles.sh
index 217ff30..7496372 100644
--- a/.gitlab/ci/env_macos_x86_64_makefiles.sh
+++ b/.gitlab/ci/env_macos_x86_64_makefiles.sh
@@ -1,3 +1,4 @@
+. .gitlab/ci/openmp-env.sh
if test "$CMAKE_CI_NIGHTLY" = "true"; then
source .gitlab/ci/ispc-env.sh
fi
diff --git a/.gitlab/ci/env_macos_x86_64_ninja.sh b/.gitlab/ci/env_macos_x86_64_ninja.sh
index 217ff30..7496372 100644
--- a/.gitlab/ci/env_macos_x86_64_ninja.sh
+++ b/.gitlab/ci/env_macos_x86_64_ninja.sh
@@ -1,3 +1,4 @@
+. .gitlab/ci/openmp-env.sh
if test "$CMAKE_CI_NIGHTLY" = "true"; then
source .gitlab/ci/ispc-env.sh
fi
diff --git a/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1 b/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1
new file mode 100755
index 0000000..e2d573e
--- /dev/null
+++ b/.gitlab/ci/env_mingw_osdn_io_mingw_makefiles.ps1
@@ -0,0 +1,3 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/mingw.ps1"
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\mingw\bin;$env:PATH"
diff --git a/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1 b/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1
new file mode 100755
index 0000000..6eccb72
--- /dev/null
+++ b/.gitlab/ci/env_mingw_osdn_io_msys_makefiles.ps1
@@ -0,0 +1,5 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/mingw.ps1"
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\mingw\msys\1.0\bin;$pwdpath\.gitlab\mingw\bin;$env:PATH"
+$env:MSYSTEM = 'MINGW32'
+$env:MAKE_MODE = 'unix'
diff --git a/.gitlab/ci/mingw.ps1 b/.gitlab/ci/mingw.ps1
new file mode 100755
index 0000000..a1b5b11
--- /dev/null
+++ b/.gitlab/ci/mingw.ps1
@@ -0,0 +1,25 @@
+$erroractionpreference = "stop"
+
+if ("$env:CMAKE_CONFIGURATION".Contains("mingw_osdn_io")) {
+ $filename = "mingw.osdn.io-2022-10-03"
+ $sha256sum = "4DCB8C351D8D855F7D3DFC2863A235042BF3DB6E69EA0BAE51FF9378189345CD"
+} else {
+ throw ('unknown CMAKE_CONFIGURATION: ' + "$env:CMAKE_CONFIGURATION")
+}
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+$ProgressPreference = 'SilentlyContinue'
+Invoke-WebRequest -Uri "https://cmake.org/files/dependencies/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+ exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir")
+Move-Item -Path "$outdir\$filename" -Destination "$outdir\mingw"
+Remove-Item "$outdir\$tarball"
+
+"$outdir/mingw /mingw" -replace '\\', '/' | Out-File -FilePath "$outdir\mingw\msys\1.0\etc\fstab" -Encoding ASCII
diff --git a/.gitlab/ci/openmp-env.sh b/.gitlab/ci/openmp-env.sh
new file mode 100644
index 0000000..82dac5b
--- /dev/null
+++ b/.gitlab/ci/openmp-env.sh
@@ -0,0 +1,3 @@
+.gitlab/ci/openmp.sh
+export CMAKE_PREFIX_PATH=$PWD/.gitlab/openmp${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}
+export DYLD_LIBRARY_PATH=$PWD/.gitlab/openmp/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}
diff --git a/.gitlab/ci/openmp.sh b/.gitlab/ci/openmp.sh
new file mode 100755
index 0000000..f411338
--- /dev/null
+++ b/.gitlab/ci/openmp.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+baseurl="https://cmake.org/files/dependencies/openmp"
+
+case "$(uname -s)-$(uname -m)" in
+ Darwin-*)
+ shatool="shasum -a 256"
+ sha256sum="6eef660db7a085a04f87e4aac79da9f37d26ff0fb17c8781d3a21bd5244997e9"
+ filename="openmp-12.0.1-darwin20-Release"
+ # tarball contains usr/local/
+ strip_components=--strip-components=2
+ ;;
+ *)
+ echo "Unrecognized platform $(uname -s)-$(uname -m)"
+ exit 1
+ ;;
+esac
+readonly shatool
+readonly sha256sum
+
+readonly tarball="$filename.tar.gz"
+
+cd .gitlab
+mkdir -p openmp
+
+echo "$sha256sum $tarball" > openmp.sha256sum
+curl -OL "$baseurl/$tarball"
+$shatool --check openmp.sha256sum
+tar -C openmp $strip_components -xzf $tarball
+rm $tarball openmp.sha256sum
diff --git a/.gitlab/ci/python-env.ps1 b/.gitlab/ci/python-env.ps1
new file mode 100755
index 0000000..4e897d8
--- /dev/null
+++ b/.gitlab/ci/python-env.ps1
@@ -0,0 +1,4 @@
+$pwdpath = $pwd.Path
+cmake -P .gitlab/ci/download_python3.cmake
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\python3;$env:PATH"
+python --version
diff --git a/.gitlab/ci/qt-env.ps1 b/.gitlab/ci/qt-env.ps1
new file mode 100755
index 0000000..7eff55f
--- /dev/null
+++ b/.gitlab/ci/qt-env.ps1
@@ -0,0 +1,10 @@
+if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
+ $pwdpath = $pwd.Path
+ cmake -P .gitlab/ci/download_qt.cmake
+ Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\qt\bin;$env:PATH"
+ qmake -v
+} elseif ("$env:PROCESSOR_ARCHITECTURE" -eq "ARM64") {
+ # Qt host tools are not yet available natively on windows-arm64.
+} else {
+ throw ('unknown PROCESSOR_ARCHITECTURE: ' + "$env:PROCESSOR_ARCHITECTURE")
+}
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 84950d2..6a99f33 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -5,7 +5,7 @@
### Release
.linux_prep_source:
- image: "fedora:36"
+ image: "fedora:37"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -68,8 +68,8 @@
### Fedora
-.fedora36:
- image: "kitware/cmake:ci-fedora36-x86_64-2022-10-04"
+.fedora37:
+ image: "kitware/cmake:ci-fedora37-x86_64-2022-11-16"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
@@ -77,37 +77,37 @@
#### Lint builds
-.fedora36_tidy:
- extends: .fedora36
+.fedora37_tidy:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_tidy
+ CMAKE_CONFIGURATION: fedora37_tidy
CTEST_NO_WARNINGS_ALLOWED: 1
CMAKE_CI_NO_INSTALL: 1
-.fedora36_clang_analyzer:
- extends: .fedora36
+.fedora37_clang_analyzer:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_clang_analyzer
+ CMAKE_CONFIGURATION: fedora37_clang_analyzer
CMAKE_CI_BUILD_TYPE: Debug
CTEST_NO_WARNINGS_ALLOWED: 1
CMAKE_CI_NO_INSTALL: 1
-.fedora36_sphinx:
- extends: .fedora36
+.fedora37_sphinx:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_sphinx
+ CMAKE_CONFIGURATION: fedora37_sphinx
CTEST_NO_WARNINGS_ALLOWED: 1
CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
CMAKE_CI_NO_INSTALL: 1
-.fedora36_sphinx_package:
- extends: .fedora36
+.fedora37_sphinx_package:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_sphinx_package
+ CMAKE_CONFIGURATION: fedora37_sphinx_package
CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
#### Build and test
@@ -153,35 +153,35 @@
CMAKE_CI_BUILD_TYPE: Release
CTEST_NO_WARNINGS_ALLOWED: 1
-.fedora36_extdeps:
- extends: .fedora36
+.fedora37_extdeps:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_extdeps
+ CMAKE_CONFIGURATION: fedora37_extdeps
CMAKE_CI_BUILD_TYPE: Release
CTEST_NO_WARNINGS_ALLOWED: 1
-.fedora36_ninja:
- extends: .fedora36
+.fedora37_ninja:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_ninja
+ CMAKE_CONFIGURATION: fedora37_ninja
CMAKE_CI_BUILD_TYPE: Release
CTEST_NO_WARNINGS_ALLOWED: 1
-.fedora36_ninja_multi:
- extends: .fedora36
+.fedora37_ninja_multi:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_ninja_multi
+ CMAKE_CONFIGURATION: fedora37_ninja_multi
CTEST_NO_WARNINGS_ALLOWED: 1
CMAKE_GENERATOR: "Ninja Multi-Config"
-.fedora36_makefiles:
- extends: .fedora36
+.fedora37_makefiles:
+ extends: .fedora37
variables:
- CMAKE_CONFIGURATION: fedora36_makefiles
+ CMAKE_CONFIGURATION: fedora37_makefiles
CTEST_NO_WARNINGS_ALLOWED: 1
CMAKE_GENERATOR: "Unix Makefiles"
@@ -213,13 +213,13 @@
CTEST_MEMORYCHECK_TYPE: AddressSanitizer
CTEST_MEMORYCHECK_SANITIZER_OPTIONS: ""
-.fedora36_asan:
+.fedora37_asan:
extends:
- - .fedora36
+ - .fedora37
- .fedora_asan_addon
variables:
- CMAKE_CONFIGURATION: fedora36_asan
+ CMAKE_CONFIGURATION: fedora37_asan
### Intel Compiler
@@ -437,7 +437,7 @@
.cmake_codespell_linux:
stage: build
- extends: .fedora36
+ extends: .fedora37
script:
- codespell
interruptible: true
@@ -580,7 +580,7 @@
.cmake_org_help:
stage: build
extends:
- - .fedora36
+ - .fedora37
- .linux_builder_tags
- .cmake_org_help_artifacts
script:
diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml
index 82bcf01..4b71a1b 100644
--- a/.gitlab/os-macos.yml
+++ b/.gitlab/os-macos.yml
@@ -143,7 +143,7 @@
- ninja --version
# Download Qt
- cmake -P .gitlab/ci/download_qt.cmake
- - export CMAKE_PREFIX_PATH=$PWD/.gitlab/qt
+ - export CMAKE_PREFIX_PATH=$PWD/.gitlab/qt${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}
.cmake_build_macos:
stage: build
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index eeed640..64b595e 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -49,6 +49,12 @@
VCVARSPLATFORM: "x64_arm64"
VCVARSVERSION: "14.34.31933"
+.windows_arm64_vcvarsall_vs2022:
+ variables:
+ VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+ VCVARSPLATFORM: "arm64"
+ VCVARSVERSION: "14.34.31933"
+
.windows_vs2022_x64_ninja:
extends:
- .windows_build_ninja
@@ -57,6 +63,14 @@
variables:
CMAKE_CONFIGURATION: windows_vs2022_x64_ninja
+.windows_arm64_vs2022_ninja:
+ extends:
+ - .windows_build_ninja
+ - .windows_arm64_vcvarsall_vs2022
+
+ variables:
+ CMAKE_CONFIGURATION: windows_arm64_vs2022_ninja
+
.windows_package:
extends:
- .windows_build_ninja
@@ -224,6 +238,39 @@
variables:
CMAKE_CONFIGURATION: windows_openwatcom1.9
+.windows_arm64_vs2022:
+ extends: .windows
+
+ variables:
+ CMAKE_CONFIGURATION: windows_arm64_vs2022
+ CMAKE_GENERATOR: "Visual Studio 17 2022"
+ CMAKE_GENERATOR_PLATFORM: "ARM64"
+ CMAKE_GENERATOR_TOOLSET: "v143,version=14.34.31933"
+ CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
+.mingw_osdn_io:
+ extends: .windows
+
+ variables:
+ # Place MinGW environment in a path without spaces.
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR\\cmake-ci-ext\\$CI_CONCURRENT_ID"
+ CMAKE_CI_BUILD_TYPE: Debug
+ CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
+.mingw_osdn_io_mingw_makefiles:
+ extends: .mingw_osdn_io
+
+ variables:
+ CMAKE_CONFIGURATION: mingw_osdn_io_mingw_makefiles
+ CMAKE_GENERATOR: "MinGW Makefiles"
+
+.mingw_osdn_io_msys_makefiles:
+ extends: .mingw_osdn_io
+
+ variables:
+ CMAKE_CONFIGURATION: mingw_osdn_io_msys_makefiles
+ CMAKE_GENERATOR: "MSYS Makefiles"
+
## Tags
.windows_tags_nonconcurrent_vs2022:
@@ -269,6 +316,24 @@
- shell
- concurrent
+.windows_arm64_tags_nonconcurrent_vs2022:
+ tags:
+ - cmake # Since this is a bare runner, pin to a project.
+ - windows-arm64
+ - shell
+ - vs2022
+ - msvc-19.34
+ - nonconcurrent
+
+.windows_arm64_tags_concurrent_vs2022:
+ tags:
+ - cmake # Since this is a bare runner, pin to a project.
+ - windows-arm64
+ - shell
+ - vs2022
+ - msvc-19.34
+ - concurrent
+
## Windows-specific scripts
.before_script_windows: &before_script_windows
@@ -281,11 +346,8 @@
- . .gitlab/ci/ninja-env.ps1
- (& "$env:WIX\bin\light.exe" -help) | Select -First 1
- cmake --version
- - cmake -P .gitlab/ci/download_qt.cmake
- - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\qt\bin;$env:PATH"
- - cmake -P .gitlab/ci/download_python3.cmake
- - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\python3;$env:PATH"
- - python --version
+ - . .gitlab/ci/qt-env.ps1
+ - . .gitlab/ci/python-env.ps1
.cmake_build_windows:
stage: build
diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml
index 38d40a9..27a6ab7 100644
--- a/.gitlab/upload.yml
+++ b/.gitlab/upload.yml
@@ -1,7 +1,7 @@
# Steps for uploading artifacts
.rsync_upload_package:
- image: "fedora:36"
+ image: "fedora:37"
stage: upload
tags:
- cmake
@@ -21,7 +21,7 @@
.rsync_upload_help:
stage: upload
- image: "fedora:36"
+ image: "fedora:37"
tags:
- cmake
- docker
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 9eb993a..5e936c2 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -2013,6 +2013,7 @@ syn keyword cmakeKWExternalProject contained
\ IGNORED
\ INACTIVITY_TIMEOUT
\ INDEPENDENT_STEP_TARGETS
+ \ INSTALL_BYPRODUCTS
\ INSTALL_COMMAND
\ INSTALL_DIR
\ JOB_POOLS
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b9eb2d..a61113a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,10 @@
# 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.13...3.23 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.24 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)
-if(POLICY CMP0129)
- cmake_policy(SET CMP0129 NEW) # CMake 3.23
-endif()
-
project(CMake)
unset(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX)
unset(CMAKE_USER_MAKE_RULES_OVERRIDE_C)
@@ -73,11 +69,7 @@ if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
if(CMAKE_CXX_COMPILER_ID STREQUAL SunPro AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.14)
set(CMAKE_CXX_STANDARD 98)
else()
- if(NOT CMAKE_VERSION VERSION_LESS 3.8)
- include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx17_check.cmake)
- else()
- set(CMake_CXX17_BROKEN 1)
- endif()
+ include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx17_check.cmake)
if(NOT CMake_CXX17_BROKEN)
set(CMAKE_CXX_STANDARD 17)
else()
@@ -130,14 +122,12 @@ option(CMake_BUILD_DEVELOPER_REFERENCE
mark_as_advanced(CMake_BUILD_DEVELOPER_REFERENCE)
# option to build using interprocedural optimizations (IPO/LTO)
-if(NOT CMAKE_VERSION VERSION_LESS 3.12.2)
- option(CMake_BUILD_LTO "Compile CMake with link-time optimization if supported" OFF)
- if(CMake_BUILD_LTO)
- include(CheckIPOSupported)
- check_ipo_supported(RESULT HAVE_IPO)
- if(HAVE_IPO)
- set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
- endif()
+option(CMake_BUILD_LTO "Compile CMake with link-time optimization if supported" OFF)
+if(CMake_BUILD_LTO)
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT HAVE_IPO)
+ if(HAVE_IPO)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endif()
@@ -277,6 +267,16 @@ if(CMake_RUN_CLANG_TIDY)
endif()
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
+ option(CMake_USE_CLANG_TIDY_MODULE "Use CMake's clang-tidy module." OFF)
+ if(CMake_USE_CLANG_TIDY_MODULE)
+ find_library(CMake_CLANG_TIDY_MODULE NAMES cmake-clang-tidy-module DOC "Location of the clang-tidy module")
+ if(NOT CMake_CLANG_TIDY_MODULE)
+ message(FATAL_ERROR "CMake_USE_CLANG_TIDY_MODULE is ON but cmake-clang-tidy-module is not found!")
+ endif()
+ list(APPEND CMAKE_CXX_CLANG_TIDY "--load=${CMake_CLANG_TIDY_MODULE}")
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMake_CLANG_TIDY_MODULE}")
+ endif()
+
# Create a preprocessor definition that depends on .clang-tidy content so
# the compile command will change when .clang-tidy changes. This ensures
# that a subsequent build re-runs clang-tidy on all sources even if they
@@ -286,6 +286,11 @@ if(CMake_RUN_CLANG_TIDY)
file(SHA1 ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy clang_tidy_sha1)
set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}")
unset(clang_tidy_sha1)
+ if(CMake_USE_CLANG_TIDY_MODULE)
+ file(SHA1 "${CMake_CLANG_TIDY_MODULE}" clang_tidy_module_sha1)
+ list(APPEND CLANG_TIDY_DEFINITIONS "CLANG_TIDY_MODULE_SHA1=${clang_tidy_module_sha1}")
+ unset(clang_tidy_module_sha1)
+ endif()
endif()
configure_file(.clang-tidy .clang-tidy COPYONLY)
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index bf8a082..6331af1 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -87,11 +87,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro AND
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
if (NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD EQUAL 98)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
- elseif(CMAKE_VERSION VERSION_LESS 3.8.20170502)
- # CMake knows how to add this flag for compilation as C++11,
- # but has not been taught that SunPro needs it for linking too.
- # Add it in a place that will be used for both.
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
diff --git a/Help/command/DEVICE_LINK_OPTIONS.txt b/Help/command/DEVICE_LINK_OPTIONS.txt
index 3d50208..878754d 100644
--- a/Help/command/DEVICE_LINK_OPTIONS.txt
+++ b/Help/command/DEVICE_LINK_OPTIONS.txt
@@ -7,8 +7,6 @@ Host And Device Specific Link Options
:prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and policy :policy:`CMP0105`,
the raw options will be delivered to the host and device link steps (wrapped in
``-Xcompiler`` or equivalent for device link). Options wrapped with
- ``$<DEVICE_LINK:...>``
- :manual:`generator expression <cmake-generator-expressions(7)>` will be used
- only for the device link step. Options wrapped with ``$<HOST_LINK:...>``
- :manual:`generator expression <cmake-generator-expressions(7)>` will be used
- only for the host link step.
+ :genex:`$<DEVICE_LINK:...>` generator expression will be used
+ only for the device link step. Options wrapped with :genex:`$<HOST_LINK:...>`
+ generator expression will be used only for the host link step.
diff --git a/Help/command/GENEX_NOTE.txt b/Help/command/GENEX_NOTE.txt
new file mode 100644
index 0000000..4a7906c
--- /dev/null
+++ b/Help/command/GENEX_NOTE.txt
@@ -0,0 +1,6 @@
+.. |more_see_also| replace:: See the :manual:`cmake-buildsystem(7)` manual
+ for more on defining buildsystem properties.
+
+Arguments to |command_name| may use generator expressions
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. |more_see_also|
diff --git a/Help/command/add_compile_definitions.rst b/Help/command/add_compile_definitions.rst
index 48e33be..ad1fc43 100644
--- a/Help/command/add_compile_definitions.rst
+++ b/Help/command/add_compile_definitions.rst
@@ -21,7 +21,10 @@ Function-style definitions are not supported. CMake will automatically
escape the value correctly for the native build system (note that CMake
language syntax may require escapes to specify some values).
-Arguments to ``add_compile_definitions`` 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.
+.. |command_name| replace:: ``add_compile_definitions``
+.. include:: GENEX_NOTE.txt
+
+See Also
+^^^^^^^^
+
+* The command :command:`target_compile_definitions` adds target-specific definitions.
diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst
index 36f403c..ad65357 100644
--- a/Help/command/add_compile_options.rst
+++ b/Help/command/add_compile_options.rst
@@ -14,10 +14,8 @@ directory and below.
Arguments
^^^^^^^^^
-Arguments to ``add_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.
+.. |command_name| replace:: ``add_compile_options``
+.. include:: GENEX_NOTE.txt
.. include:: OPTIONS_SHELL.txt
@@ -40,12 +38,12 @@ this command is in a compiler-specific conditional clause:
See Also
^^^^^^^^
-This command can be used to add any options. However, for
-adding preprocessor definitions and include directories it is recommended
-to use the more specific commands :command:`add_compile_definitions`
-and :command:`include_directories`.
+* This command can be used to add any options. However, for
+ adding preprocessor definitions and include directories it is recommended
+ to use the more specific commands :command:`add_compile_definitions`
+ and :command:`include_directories`.
-The command :command:`target_compile_options` adds target-specific options.
+* The command :command:`target_compile_options` adds target-specific options.
-The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one
-source file.
+* The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one
+ source file.
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 99adc85..a999c2d 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -490,3 +490,8 @@ Ninja Multi-Config
``add_custom_command`` supports the :generator:`Ninja Multi-Config`
generator's cross-config capabilities. See the generator documentation
for more information.
+
+See Also
+^^^^^^^^
+
+* :command:`add_custom_target`
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index d8882ca..ec02ee2 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -181,3 +181,8 @@ Ninja Multi-Config
``add_custom_target`` supports the :generator:`Ninja Multi-Config`
generator's cross-config capabilities. See the generator documentation
for more information.
+
+See Also
+^^^^^^^^
+
+* :command:`add_custom_command`
diff --git a/Help/command/add_definitions.rst b/Help/command/add_definitions.rst
index fe69188..5c1f7b4 100644
--- a/Help/command/add_definitions.rst
+++ b/Help/command/add_definitions.rst
@@ -1,7 +1,7 @@
add_definitions
---------------
-Add -D define flags to the compilation of source files.
+Add ``-D`` define flags to the compilation of source files.
.. code-block:: cmake
@@ -31,5 +31,8 @@ backwards compatibility. See documentation of the
properties for details on adding preprocessor definitions to specific
scopes and configurations.
-See the :manual:`cmake-buildsystem(7)` manual for more on defining
-buildsystem properties.
+See Also
+^^^^^^^^
+
+* The :manual:`cmake-buildsystem(7)` manual for more on defining
+ buildsystem properties.
diff --git a/Help/command/add_dependencies.rst b/Help/command/add_dependencies.rst
index 14c0183..23cb405 100644
--- a/Help/command/add_dependencies.rst
+++ b/Help/command/add_dependencies.rst
@@ -20,7 +20,12 @@ transitively in its place since the target itself does not build.
.. versionadded:: 3.3
Allow adding dependencies to interface libraries.
-See the ``DEPENDS`` option of :command:`add_custom_target` and
-:command:`add_custom_command` commands for adding file-level
-dependencies in custom rules. See the :prop_sf:`OBJECT_DEPENDS`
-source file property to add file-level dependencies to object files.
+See Also
+^^^^^^^^
+
+* The ``DEPENDS`` option of :command:`add_custom_target` and
+ :command:`add_custom_command` commands for adding file-level
+ dependencies in custom rules.
+
+* The :prop_sf:`OBJECT_DEPENDS` source file property to add
+ file-level dependencies to object files.
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index dde9429..d9ea0da 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -107,3 +107,8 @@ The ``<name>`` may not be used to modify properties of ``<target>``, that
is, it may not be used as the operand of :command:`set_property`,
:command:`set_target_properties`, :command:`target_link_libraries` etc.
An ``ALIAS`` target may not be installed or exported.
+
+See Also
+^^^^^^^^
+
+* :command:`add_library`
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 7dc4365..43cefca 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -85,8 +85,8 @@ Creates an :ref:`Object Library <Object Libraries>`. An object library
compiles source files but does not archive or link their object files into a
library. Instead other targets created by :command:`add_library` or
:command:`add_executable` may reference the objects using an expression of the
-form ``$<TARGET_OBJECTS:objlib>`` as a source, where ``objlib`` is the
-object library name. For example:
+form :genex:`$\<TARGET_OBJECTS:objlib\> <TARGET_OBJECTS>` as a source, where
+``objlib`` is the object library name. For example:
.. code-block:: cmake
@@ -101,7 +101,7 @@ They may contain custom commands generating such sources, but not
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Some native build
systems (such as Xcode) may not like targets that have only object files, so
consider adding at least one real source file to any target that references
-``$<TARGET_OBJECTS:objlib>``.
+:genex:`$\<TARGET_OBJECTS:objlib\> <TARGET_OBJECTS>`.
.. versionadded:: 3.12
Object libraries can be linked to with :command:`target_link_libraries`.
@@ -261,3 +261,8 @@ to modify properties of ``<target>``, that is, it may not be used as the
operand of :command:`set_property`, :command:`set_target_properties`,
:command:`target_link_libraries` etc. An ``ALIAS`` target may not be
installed or exported.
+
+See Also
+^^^^^^^^
+
+* :command:`add_executable`
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
index f03e7c0..c09e106 100644
--- a/Help/command/add_link_options.rst
+++ b/Help/command/add_link_options.rst
@@ -23,13 +23,18 @@ exist to add libraries (:command:`target_link_libraries` or
since they do not use a linker. To add archiver or MSVC librarian flags,
see the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
-Arguments to ``add_link_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.
+.. |command_name| replace:: ``add_link_options``
+.. include:: GENEX_NOTE.txt
.. include:: DEVICE_LINK_OPTIONS.txt
.. include:: OPTIONS_SHELL.txt
.. include:: LINK_OPTIONS_LINKER.txt
+
+See Also
+^^^^^^^^
+
+* :command:`link_libraries`
+* :command:`target_link_libraries`
+* :command:`target_link_options`
diff --git a/Help/command/block.rst b/Help/command/block.rst
index dfd60d4..a352e83 100644
--- a/Help/command/block.rst
+++ b/Help/command/block.rst
@@ -71,6 +71,6 @@ inside the block.
See Also
^^^^^^^^
- * :command:`endblock`
- * :command:`return`
- * :command:`cmake_policy`
+* :command:`endblock`
+* :command:`return`
+* :command:`cmake_policy`
diff --git a/Help/command/build_name.rst b/Help/command/build_name.rst
index 2a1fbae..5acf858 100644
--- a/Help/command/build_name.rst
+++ b/Help/command/build_name.rst
@@ -5,7 +5,7 @@ Disallowed since version 3.0. See CMake Policy :policy:`CMP0036`.
Use ``${CMAKE_SYSTEM}`` and ``${CMAKE_CXX_COMPILER}`` instead.
-::
+.. code-block:: cmake
build_name(variable)
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index c84c5b5..76824ef 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -17,7 +17,7 @@ Synopsis
Query host system specific information
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
+.. code-block:: cmake
cmake_host_system_information(RESULT <variable> QUERY <key> ...)
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst
index d159770..031bd56 100644
--- a/Help/command/cmake_minimum_required.rst
+++ b/Help/command/cmake_minimum_required.rst
@@ -79,3 +79,8 @@ invokes
cmake_policy(VERSION 2.4[...<max>])
which enables compatibility features for CMake 2.4 and lower.
+
+See Also
+^^^^^^^^
+
+* :command:`cmake_policy`
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
index 7c85da6..0bb1d91 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -113,3 +113,9 @@ interpreted as the beginning of the new option. E.g.
is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty (but added
to ``MY_INSTALL_KEYWORDS_MISSING_VALUES``) and ``MY_INSTALL_OPTIONAL`` will
therefore be set to ``TRUE``.
+
+See Also
+^^^^^^^^
+
+* :command:`function`
+* :command:`macro`
diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst
index eb7da07..4e6bedb 100644
--- a/Help/command/cmake_path.rst
+++ b/Help/command/cmake_path.rst
@@ -237,7 +237,7 @@ The following forms of the ``GET`` subcommand each retrieve a different
component or group of components from a path. See
`Path Structure And Terminology`_ for the meaning of each path component.
-::
+.. code-block:: cmake
cmake_path(GET <path-var> ROOT_NAME <out-var>)
cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>)
@@ -408,7 +408,7 @@ meaning of each path component.
.. _HAS_RELATIVE_PART:
.. _HAS_PARENT_PATH:
-::
+.. code-block:: cmake
cmake_path(HAS_ROOT_NAME <path-var> <out-var>)
cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>)
@@ -432,7 +432,7 @@ Note the following special cases:
.. _IS_ABSOLUTE:
-::
+.. code-block:: cmake
cmake_path(IS_ABSOLUTE <path-var> <out-var>)
@@ -446,7 +446,7 @@ false while ``HAS_ROOT_DIRECTORY`` can be true.
.. _IS_RELATIVE:
-::
+.. code-block:: cmake
cmake_path(IS_RELATIVE <path-var> <out-var>)
@@ -454,7 +454,7 @@ This will store the opposite of ``IS_ABSOLUTE`` in ``<out-var>``.
.. _IS_PREFIX:
-::
+.. code-block:: cmake
cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>)
@@ -476,7 +476,7 @@ are :ref:`normalized <Normalization>` before the check.
.. _Path COMPARE:
.. _COMPARE:
-::
+.. code-block:: cmake
cmake_path(COMPARE <input1> EQUAL <input2> <out-var>)
cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>)
@@ -510,7 +510,7 @@ Modification
.. _cmake_path-SET:
-::
+.. code-block:: cmake
cmake_path(SET <path-var> [NORMALIZE] <input>)
@@ -539,7 +539,7 @@ Output::
.. _APPEND:
-::
+.. code-block:: cmake
cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
@@ -570,7 +570,7 @@ the following algorithm (pseudo-code) applies:
.. _APPEND_STRING:
-::
+.. code-block:: cmake
cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
@@ -579,7 +579,7 @@ Append all the ``<input>`` arguments to the ``<path-var>`` without adding any
.. _REMOVE_FILENAME:
-::
+.. code-block:: cmake
cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>])
@@ -609,7 +609,7 @@ Output::
.. _REPLACE_FILENAME:
-::
+.. code-block:: cmake
cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>])
@@ -628,7 +628,7 @@ equivalent to the following:
.. _REMOVE_EXTENSION:
-::
+.. code-block:: cmake
cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY]
[OUTPUT_VARIABLE <out-var>])
@@ -637,7 +637,7 @@ Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``.
.. _REPLACE_EXTENSION:
-::
+.. code-block:: cmake
cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input>
[OUTPUT_VARIABLE <out-var>])
@@ -661,7 +661,7 @@ Generation
.. _NORMAL_PATH:
-::
+.. code-block:: cmake
cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>])
@@ -670,7 +670,7 @@ Normalize ``<path-var>`` according the steps described in :ref:`Normalization`.
.. _cmake_path-RELATIVE_PATH:
.. _RELATIVE_PATH:
-::
+.. code-block:: cmake
cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>]
[OUTPUT_VARIABLE <out-var>])
@@ -686,7 +686,7 @@ as that used by C++
.. _ABSOLUTE_PATH:
-::
+.. code-block:: cmake
cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE]
[OUTPUT_VARIABLE <out-var>])
@@ -713,7 +713,7 @@ target platform when cross-compiling.
.. _cmake_path-NATIVE_PATH:
.. _NATIVE_PATH:
-::
+.. code-block:: cmake
cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>)
@@ -727,7 +727,7 @@ When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
.. _cmake_path-TO_CMAKE_PATH_LIST:
.. _TO_CMAKE_PATH_LIST:
-::
+.. code-block:: cmake
cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE])
@@ -749,7 +749,7 @@ When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
.. _cmake_path-TO_NATIVE_PATH_LIST:
.. _TO_NATIVE_PATH_LIST:
-::
+.. code-block:: cmake
cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE])
@@ -788,7 +788,7 @@ Hashing
.. _HASH:
-::
+.. code-block:: cmake
cmake_path(HASH <path-var> <out-var>)
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
index 54fc548..cde74a7 100644
--- a/Help/command/cmake_policy.rst
+++ b/Help/command/cmake_policy.rst
@@ -150,3 +150,8 @@ use the pre-record policies when they are invoked. If the function or
macro implementation sets policies, the changes automatically
propagate up through callers until they reach the closest nested
policy stack entry.
+
+See Also
+^^^^^^^^
+
+* :command:`cmake_minimum_required`
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
index 1d81423..7fa2941 100644
--- a/Help/command/configure_file.rst
+++ b/Help/command/configure_file.rst
@@ -182,3 +182,8 @@ specify the output directory as an include directory:
include_directories(${CMAKE_CURRENT_BINARY_DIR})
so that sources may include the header as ``#include <foo.h>``.
+
+See Also
+^^^^^^^^
+
+* :command:`file(GENERATE)`
diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst
index 8c81f2d..bce1739 100644
--- a/Help/command/ctest_build.rst
+++ b/Help/command/ctest_build.rst
@@ -3,7 +3,7 @@ ctest_build
Perform the :ref:`CTest Build Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_build([BUILD <build-dir>] [APPEND]
[CONFIGURATION <config>]
diff --git a/Help/command/ctest_configure.rst b/Help/command/ctest_configure.rst
index 95712aa..f23dd22 100644
--- a/Help/command/ctest_configure.rst
+++ b/Help/command/ctest_configure.rst
@@ -3,7 +3,7 @@ ctest_configure
Perform the :ref:`CTest Configure Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_configure([BUILD <build-dir>] [SOURCE <source-dir>] [APPEND]
[OPTIONS <options>] [RETURN_VALUE <result-var>] [QUIET]
diff --git a/Help/command/ctest_coverage.rst b/Help/command/ctest_coverage.rst
index a6c643b..319c978 100644
--- a/Help/command/ctest_coverage.rst
+++ b/Help/command/ctest_coverage.rst
@@ -3,7 +3,7 @@ ctest_coverage
Perform the :ref:`CTest Coverage Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_coverage([BUILD <build-dir>] [APPEND]
[LABELS <label>...]
diff --git a/Help/command/ctest_empty_binary_directory.rst b/Help/command/ctest_empty_binary_directory.rst
index 7753667..5d26de1 100644
--- a/Help/command/ctest_empty_binary_directory.rst
+++ b/Help/command/ctest_empty_binary_directory.rst
@@ -3,9 +3,9 @@ ctest_empty_binary_directory
empties the binary directory
-::
+.. code-block:: cmake
- ctest_empty_binary_directory( directory )
+ ctest_empty_binary_directory(<directory>)
Removes a binary directory. This command will perform some checks
prior to deleting the directory in an attempt to avoid malicious or
diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst
index 8b79077..4ca7364 100644
--- a/Help/command/ctest_memcheck.rst
+++ b/Help/command/ctest_memcheck.rst
@@ -3,7 +3,7 @@ ctest_memcheck
Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_memcheck([BUILD <build-dir>] [APPEND]
[START <start-number>]
diff --git a/Help/command/ctest_read_custom_files.rst b/Help/command/ctest_read_custom_files.rst
index cf8e17a..53c093e 100644
--- a/Help/command/ctest_read_custom_files.rst
+++ b/Help/command/ctest_read_custom_files.rst
@@ -3,9 +3,9 @@ ctest_read_custom_files
read CTestCustom files.
-::
+.. code-block:: cmake
- ctest_read_custom_files( directory ... )
+ ctest_read_custom_files(<directory>...)
Read all the CTestCustom.ctest or CTestCustom.cmake files from the
given directory.
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst
index a2b348f..145bd90 100644
--- a/Help/command/ctest_run_script.rst
+++ b/Help/command/ctest_run_script.rst
@@ -3,7 +3,7 @@ ctest_run_script
runs a :option:`ctest -S` script
-::
+.. code-block:: cmake
ctest_run_script([NEW_PROCESS] script_file_name script_file_name1
script_file_name2 ... [RETURN_VALUE var])
diff --git a/Help/command/ctest_sleep.rst b/Help/command/ctest_sleep.rst
index 16a914c..42b9768 100644
--- a/Help/command/ctest_sleep.rst
+++ b/Help/command/ctest_sleep.rst
@@ -3,13 +3,13 @@ ctest_sleep
sleeps for some amount of time
-::
+.. code-block:: cmake
ctest_sleep(<seconds>)
Sleep for given number of seconds.
-::
+.. code-block:: cmake
ctest_sleep(<time1> <duration> <time2>)
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
index 921279a..2d68a37 100644
--- a/Help/command/ctest_start.rst
+++ b/Help/command/ctest_start.rst
@@ -3,7 +3,7 @@ ctest_start
Starts the testing for a given model
-::
+.. code-block:: cmake
ctest_start(<model> [<source> [<binary>]] [GROUP <group>] [QUIET])
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst
index d661825..3b6bf3a 100644
--- a/Help/command/ctest_submit.rst
+++ b/Help/command/ctest_submit.rst
@@ -3,7 +3,7 @@ ctest_submit
Perform the :ref:`CTest Submit Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_submit([PARTS <part>...] [FILES <file>...]
[SUBMIT_URL <url>]
@@ -96,7 +96,7 @@ Submit to CDash Upload API
.. versionadded:: 3.2
-::
+.. code-block:: cmake
ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]
[SUBMIT_URL <url>]
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 4f9f891..cf20ade 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -3,7 +3,7 @@ ctest_test
Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_test([BUILD <build-dir>] [APPEND]
[START <start-number>]
@@ -30,7 +30,7 @@ Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
)
..
- _note: If updating the argument list here, please also update the argument
+ NOTE If updating the argument list here, please also update the argument
list documentation for :command:`ctest_memcheck` as well.
Run tests in the project build tree and store results in
diff --git a/Help/command/ctest_update.rst b/Help/command/ctest_update.rst
index 63f991b..836cdf1 100644
--- a/Help/command/ctest_update.rst
+++ b/Help/command/ctest_update.rst
@@ -3,7 +3,7 @@ ctest_update
Perform the :ref:`CTest Update Step` as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_update([SOURCE <source-dir>]
[RETURN_VALUE <result-var>]
diff --git a/Help/command/ctest_upload.rst b/Help/command/ctest_upload.rst
index ffddd0a..344979a 100644
--- a/Help/command/ctest_upload.rst
+++ b/Help/command/ctest_upload.rst
@@ -3,7 +3,7 @@ ctest_upload
Upload files to a dashboard server as a :ref:`Dashboard Client`.
-::
+.. code-block:: cmake
ctest_upload(FILES <file>... [QUIET] [CAPTURE_CMAKE_ERROR <result-var>])
diff --git a/Help/command/define_property.rst b/Help/command/define_property.rst
index 76b060b..5278e30 100644
--- a/Help/command/define_property.rst
+++ b/Help/command/define_property.rst
@@ -73,3 +73,9 @@ project via corresponding options to the :command:`get_property` command.
with ``CMAKE_`` or ``_CMAKE_``. The property name must contain at least one
underscore. It is recommended that the property name have a prefix specific
to the project.
+
+See Also
+^^^^^^^^
+
+* :command:`get_property`
+* :command:`set_property`
diff --git a/Help/command/exec_program.rst b/Help/command/exec_program.rst
index bc9b069..983a6df 100644
--- a/Help/command/exec_program.rst
+++ b/Help/command/exec_program.rst
@@ -8,7 +8,7 @@ exec_program
Run an executable program during the processing of the CMakeList.txt
file.
-::
+.. code-block:: cmake
exec_program(Executable [directory in which to run]
[ARGS <arguments to executable>]
diff --git a/Help/command/export_library_dependencies.rst b/Help/command/export_library_dependencies.rst
index 9753abf..6cb4643 100644
--- a/Help/command/export_library_dependencies.rst
+++ b/Help/command/export_library_dependencies.rst
@@ -15,7 +15,7 @@ The old-style library dependencies file does not take into account
per-configuration names of libraries or the
:prop_tgt:`LINK_INTERFACE_LIBRARIES` target property.
-::
+.. code-block:: cmake
export_library_dependencies(<file> [APPEND])
diff --git a/Help/command/file.rst b/Help/command/file.rst
index fbe2a81..2348937 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -526,10 +526,10 @@ from the input content to produce the output content. The options are:
``OUTPUT <output-file>``
Specify the output file name to generate. Use generator expressions
- such as ``$<CONFIG>`` to specify a configuration-specific output file
- name. Multiple configurations may generate the same output file only
- if the generated content is identical. Otherwise, the ``<output-file>``
- must evaluate to an unique name for each configuration.
+ such as :genex:`$<CONFIG>` to specify a configuration-specific
+ output file name. Multiple configurations may generate the same output
+ file only if the generated content is identical. Otherwise, the
+ ``<output-file>`` must evaluate to an unique name for each configuration.
.. versionchanged:: 3.10
A relative path (after evaluating generator expressions) is treated
@@ -540,8 +540,9 @@ from the input content to produce the output content. The options are:
.. versionadded:: 3.19
Specify which target to use when evaluating generator expressions that
- require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
- ``$<TARGET_PROPERTY:prop>``).
+ require a target for evaluation (e.g.
+ :genex:`$<COMPILE_FEATURES:...>`,
+ :genex:`$<TARGET_PROPERTY:prop>`).
``NO_SOURCE_PERMISSIONS``
.. versionadded:: 3.20
@@ -1213,6 +1214,9 @@ directed to do so with the ``COMPRESSION`` option. Valid values for
The ``<compression-level>`` should be between 0-9, with the default being 0.
The ``COMPRESSION`` option must be present when ``COMPRESSION_LEVEL`` is given.
+.. versionadded:: 3.26
+ The ``<compression-level>`` of the ``Zstd`` algorithm can be set between 0-19.
+
.. note::
With ``FORMAT`` set to ``raw`` only one file will be compressed with the
compression type specified by ``COMPRESSION``.
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index ddf8dfa..c3fdbf7 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -74,8 +74,7 @@ processed:
message(STATUS "X=${X}")
endforeach()
-yields
-::
+yields::
-- X=0
-- X=1
@@ -119,8 +118,7 @@ iteration variables as follows:
message(STATUS "en=${en}, ba=${ba}")
endforeach()
-yields
-::
+yields::
-- num_0=one, num_1=satu
-- num_0=two, num_1=dua
diff --git a/Help/command/function.rst b/Help/command/function.rst
index fc55c03..069f9fa 100644
--- a/Help/command/function.rst
+++ b/Help/command/function.rst
@@ -77,5 +77,6 @@ extra argument.
See Also
^^^^^^^^
+* :command:`cmake_parse_arguments`
* :command:`endfunction`
* :command:`return`
diff --git a/Help/command/get_cmake_property.rst b/Help/command/get_cmake_property.rst
index 96764a3..b1d18a0 100644
--- a/Help/command/get_cmake_property.rst
+++ b/Help/command/get_cmake_property.rst
@@ -12,9 +12,12 @@ the ``<property>`` is stored in the variable ``<var>``.
If the property is not found, ``<var>`` will be set to ``NOTFOUND``.
See the :manual:`cmake-properties(7)` manual for available properties.
-See also the :command:`get_property` command ``GLOBAL`` option.
-
In addition to global properties, this command (for historical reasons)
also supports the :prop_dir:`VARIABLES` and :prop_dir:`MACROS` directory
properties. It also supports a special ``COMPONENTS`` global property that
lists the components given to the :command:`install` command.
+
+See Also
+^^^^^^^^
+
+* the :command:`get_property` command ``GLOBAL`` option
diff --git a/Help/command/get_directory_property.rst b/Help/command/get_directory_property.rst
index 0ccbfb0..209d2f8 100644
--- a/Help/command/get_directory_property.rst
+++ b/Help/command/get_directory_property.rst
@@ -33,4 +33,9 @@ the search will chain to a parent scope as described for the
Get a variable definition from a directory. This form is useful to
get a variable definition from another directory.
-See also the more general :command:`get_property` command.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* the more general :command:`get_property` command
diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst
index 4bfe087..899ede6 100644
--- a/Help/command/get_filename_component.rst
+++ b/Help/command/get_filename_component.rst
@@ -69,3 +69,8 @@ left as a full path. If ``PROGRAM_ARGS`` is present with ``PROGRAM``, then
any command-line arguments present in the ``<FileName>`` string are split
from the program name and stored in ``<arg_var>``. This is used to
separate a program name from its arguments in a command line string.
+
+See Also
+^^^^^^^^
+
+* :command:`cmake_path`
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index 46da285..6b9931e 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -99,3 +99,9 @@ documentation is requested for a property that has not been defined
The :prop_sf:`GENERATED` source file property may be globally visible.
See its documentation for details.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* :command:`set_property`
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index ae41565..e83e9c2 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -39,9 +39,14 @@ Use :command:`set_source_files_properties` to set property values. Source
file properties usually control how the file is built. One property that is
always there is :prop_sf:`LOCATION`.
-See also the more general :command:`get_property` command.
-
.. note::
The :prop_sf:`GENERATED` source file property may be globally visible.
See its documentation for details.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* the more general :command:`get_property` command
+* :command:`set_source_files_properties`
diff --git a/Help/command/get_target_property.rst b/Help/command/get_target_property.rst
index 985b1ff..8c6dcb1 100644
--- a/Help/command/get_target_property.rst
+++ b/Help/command/get_target_property.rst
@@ -22,6 +22,10 @@ query the target instead. This command can get properties for any
target so far created. The targets do not need to be in the current
``CMakeLists.txt`` file.
-See also the more general :command:`get_property` command.
+See Also
+^^^^^^^^
-See :ref:`Target Properties` for the list of properties known to CMake.
+* :command:`define_property`
+* the more general :command:`get_property` command
+* :command:`set_target_properties`
+* :ref:`Target Properties` for the list of properties known to CMake
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
index 6bcc1ef..2b6f354 100644
--- a/Help/command/get_test_property.rst
+++ b/Help/command/get_test_property.rst
@@ -19,4 +19,8 @@ an empty string.
For a list of standard properties you can type
:option:`cmake --help-property-list`.
-See also the more general :command:`get_property` command.
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* the more general :command:`get_property` command
diff --git a/Help/command/if.rst b/Help/command/if.rst
index b72769f..a57630b 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -428,6 +428,6 @@ condition syntax accepts ``<variable|string>``.
See also
^^^^^^^^
- * :command:`else`
- * :command:`elseif`
- * :command:`endif`
+* :command:`else`
+* :command:`elseif`
+* :command:`endif`
diff --git a/Help/command/include_directories.rst b/Help/command/include_directories.rst
index fe281c3..d2948ed 100644
--- a/Help/command/include_directories.rst
+++ b/Help/command/include_directories.rst
@@ -29,13 +29,16 @@ Signalling this setting might achieve effects such as the compiler
skipping warnings, or these fixed-install system files not being
considered in dependency calculations - see compiler docs.
-Arguments to ``include_directories`` 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.
+.. |command_name| replace:: ``include_directories``
+.. include:: GENEX_NOTE.txt
.. note::
Prefer the :command:`target_include_directories` command to add include
directories to individual targets and optionally propagate/export them
to dependents.
+
+See Also
+^^^^^^^^
+
+* :command:`target_include_directories`
diff --git a/Help/command/install.rst b/Help/command/install.rst
index feff436..d036a20 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -379,7 +379,7 @@ top level:
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property of the
``<targets>`` when exported by the `install(EXPORT)`_ command. If a
relative path is specified, it is treated as relative to the
- ``$<INSTALL_PREFIX>``.
+ :genex:`$<INSTALL_PREFIX>`.
``RUNTIME_DEPENDENCY_SET``
.. versionadded:: 3.21
diff --git a/Help/command/install_files.rst b/Help/command/install_files.rst
index 494f3d0..9b19124 100644
--- a/Help/command/install_files.rst
+++ b/Help/command/install_files.rst
@@ -11,7 +11,7 @@ directly replaced by the ``FILES`` form of the :command:`install`
command. The regexp form can be expressed more clearly using the ``GLOB``
form of the :command:`file` command.
-::
+.. code-block:: cmake
install_files(<dir> extension file file ...)
@@ -23,14 +23,14 @@ removed first. This is useful for providing lists of source files
such as foo.cxx when you want the corresponding foo.h to be installed.
A typical extension is ``.h``.
-::
+.. code-block:: cmake
install_files(<dir> regexp)
Any files in the current source directory that match the regular
expression will be installed.
-::
+.. code-block:: cmake
install_files(<dir> FILES file file ...)
diff --git a/Help/command/install_programs.rst b/Help/command/install_programs.rst
index eafae89..5b42904 100644
--- a/Help/command/install_programs.rst
+++ b/Help/command/install_programs.rst
@@ -11,7 +11,7 @@ directly replaced by the ``PROGRAMS`` form of the :command:`install`
command. The regexp form can be expressed more clearly using the ``GLOB``
form of the :command:`file` command.
-::
+.. code-block:: cmake
install_programs(<dir> file1 file2 [file3 ...])
install_programs(<dir> FILES file1 [file2 ...])
@@ -20,7 +20,7 @@ Create rules to install the listed programs into the given directory.
Use the ``FILES`` argument to guarantee that the file list version of the
command will be used even when there is only one argument.
-::
+.. code-block:: cmake
install_programs(<dir> regexp)
diff --git a/Help/command/install_targets.rst b/Help/command/install_targets.rst
index 9355f8d..7653776 100644
--- a/Help/command/install_targets.rst
+++ b/Help/command/install_targets.rst
@@ -8,7 +8,7 @@ install_targets
This command has been superseded by the :command:`install` command. It is
provided for compatibility with older CMake code.
-::
+.. code-block:: cmake
install_targets(<dir> [RUNTIME_DIRECTORY dir] target target)
diff --git a/Help/command/link_directories.rst b/Help/command/link_directories.rst
index 6732402..5e7fc39 100644
--- a/Help/command/link_directories.rst
+++ b/Help/command/link_directories.rst
@@ -53,3 +53,9 @@ The command will apply only to targets created after it is called.
where possible by using the :command:`target_link_directories` command
rather than ``link_directories()``. The target-specific command can also
control how the search directories propagate to other dependent targets.
+
+See Also
+^^^^^^^^
+
+* :command:`target_link_directories`
+* :command:`target_link_libraries`
diff --git a/Help/command/load_command.rst b/Help/command/load_command.rst
index dc23599..4b3888f 100644
--- a/Help/command/load_command.rst
+++ b/Help/command/load_command.rst
@@ -5,7 +5,7 @@ Disallowed since version 3.0. See CMake Policy :policy:`CMP0031`.
Load a command into a running CMake.
-::
+.. code-block:: cmake
load_command(COMMAND_NAME <loc1> [loc2 ...])
@@ -15,7 +15,7 @@ added to the set of available CMake commands. Usually,
:command:`try_compile` is used before this command to compile the
module. If the command is successfully loaded a variable named
-::
+.. code-block:: cmake
CMAKE_LOADED_COMMAND_<COMMAND_NAME>
diff --git a/Help/command/macro.rst b/Help/command/macro.rst
index 5fe4c00..2858622 100644
--- a/Help/command/macro.rst
+++ b/Help/command/macro.rst
@@ -149,3 +149,9 @@ existing variable instead of the arguments. For example:
Will loop over ``a;b;c`` and not over ``x;y;z`` as one might have expected.
If you want true CMake variables and/or better CMake scope control you
should look at the function command.
+
+See Also
+^^^^^^^^
+
+* :command:`cmake_parse_arguments`
+* :command:`endmacro`
diff --git a/Help/command/make_directory.rst b/Help/command/make_directory.rst
index 8469b0a..959749d 100644
--- a/Help/command/make_directory.rst
+++ b/Help/command/make_directory.rst
@@ -5,7 +5,7 @@ make_directory
Use the :command:`file(MAKE_DIRECTORY)` command instead.
-::
+.. code-block:: cmake
make_directory(directory)
diff --git a/Help/command/message.rst b/Help/command/message.rst
index 77d21c8..9ac4277 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -193,3 +193,8 @@ Output from the above would appear something like the following::
-- Finding partB
-- Finding partB - not found
-- Finding my things - missing components: B
+
+See Also
+^^^^^^^^
+
+* :command:`cmake_language(GET_MESSAGE_LOG_LEVEL)`
diff --git a/Help/command/output_required_files.rst b/Help/command/output_required_files.rst
index b3a6e86..fbe5dbd 100644
--- a/Help/command/output_required_files.rst
+++ b/Help/command/output_required_files.rst
@@ -9,7 +9,7 @@ This command exists only because ancient CMake versions provided it.
CMake handles preprocessor dependency scanning automatically using a
more advanced scanner.
-::
+.. code-block:: cmake
output_required_files(srcfile outputfile)
diff --git a/Help/command/project.rst b/Help/command/project.rst
index 8f32fa3..4e57d09 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -188,5 +188,6 @@ call exists, CMake will issue a warning and pretend there is a
Call the ``project()`` command near the top of the top-level
``CMakeLists.txt``, but *after* calling :command:`cmake_minimum_required`.
It is important to establish version and policy settings before invoking
- other commands whose behavior they may affect.
+ other commands whose behavior they may affect and for this reason the
+ ``project()`` command will issue a warning if this order is not kept.
See also policy :policy:`CMP0000`.
diff --git a/Help/command/remove.rst b/Help/command/remove.rst
index 543d016..e12a937 100644
--- a/Help/command/remove.rst
+++ b/Help/command/remove.rst
@@ -5,7 +5,7 @@ remove
Use the :command:`list(REMOVE_ITEM)` command instead.
-::
+.. code-block:: cmake
remove(VAR VALUE VALUE ...)
diff --git a/Help/command/return.rst b/Help/command/return.rst
index 3013b52..795dbeb 100644
--- a/Help/command/return.rst
+++ b/Help/command/return.rst
@@ -88,4 +88,5 @@ command. All arguments are ignored unless that policy is set to ``NEW``.
See Also
^^^^^^^^
- * :command:`block`
+* :command:`block`
+* :command:`function`
diff --git a/Help/command/set.rst b/Help/command/set.rst
index 90b57d2..c724844 100644
--- a/Help/command/set.rst
+++ b/Help/command/set.rst
@@ -111,3 +111,8 @@ environment variable.
Arguments after ``<value>`` are ignored. If extra arguments are found,
then an author warning is issued.
+
+See Also
+^^^^^^^^
+
+* :command:`unset`
diff --git a/Help/command/set_directory_properties.rst b/Help/command/set_directory_properties.rst
index f02a8e6..93ad39b 100644
--- a/Help/command/set_directory_properties.rst
+++ b/Help/command/set_directory_properties.rst
@@ -13,3 +13,10 @@ See also the :command:`set_property(DIRECTORY)` command.
See :ref:`Directory Properties` for the list of properties known to CMake
and their individual documentation for the behavior of each property.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* :command:`get_directory_property`
+* the more general :command:`set_property` command
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index b9b12c4..d446a2d 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -107,10 +107,15 @@ finding the initial value to append to. If the property is not already
directly set in the nominated scope, the command will behave as though
``APPEND`` or ``APPEND_STRING`` had not been given.
-See the :manual:`cmake-properties(7)` manual for a list of properties
-in each scope.
-
.. note::
The :prop_sf:`GENERATED` source file property may be globally visible.
See its documentation for details.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* :command:`get_property`
+* The :manual:`cmake-properties(7)` manual for a list of properties
+ in each scope.
diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst
index 61c69a2..d937b33 100644
--- a/Help/command/set_source_files_properties.rst
+++ b/Help/command/set_source_files_properties.rst
@@ -34,10 +34,15 @@ list.
Use :command:`get_source_file_property` to get property values.
See also the :command:`set_property(SOURCE)` command.
-See :ref:`Source File Properties` for the list of properties known
-to CMake.
-
.. note::
The :prop_sf:`GENERATED` source file property may be globally visible.
See its documentation for details.
+
+See Also
+^^^^^^^^
+
+* :command:`define_property`
+* :command:`get_source_file_property`
+* :ref:`Source File Properties` for the list of properties known
+ to CMake
diff --git a/Help/command/set_target_properties.rst b/Help/command/set_target_properties.rst
index 597be23..856b92c 100644
--- a/Help/command/set_target_properties.rst
+++ b/Help/command/set_target_properties.rst
@@ -15,6 +15,10 @@ set next. You can use any prop value pair you want and extract it
later with the :command:`get_property` or :command:`get_target_property`
command.
-See also the :command:`set_property(TARGET)` command.
+See Also
+^^^^^^^^
-See :ref:`Target Properties` for the list of properties known to CMake.
+* :command:`define_property`
+* :command:`get_target_property`
+* the more general :command:`set_property` command
+* :ref:`Target Properties` for the list of properties known to CMake
diff --git a/Help/command/set_tests_properties.rst b/Help/command/set_tests_properties.rst
index eadde33..125e460 100644
--- a/Help/command/set_tests_properties.rst
+++ b/Help/command/set_tests_properties.rst
@@ -14,6 +14,10 @@ Test property values may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature.
-See also the :command:`set_property(TEST)` command.
+See Also
+^^^^^^^^
-See :ref:`Test Properties` for the list of properties known to CMake.
+* :command:`add_test`
+* :command:`define_property`
+* the more general :command:`set_property` command
+* :ref:`Target Properties` for the list of properties known to CMake
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 86cbd2e..217157c 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -522,6 +522,17 @@ specifiers:
``%Y``
The current year.
+``%z``
+ .. versionadded:: 3.26
+
+ The offset of the time zone from UTC, in hours and minutes,
+ with format ``+hhmm`` or ``-hhmm``.
+
+``%Z``
+ .. versionadded:: 3.26
+
+ The time zone name.
+
Unknown format specifiers will be ignored and copied to the output
as-is.
diff --git a/Help/command/subdir_depends.rst b/Help/command/subdir_depends.rst
index 0c1b3c1..2115b33 100644
--- a/Help/command/subdir_depends.rst
+++ b/Help/command/subdir_depends.rst
@@ -5,7 +5,7 @@ Disallowed since version 3.0. See CMake Policy :policy:`CMP0029`.
Does nothing.
-::
+.. code-block:: cmake
subdir_depends(subdir dep1 dep2 ...)
diff --git a/Help/command/subdirs.rst b/Help/command/subdirs.rst
index 530951b..ecc6d1f 100644
--- a/Help/command/subdirs.rst
+++ b/Help/command/subdirs.rst
@@ -7,7 +7,7 @@ subdirs
Add a list of subdirectories to the build.
-::
+.. code-block:: cmake
subdirs(dir1 dir2 ...[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...]
[PREORDER] )
diff --git a/Help/command/target_compile_definitions.rst b/Help/command/target_compile_definitions.rst
index 2d292af..2290efb 100644
--- a/Help/command/target_compile_definitions.rst
+++ b/Help/command/target_compile_definitions.rst
@@ -25,10 +25,8 @@ same ``<target>`` append items in the order called.
.. versionadded:: 3.11
Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
-Arguments to ``target_compile_definitions`` 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.
+.. |command_name| replace:: ``target_compile_definitions``
+.. include:: GENEX_NOTE.txt
Any leading ``-D`` on an item will be removed. Empty items are ignored.
For example, the following are all equivalent:
@@ -48,3 +46,16 @@ Definitions may optionally have values:
Note that many compilers treat ``-DFOO`` as equivalent to ``-DFOO=1``, but
other tools may not recognize this in all circumstances (e.g. IntelliSense).
+
+See Also
+^^^^^^^^
+
+* :command:`add_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index 58502bf..531af81 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -30,8 +30,20 @@ The named ``<target>`` must have been created by a command such as
:command:`add_executable` or :command:`add_library` and must not be an
:ref:`ALIAS target <Alias Targets>`.
-Arguments to ``target_compile_features`` may use "generator expressions"
-with the syntax ``$<...>``.
-See the :manual:`cmake-generator-expressions(7)` manual for available
-expressions. See the :manual:`cmake-compile-features(7)` manual for
-information on compile features and a list of supported compilers.
+.. |command_name| replace:: ``target_compile_features``
+.. |more_see_also| replace:: See the :manual:`cmake-compile-features(7)`
+ manual for information on compile features and a list of supported compilers.
+.. include:: GENEX_NOTE.txt
+ :start-line: 1
+
+See Also
+^^^^^^^^
+
+* :command:`target_compile_definitions`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
index 0d86c91..8f13f45 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_compile_options.rst
@@ -32,21 +32,26 @@ The following arguments specify compile options. Repeated calls for the same
.. versionadded:: 3.11
Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
-Arguments to ``target_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.
+.. |command_name| replace:: ``target_compile_options``
+.. include:: GENEX_NOTE.txt
.. include:: OPTIONS_SHELL.txt
See Also
^^^^^^^^
-This command can be used to add any options. However, for adding
-preprocessor definitions and include directories it is recommended
-to use the more specific commands :command:`target_compile_definitions`
-and :command:`target_include_directories`.
+* This command can be used to add any options. However, for adding
+ preprocessor definitions and include directories it is recommended
+ to use the more specific commands :command:`target_compile_definitions`
+ and :command:`target_include_directories`.
-For directory-wide settings, there is the command :command:`add_compile_options`.
+* For directory-wide settings, there is the command :command:`add_compile_options`.
-For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`.
+* For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`.
+
+* :command:`target_compile_features`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst
index f13ff29..2a410ec 100644
--- a/Help/command/target_include_directories.rst
+++ b/Help/command/target_include_directories.rst
@@ -40,10 +40,8 @@ If ``SYSTEM`` is used together with ``PUBLIC`` or ``INTERFACE``, the
:prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` target property will be
populated with the specified directories.
-Arguments to ``target_include_directories`` 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.
+.. |command_name| replace:: ``target_include_directories``
+.. include:: GENEX_NOTE.txt
Specified include directories may be absolute paths or relative paths.
A relative path will be interpreted as relative to the current source
@@ -74,3 +72,16 @@ Creating Relocatable Packages
.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
+
+See Also
+^^^^^^^^
+
+* :command:`include_directories`
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_link_directories.rst b/Help/command/target_link_directories.rst
index b72f746..2854c96 100644
--- a/Help/command/target_link_directories.rst
+++ b/Help/command/target_link_directories.rst
@@ -34,10 +34,8 @@ calls for the same ``<target>`` append items in the order called.
If ``BEFORE`` is specified, the content will be prepended to the relevant
property instead of being appended.
-Arguments to ``target_link_directories`` 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.
+.. |command_name| replace:: ``target_link_directories``
+.. include:: GENEX_NOTE.txt
.. note::
@@ -56,3 +54,16 @@ manual for more on defining buildsystem properties.
that expect to be found via ``RPATH`` mechanisms, but some linkers
are not able to fully decode those paths (e.g. due to the presence
of things like ``$ORIGIN``).
+
+See Also
+^^^^^^^^
+
+* :command:`link_directories`
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index bb7b5cc..1d27660 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -293,8 +293,8 @@ will be included in the link too.
.. _`Linking Object Libraries via $<TARGET_OBJECTS>`:
-Linking Object Libraries via $<TARGET_OBJECTS>
-""""""""""""""""""""""""""""""""""""""""""""""
+Linking Object Libraries via ``$<TARGET_OBJECTS>``
+""""""""""""""""""""""""""""""""""""""""""""""""""
.. versionadded:: 3.21
@@ -407,3 +407,15 @@ Creating Relocatable Packages
.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES`
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
+
+See Also
+^^^^^^^^
+
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index 3cd0e64..0d026f2 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -42,13 +42,23 @@ The following arguments specify link options. Repeated calls for the same
.. note::
:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.
-Arguments to ``target_link_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.
+.. |command_name| replace:: ``target_link_options``
+.. include:: GENEX_NOTE.txt
.. include:: DEVICE_LINK_OPTIONS.txt
.. include:: OPTIONS_SHELL.txt
.. include:: LINK_OPTIONS_LINKER.txt
+
+See Also
+^^^^^^^^
+
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_precompile_headers`
+* :command:`target_sources`
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
index 84f5d12..8e5c0e9 100644
--- a/Help/command/target_precompile_headers.rst
+++ b/Help/command/target_precompile_headers.rst
@@ -70,17 +70,16 @@ included by absolute path. For example:
<unordered_map>
)
-Arguments to ``target_precompile_headers()`` may use "generator expressions"
-with the syntax ``$<...>``.
-See the :manual:`cmake-generator-expressions(7)` manual for available
-expressions.
-The :genex:`$<COMPILE_LANGUAGE:...>` generator expression is particularly
-useful for specifying a language-specific header to precompile for
-only one language (e.g. ``CXX`` and not ``C``). In this case, header
-file names that are not explicitly in double quotes or angle brackets
-must be specified by absolute path. Also, when specifying angle brackets
-inside a generator expression, be sure to encode the closing ``>`` as
-``$<ANGLE-R>``. For example:
+.. |command_name| replace:: ``target_compile_features``
+.. |more_see_also| replace:: The :genex:`$<COMPILE_LANGUAGE:...>` generator
+ expression is particularly useful for specifying a language-specific header
+ to precompile for only one language (e.g. ``CXX`` and not ``C``). In this
+ case, header file names that are not explicitly in double quotes or angle
+ brackets must be specified by absolute path. Also, when specifying angle
+ brackets inside a generator expression, be sure to encode the closing
+ ``>`` as :genex:`$<ANGLE-R>`. For example:
+.. include:: GENEX_NOTE.txt
+ :start-line: 1
.. code-block:: cmake
@@ -118,8 +117,17 @@ the ``REUSE_FROM`` form is used.
See Also
^^^^^^^^
-To disable precompile headers for specific targets, see the
-:prop_tgt:`DISABLE_PRECOMPILE_HEADERS` target property.
+* To disable precompile headers for specific targets, see the
+ :prop_tgt:`DISABLE_PRECOMPILE_HEADERS` target property.
-To prevent precompile headers from being used when compiling a specific
-source file, see the :prop_sf:`SKIP_PRECOMPILE_HEADERS` source file property.
+* To prevent precompile headers from being used when compiling a specific
+ source file, see the :prop_sf:`SKIP_PRECOMPILE_HEADERS` source file property.
+
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_sources`
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index 461175a..5d07f54 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -202,3 +202,17 @@ Target properties related to include directories are also modified by
of the file set is ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of
the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this
property.
+
+See Also
+^^^^^^^^
+
+* :command:`add_executable`
+* :command:`add_library`
+* :command:`target_compile_definitions`
+* :command:`target_compile_features`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :command:`target_link_directories`
+* :command:`target_link_options`
+* :command:`target_precompile_headers`
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 9e9f39f..6ae245f 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -105,9 +105,9 @@ contain something like the following:
CMake automatically generates, for each ``try_compile`` operation, a
unique directory under ``${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch``
with an unspecified name. These directories are cleaned automatically unless
-:option:`--debug-trycompile <cmake --debug-trycompile>` is passed to ``cmake``.
+:option:`--debug-trycompile <cmake --debug-trycompile>` is passed to :program:`cmake`.
Such directories from previous runs are also unconditionally cleaned at the
-beginning of any ``cmake`` execution.
+beginning of any :program:`cmake` execution.
This command also supports an alternate signature
which was present in older versions of CMake:
@@ -130,7 +130,7 @@ which was present in older versions of CMake:
In this version, ``try_compile`` will use ``<bindir>/CMakeFiles/CMakeTmp`` for
its operation, and all such files will be cleaned automatically.
For debugging, :option:`--debug-trycompile <cmake --debug-trycompile>` can be
-passed to ``cmake`` to avoid this clean. However, multiple sequential
+passed to :program:`cmake` to avoid this clean. However, multiple sequential
``try_compile`` operations, if given the same ``<bindir>``, will reuse this
single output directory, such that you can only debug one such ``try_compile``
call at a time. Use of the newer signature is recommended to simplify
@@ -327,3 +327,8 @@ a build configuration.
If :policy:`CMP0141` is set to ``NEW``, one can use
:variable:`CMAKE_MSVC_DEBUG_INFORMATION_FORMAT` to specify the MSVC debug
information format.
+
+See Also
+^^^^^^^^
+
+* :command:`try_run`
diff --git a/Help/command/unset.rst b/Help/command/unset.rst
index 7521052..1cd1398 100644
--- a/Help/command/unset.rst
+++ b/Help/command/unset.rst
@@ -39,3 +39,8 @@ Subsequent calls of ``$ENV{<variable>}`` will return the empty string.
This command affects only the current CMake process, not the process
from which CMake was called, nor the system environment at large,
nor the environment of subsequent build or test processes.
+
+See Also
+^^^^^^^^
+
+* :command:`set`
diff --git a/Help/command/use_mangled_mesa.rst b/Help/command/use_mangled_mesa.rst
index 5b0e2ee..bc84bb3 100644
--- a/Help/command/use_mangled_mesa.rst
+++ b/Help/command/use_mangled_mesa.rst
@@ -5,7 +5,7 @@ Disallowed since version 3.0. See CMake Policy :policy:`CMP0030`.
Copy mesa headers for use in combination with system GL.
-::
+.. code-block:: cmake
use_mangled_mesa(PATH_TO_MESA OUTPUT_DIRECTORY)
diff --git a/Help/command/utility_source.rst b/Help/command/utility_source.rst
index 94d6a4e..3c2bf39 100644
--- a/Help/command/utility_source.rst
+++ b/Help/command/utility_source.rst
@@ -5,7 +5,7 @@ Disallowed since version 3.0. See CMake Policy :policy:`CMP0034`.
Specify the source tree of a third-party utility.
-::
+.. code-block:: cmake
utility_source(cache_entry executable_name
path_to_source [file1 file2 ...])
diff --git a/Help/command/variable_requires.rst b/Help/command/variable_requires.rst
index 322b154..1dbb02d 100644
--- a/Help/command/variable_requires.rst
+++ b/Help/command/variable_requires.rst
@@ -7,7 +7,7 @@ Use the :command:`if` command instead.
Assert satisfaction of an option's required variables.
-::
+.. code-block:: cmake
variable_requires(TEST_VARIABLE RESULT_VARIABLE
REQUIRED_VARIABLE1
diff --git a/Help/command/while.rst b/Help/command/while.rst
index 0bafae5..cb0fa2d 100644
--- a/Help/command/while.rst
+++ b/Help/command/while.rst
@@ -27,7 +27,7 @@ If used, it must be a verbatim repeat of the argument of the opening
See Also
^^^^^^^^
- * :command:`break`
- * :command:`continue`
- * :command:`foreach`
- * :command:`endwhile`
+* :command:`break`
+* :command:`continue`
+* :command:`foreach`
+* :command:`endwhile`
diff --git a/Help/command/write_file.rst b/Help/command/write_file.rst
index 4d476bd..4d0bc63 100644
--- a/Help/command/write_file.rst
+++ b/Help/command/write_file.rst
@@ -5,7 +5,7 @@ write_file
Use the :command:`file(WRITE)` command instead.
-::
+.. code-block:: cmake
write_file(filename "message to write"... [APPEND])
diff --git a/Help/envvar/ASM_DIALECT.rst b/Help/envvar/ASM_DIALECT.rst
index c89515e..11dbe5a 100644
--- a/Help/envvar/ASM_DIALECT.rst
+++ b/Help/envvar/ASM_DIALECT.rst
@@ -4,8 +4,14 @@ ASM<DIALECT>
.. include:: ENV_VAR.txt
Preferred executable for compiling a specific dialect of assembly language
-files. ``ASM<DIALECT>`` can be ``ASM``, ``ASM_NASM`` (Netwide Assembler),
-``ASM_MASM`` (Microsoft Assembler) or ``ASM-ATT`` (Assembler AT&T).
+files. ``ASM<DIALECT>`` can be one of:
+
+* ``ASM``
+* ``ASM_NASM`` (Netwide Assembler)
+* ``ASM_MASM`` (Microsoft Assembler)
+* ``ASM_MARMASM`` (Microsoft ARM Assembler)
+* ``ASM-ATT`` (Assembler AT&T)
+
Will only be used by CMake on the first configuration to determine
``ASM<DIALECT>`` compiler, after which the value for ``ASM<DIALECT>`` is stored
in the cache as
diff --git a/Help/envvar/ASM_DIALECTFLAGS.rst b/Help/envvar/ASM_DIALECTFLAGS.rst
index 2af4b58..f13efbb 100644
--- a/Help/envvar/ASM_DIALECTFLAGS.rst
+++ b/Help/envvar/ASM_DIALECTFLAGS.rst
@@ -9,6 +9,7 @@ of an assembly language. ``ASM<DIALECT>FLAGS`` can be one of:
* ``ASMFLAGS``
* ``ASM_NASMFLAGS``
* ``ASM_MASMFLAGS``
+* ``ASM_MARMASMFLAGS``
* ``ASM-ATTFLAGS``
.. |CMAKE_LANG_FLAGS| replace:: :variable:`CMAKE_ASM<DIALECT>_FLAGS <CMAKE_<LANG>_FLAGS>`
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index 2cf823a..f669ad4 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -106,14 +106,14 @@ If either ``OUTPUT`` or ``BYPRODUCTS`` names a path that is common to
more than one configuration (e.g. it does not use any generator expressions),
all arguments are evaluated in the command config by default.
If all ``OUTPUT`` and ``BYPRODUCTS`` paths are unique to each configuration
-(e.g. by using the ``$<CONFIG>`` generator expression), the first argument of
+(e.g. by using the :genex:`$<CONFIG>` generator expression), the first argument of
``COMMAND`` is still evaluated in the command config by default, while all
subsequent arguments, as well as the arguments to ``DEPENDS`` and
``WORKING_DIRECTORY``, are evaluated in the output config. These defaults can
-be overridden with the ``$<OUTPUT_CONFIG:...>`` and ``$<COMMAND_CONFIG:...>``
+be overridden with the :genex:`$<OUTPUT_CONFIG:...>` and :genex:`$<COMMAND_CONFIG:...>`
generator-expressions. Note that if a target is specified by its name in
``DEPENDS``, or as the first argument of ``COMMAND``, it is always evaluated
-in the command config, even if it is wrapped in ``$<OUTPUT_CONFIG:...>``
+in the command config, even if it is wrapped in :genex:`$<OUTPUT_CONFIG:...>`
(because its plain name is not a generator expression).
As an example, consider the following:
diff --git a/Help/guide/importing-exporting/index.rst b/Help/guide/importing-exporting/index.rst
index dd3efb8..51a09c0 100644
--- a/Help/guide/importing-exporting/index.rst
+++ b/Help/guide/importing-exporting/index.rst
@@ -563,8 +563,7 @@ include directories should be specified as relative paths to the
$<INSTALL_INTERFACE:include/TgtName>
)
-The ``$<INSTALL_PREFIX>``
-:manual:`generator expression <cmake-generator-expressions(7)>` may be used as
+The :genex:`$<INSTALL_PREFIX>` generator expression may be used as
a placeholder for the install prefix without resulting in a non-relocatable
package. This is necessary if complex generator expressions are used:
diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
index 45d5976..787e777 100644
--- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
+++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
@@ -4,33 +4,40 @@ Step 6: Adding Support for a Testing Dashboard
Adding support for submitting our test results to a dashboard is simple. We
already defined a number of tests for our project in
:ref:`Testing Support <Tutorial Testing Support>`. Now we just have to run
-those tests and submit them to a dashboard. To include support for dashboards
-we include the :module:`CTest` module in our top-level ``CMakeLists.txt``.
+those tests and submit them to CDash.
-Replace:
-.. literalinclude:: Step6/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-enable_testing-remove
- :language: cmake
- :start-after: # enable testing
- :end-before: # does the application run
+Exercise 1 - Send Results to a Testing Dashboard
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-With:
+Goal
+----
-.. literalinclude:: Step7/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-include-CTest
- :language: cmake
- :start-after: # enable testing
- :end-before: # does the application run
+Display our CTest results with CDash.
+
+Helpful Resources
+-----------------
+
+* :manual:`ctest(1)`
+* :command:`include`
+* :module:`CTest`
+
+Files to Edit
+-------------
-The :module:`CTest` module will automatically call ``enable_testing()``, so we
-can remove it from our CMake files.
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+For this exercise, complete ``TODO 1`` in the top-level ``CMakeLists.txt`` by
+including the :module:`CTest` module. This will enable testing with CTest as
+well as dashboard submissions to CDash, so we can safely remove the call to
+:command:`enable_testing`.
We will also need to acquire a ``CTestConfig.cmake`` file to be placed in the
-top-level directory where we can specify information to CTest about the
-project. It contains:
+top-level directory. When run, the :manual:`ctest <ctest(1)>` executable will
+read this file to gather information about the testing dashboard. It contains:
* The project name
@@ -41,9 +48,10 @@ project. It contains:
* The URL of the CDash instance where the submission's generated documents
will be sent
-One has been provided for you in this directory. It would normally be
-downloaded from the ``Settings`` page of the project on the CDash
-instance that will host and display the test results. Once downloaded from
+For this tutorial, a public dashboard server is used and its corresponding
+``CTestConfig.cmake`` file is provided for you in this step's root directory.
+In practice, this file would be downloaded from a project's ``Settings`` page
+on the CDash instance intended to host the test results. Once downloaded from
CDash, the file should not be modified locally.
.. literalinclude:: Step7/CTestConfig.cmake
@@ -51,11 +59,16 @@ CDash, the file should not be modified locally.
:name: CTestConfig.cmake
:language: cmake
-The :manual:`ctest <ctest(1)>` executable will read in this file when it runs.
-To create a simple dashboard you can run the :manual:`cmake <cmake(1)>`
-executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project,
-but do not build it yet. Instead, change directory to the binary tree, and then
-run:
+
+Build and Run
+-------------
+
+Note that as part of the CDash submission some information about your
+development system (e.g. site name or full pathnames) may displayed publicly.
+
+To create a simple test dashboard, run the :manual:`cmake <cmake(1)>`
+executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
+but do not build it yet. Instead, navigate to the build directory and run:
.. code-block:: console
@@ -70,6 +83,28 @@ type must be specified:
Or, from an IDE, build the ``Experimental`` target.
-The :manual:`ctest <ctest(1)>` executable will build and test the project and
-submit the results to Kitware's public dashboard:
+The :manual:`ctest <ctest(1)>` executable will build the project, run any
+tests, and submit the results to Kitware's public dashboard:
https://my.cdash.org/index.php?project=CMakeTutorial.
+
+Solution
+--------
+
+The only CMake code changed needed in this step was to enable dashboard
+submissions to CDash by including the :module:`CTest` module in our top-level
+``CMakeLists.txt``:
+
+.. raw:: html
+
+ <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/CMakeLists.txt
+ :caption: TODO 1: CMakeLists.txt
+ :name: CMakeLists.txt-include-CTest
+ :language: cmake
+ :start-after: # enable testing
+ :end-before: # does the application run
+
+.. raw:: html
+
+ </details>
diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst
index ba91df4..b69abd2 100644
--- a/Help/guide/tutorial/Adding System Introspection.rst
+++ b/Help/guide/tutorial/Adding System Introspection.rst
@@ -7,53 +7,156 @@ depends on whether or not the target platform has the ``log`` and ``exp``
functions. Of course almost every platform has these functions but for this
tutorial assume that they are not common.
-If the platform has ``log`` and ``exp`` then we will use them to compute the
-square root in the ``mysqrt`` function. We first test for the availability of
-these functions using the :module:`CheckCXXSourceCompiles` module in
+Exercise 1 - Assessing Dependency Availability
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Goal
+----
+
+Change implementation based on available system dependencies.
+
+Helpful Resources
+-----------------
+
+* :module:`CheckCXXSourceCompiles`
+* :command:`target_compile_definitions`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/mysqrt.cxx``
+
+Getting Started
+---------------
+
+The starting source code is provided in the ``Step7`` directory. In this
+exercise, complete ``TODO 1`` through ``TODO 5``.
+
+Start by editing ``MathFunctions/CMakeLists.txt``. Include the
+:module:`CheckCXXSourceCompiles` module. Then, use
+``check_cxx_source_compiles`` to determine whether ``log`` and ``exp`` are
+available from ``cmath``. If they are available, use
+:command:`target_compile_definitions` to specify ``HAVE_LOG`` and ``HAVE_EXP``
+as compile definitions.
+
+In the ``MathFunctions/mysqrt.cxx``, include ``cmath``. Then, if the system has
+``log`` and ``exp``, use them to compute the square root.
+
+Build and Run
+-------------
+
+Make a new directory called ``Step7_build``. Run the
+:manual:`cmake <cmake(1)>` executable or the
+:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
+with your chosen build tool and run the ``Tutorial`` executable.
+
+This can look like the following:
+
+.. code-block:: console
+
+ mkdir Step7_build
+ cd Step7_build
+ cmake ../Step7
+ cmake --build .
+
+Which function gives better results now, ``sqrt`` or ``mysqrt``?
+
+Solution
+--------
+
+In this exercise we will use functions from the
+:module:`CheckCXXSourceCompiles` module so first we must include it in
``MathFunctions/CMakeLists.txt``.
-Add the checks for ``log`` and ``exp`` to ``MathFunctions/CMakeLists.txt``,
-after the call to :command:`target_include_directories`:
+.. raw:: html
+
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
- :caption: MathFunctions/CMakeLists.txt
+ :caption: TODO 1: MathFunctions/CMakeLists.txt
+ :name: MathFunctions/CMakeLists.txt-include-check_cxx_source_compiles
+ :language: cmake
+ :start-after: # does this system provide the log and exp functions?
+ :end-before: check_cxx_source_compiles
+
+.. raw:: html
+
+ </details>
+
+Then test for the availability of
+``log`` and ``exp`` using ``check_cxx_compiles_source``. This function
+lets us try compiling simple code with the required dependency prior to
+the true source code compilation. The resulting variables ``HAVE_LOG``
+and ``HAVE_EXP`` represent whether those dependencies are available.
+
+.. raw:: html
+
+ <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
+ :caption: TODO 2: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-check_cxx_source_compiles
:language: cmake
- :start-after: # to find MathFunctions.h, while we don't.
+ :start-after: include(CheckCXXSourceCompiles)
:end-before: # add compile definitions
-If available, use :command:`target_compile_definitions` to specify
+.. raw:: html
+
+ </details>
+
+Next, we need to pass these CMake variables to our source code. This way,
+our source code can tell what resources are available. If both ``log`` and
+``exp`` are available, use :command:`target_compile_definitions` to specify
``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions.
+.. raw:: html
+
+ <details><summary>TODO 3: Click to show/hide answer</summary>
+
.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
- :caption: MathFunctions/CMakeLists.txt
+ :caption: TODO 3: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_compile_definitions
:language: cmake
:start-after: # add compile definitions
:end-before: # install libs
-If ``log`` and ``exp`` are available on the system, then we will use them to
-compute the square root in the ``mysqrt`` function. Add the following code to
-the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the
-``#endif`` before returning the result!):
+.. raw:: html
-.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
- :caption: MathFunctions/mysqrt.cxx
- :name: MathFunctions/mysqrt.cxx-ifdef
- :language: c++
- :start-after: // if we have both log and exp then use them
- :end-before: // do ten iterations
+ </details>
+
+Since we may be using ``log`` and ``exp``, we need to modify
+``mysqrt.cxx`` to include ``cmath``.
+
+.. raw:: html
-We will also need to modify ``mysqrt.cxx`` to include ``cmath``.
+ <details><summary>TODO 4: Click to show/hide answer</summary>
.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
- :caption: MathFunctions/mysqrt.cxx
+ :caption: TODO 4: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-include-cmath
:language: c++
:end-before: #include <iostream>
-Run the :manual:`cmake <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool and run the Tutorial executable.
+.. raw:: html
-Which function gives better results now, ``sqrt`` or ``mysqrt``?
+ </details>
+
+If ``log`` and ``exp`` are available on the system, then use them to
+compute the square root in the ``mysqrt`` function. The ``mysqrt`` function in
+``MathFunctions/mysqrt.cxx`` will look as follows:
+
+.. raw:: html
+
+ <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
+ :caption: TODO 5: MathFunctions/mysqrt.cxx
+ :name: MathFunctions/mysqrt.cxx-ifdef
+ :language: c++
+ :start-after: // if we have both log and exp then use them
+ :end-before: // do ten iterations
+
+.. raw:: html
+
+ </details>
diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst
index fa13040..aa3fb74 100644
--- a/Help/guide/tutorial/Installing and Testing.rst
+++ b/Help/guide/tutorial/Installing and Testing.rst
@@ -145,7 +145,7 @@ are similar. To the end of the top-level ``CMakeLists.txt`` we add:
:name: TODO 3,4: CMakeLists.txt-install-TARGETS
:language: cmake
:start-after: # add the install targets
- :end-before: # enable testing
+ :end-before: # TODO 1: Replace enable_testing() with include(CTest)
.. raw:: html
@@ -195,7 +195,7 @@ Build and Run
-------------
Navigate to the build directory and rebuild the application. Then, run the
-``ctest`` executable: :option:`ctest -N` and :option:`ctest -VV`. For
+:program:`ctest` executable: :option:`ctest -N` and :option:`ctest -VV`. For
multi-config generators (e.g. Visual Studio), the configuration type must be
specified with the :option:`-C \<mode\> <ctest -C>` flag. For example, to run tests in Debug
mode use ``ctest -C Debug -VV`` from the build directory
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index da9e852..c11e307 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -45,6 +45,7 @@ install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include
)
+# TODO 1: Replace enable_testing() with include(CTest)
# enable testing
enable_testing()
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index b4724c4..e5bdc4d 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -9,6 +9,26 @@ target_include_directories(MathFunctions
# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
+# TODO 1: Include CheckCXXSourceCompiles
+
+# TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
+# availability of:
+# * std::log
+# * std::exp
+# Store the results in HAVE_LOG and HAVE_EXP respectively.
+
+# Hint: Sample C++ code which uses log:
+# #include <cmath>
+# int main() {
+# std::log(1.0);
+# return 0;
+# }
+
+# TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
+# definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
+
+#Hint: Use target_compile_definitions()
+
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
install(TARGETS ${installable_libs} DESTINATION lib)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
index abe767d..3d2492a 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
@@ -1,5 +1,6 @@
#include <iostream>
+// TODO 4: include cmath
#include "MathFunctions.h"
// a hack square root calculation using simple operations
@@ -9,6 +10,14 @@ double mysqrt(double x)
return 0;
}
+ // TODO 5: If both HAVE_LOG and HAVE_EXP are defined, use the following:
+ //// double result = std::exp(std::log(x) * 0.5);
+ //// std::cout << "Computing sqrt of " << x << " to be " << result
+ //// << " using log and exp" << std::endl;
+ // else, use the existing logic.
+
+ // Hint: Don't forget the #endif before returning the result!
+
double result = x;
// do ten iterations
@@ -20,5 +29,6 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
+
return result;
}
diff --git a/Help/manual/ccmake.1.rst b/Help/manual/ccmake.1.rst
index cd66d51..a09857b 100644
--- a/Help/manual/ccmake.1.rst
+++ b/Help/manual/ccmake.1.rst
@@ -13,7 +13,7 @@ Synopsis
Description
===========
-The **ccmake** executable is the CMake curses interface. Project
+The :program:`ccmake` executable is the CMake curses interface. Project
configuration settings may be specified interactively through this
GUI. Brief instructions are provided at the bottom of the terminal
when the program is running.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index b14160c..07e55cf 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -119,7 +119,7 @@ Object Libraries
The ``OBJECT`` library type defines a non-archival collection of object files
resulting from compiling the given source files. The object files collection
may be used as source inputs to other targets by using the syntax
-``$<TARGET_OBJECTS:name>``. This is a
+:genex:`$<TARGET_OBJECTS:name>`. This is a
:manual:`generator expression <cmake-generator-expressions(7)>` that can be
used to supply the ``OBJECT`` library content to other targets:
@@ -854,7 +854,7 @@ the generator used. For example:
In the presence of :prop_tgt:`IMPORTED` targets, the content of
:prop_tgt:`MAP_IMPORTED_CONFIG_DEBUG <MAP_IMPORTED_CONFIG_<CONFIG>>` is also
-accounted for by the above ``$<CONFIG:Debug>`` expression.
+accounted for by the above :genex:`$<CONFIG:Debug>` expression.
Case Sensitivity
@@ -862,7 +862,7 @@ Case Sensitivity
:variable:`CMAKE_BUILD_TYPE` and :variable:`CMAKE_CONFIGURATION_TYPES` are
just like other variables in that any string comparisons made with their
-values will be case-sensitive. The ``$<CONFIG>`` generator expression also
+values will be case-sensitive. The :genex:`$<CONFIG>` generator expression also
preserves the casing of the configuration as set by the user or CMake defaults.
For example:
@@ -887,7 +887,7 @@ For example:
In contrast, CMake treats the configuration type case-insensitively when
using it internally in places that modify behavior based on the configuration.
-For example, the ``$<CONFIG:Debug>`` generator expression will evaluate to 1
+For example, the :genex:`$<CONFIG:Debug>` generator expression will evaluate to 1
for a configuration of not only ``Debug``, but also ``DEBUG``, ``debug`` or
even ``DeBuG``. Therefore, you can specify configuration types in
:variable:`CMAKE_BUILD_TYPE` and :variable:`CMAKE_CONFIGURATION_TYPES` with
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index 0f3c30a..a09bd14 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -560,7 +560,7 @@ The ``RELEASE`` variant should be listed first in the property
so that the variant is chosen if the user uses a configuration which is
not an exact match for any listed ``IMPORTED_CONFIGURATIONS``.
-Most of the cache variables should be hidden in the ``ccmake`` interface unless
+Most of the cache variables should be hidden in the :program:`ccmake` interface unless
the user explicitly asks to edit them.
.. code-block:: cmake
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 4b8ac65..65c5239 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -258,8 +258,8 @@ The members are:
``paths``
A JSON object specifying paths to things that come with CMake.
- It has members for ``cmake``, ``ctest``, and ``cpack`` whose values
- are JSON strings specifying the absolute path to each tool,
+ It has members for :program:`cmake`, :program:`ctest`, and :program:`cpack`
+ whose values are JSON strings specifying the absolute path to each tool,
represented with forward slashes. It also has a ``root`` member for
the absolute path to the directory containing CMake resources like the
``Modules/`` directory (see :variable:`CMAKE_ROOT`).
@@ -425,7 +425,7 @@ Version 1 does not exist to avoid confusion with that from
{
"kind": "codemodel",
- "version": { "major": 2, "minor": 4 },
+ "version": { "major": 2, "minor": 5 },
"paths": {
"source": "/path/to/top-level-source-dir",
"build": "/path/to/top-level-build-dir"
@@ -1071,6 +1071,27 @@ with members:
available. The value is an unsigned integer 0-based index into
the ``backtraceGraph`` member's ``nodes`` array.
+``fileSets``
+ A JSON array of entries corresponding to the target's file sets. Each entry
+ is a JSON object with members:
+
+ ``name``
+ A string specifying the name of the file set.
+
+ ``type``
+ A string specifying the type of the file set. See
+ :command:`target_sources` supported file set types.
+
+ ``visibility``
+ A string specifying the visibility of the file set; one of ``PUBLIC``,
+ ``PRIVATE``, or ``INTERFACE``.
+
+ ``baseDirectories``
+ A JSON array of strings specifying the base directories containing sources
+ in the file set.
+
+ This field was added in codemodel version 2.5.
+
``sources``
A JSON array of entries corresponding to the target's source files.
Each entry is a JSON object with members:
@@ -1096,6 +1117,13 @@ with members:
Optional member that is present with boolean value ``true`` if
the source is :prop_sf:`GENERATED`.
+ ``fileSetIndex``
+ Optional member that is present when the source is part of a file set.
+ The value is an unsigned integer 0-based index into the ``fileSets``
+ array.
+
+ This field was added in codemodel version 2.5.
+
``backtrace``
Optional member that is present when a CMake language backtrace to
the :command:`target_sources`, :command:`add_executable`,
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 69e3f20..faa793f 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -142,9 +142,9 @@ to generate debug messages is to add a custom target:
add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$<...>")
-After running ``cmake``, you can then build the ``genexdebug`` target to print
+After running :program:`cmake`, you can then build the ``genexdebug`` target to print
the result of the ``$<...>`` expression (i.e. run the command
-``cmake --build ... --target genexdebug``).
+:option:`cmake --build ... --target genexdebug <cmake--build --target>`).
Another way is to write debug messages to a file with :command:`file(GENERATE)`:
diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst
index dd0eeca..cdb860f 100644
--- a/Help/manual/cmake-gui.1.rst
+++ b/Help/manual/cmake-gui.1.rst
@@ -16,7 +16,7 @@ Synopsis
Description
===========
-The **cmake-gui** executable is the CMake GUI. Project configuration
+The :program:`cmake-gui` executable is the CMake GUI. Project configuration
settings may be specified interactively. Brief instructions are
provided at the bottom of the window when the program is running.
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
index 0bd561f..a0d872f 100644
--- a/Help/manual/cmake-language.7.rst
+++ b/Help/manual/cmake-language.7.rst
@@ -37,10 +37,10 @@ Scripts
An individual ``<script>.cmake`` source file may be processed
in *script mode* by using the :manual:`cmake(1)` command-line tool
-with the ``-P`` option. Script mode simply runs the commands in
-the given CMake Language source file and does not generate a
-build system. It does not allow CMake commands that define build
-targets or actions.
+with the :option:`-P <cmake -P>` option. Script mode simply runs
+the commands in the given CMake Language source file and does not
+generate a build system. It does not allow CMake commands that
+define build targets or actions.
Modules
-------
@@ -206,7 +206,7 @@ enclosed content, such as `Escape Sequences`_ or `Variable References`_,
is performed. A bracket argument is always given to the command
invocation as exactly one argument.
-.. No code-block syntax highlighting in the following example
+.. ATTENTION No code-block syntax highlighting in the following example
(long string literal not supported by our cmake.py)
For example::
@@ -254,7 +254,7 @@ closing quotes. Both `Escape Sequences`_ and `Variable References`_
are evaluated. A quoted argument is always given to the command
invocation as exactly one argument.
-.. No code-block syntax highlighting in the following example
+.. ATTENTION No code-block syntax highlighting in the following example
(escape \" not supported by our cmake.py)
For example:
@@ -268,7 +268,7 @@ For example:
It does end in an unescaped double quote.
")
-.. No code-block syntax highlighting in the following example
+.. ATTENTION No code-block syntax highlighting in the following example
(for conformity with the two above examples)
The final ``\`` on any line ending in an odd number of backslashes
@@ -542,8 +542,8 @@ Directory Scope
bindings. Before processing the ``CMakeLists.txt`` file for a
directory, CMake copies all variable bindings currently defined
in the parent directory, if any, to initialize the new directory
- scope. CMake `Scripts`_, when processed with ``cmake -P``, bind
- variables in one "directory" scope.
+ scope. CMake `Scripts`_, when processed with :option:`cmake -P`,
+ bind variables in one "directory" scope.
A variable "set" or "unset" not inside a function call binds
to the current directory scope.
@@ -597,11 +597,11 @@ Initialization
Changed values are not written back to the calling process,
and they are not seen by subsequent build or test processes.
- See the :ref:`cmake -E env <Run a Command-Line Tool>` command-line
+ See the :option:`cmake -E env <cmake-E env>` command-line
tool to run a command in a modified environment.
Inspection
- See the :ref:`cmake -E environment <Run a Command-Line Tool>` command-line
+ See the :option:`cmake -E environment <cmake-E environment>` command-line
tool to display all current environment variables.
The :manual:`cmake-env-variables(7)` manual documents environment
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index d6a30ff..22e9eb2 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,13 @@ 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.26
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0143: USE_FOLDERS global property is treated as ON by default. </policy/CMP0143>
Policies Introduced by CMake 3.25
=================================
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index b31ad11..dc51383 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -39,20 +39,20 @@ Synopsis
Description
===========
-The **cmake** executable is the command-line interface of the cross-platform
+The :program:`cmake` executable is the command-line interface of the cross-platform
buildsystem generator CMake. The above `Synopsis`_ lists various actions
the tool can perform as described in sections below.
To build a software project with CMake, `Generate a Project Buildsystem`_.
-Optionally use **cmake** to `Build a Project`_, `Install a Project`_ or just
-run the corresponding build tool (e.g. ``make``) directly. **cmake** can also
+Optionally use :program:`cmake` to `Build a Project`_, `Install a Project`_ or just
+run the corresponding build tool (e.g. ``make``) directly. :program:`cmake` can also
be used to `View Help`_.
The other actions are meant for use by software developers writing
scripts in the :manual:`CMake language <cmake-language(7)>` to support
their builds.
-For graphical user interfaces that may be used in place of **cmake**,
+For graphical user interfaces that may be used in place of :program:`cmake`,
see :manual:`ccmake <ccmake(1)>` and :manual:`cmake-gui <cmake-gui(1)>`.
For command-line interfaces to the CMake testing and packaging facilities,
see :manual:`ctest <ctest(1)>` and :manual:`cpack <cpack(1)>`.
@@ -193,7 +193,7 @@ build tool to build the project. For example, after using the
$ make
$ make install
-Alternatively, one may use **cmake** to `Build a Project`_ by
+Alternatively, one may use :program:`cmake` to `Build a Project`_ by
automatically choosing and invoking the appropriate native build tool.
.. _`CMake Options`:
@@ -362,9 +362,8 @@ Options
separated by a newline ( ``\n`` ). It is guaranteed that no
newline characters will be present inside a JSON document.
- JSON trace format:
-
.. code-block:: json
+ :caption: JSON trace format
{
"file": "/full/path/to/the/CMake/file.txt",
@@ -417,9 +416,8 @@ Options
Additionally, the first JSON document outputted contains the
``version`` key for the current major and minor version of the
- JSON trace format:
-
.. code-block:: json
+ :caption: JSON version format
{
"version": {
@@ -850,17 +848,21 @@ Available commands are:
.. program:: cmake-E
-.. option:: copy <file>... <destination>
+.. option:: copy <file>... <destination>, copy -t <destination> <file>...
Copy files to ``<destination>`` (either file or directory).
- If multiple files are specified, the ``<destination>`` must be
- directory and it must exist. Wildcards are not supported.
- ``copy`` does follow symlinks. That means it does not copy symlinks,
- but the files or directories it point to.
+ If multiple files are specified, or if ``-t`` is specified, the
+ ``<destination>`` must be directory and it must exist. If ``-t`` is not
+ specified, the last argument is assumed to be the ``<destination>``.
+ Wildcards are not supported. ``copy`` does follow symlinks. That means it
+ does not copy symlinks, but the files or directories it point to.
.. versionadded:: 3.5
Support for multiple input files.
+ .. versionadded:: 3.26
+ Support for ``-t`` argument.
+
.. option:: copy_directory <dir>... <destination>
Copy content of ``<dir>...`` directories to ``<destination>`` directory.
@@ -939,7 +941,7 @@ Available commands are:
The ``NAME=VALUE`` and ``--unset=NAME`` options are equivalent to
``--modify NAME=set:VALUE`` and ``--modify NAME=unset:``, respectively.
Note that ``--modify NAME=reset:`` resets ``NAME`` to the value it had
- when ``cmake`` launched (or unsets it), not to the most recent
+ when :program:`cmake` launched (or unsets it), not to the most recent
``NAME=VALUE`` option.
.. option:: --
@@ -1319,7 +1321,7 @@ To view the presets available for a project, use
Return Value (Exit Code)
========================
-Upon regular termination, the ``cmake`` executable returns the exit code ``0``.
+Upon regular termination, the :program:`cmake` executable returns the exit code ``0``.
If termination is caused by the command :command:`message(FATAL_ERROR)`,
or another error condition, then a non-zero exit code is returned.
diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst
index 3f26d72..1a101a4 100644
--- a/Help/manual/cpack.1.rst
+++ b/Help/manual/cpack.1.rst
@@ -13,10 +13,10 @@ Synopsis
Description
===========
-The **cpack** executable is the CMake packaging program. It generates
+The :program:`cpack` executable is the CMake packaging program. It generates
installers and source packages in a variety of formats.
-For each installer or package format, **cpack** has a specific backend,
+For each installer or package format, :program:`cpack` has a specific backend,
called "generator". A generator is responsible for generating the required
inputs and invoking the specific package creation tools. These installer
or package generators are not to be confused with the makefile generators
@@ -28,7 +28,7 @@ list of generators supported for the target platform. Which of them are
to be used can be selected through the :variable:`CPACK_GENERATOR` variable
or through the command-line option :option:`-G <cpack -G>`.
-The **cpack** program is steered by a configuration file written in the
+The :program:`cpack` program is steered by a configuration file written in the
:manual:`CMake language <cmake-language(7)>`. Unless chosen differently
through the command-line option :option:`--config <cpack --config>`, the
file ``CPackConfig.cmake`` in the current directory is used.
@@ -45,7 +45,7 @@ Options
.. option:: -G <generators>
``<generators>`` is a :ref:`semicolon-separated list <CMake Language Lists>`
- of generator names. ``cpack`` will iterate through this list and produce
+ of generator names. :program:`cpack` will iterate through this list and produce
package(s) in that generator's format according to the details provided in
the ``CPackConfig.cmake`` configuration file. If this option is not given,
the :variable:`CPACK_GENERATOR` variable determines the default set of
@@ -58,30 +58,30 @@ Options
:ref:`semicolon-separated list <CMake Language Lists>`.
When the CMake project uses a multi-configuration
generator such as Xcode or Visual Studio, this option is needed to tell
- ``cpack`` which built executables to include in the package.
+ :program:`cpack` which built executables to include in the package.
The user is responsible for ensuring that the configuration(s) listed
- have already been built before invoking ``cpack``.
+ have already been built before invoking :program:`cpack`.
.. option:: -D <var>=<value>
Set a CPack variable. This will override any value set for ``<var>`` in the
- input file read by ``cpack``.
+ input file read by :program:`cpack`.
.. option:: --config <configFile>
- Specify the configuration file read by ``cpack`` to provide the packaging
+ Specify the configuration file read by :program:`cpack` to provide the packaging
details. By default, ``CPackConfig.cmake`` in the current directory will
be used.
.. option:: -V, --verbose
- Run ``cpack`` with verbose output. This can be used to show more details
+ Run :program:`cpack` with verbose output. This can be used to show more details
from the package generation tools and is suitable for project developers.
.. option:: --debug
- Run ``cpack`` with debug output. This option is intended mainly for the
- developers of ``cpack`` itself and is not normally needed by project
+ Run :program:`cpack` with debug output. This option is intended mainly for the
+ developers of :program:`cpack` itself and is not normally needed by project
developers.
.. option:: --trace
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 3497a9f..30a9eae 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -32,7 +32,7 @@ Synopsis
Description
===========
-The **ctest** executable is the CMake test driver program.
+The :program:`ctest` executable is the CMake test driver program.
CMake-generated build trees created for projects that use the
:command:`enable_testing` and :command:`add_test` commands have testing support.
This program will run the tests and report results.
@@ -69,7 +69,7 @@ Run Tests
Enable short progress output from tests.
- When the output of **ctest** is being sent directly to a terminal, the
+ When the output of :program:`ctest` is being sent directly to a terminal, the
progress through the set of tests is reported by updating the same line
rather than printing start and end messages for each test on new lines.
This can significantly reduce the verbosity of the test output.
@@ -137,7 +137,7 @@ Run Tests
:ref:`resource specification file <ctest-resource-specification-file>`
specified in ``<file>``.
- When ``ctest`` is run as a `Dashboard Client`_ this sets the
+ When :program:`ctest` is run as a `Dashboard Client`_ this sets the
``ResourceSpecFile`` option of the `CTest Test Step`_.
.. option:: --test-load <level>
@@ -146,7 +146,7 @@ Run Tests
not to start tests when they may cause the CPU load to pass above a given
threshold.
- When ``ctest`` is run as a `Dashboard Client`_ this sets the
+ When :program:`ctest` is run as a `Dashboard Client`_ this sets the
``TestLoad`` option of the `CTest Test Step`_.
.. option:: -Q, --quiet
@@ -473,7 +473,7 @@ with the following labels:
* *test4* has label *wednesday*
* *test5* has labels *friday* and *test*
-Running ``ctest`` with ``-L tuesday -L test`` will select *test2*, which has
+Running :program:`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.
@@ -832,7 +832,7 @@ Dashboard Client via CTest Command-Line
---------------------------------------
CTest can perform testing on an already-generated build tree.
-Run the ``ctest`` command with the current working directory set
+Run the :program:`ctest` command with the current working directory set
to the build tree and use one of these signatures::
ctest -D <mode>[<step>]
@@ -865,7 +865,7 @@ Dashboard Client via CTest Script
CTest can perform testing driven by a :manual:`cmake-language(7)`
script that creates and maintains the source and build tree as
-well as performing the testing steps. Run the ``ctest`` command
+well as performing the testing steps. Run the :program:`ctest` command
with the current working directory set outside of any build tree
and use one of these signatures::
@@ -1142,7 +1142,7 @@ Configuration settings include:
When the build system to be launched allows build-time selection
of the configuration (e.g. ``Debug``, ``Release``), this specifies
the default configuration to be built when no :option:`-C <ctest -C>`
- option is given to the ``ctest`` command. The value will be substituted
+ option is given to the :program:`ctest` command. The value will be substituted
into the value of ``MakeCommand`` to replace the literal string
``${CTEST_CONFIGURATION_TYPE}`` if it appears.
@@ -1624,7 +1624,7 @@ resource allocation feature. Tests should check the
resource allocation is activated. This variable will always (and only) be
defined if resource allocation is activated. If resource allocation is not
activated, then the ``CTEST_RESOURCE_GROUP_COUNT`` variable will not exist,
-even if it exists for the parent ``ctest`` process. If a test absolutely must
+even if it exists for the parent :program:`ctest` process. If a test absolutely must
have resource allocation, then it can return a failing exit code or use the
:prop_test:`SKIP_RETURN_CODE` or :prop_test:`SKIP_REGULAR_EXPRESSION`
properties to indicate a skipped test.
diff --git a/Help/policy/CMP0143.rst b/Help/policy/CMP0143.rst
new file mode 100644
index 0000000..7a7aee7
--- /dev/null
+++ b/Help/policy/CMP0143.rst
@@ -0,0 +1,30 @@
+CMP0143
+-------
+
+.. versionadded:: 3.26
+
+:prop_gbl:`USE_FOLDERS` global property is treated as ``ON`` by default.
+
+When using CMake 3.25 and below, :prop_gbl:`USE_FOLDERS` is treated
+as ``OFF`` by default unless projects enable the feature. For example:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.25)
+ project(foobar LANGUAGES CXX)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+CMake 3.26 and later prefer to enable the feature by default.
+
+This policy provides compatibility with projects that have not been updated
+to expect enabling of folders. Enabling folders causes projects to appear
+differently in IDEs.
+
+This policy was introduced in CMake version 3.26. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+The policy setting must be in scope at the end of the top-level
+``CMakeLists.txt`` file of the project and has global effect.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_gbl/USE_FOLDERS.rst b/Help/prop_gbl/USE_FOLDERS.rst
index 5919723..965b5d6 100644
--- a/Help/prop_gbl/USE_FOLDERS.rst
+++ b/Help/prop_gbl/USE_FOLDERS.rst
@@ -4,7 +4,16 @@ USE_FOLDERS
Use the :prop_tgt:`FOLDER` target property to organize targets into
folders.
-If not set, CMake treats this property as ``OFF`` by default. CMake
-generators that are capable of organizing into a hierarchy of folders
+.. versionchanged:: 3.26
+
+ CMake treats this property as ``ON`` by default.
+ See policy :policy:`CMP0143`.
+
+CMake generators that are capable of organizing into a hierarchy of folders
use the values of the :prop_tgt:`FOLDER` target property to name those
-folders. See also the documentation for the :prop_tgt:`FOLDER` target property.
+folders. (i.e.: Visual Studio / XCode)
+
+IDE's can also take advantage of this property to organize CMake targets.
+Regardless of generator support.
+
+See also the documentation for the :prop_tgt:`FOLDER` target property.
diff --git a/Help/prop_test/LABELS.rst b/Help/prop_test/LABELS.rst
index d827adc..02e2fae 100644
--- a/Help/prop_test/LABELS.rst
+++ b/Help/prop_test/LABELS.rst
@@ -2,7 +2,7 @@ LABELS
------
Specify a list of text labels associated with a test. The labels are
-reported in both the ``ctest`` output summary and in dashboard submissions.
+reported in both the :program:`ctest` output summary and in dashboard submissions.
They can also be used to filter the set of tests to be executed (see the
:option:`ctest -L` and :option:`ctest -LE` options).
diff --git a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
index adfa6f7..7ce0023 100644
--- a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
+++ b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
@@ -7,13 +7,30 @@ By setting this target property, the target is configured to build with
``C++/CLI`` support.
The Visual Studio generator defines the ``clr`` parameter depending on
-the value of ``COMMON_LANGUAGE_RUNTIME``:
+the value of the ``COMMON_LANGUAGE_RUNTIME`` target property:
-* property not set: native C++ (i.e. default)
-* property set but empty: mixed unmanaged/managed C++
-* property set to any non empty value: managed C++
+Not Set (default)
-Supported values: ``""``, ``"pure"``, ``"safe"``
+ Native C++.
+
+``""`` (set but empty)
+
+ Mixed unmanaged/managed C++ using .NET Framework.
+
+``netcore``
+ .. versionadded:: 3.26
+
+ Mixed unmanaged/managed C++ using .NET Core.
+
+ This required VS 2019's v142 toolset or higher.
+
+``pure``
+
+ Managed C++.
+
+``safe``
+
+ Managed C++.
This property is only evaluated :ref:`Visual Studio Generators` for
VS 2010 and above.
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst
index c74a319..9cc12a1 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst
@@ -5,5 +5,4 @@ INTERFACE_COMPILE_DEFINITIONS
.. |command_name| replace:: :command:`target_compile_definitions`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_DEFINITIONS``
.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_DEFINITIONS`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
index 0db3b0c..50d6161 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -7,7 +7,6 @@ INTERFACE_COMPILE_FEATURES
.. |command_name| replace:: :command:`target_compile_features`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_FEATURES``
.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_FEATURES`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_FEATURES>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
See the :manual:`cmake-compile-features(7)` manual for information on compile
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst
index 7f0b385..2af7a99 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst
@@ -5,5 +5,4 @@ INTERFACE_COMPILE_OPTIONS
.. |command_name| replace:: :command:`target_compile_options`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_OPTIONS``
.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_OPTIONS`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst
index b1c40b2..8795c80 100644
--- a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst
+++ b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst
@@ -5,7 +5,6 @@ INTERFACE_INCLUDE_DIRECTORIES
.. |command_name| replace:: :command:`target_include_directories`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_INCLUDE_DIRECTORIES``
.. |PROPERTY_LINK| replace:: :prop_tgt:`INCLUDE_DIRECTORIES`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
Include directories usage requirements commonly differ between the build-tree
diff --git a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
index de1dabb..45b3225 100644
--- a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
@@ -7,5 +7,4 @@ INTERFACE_LINK_DIRECTORIES
.. |command_name| replace:: :command:`target_link_directories`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_DIRECTORIES``
.. |PROPERTY_LINK| replace:: :prop_tgt:`LINK_DIRECTORIES`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_LINK_DIRECTORIES>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
index 4245fe9..785b17c 100644
--- a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -7,5 +7,4 @@ INTERFACE_LINK_OPTIONS
.. |command_name| replace:: :command:`target_link_options`
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS``
.. |PROPERTY_LINK| replace:: :prop_tgt:`LINK_OPTIONS`
-.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_LINK_OPTIONS>``
.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst
index 27eadf9..7c37122 100644
--- a/Help/prop_tgt/LINK_OPTIONS.rst
+++ b/Help/prop_tgt/LINK_OPTIONS.rst
@@ -9,8 +9,8 @@ libraries need to use the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
These options are used for both normal linking and device linking
(see policy :policy:`CMP0105`). To control link options for normal and device
-link steps, ``$<HOST_LINK>`` and ``$<DEVICE_LINK>``
-:manual:`generator expressions <cmake-generator-expressions(7)>` can be used.
+link steps, :genex:`$<HOST_LINK>` and ::genex:`$<DEVICE_LINK>` generator
+expressions can be used.
This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of
options specified so far for its target. Use the :command:`target_link_options`
diff --git a/Help/release/3.15.rst b/Help/release/3.15.rst
index 6b1a800..de3ced0 100644
--- a/Help/release/3.15.rst
+++ b/Help/release/3.15.rst
@@ -243,46 +243,42 @@ Modules
Generator Expressions
---------------------
-* The :manual:`generator expressions <cmake-generator-expressions(7)>`
- ``C_COMPILER_ID``, ``CXX_COMPILER_ID``, ``CUDA_COMPILER_ID``,
- ``Fortran_COMPILER_ID``, ``COMPILE_LANGUAGE``, ``COMPILE_LANG_AND_ID``, and
- ``PLATFORM_ID`` learned to support matching one value from a comma-separated
- list.
+* The generator expressions :genex:`$<C_COMPILER_ID>`,
+ :genex:`$<CXX_COMPILER_ID>`, :genex:`$<CUDA_COMPILER_ID>`,
+ :genex:`$<Fortran_COMPILER_ID>`, :genex:`$<COMPILE_LANGUAGE>`,
+ :genex:`$<COMPILE_LANG_AND_ID>`, and :genex:`$<PLATFORM_ID>` learned to
+ support matching one value from a comma-separated list.
-* The ``$<CUDA_COMPILER_ID:...>`` and ``$<CUDA_COMPILER_VERSION:...>``
- :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
+* The :genex:`$<CUDA_COMPILER_ID:...>` and :genex:`$<CUDA_COMPILER_VERSION:...>`
+ generator expressions were added.
-* The ``$<COMPILE_LANG_AND_ID:...>`` generator expression was introduced to
+* The :genex:`$<COMPILE_LANG_AND_ID:...>` generator expression was introduced to
allow specification of compile options for target files based on the
:variable:`CMAKE_<LANG>_COMPILER_ID` and :prop_sf:`LANGUAGE` of
each source file.
-* A ``$<FILTER:list,INCLUDE|EXCLUDE,regex>``
- :manual:`generator expression <cmake-generator-expressions(7)>`
- has been added.
+* A :genex:`$<FILTER:list,INCLUDE|EXCLUDE,regex>` generator expression has
+ been added.
-* A ``$<REMOVE_DUPLICATES:list>``
- :manual:`generator expression <cmake-generator-expressions(7)>`
- has been added.
+* A :genex:`$<REMOVE_DUPLICATES:list>` generator expression has been added.
-* The ``$<SHELL_PATH:...>`` :manual:`generator expression
- <cmake-generator-expressions(7)>` gained support for a list of paths.
+* The :genex:`$<SHELL_PATH:...>` generator expression gained support for a
+ list of paths.
* New ``$<TARGET_FILE*>`` :manual:`generator expressions
<cmake-generator-expressions(7)>` were added to retrieve the prefix, base
name, and suffix of the file names of various artifacts:
- * ``$<TARGET_FILE_PREFIX:...>``
- * ``$<TARGET_FILE_BASE_NAME:...>``
- * ``$<TARGET_FILE_SUFFIX:...>``
- * ``$<TARGET_LINKER_FILE_PREFIX:...>``
- * ``$<TARGET_LINKER_FILE_BASE_NAME:...>``
- * ``$<TARGET_LINKER_FILE_SUFFIX:...>``
- * ``$<TARGET_PDB_FILE_BASE_NAME:...>``
-
-* The ``$<TARGET_OBJECTS:...>`` :manual:`generator expression
- <cmake-generator-expressions(7)>` is now supported on ``SHARED``,
- ``STATIC``, ``MODULE`` libraries and executables.
+ * :genex:`$<TARGET_FILE_PREFIX:...>`
+ * :genex:`$<TARGET_FILE_BASE_NAME:...>`
+ * :genex:`$<TARGET_FILE_SUFFIX:...>`
+ * :genex:`$<TARGET_LINKER_FILE_PREFIX:...>`
+ * :genex:`$<TARGET_LINKER_FILE_BASE_NAME:...>`
+ * :genex:`$<TARGET_LINKER_FILE_SUFFIX:...>`
+ * :genex:`$<TARGET_PDB_FILE_BASE_NAME:...>`
+
+* The :genex:`$<TARGET_OBJECTS:...>` generator expression is now supported
+ on ``SHARED``, ``STATIC``, ``MODULE`` libraries and executables.
CTest
-----
diff --git a/Help/release/3.17.rst b/Help/release/3.17.rst
index 1aa475f..a27d638 100644
--- a/Help/release/3.17.rst
+++ b/Help/release/3.17.rst
@@ -140,7 +140,7 @@ Properties
* The :prop_tgt:`INSTALL_NAME_DIR` target property now supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
- In particular, the ``$<INSTALL_PREFIX>`` generator expression can
+ In particular, the :genex:`$<INSTALL_PREFIX>` generator expression can
be used to set the directory relative to the install-time prefix.
* Target properties :prop_tgt:`MACHO_COMPATIBILITY_VERSION` and
diff --git a/Help/release/3.18.rst b/Help/release/3.18.rst
index f97e4df..c120b9f 100644
--- a/Help/release/3.18.rst
+++ b/Help/release/3.18.rst
@@ -211,12 +211,11 @@ Modules
Generator Expressions
---------------------
-* The ``$<DEVICE_LINK:...>`` and ``$<HOST_LINK:...>``
- :manual:`generator expressions <cmake-generator-expressions(7)>` were added
- to manage device and host link steps.
+* The :genex:`$<DEVICE_LINK:...>` and :genex:`$<HOST_LINK:...>`
+ generator expressions were added to manage device and host link steps.
-* The ``$<LINK_LANGUAGE:...>`` and ``$<LINK_LANG_AND_ID:...>``
- :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
+* The :genex:`$<LINK_LANGUAGE:...>` and :genex:`$<LINK_LANG_AND_ID:...>`
+ generator expressions were added.
CTest
-----
diff --git a/Help/release/3.20.rst b/Help/release/3.20.rst
index 40cac41..ebd0f91 100644
--- a/Help/release/3.20.rst
+++ b/Help/release/3.20.rst
@@ -86,8 +86,8 @@ Commands
in their ``OUTPUT`` and ``BYPRODUCTS`` options.
Their ``COMMAND``, ``WORKING_DIRECTORY``, and ``DEPENDS`` options gained
- support for new generator expressions ``$<COMMAND_CONFIG:...>`` and
- ``$<OUTPUT_CONFIG:...>`` that control cross-config handling when using
+ support for new generator expressions :genex:`$<COMMAND_CONFIG:...>` and
+ :genex:`$<OUTPUT_CONFIG:...>` that control cross-config handling when using
the :generator:`Ninja Multi-Config` generator.
* The :command:`add_custom_command` command gained ``DEPFILE`` support on
diff --git a/Help/release/3.23.rst b/Help/release/3.23.rst
index 6376d77..5d85777 100644
--- a/Help/release/3.23.rst
+++ b/Help/release/3.23.rst
@@ -274,8 +274,8 @@ Other Changes
* tries to detect invalid architectures and issue an error.
* ``CUDA`` with Clang now implements policy :policy:`CMP0105` and
- the ``$<DEVICE_LINK:...>`` and ``$<HOST_LINK:...>``
- :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ the :genex:`$<DEVICE_LINK:...>` and :genex:`$<HOST_LINK:...>`
+ generator expressions.
* The :command:`define_property` command's ``BRIEF_DOCS`` and ``FULL_DOCS``
arguments are now optional.
diff --git a/Help/release/3.9.rst b/Help/release/3.9.rst
index 89da627..09e4ea6 100644
--- a/Help/release/3.9.rst
+++ b/Help/release/3.9.rst
@@ -256,11 +256,11 @@ Other
:command:`file(GENERATE)` commands.
* Two new informational generator expressions to retrieve Apple Bundle
- directories have been added. The first one ``$<TARGET_BUNDLE_DIR:tgt>``
+ directories have been added. The first one :genex:`$<TARGET_BUNDLE_DIR:tgt>`
outputs the full path to the Bundle directory, the other one
- ``$<TARGET_BUNDLE_CONTENT_DIR:tgt>`` outputs the full path to the
+ :genex:`$<TARGET_BUNDLE_CONTENT_DIR:tgt>` outputs the full path to the
``Contents`` directory of macOS Bundles and App Bundles. For all other
- bundle types and SDKs it is identical with ``$<TARGET_BUNDLE_DIR:tgt>``.
+ bundle types and SDKs it is identical with :genex:`$<TARGET_BUNDLE_DIR:tgt>`.
The new expressions are helpful to query Bundle locations independent of
the different Bundle types and layouts on macOS and iOS.
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/ExternalProject-INSTALL_BYPRODUCTS.rst b/Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst
new file mode 100644
index 0000000..233596f
--- /dev/null
+++ b/Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst
@@ -0,0 +1,6 @@
+ExternalProject-INSTALL_BYPRODUCTS
+----------------------------------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
+ gained an ``INSTALL_BYPRODUCTS`` option to specify files generated by the
+ "install" step.
diff --git a/Help/release/dev/UseSWIG-perl5.rst b/Help/release/dev/UseSWIG-perl5.rst
new file mode 100644
index 0000000..67d4161
--- /dev/null
+++ b/Help/release/dev/UseSWIG-perl5.rst
@@ -0,0 +1,4 @@
+UseSWIG-perl5
+-------------
+
+* The :module:`UseSWIG` module gained the support of ``perl5`` language.
diff --git a/Help/release/dev/cmake-E-copy-t-arg.rst b/Help/release/dev/cmake-E-copy-t-arg.rst
new file mode 100644
index 0000000..ca897d3
--- /dev/null
+++ b/Help/release/dev/cmake-E-copy-t-arg.rst
@@ -0,0 +1,4 @@
+cmake-E-copy-t-arg
+------------------
+
+* The :option:`cmake -E copy <cmake-E copy>` argument now supports a ``-t`` argument.
diff --git a/Help/release/dev/compile-commands-output-field.rst b/Help/release/dev/compile-commands-output-field.rst
new file mode 100644
index 0000000..110fd4e
--- /dev/null
+++ b/Help/release/dev/compile-commands-output-field.rst
@@ -0,0 +1,7 @@
+compile-commands-output-field
+-----------------------------
+
+* The :prop_tgt:`EXPORT_COMPILE_COMMANDS` target property will now have the
+ ``output`` field in the compile commands objects. This allows multi-config
+ generators (namely :generator:`Ninja Multi-Config` generator) to contain the
+ compile commands for all configurations.
diff --git a/Help/release/dev/file-api-file-sets.rst b/Help/release/dev/file-api-file-sets.rst
new file mode 100644
index 0000000..8a8b8d3
--- /dev/null
+++ b/Help/release/dev/file-api-file-sets.rst
@@ -0,0 +1,9 @@
+file-api-file-sets
+------------------
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+ been updated to 2.5.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object
+ gained a new ``fileSets`` field and associated ``fileSetIndex``
+ field to ``sources`` objects.
diff --git a/Help/release/dev/marmasm-language.rst b/Help/release/dev/marmasm-language.rst
new file mode 100644
index 0000000..2101e6c
--- /dev/null
+++ b/Help/release/dev/marmasm-language.rst
@@ -0,0 +1,4 @@
+marmasm-language
+----------------
+
+* The ``ASM_MARMASM`` language was added to support the Microsoft ARM assembler language.
diff --git a/Help/release/dev/timestamp-timezone.rst b/Help/release/dev/timestamp-timezone.rst
new file mode 100644
index 0000000..178fa9a
--- /dev/null
+++ b/Help/release/dev/timestamp-timezone.rst
@@ -0,0 +1,5 @@
+timestamp-timezone
+------------------
+
+* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)` commands
+ now support the ``%z`` and ``%Z`` specifiers for the time zone.
diff --git a/Help/release/dev/top-level-command-order.rst b/Help/release/dev/top-level-command-order.rst
new file mode 100644
index 0000000..07f87fb
--- /dev/null
+++ b/Help/release/dev/top-level-command-order.rst
@@ -0,0 +1,6 @@
+top-level-command-order
+-----------------------
+
+* The top-level :command:`project` call will now emit an author warning if the
+ documented command order in relation to :command:`cmake_minimum_required` is
+ not respected.
diff --git a/Help/release/dev/trace-try_compile.rst b/Help/release/dev/trace-try_compile.rst
new file mode 100644
index 0000000..886aaad
--- /dev/null
+++ b/Help/release/dev/trace-try_compile.rst
@@ -0,0 +1,5 @@
+trace-try_compile
+-----------------
+
+* The :option:`cmake --trace` option now follows :command:`try_compile` and
+ :command:`try_run` invocations.
diff --git a/Help/release/dev/use-folder-on-by-default.rst b/Help/release/dev/use-folder-on-by-default.rst
new file mode 100644
index 0000000..4e91c2e
--- /dev/null
+++ b/Help/release/dev/use-folder-on-by-default.rst
@@ -0,0 +1,5 @@
+use-folder-on-by-default
+------------------------
+
+* Global property :prop_gbl:`USE_FOLDERS` is treated as ``ON`` by default.
+ See policy :policy:`CMP0143`.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index b6ecf7b..50e06bb 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_DEPENDS_USE_COMPILER.rst b/Help/variable/CMAKE_DEPENDS_USE_COMPILER.rst
index bdad59e..ada4ba6 100644
--- a/Help/variable/CMAKE_DEPENDS_USE_COMPILER.rst
+++ b/Help/variable/CMAKE_DEPENDS_USE_COMPILER.rst
@@ -6,4 +6,4 @@ CMAKE_DEPENDS_USE_COMPILER
For the :ref:`Makefile Generators`, source dependencies are now, for a
selection of compilers, generated by the compiler itself. By defining this
variable with value ``FALSE``, you can restore the legacy behavior (i.e. using
-``CMake`` for dependencies discovery).
+CMake for dependencies discovery).
diff --git a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
index aea1be8..9158631 100644
--- a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
+++ b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
@@ -49,14 +49,14 @@
* ``[/path/to/]FwName.framework/Versions/*/FwName[suffix]``
Note that CMake recognizes and automatically handles framework targets,
- even without using the ``$<LINK_LIBRARY:FRAMEWORK,...>`` expression.
+ even without using the :genex:`$<LINK_LIBRARY:FRAMEWORK,...>` expression.
The generator expression can still be used with a CMake target if the
project wants to be explicit about it, but it is not required to do so.
The linker command line may have some differences between using the
generator expression or not, but the final result should be the same.
On the other hand, if a file path is given, CMake will recognize some paths
automatically, but not all cases. The project may want to use
- ``$<LINK_LIBRARY:FRAMEWORK,...>`` for file paths so that the expected
+ :genex:`$<LINK_LIBRARY:FRAMEWORK,...>` for file paths so that the expected
behavior is clear.
.. versionadded:: 3.25
diff --git a/Modules/CMakeASM_MARMASMInformation.cmake b/Modules/CMakeASM_MARMASMInformation.cmake
new file mode 100644
index 0000000..ac81097
--- /dev/null
+++ b/Modules/CMakeASM_MARMASMInformation.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.
+
+
+# support for the MS ARM assembler, marmasm and marmasm64
+
+set(ASM_DIALECT "_MARMASM")
+
+set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
+
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
+
+# The ASM_MARMASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
+
+include(CMakeASMInformation)
+set(ASM_DIALECT)
diff --git a/Modules/CMakeDetermineASM_MARMASMCompiler.cmake b/Modules/CMakeDetermineASM_MARMASMCompiler.cmake
new file mode 100644
index 0000000..26714dd
--- /dev/null
+++ b/Modules/CMakeDetermineASM_MARMASMCompiler.cmake
@@ -0,0 +1,18 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# Find the MS ARM assembler (marmasm or marmasm64)
+
+set(ASM_DIALECT "_MARMASM")
+
+# if we are using the 64bit cl compiler, assume we also want the 64bit assembler
+if(";${CMAKE_VS_PLATFORM_NAME};${CMAKE_C_COMPILER_ARCHITECTURE_ID};${CMAKE_CXX_COMPILER_ARCHITECTURE_ID};"
+ MATCHES ";(ARM64);")
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm64)
+else()
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm)
+endif()
+
+include(CMakeDetermineASMCompiler)
+set(ASM_DIALECT)
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index 2c2c2ac..94e92e8 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -33,20 +33,32 @@
# find out on which system cmake runs
if(CMAKE_HOST_UNIX)
- find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin )
+ find_program(CMAKE_UNAME NAMES uname PATHS /bin /usr/bin /usr/local/bin)
if(CMAKE_UNAME)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "AIX")
- exec_program(${CMAKE_UNAME} ARGS -v OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION)
- exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION)
+ execute_process(COMMAND ${CMAKE_UNAME} -v
+ OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ execute_process(COMMAND ${CMAKE_UNAME} -r
+ OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
set(CMAKE_HOST_SYSTEM_VERSION "${_CMAKE_HOST_SYSTEM_MAJOR_VERSION}.${_CMAKE_HOST_SYSTEM_MINOR_VERSION}")
unset(_CMAKE_HOST_SYSTEM_MAJOR_VERSION)
unset(_CMAKE_HOST_SYSTEM_MINOR_VERSION)
else()
- exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
+ execute_process(COMMAND ${CMAKE_UNAME} -r
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
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)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
# If we are running on Apple Silicon, honor CMAKE_APPLE_SILICON_PROCESSOR.
if(DEFINED CMAKE_APPLE_SILICON_PROCESSOR)
@@ -74,8 +86,11 @@ if(CMAKE_HOST_UNIX)
if(_CMAKE_APPLE_SILICON_PROCESSOR)
set(CMAKE_HOST_SYSTEM_PROCESSOR "${_CMAKE_APPLE_SILICON_PROCESSOR}")
else()
- exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
unset(_CMAKE_APPLE_SILICON_PROCESSOR)
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
@@ -83,14 +98,23 @@ if(CMAKE_HOST_UNIX)
set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
- exec_program(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND arch -s
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
else()
- exec_program(${CMAKE_UNAME} ARGS -p OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -p
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
if("${val}" GREATER 0)
- exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
- RETURN_VALUE val)
+ execute_process(COMMAND ${CMAKE_UNAME} -m
+ OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RESULT_VARIABLE val
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
endif()
endif()
# check the return of the last uname -m or -p
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index e2925dc..77c1780 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -30,12 +30,18 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
# LINK_LIBRARY_OVERRIDE_<LIBRARY> target properties
set(CMAKE_LINK_LIBRARY_USING_DEFAULT_SUPPORTED TRUE)
-set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
-set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
+if(NOT DEFINED CMAKE_AUTOGEN_ORIGIN_DEPENDS)
+ set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
+endif()
+if(NOT DEFINED CMAKE_AUTOMOC_COMPILER_PREDEFINES)
+ set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
+endif()
if(NOT DEFINED CMAKE_AUTOMOC_PATH_PREFIX)
set(CMAKE_AUTOMOC_PATH_PREFIX OFF)
endif()
-set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT")
+if(NOT DEFINED CMAKE_AUTOMOC_MACRO_NAMES)
+ set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT")
+endif()
# basically all general purpose OSs support shared libs
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 16726d2..62f7ef2 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -65,10 +65,22 @@ set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -libc MD)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -libc MTd)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -libc MDd)
-set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g")
-set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
-set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
-set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+if(CMAKE_GENERATOR STREQUAL "Xcode")
+ # Xcode has a separate Xcode project option (SWIFT_COMPILATION_MODE) used to set
+ # whether compiling with whole-module optimizations or incrementally. Setting
+ # these options here will have no effect when compiling with the built-in driver,
+ # and will explode violently, leaving build products in the source directory, when
+ # using the old swift driver.
+ set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g")
+ set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
+ set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+ set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+else()
+ set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g -incremental")
+ set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O -wmo")
+ set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g -wmo")
+ set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize -wmo")
+endif()
if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG)
@@ -91,7 +103,7 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
- set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
+ set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
@@ -99,11 +111,11 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
- set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
- set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+ set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>")
set(CMAKE_Swift_ARCHIVE_FINISH "")
diff --git a/Modules/CMakeTestASM_MARMASMCompiler.cmake b/Modules/CMakeTestASM_MARMASMCompiler.cmake
new file mode 100644
index 0000000..a6de04c
--- /dev/null
+++ b/Modules/CMakeTestASM_MARMASMCompiler.cmake
@@ -0,0 +1,13 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM_MARMASM "compiler" (should be marmasm or marmasm64)
+# works. For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+set(ASM_DIALECT "_MARMASM")
+include(CMakeTestASMCompiler)
+set(ASM_DIALECT)
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 7c3ad6b..f9cf33f 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -262,7 +262,7 @@ installers. The most commonly-used variables are:
Lists each of the executables and associated text label to be used to
create Start Menu shortcuts. For example, setting this to the list
``ccmake;CMake`` will create a shortcut named "CMake" that will execute the
- installed executable ``ccmake``. Not all CPack generators use it (at least
+ installed executable :program:`ccmake`. Not all CPack generators use it (at least
NSIS, and WIX do).
.. variable:: CPACK_STRIP_FILES
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index 4f9af37..b59b38c 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -44,7 +44,7 @@ else()
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
- if(CMAKE_${lang}_COMPILER_TARGET)
+ if(CMAKE_${lang}_COMPILER_TARGET AND "${lang}" STREQUAL "CXX")
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0)
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-target" "${CMAKE_${lang}_COMPILER_TARGET}")
else()
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 48639cd..5930e37 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -121,13 +121,15 @@ macro(__compiler_gnu lang)
)
endif()
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
if(NOT "x${lang}" STREQUAL "xFortran")
set(CMAKE_PCH_EXTENSION .gch)
diff --git a/Modules/Compiler/IBMClang.cmake b/Modules/Compiler/IBMClang.cmake
index 9ed7658..a9d760f 100644
--- a/Modules/Compiler/IBMClang.cmake
+++ b/Modules/Compiler/IBMClang.cmake
@@ -36,7 +36,7 @@ macro(__compiler_ibmclang lang)
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
- if(CMAKE_${lang}_COMPILER_TARGET)
+ if(CMAKE_${lang}_COMPILER_TARGET AND "${lang}" STREQUAL "CXX")
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
endif()
@@ -66,7 +66,9 @@ macro(__compiler_ibmclang lang)
"\"${__ranlib}\" <TARGET>"
)
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+ if("${lang}" STREQUAL "CXX")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+ endif()
set(CMAKE_PCH_EXTENSION .pch)
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index 642e58a..317cfc7 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -30,13 +30,15 @@ else()
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g")
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
if("x${lang}" STREQUAL "xFortran")
set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-warn" "errors")
diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake
index 30de1a9..e256c8f 100644
--- a/Modules/Compiler/IntelLLVM.cmake
+++ b/Modules/Compiler/IntelLLVM.cmake
@@ -80,15 +80,17 @@ else()
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
- endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
- if(CMAKE_${lang}_COMPILER_TARGET)
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
+ if(CMAKE_${lang}_COMPILER_TARGET)
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
+ endif()
endif()
if("x${lang}" STREQUAL "xFortran")
diff --git a/Modules/Compiler/LCC.cmake b/Modules/Compiler/LCC.cmake
index bdee9a6..f8c2084 100644
--- a/Modules/Compiler/LCC.cmake
+++ b/Modules/Compiler/LCC.cmake
@@ -76,13 +76,15 @@ macro(__compiler_lcc lang)
"\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>"
)
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
if(NOT "x${lang}" STREQUAL "xFortran")
set(CMAKE_PCH_EXTENSION .gch)
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index c8dcd2a..34dd09a 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -70,7 +70,7 @@ if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
endif()
set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
-set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
+set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA "-isystem ")
if (CMAKE_CUDA_SIMULATE_ID STREQUAL "GNU")
set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Wl,")
diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake
index 7fbfd10..b720dc1 100644
--- a/Modules/Compiler/QCC.cmake
+++ b/Modules/Compiler/QCC.cmake
@@ -22,13 +22,15 @@ macro(__compiler_qcc lang)
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE NO)
set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Wp,-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Wp,-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
unset(CMAKE_${lang}_COMPILE_OPTIONS_IPO)
unset(CMAKE_${lang}_ARCHIVE_CREATE_IPO)
diff --git a/Modules/Compiler/Tasking.cmake b/Modules/Compiler/Tasking.cmake
index 5bf066e..82622fa 100644
--- a/Modules/Compiler/Tasking.cmake
+++ b/Modules/Compiler/Tasking.cmake
@@ -43,12 +43,14 @@ macro(__compiler_tasking lang)
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -cs <SOURCE> -o <ASSEMBLY_SOURCE>")
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -Ep <SOURCE> > <PREPROCESSED_SOURCE>")
- set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
- if(CMAKE_${lang}_COMPILER_ARG1)
- separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
- unset(_COMPILER_ARGS)
+ if("${lang}" STREQUAL "CXX")
+ set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
+ if(CMAKE_${lang}_COMPILER_ARG1)
+ separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
+ unset(_COMPILER_ARGS)
+ endif()
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Ep" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Ep" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
endmacro()
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 22a25bd..3752ceb 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -525,9 +525,9 @@ External Project Definition
option without the ``CMAKE_GENERATOR`` option.
``CMAKE_ARGS <arg>...``
- The specified arguments are passed to the ``cmake`` command line. They
- can be any argument the ``cmake`` command understands, not just cache
- values defined by ``-D...`` arguments (see also
+ The specified arguments are passed to the :program:`cmake` command line.
+ They can be any argument the :program:`cmake` command understands, not just
+ cache values defined by ``-D...`` arguments (see also
:manual:`CMake Options <cmake(1)>`).
.. versionadded:: 3.3
@@ -611,9 +611,9 @@ External Project Definition
supported). If this option is not given, the default build command will
be chosen to integrate with the main build in the most appropriate way
(e.g. using recursive ``make`` for Makefile generators or
- ``cmake --build`` if the project uses a CMake build). This option can be
- specified with an empty string as the command to make the build step do
- nothing.
+ :option:`cmake --build` if the project uses a CMake build). This option
+ can be specified with an empty string as the command to make the build
+ step do nothing.
``BUILD_IN_SOURCE <bool>``
When this option is enabled, the build will be done directly within the
@@ -637,8 +637,11 @@ External Project Definition
Specifies files that will be generated by the build command but which
might or might not have their modification time updated by subsequent
- builds. These ultimately get passed through as ``BYPRODUCTS`` to the
- build step's own underlying call to :command:`add_custom_command`.
+ builds. This may also be required to explicitly declare dependencies
+ when using the :generator:`Ninja` generator.
+ These ultimately get passed through as ``BYPRODUCTS`` to the
+ build step's own underlying call to :command:`add_custom_command`, which
+ has additional documentation.
**Install Step Options:**
If the configure step assumed the external project uses CMake as its build
@@ -661,6 +664,17 @@ External Project Definition
supported). Passing an empty string as the ``<cmd>`` makes the install
step do nothing.
+ ``INSTALL_BYPRODUCTS <file>...``
+ .. versionadded:: 3.26
+
+ Specifies files that will be generated by the install command but which
+ might or might not have their modification time updated by subsequent
+ installs. This may also be required to explicitly declare dependencies
+ when using the :generator:`Ninja` generator.
+ These ultimately get passed through as ``BYPRODUCTS`` to the
+ install step's own underlying call to :command:`add_custom_command`, which
+ has additional documentation.
+
.. note::
If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
main project is built, it will only have an effect if the following
@@ -943,9 +957,12 @@ control needed to implement such step-level capabilities.
.. versionadded:: 3.2
Files that will be generated by this custom step but which might or might
- not have their modification time updated by subsequent builds. This list of
+ not have their modification time updated by subsequent builds.
+ This may also be required to explicitly declare dependencies
+ when using the :generator:`Ninja` generator. This list of
files will ultimately be passed through as the ``BYPRODUCTS`` option to the
- :command:`add_custom_command` used to implement the custom step internally.
+ :command:`add_custom_command` used to implement the custom step internally,
+ which has additional documentation.
``ALWAYS <bool>``
When enabled, this option specifies that the custom step should always be
@@ -3642,7 +3659,7 @@ function(_ep_extract_configure_command var name)
)
endif()
- list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>")
+ list(APPEND cmd -S "<SOURCE_DIR><SOURCE_SUBDIR>" -B "<BINARY_DIR>")
endif()
set("${var}" "${cmd}" PARENT_SCOPE)
@@ -3846,6 +3863,11 @@ function(_ep_add_install_command name)
set(always 0)
endif()
+ get_property(install_byproducts
+ TARGET ${name}
+ PROPERTY _EP_INSTALL_BYPRODUCTS
+ )
+
set(__cmdQuoted)
foreach(__item IN LISTS cmd)
string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -3854,6 +3876,7 @@ function(_ep_add_install_command name)
ExternalProject_Add_Step(${name} install
INDEPENDENT FALSE
COMMAND ${__cmdQuoted}
+ BYPRODUCTS \${install_byproducts}
WORKING_DIRECTORY \${binary_dir}
DEPENDEES build
ALWAYS \${always}
@@ -4081,6 +4104,7 @@ function(ExternalProject_Add name)
# Install step options
#
INSTALL_COMMAND
+ INSTALL_BYPRODUCTS
#
# Test step options
#
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index ac3918c..80554d0 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -923,9 +923,8 @@ it depends directly on projects ``projB`` and ``projC``. Both ``projB`` and
that all five projects are available on a company git server. The
``CMakeLists.txt`` of each project might have sections like the following:
-*projA*:
-
.. code-block:: cmake
+ :caption: *projA*
include(FetchContent)
FetchContent_Declare(
@@ -952,9 +951,9 @@ that all five projects are available on a company git server. The
# Order is important, see notes in the discussion further below
FetchContent_MakeAvailable(projD projB projC)
-*projB*:
.. code-block:: cmake
+ :caption: *projB*
include(FetchContent)
FetchContent_Declare(
@@ -970,9 +969,9 @@ that all five projects are available on a company git server. The
FetchContent_MakeAvailable(projD projE)
-*projC*:
.. code-block:: cmake
+ :caption: *projC*
include(FetchContent)
FetchContent_Declare(
@@ -1047,7 +1046,7 @@ directory. The :variable:`CMAKE_TOOLCHAIN_FILE` variable is not used until
the :command:`project` command is reached, at which point CMake looks for the
named toolchain file relative to the build directory. Because the tarball has
already been downloaded and unpacked by then, the toolchain file will be in
-place, even the very first time that ``cmake`` is run in the build directory.
+place, even the very first time that :program:`cmake` is run in the build directory.
Populating Content In CMake Script Mode
"""""""""""""""""""""""""""""""""""""""
@@ -1058,9 +1057,8 @@ firmware tarball using CMake's :manual:`script mode <cmake(1)>`. The call to
unpacked firmware will be placed in a ``firmware`` directory below the
current working directory.
-*getFirmware.cmake*:
-
.. code-block:: cmake
+ :caption: :file:`getFirmware.cmake`
# NOTE: Intended to be run in script mode with cmake -P
include(FetchContent)
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index 355c4bb..326e700 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -29,8 +29,11 @@ This module defines the following variables:
Link these to use BZip2
``BZIP2_NEED_PREFIX``
this is set if the functions are prefixed with ``BZ2_``
-``BZIP2_VERSION_STRING``
- the version of BZip2 found
+``BZIP2_VERSION``
+ .. versionadded:: 3.26
+ the version of BZip2 found.
+
+ See also legacy variable ``BZIP2_VERSION_STRING``.
Cache variables
^^^^^^^^^^^^^^^
@@ -39,6 +42,17 @@ The following cache variables may also be set:
``BZIP2_INCLUDE_DIR``
the BZip2 include directory
+
+Legacy Variables
+^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``BZIP2_VERSION_STRING``
+ the version of BZip2 found.
+
+ .. versionchanged:: 3.26
+ Superseded by ``BZIP2_VERSION``.
#]=======================================================================]
set(_BZIP2_PATHS PATHS
@@ -60,12 +74,13 @@ endif ()
if (BZIP2_INCLUDE_DIR AND EXISTS "${BZIP2_INCLUDE_DIR}/bzlib.h")
file(STRINGS "${BZIP2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ")
string(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}")
+ set(BZIP2_VERSION ${BZIP2_VERSION_STRING})
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
REQUIRED_VARS BZIP2_LIBRARIES BZIP2_INCLUDE_DIR
- VERSION_VAR BZIP2_VERSION_STRING)
+ VERSION_VAR BZIP2_VERSION)
if (BZIP2_FOUND)
set(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR})
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index f06f0e8..62e54c8 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -834,8 +834,8 @@ endif()
# The NVHPC layout moves math library headers and libraries to a sibling directory.
# Create a separate variable so this directory can be selectively added to math targets.
if(NOT EXISTS "${CUDAToolkit_INCLUDE_DIR}/cublas_v2.h")
- set(CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/../../math_libs/include")
- cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR)
+ file(REAL_PATH "${CUDAToolkit_TARGET_DIR}/../../" CUDAToolkit_MATH_INCLUDE_DIR)
+ cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "math_libs/include")
if(NOT EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/cublas_v2.h")
if(NOT CUDAToolkit_FIND_QUIETLY)
message(STATUS "Unable to find cublas_v2.h in either \"${CUDAToolkit_INCLUDE_DIR}\" or \"${CUDAToolkit_MATH_INCLUDE_DIR}\"")
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 9ec8f07..c298bab 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -33,6 +33,17 @@ This module will set the following variables in your project:
True if lzma_easy_encoder() is found (required).
``LIBLZMA_HAS_LZMA_PRESET``
True if lzma_lzma_preset() is found (required).
+``LIBLZMA_VERSION``
+ .. versionadded:: 3.26
+ the version of LZMA found.
+
+ See also legacy variable ``LIBLZMA_VERSION_STRING``.
+
+Legacy Variables
+^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
``LIBLZMA_VERSION_MAJOR``
The major version of lzma
``LIBLZMA_VERSION_MINOR``
@@ -41,6 +52,10 @@ This module will set the following variables in your project:
The patch version of lzma
``LIBLZMA_VERSION_STRING``
version number as a string (ex: "5.0.3")
+
+ .. versionchanged:: 3.26
+ Superseded by ``LIBLZMA_VERSION``.
+
#]=======================================================================]
find_path(LIBLZMA_INCLUDE_DIR lzma.h )
@@ -61,6 +76,7 @@ if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")
set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
+ set(LIBLZMA_VERSION ${LIBLZMA_VERSION_STRING})
unset(LIBLZMA_HEADER_CONTENTS)
endif()
@@ -91,7 +107,7 @@ find_package_handle_standard_args(LibLZMA REQUIRED_VARS LIBLZMA_LIBRARY
LIBLZMA_HAS_AUTO_DECODER
LIBLZMA_HAS_EASY_ENCODER
LIBLZMA_HAS_LZMA_PRESET
- VERSION_VAR LIBLZMA_VERSION_STRING
+ VERSION_VAR LIBLZMA_VERSION
)
mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 04f9d8c..3fb56e4 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -56,7 +56,7 @@ To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and
If components ``Interpreter`` and ``Development`` (or one of its
sub-components) are both specified, this module search only for interpreter
- with same platform architecture as the one defined by ``CMake``
+ with same platform architecture as the one defined by CMake
configuration. This constraint does not apply if only ``Interpreter``
component is specified.
@@ -139,12 +139,11 @@ This module will set the following variables in your project
Extension suffix for modules.
- Information returned by
- ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
- ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
- ``python-config --extension-suffix``. If package ``distutils.sysconfig`` is
- not available, ``sysconfig.get_config_var('SOABI')`` or
- ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
+ Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')``
+ or ``distutils.sysconfig.get_config_var('SOABI')`` or
+ ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is
+ not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or
+ ``sysconfig.get_config_var('SOABI')`` are used.
``Python_Compiler_FOUND``
System has the Python compiler.
@@ -449,7 +448,7 @@ setting the following variables:
By default, this module supports multiple calls in different directories of a
project with different version/component requirements while providing correct
-and consistent results for each call. To support this behavior, ``CMake`` cache
+and consistent results for each call. To support this behavior, CMake cache
is not used in the traditional way which can be problematic for interactive
specification. So, to enable also interactive specification, module behavior
can be controlled with the following variable:
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 7a127e4..9b78220 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -508,21 +508,16 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
list (REMOVE_DUPLICATES _values)
endif()
elseif (NAME STREQUAL "SOABI")
+ # first step: compute SOABI form EXT_SUFFIX config variable
execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '',sysconfig.get_config_var('SO') or '']))"
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')\nexcept Exception:\n import sysconfig;sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')"
RESULT_VARIABLE _result
- OUTPUT_VARIABLE _soabi
+ OUTPUT_VARIABLE _values
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_result)
unset (_values)
else()
- foreach (_item IN LISTS _soabi)
- if (_item)
- set (_values "${_item}")
- break()
- endif()
- endforeach()
if (_values)
# clean-up: remove prefix character and suffix
if (_values MATCHES "^(\\.${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$")
@@ -532,6 +527,34 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
endif()
endif()
endif()
+
+ # second step: use SOABI or SO config variables as fallback
+ if (NOT _values)
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _soabi
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ else()
+ foreach (_item IN LISTS _soabi)
+ if (_item)
+ set (_values "${_item}")
+ break()
+ endif()
+ endforeach()
+ if (_values)
+ # clean-up: remove prefix character and suffix
+ if (_values MATCHES "^(\\.${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$")
+ set(_values "")
+ else()
+ string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
+ endif()
+ endif()
+ endif()
+ endif()
else()
set (config_flag "${NAME}")
if (NAME STREQUAL "CONFIGDIR")
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 268acfe..41d9b68 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -57,7 +57,7 @@ for you.
If components ``Interpreter`` and ``Development`` (or one of its
sub-components) are both specified, this module search only for interpreter
- with same platform architecture as the one defined by ``CMake``
+ with same platform architecture as the one defined by CMake
configuration. This constraint does not apply if only ``Interpreter``
component is specified.
@@ -388,7 +388,7 @@ setting the following variables:
By default, this module supports multiple calls in different directories of a
project with different version/component requirements while providing correct
-and consistent results for each call. To support this behavior, ``CMake`` cache
+and consistent results for each call. To support this behavior, CMake cache
is not used in the traditional way which can be problematic for interactive
specification. So, to enable also interactive specification, module behavior
can be controlled with the following variable:
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index 4f198bb..837300e 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -57,7 +57,7 @@ for you.
If components ``Interpreter`` and ``Development`` (or one of its
sub-components) are both specified, this module search only for interpreter
- with same platform architecture as the one defined by ``CMake``
+ with same platform architecture as the one defined by CMake
configuration. This constraint does not apply if only ``Interpreter``
component is specified.
@@ -140,12 +140,11 @@ This module will set the following variables in your project
Extension suffix for modules.
- Information returned by
- ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
- ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+ Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')``
+ or ``distutils.sysconfig.get_config_var('SOABI')`` or
``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is
- not available, ``sysconfig.get_config_var('SOABI')`` or
- ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
+ not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or
+ ``sysconfig.get_config_var('SOABI')`` are used.
``Python3_Compiler_FOUND``
System has the Python 3 compiler.
@@ -447,7 +446,7 @@ setting the following variables:
By default, this module supports multiple calls in different directories of a
project with different version/component requirements while providing correct
-and consistent results for each call. To support this behavior, ``CMake`` cache
+and consistent results for each call. To support this behavior, CMake cache
is not used in the traditional way which can be problematic for interactive
specification. So, to enable also interactive specification, module behavior
can be controlled with the following variable:
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
index be5c775..d0deb87 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -20,33 +20,57 @@ Result Variables
This module defines the following variables:
-::
+``ZLIB_INCLUDE_DIRS``
+ where to find zlib.h, etc.
+``ZLIB_LIBRARIES``
+ List of libraries when using zlib.
+``ZLIB_FOUND``
+ True if zlib found.
+``ZLIB_VERSION``
+ .. versionadded:: 3.26
+ the version of Zlib found.
+
+ See also legacy variable ``ZLIB_VERSION_STRING``.
- ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
- ZLIB_LIBRARIES - List of libraries when using zlib.
- ZLIB_FOUND - True if zlib found.
+.. versionadded:: 3.4
+ Debug and Release variants are found separately.
-::
+Legacy Variables
+^^^^^^^^^^^^^^^^
- ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
- ZLIB_VERSION_MAJOR - The major version of zlib
- ZLIB_VERSION_MINOR - The minor version of zlib
- ZLIB_VERSION_PATCH - The patch version of zlib
- ZLIB_VERSION_TWEAK - The tweak version of zlib
+The following variables are provided for backward compatibility:
-.. versionadded:: 3.4
- Debug and Release variants are found separately.
+``ZLIB_VERSION_MAJOR``
+ The major version of zlib.
-Backward Compatibility
-^^^^^^^^^^^^^^^^^^^^^^
+ .. versionchanged:: 3.26
+ Superseded by ``ZLIB_VERSION``.
+``ZLIB_VERSION_MINOR``
+ The minor version of zlib.
-The following variable are provided for backward compatibility
+ .. versionchanged:: 3.26
+ Superseded by ``ZLIB_VERSION``.
+``ZLIB_VERSION_PATCH``
+ The patch version of zlib.
-::
+ .. versionchanged:: 3.26
+ Superseded by ``ZLIB_VERSION``.
+``ZLIB_VERSION_TWEAK``
+ The tweak version of zlib.
- ZLIB_MAJOR_VERSION - The major version of zlib
- ZLIB_MINOR_VERSION - The minor version of zlib
- ZLIB_PATCH_VERSION - The patch version of zlib
+ .. versionchanged:: 3.26
+ Superseded by ``ZLIB_VERSION``.
+``ZLIB_VERSION_STRING``
+ The version of zlib found (x.y.z)
+
+ .. versionchanged:: 3.26
+ Superseded by ``ZLIB_VERSION``.
+``ZLIB_MAJOR_VERSION``
+ The major version of zlib. Superseded by ``ZLIB_VERSION_MAJOR``.
+``ZLIB_MINOR_VERSION``
+ The minor version of zlib. Superseded by ``ZLIB_VERSION_MINOR``.
+``ZLIB_PATCH_VERSION``
+ The patch version of zlib. Superseded by ``ZLIB_VERSION_PATCH``.
Hints
^^^^^
@@ -60,6 +84,14 @@ module where to look.
#]=======================================================================]
+if(ZLIB_FIND_COMPONENTS AND NOT ZLIB_FIND_QUIETLY)
+ message(AUTHOR_WARNING
+ "ZLIB does not provide any COMPONENTS. Calling\n"
+ " find_package(ZLIB COMPONENTS ...)\n"
+ "will always fail."
+ )
+endif()
+
set(_ZLIB_SEARCHES)
# Search ZLIB_ROOT first if it is set.
@@ -160,11 +192,14 @@ if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
+
+ set(ZLIB_VERSION ${ZLIB_VERSION_STRING})
endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR
- VERSION_VAR ZLIB_VERSION_STRING)
+ VERSION_VAR ZLIB_VERSION
+ HANDLE_COMPONENTS)
if(ZLIB_FOUND)
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index b8dc482..57a7476 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -212,7 +212,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
discovery. Note that the expression is a wildcard-based format that
matches against the original test names as used by gtest. For type or
value-parameterized tests, these names may be different to the potentially
- pretty-printed test names that ``ctest`` uses.
+ pretty-printed test names that :program:`ctest` uses.
``NO_PRETTY_TYPES``
By default, the type index of type-parameterized tests is replaced by the
@@ -405,6 +405,12 @@ function(gtest_add_tests)
--gtest_filter=${gtest_test_name}
${ARGS_EXTRA_ARGS}
)
+ # Makes sure a skipped GTest is reported as so by CTest
+ set_tests_properties(
+ ${ctest_test_name}
+ PROPERTIES
+ SKIP_REGULAR_EXPRESSION "\\[ SKIPPED \\]"
+ )
list(APPEND testList ${ctest_test_name})
endif()
endforeach()
diff --git a/Modules/Internal/CheckFlagCommonConfig.cmake b/Modules/Internal/CheckFlagCommonConfig.cmake
index c011c24..f8481cd 100644
--- a/Modules/Internal/CheckFlagCommonConfig.cmake
+++ b/Modules/Internal/CheckFlagCommonConfig.cmake
@@ -48,6 +48,8 @@ macro(CMAKE_CHECK_FLAG_COMMON_INIT _FUNC _LANG _SRC _PATTERNS)
FAIL_REGEX "argument unused during compilation: .*") # Clang
elseif("${_LANG}" STREQUAL "ISPC")
set(${_SRC} "float func(uniform int32, float a) { return a / 2.25; }")
+ elseif("${_LANG}" STREQUAL "Swift")
+ set(${_SRC} "func blarpy() { }")
else()
message (SEND_ERROR "${_FUNC}: ${_LANG}: unknown language.")
return()
diff --git a/Modules/Internal/CheckSourceCompiles.cmake b/Modules/Internal/CheckSourceCompiles.cmake
index eadf3da..bf5a82d 100644
--- a/Modules/Internal/CheckSourceCompiles.cmake
+++ b/Modules/Internal/CheckSourceCompiles.cmake
@@ -9,7 +9,7 @@ cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
if(NOT DEFINED "${_var}")
-
+ set(_lang_filename "src")
if(_lang STREQUAL "C")
set(_lang_textual "C")
set(_lang_ext "c")
@@ -34,6 +34,13 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
elseif(_lang STREQUAL "OBJCXX")
set(_lang_textual "Objective-C++")
set(_lang_ext "mm")
+ elseif(_lang STREQUAL "Swift")
+ set(_lang_textual "Swift")
+ set(_lang_ext "swift")
+ if (NOT DEFINED CMAKE_TRY_COMPILE_TARGET_TYPE
+ OR CMAKE_TRY_COMPILE_TARGET_TYPE STREQUAL "EXECUTABLE")
+ set(_lang_filename "main")
+ endif()
else()
message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.")
return()
@@ -92,7 +99,7 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
endif()
string(APPEND _source "\n")
try_compile(${_var}
- SOURCE_FROM_VAR "src.${_SRC_EXT}" _source
+ SOURCE_FROM_VAR "${_lang_filename}.${_SRC_EXT}" _source
COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 3a279ca..aaaae9b 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -77,7 +77,9 @@ macro(__android_compiler_clang lang)
if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}")
endif()
- list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
+ if("${lang}" STREQUAL "CXX")
+ list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
+ endif()
endif()
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(_ANDROID_STL_NOSTDLIBXX 1)
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index 1511bfd..54a8cf7 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -7,7 +7,7 @@ UseJava
This file provides support for ``Java``. It is assumed that
:module:`FindJava` has already been loaded. See :module:`FindJava` for
-information on how to load Java into your ``CMake`` project.
+information on how to load Java into your CMake project.
Synopsis
^^^^^^^^
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index fd6596b..e0e01f5 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -378,6 +378,7 @@ set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py")
set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")
set(SWIG_CSHARP_EXTRA_FILE_EXTENSIONS ".cs" "PINVOKE.cs")
set(SWIG_PERL_EXTRA_FILE_EXTENSIONS ".pm")
+set(SWIG_PERL5_EXTRA_FILE_EXTENSIONS ".pm")
set(SWIG_MANAGE_SUPPORT_FILES_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/UseSWIG/ManageSupportFiles.cmake")
@@ -414,8 +415,8 @@ macro(SWIG_MODULE_INITIALIZE name language)
endif()
if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN")
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
- elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" AND
- NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS)
+ elseif((SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" OR SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL5")
+ AND NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS)
list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
endif()
endmacro()
@@ -971,7 +972,7 @@ function(SWIG_ADD_LIBRARY name)
if (APPLE)
set_target_properties (${target_name} PROPERTIES SUFFIX ".bundle")
endif ()
- elseif (swig_lowercase_language STREQUAL "perl")
+ elseif (swig_lowercase_language STREQUAL "perl" OR swig_lowercase_language STREQUAL "perl5")
# assume empty prefix because we expect the module to be dynamically loaded
set_target_properties (${target_name} PROPERTIES PREFIX "")
if (APPLE)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index a57b47c..ee7639f 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 25)
-set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_PATCH 20221118)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index fd20398..1f3633d 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -122,10 +122,15 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
cmakeConfigureCommand += "\"";
}
- cmakeConfigureCommand += " \"";
+ cmakeConfigureCommand += " \"-S";
cmakeConfigureCommand += source_dir;
cmakeConfigureCommand += "\"";
+ cmakeConfigureCommand += " \"-B";
+ cmakeConfigureCommand +=
+ this->CTest->GetCTestConfiguration("BuildDirectory");
+ cmakeConfigureCommand += "\"";
+
this->CTest->SetCTestConfiguration("ConfigureCommand",
cmakeConfigureCommand, this->Quiet);
} else {
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 1f7776c..70ed648 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -77,7 +77,7 @@ int main(int argc, char const* const* argv)
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(argc, argv)) {
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index fb12b7d..591b793 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -79,7 +79,7 @@ int main(int argc, char** argv)
doc.addCMakeStandardDocSections();
if (argc2 > 1 && doc.CheckOptions(argc2, argv2)) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index 33c91bc..003e972 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
+#include <cm/optional>
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -250,6 +252,15 @@ private:
return true;
};
}
+
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToValue(cm::optional<std::string>& value1)
+ {
+ return [&value1](const std::string& arg, CallState&&...) -> bool {
+ value1 = arg;
+ return true;
+ };
+ }
};
std::string extract_single_value(std::string const& input,
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 41d4442..57b009a 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -172,7 +172,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
};
}
- cmGeneratorExpression ge(cc.GetBacktrace());
+ cmGeneratorExpression ge(*lg->GetCMakeInstance(), cc.GetBacktrace());
cmGeneratorTarget const* target{ lg->FindGeneratorTargetToUse(
this->Target) };
@@ -417,7 +417,8 @@ std::string cmCustomCommandGenerator::GetDepfile() const
return "";
}
- cmGeneratorExpression ge(this->CC->GetBacktrace());
+ cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
+ this->CC->GetBacktrace());
return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig);
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 50bc78c..bd2b6af 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -379,7 +379,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
cmValue input = target->GetProperty(propName);
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*target->Makefile->GetCMakeInstance());
std::string dirs = cmGeneratorExpression::Preprocess(
cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(te), ";"),
@@ -939,13 +939,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.23 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.24 (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.8.3...3.23)\n";
+ << "cmake_policy(VERSION 2.8.3...3.24)\n";
/* clang-format on */
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 195737b..5e190f4 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -570,7 +570,7 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge = ge.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
for (auto const& config : configs) {
@@ -617,7 +617,7 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
auto fileEntries = fileSet->CompileFileEntries();
auto directoryEntries = fileSet->CompileDirectoryEntries();
- cmGeneratorExpression destGe;
+ cmGeneratorExpression destGe(*gte->Makefile->GetCMakeInstance());
auto destCge =
destGe.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index e98aa05..33c057d 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -70,7 +70,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
return std::string();
}
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*tgt->Makefile->GetCMakeInstance());
std::unique_ptr<cmGeneratorExpressionDAGChecker> parentDagChecker;
if (propName == "INTERFACE_LINK_OPTIONS") {
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 7f8374d..3fc2179 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -687,7 +687,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
// Update Help/manual/cmake-file-api.7.rst when updating this constant.
-static unsigned int const CodeModelV2Minor = 4;
+static unsigned int const CodeModelV2Minor = 5;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 0581802..56221a5 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -17,6 +17,7 @@
#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/json/value.h>
@@ -44,6 +45,7 @@
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
@@ -434,6 +436,8 @@ class Target
std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap;
std::vector<CompileGroup> CompileGroups;
+ using FileSetDatabase = std::map<std::string, Json::ArrayIndex>;
+
template <typename T>
JBT<T> ToJBT(BT<T> const& bt)
{
@@ -466,9 +470,12 @@ class Target
Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
Json::Value DumpDefine(JBT<std::string> const& def);
- Json::Value DumpSources();
+ std::pair<Json::Value, FileSetDatabase> DumpFileSets();
+ Json::Value DumpFileSet(cmFileSet const* fs,
+ std::vector<std::string> const& directories);
+ Json::Value DumpSources(FileSetDatabase const& fsdb);
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
- Json::ArrayIndex si);
+ Json::ArrayIndex si, FileSetDatabase const& fsdb);
Json::Value DumpSourceGroups();
Json::Value DumpSourceGroup(SourceGroup& sg);
Json::Value DumpCompileGroups();
@@ -1216,7 +1223,13 @@ Json::Value Target::Dump()
{
this->ProcessLanguages();
- target["sources"] = this->DumpSources();
+ auto fileSetInfo = this->DumpFileSets();
+
+ if (!fileSetInfo.first.isNull()) {
+ target["fileSets"] = fileSetInfo.first;
+ }
+
+ target["sources"] = this->DumpSources(fileSetInfo.second);
Json::Value folder = this->DumpFolder();
if (!folder.isNull()) {
@@ -1527,29 +1540,113 @@ Json::Value Target::DumpPaths()
return paths;
}
-Json::Value Target::DumpSources()
+std::pair<Json::Value, Target::FileSetDatabase> Target::DumpFileSets()
+{
+ Json::Value fsJson = Json::nullValue;
+ FileSetDatabase fsdb;
+
+ // Build the fileset database.
+ auto const* tgt = this->GT->Target;
+ auto const& fs_names = tgt->GetAllFileSetNames();
+
+ if (!fs_names.empty()) {
+ fsJson = Json::arrayValue;
+ size_t fsIndex = 0;
+ for (auto const& fs_name : fs_names) {
+ auto const* fs = tgt->GetFileSet(fs_name);
+ if (!fs) {
+ this->GT->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", fs_name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = fs->CompileFileEntries();
+ auto directoryEntries = fs->CompileDirectoryEntries();
+
+ auto directories = fs->EvaluateDirectoryEntries(
+ directoryEntries, this->GT->LocalGenerator, this->Config, this->GT);
+
+ fsJson.append(this->DumpFileSet(fs, directories));
+
+ std::map<std::string, std::vector<std::string>> files_per_dirs;
+ for (auto const& entry : fileEntries) {
+ fs->EvaluateFileEntry(directories, files_per_dirs, entry,
+ this->GT->LocalGenerator, this->Config,
+ this->GT);
+ }
+
+ for (auto const& files_per_dir : files_per_dirs) {
+ auto const& dir = files_per_dir.first;
+ for (auto const& file : files_per_dir.second) {
+ std::string sf_path;
+ if (dir.empty()) {
+ sf_path = file;
+ } else {
+ sf_path = cmStrCat(dir, '/', file);
+ }
+ fsdb[sf_path] = static_cast<Json::ArrayIndex>(fsIndex);
+ }
+ }
+
+ ++fsIndex;
+ }
+ }
+
+ return std::make_pair(fsJson, fsdb);
+}
+
+Json::Value Target::DumpFileSet(cmFileSet const* fs,
+ std::vector<std::string> const& directories)
+{
+ Json::Value fileSet = Json::objectValue;
+
+ fileSet["name"] = fs->GetName();
+ fileSet["type"] = fs->GetType();
+ fileSet["visibility"] =
+ std::string(cmFileSetVisibilityToName(fs->GetVisibility()));
+
+ Json::Value baseDirs = Json::arrayValue;
+ for (auto const& directory : directories) {
+ baseDirs.append(directory);
+ }
+ fileSet["baseDirectories"] = baseDirs;
+
+ return fileSet;
+}
+
+Json::Value Target::DumpSources(FileSetDatabase const& fsdb)
{
Json::Value sources = Json::arrayValue;
cmGeneratorTarget::KindedSources const& kinded =
this->GT->GetKindedSources(this->Config);
for (cmGeneratorTarget::SourceAndKind const& sk : kinded.Sources) {
- sources.append(this->DumpSource(sk, sources.size()));
+ sources.append(this->DumpSource(sk, sources.size(), fsdb));
}
return sources;
}
Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
- Json::ArrayIndex si)
+ Json::ArrayIndex si,
+ FileSetDatabase const& fsdb)
{
Json::Value source = Json::objectValue;
- std::string const path = sk.Source.Value->ResolveFullPath();
+ cmSourceFile* sf = sk.Source.Value;
+ std::string const path = sf->ResolveFullPath();
source["path"] = RelativeIfUnder(this->TopSource, path);
if (sk.Source.Value->GetIsGenerated()) {
source["isGenerated"] = true;
}
this->AddBacktrace(source, sk.Source.Backtrace);
+ auto fsit = fsdb.find(path);
+ if (fsit != fsdb.end()) {
+ source["fileSetIndex"] = fsit->second;
+ }
+
if (cmSourceGroup* sg =
this->GT->Makefile->FindSourceGroup(path, this->SourceGroupsLocal)) {
source["sourceGroupIndex"] = this->AddSourceGroup(sg, si);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index fe38db5..85f528d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2107,6 +2107,14 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// Verify MD5 sum if requested:
//
if (hash) {
+ if (res != CURLE_OK) {
+ status.SetError(cmStrCat(
+ "DOWNLOAD cannot compute hash on failed download\n"
+ " status: [",
+ static_cast<int>(res), ";\"", ::curl_easy_strerror(res), "\"]"));
+ return false;
+ }
+
std::string actualHash = hash->HashFile(file);
if (actualHash.empty()) {
status.SetError("DOWNLOAD cannot compute hash on downloaded file");
@@ -2130,11 +2138,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
expectedHash,
"]\n"
" actual hash: [",
- actualHash,
- "]\n"
- " status: [",
- static_cast<int>(res), ";\"",
- ::curl_easy_strerror(res), "\"]\n"));
+ actualHash, "]\n"));
return false;
}
}
@@ -2458,11 +2462,13 @@ void AddEvaluationFile(const std::string& inputName,
{
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
- cmGeneratorExpression outputGe(lfbt);
+ cmGeneratorExpression outputGe(*status.GetMakefile().GetCMakeInstance(),
+ lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> outputCge =
outputGe.Parse(outputExpr);
- cmGeneratorExpression conditionGe(lfbt);
+ cmGeneratorExpression conditionGe(*status.GetMakefile().GetCMakeInstance(),
+ lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> conditionCge =
conditionGe.Parse(condition);
@@ -3398,20 +3404,29 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
}
int compressionLevel = 0;
+ int minCompressionLevel = 0;
+ int maxCompressionLevel = 9;
+ if (compress == cmSystemTools::TarCompressZstd) {
+ maxCompressionLevel = 19;
+ }
+
if (!parsedArgs.CompressionLevel.empty()) {
if (parsedArgs.CompressionLevel.size() != 1 &&
!std::isdigit(parsedArgs.CompressionLevel[0])) {
- status.SetError(cmStrCat("compression level ",
- parsedArgs.CompressionLevel,
- " should be in range 0 to 9"));
+ status.SetError(
+ cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
+ parsedArgs.Compression, " should be in range ",
+ minCompressionLevel, " to ", maxCompressionLevel));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
compressionLevel = std::stoi(parsedArgs.CompressionLevel);
- if (compressionLevel < 0 || compressionLevel > 9) {
- status.SetError(cmStrCat("compression level ",
- parsedArgs.CompressionLevel,
- " should be in range 0 to 9"));
+ if (compressionLevel < minCompressionLevel ||
+ compressionLevel > maxCompressionLevel) {
+ status.SetError(
+ cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
+ parsedArgs.Compression, " should be in range ",
+ minCompressionLevel, " to ", maxCompressionLevel));
cmSystemTools::SetFatalErrorOccurred();
return false;
}
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index d6665a2..b96ba6e 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -78,9 +78,10 @@ bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis)
return false;
}
-cmFileSet::cmFileSet(std::string name, std::string type,
+cmFileSet::cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSetVisibility visibility)
- : Name(std::move(name))
+ : CMakeInstance(cmakeInstance)
+ , Name(std::move(name))
, Type(std::move(type))
, Visibility(visibility)
{
@@ -113,7 +114,7 @@ cmFileSet::CompileFileEntries() const
for (auto const& entry : this->FileEntries) {
for (auto const& ex : cmExpandedList(entry.Value)) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
@@ -129,7 +130,7 @@ cmFileSet::CompileDirectoryEntries() const
for (auto const& entry : this->DirectoryEntries) {
for (auto const& ex : cmExpandedList(entry.Value)) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
diff --git a/Source/cmFileSet.h b/Source/cmFileSet.h
index 5357e77..54d430c 100644
--- a/Source/cmFileSet.h
+++ b/Source/cmFileSet.h
@@ -17,6 +17,7 @@ struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
+class cmake;
enum class cmFileSetVisibility
{
@@ -33,7 +34,7 @@ bool cmFileSetVisibilityIsForInterface(cmFileSetVisibility vis);
class cmFileSet
{
public:
- cmFileSet(std::string name, std::string type,
+ cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSetVisibility visibility);
const std::string& GetName() const { return this->Name; }
@@ -77,6 +78,7 @@ public:
static bool IsValidName(const std::string& name);
private:
+ cmake& CMakeInstance;
std::string Name;
std::string Type;
cmFileSetVisibility Visibility;
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 3f8378b..60b0a7b 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -377,6 +377,8 @@ private:
# pragma diag_suppress 1222 // invalid error number (3288, but works anyway)
# define CM_LCC_DIAG_SUPPRESS_3288
# pragma diag_suppress 3288 // parameter was declared but never referenced
+# define CM_LCC_DIAG_SUPPRESS_3301
+# pragma diag_suppress 3301 // parameter was declared but never referenced
#endif
void ResetGenerator()
@@ -421,6 +423,11 @@ bool TryGeneratedPaths(CallbackFn&& filesCollector,
return false;
}
+#ifdef CM_LCC_DIAG_SUPPRESS_3301
+# undef CM_LCC_DIAG_SUPPRESS_3301
+# pragma diag_default 3301
+#endif
+
#ifdef CM_LCC_DIAG_SUPPRESS_3288
# undef CM_LCC_DIAG_SUPPRESS_3288
# pragma diag_default 3288
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index c72d6a7..133bf5f 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -27,7 +27,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
bool quiet, Encoding encoding)
: cmGeneratedFileStreamBase(name)
- , Stream(this->TempName.c_str())
+ , Stream(this->TempName.c_str()) // NOLINT(cmake-use-cmsys-fstream)
{
// Check if the file opened.
if (!*this && !quiet) {
@@ -67,10 +67,11 @@ cmGeneratedFileStream& cmGeneratedFileStream::Open(std::string const& name,
// Open the temporary output file.
if (binaryFlag) {
- this->Stream::open(this->TempName.c_str(),
- std::ios::out | std::ios::binary);
+ this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
+ this->TempName.c_str(), std::ios::out | std::ios::binary);
} else {
- this->Stream::open(this->TempName.c_str());
+ this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
+ this->TempName.c_str());
}
// Check if the file opened.
@@ -87,7 +88,7 @@ bool cmGeneratedFileStream::Close()
this->Okay = !this->fail();
// Close the temporary output file.
- this->Stream::close();
+ this->Stream::close(); // NOLINT(cmake-use-cmsys-fstream)
// Remove the temporary file (possibly by renaming to the real file).
return this->cmGeneratedFileStreamBase::Close();
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index f988e54..21ace89 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -13,11 +13,15 @@
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
+#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
-cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
- : Backtrace(std::move(backtrace))
+cmGeneratorExpression::cmGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace)
+ : CMakeInstance(cmakeInstance)
+ , Backtrace(std::move(backtrace))
{
}
@@ -29,7 +33,8 @@ std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
std::string input) const
{
return std::unique_ptr<cmCompiledGeneratorExpression>(
- new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
+ new cmCompiledGeneratorExpression(this->CMakeInstance, this->Backtrace,
+ std::move(input)));
}
std::string cmGeneratorExpression::Evaluate(
@@ -39,7 +44,13 @@ std::string cmGeneratorExpression::Evaluate(
cmGeneratorTarget const* currentTarget, std::string const& language)
{
if (Find(input) != std::string::npos) {
- cmCompiledGeneratorExpression cge(cmListFileBacktrace(), std::move(input));
+#ifndef CMAKE_BOOTSTRAP
+ auto profilingRAII = lg->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_compile_eval", input);
+#endif
+
+ cmCompiledGeneratorExpression cge(*lg->GetCMakeInstance(),
+ cmListFileBacktrace(), std::move(input));
return cge.Evaluate(lg, config, headTarget, dagChecker, currentTarget,
language);
}
@@ -97,10 +108,15 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
}
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
- cmListFileBacktrace backtrace, std::string input)
+ cmake& cmakeInstance, cmListFileBacktrace backtrace, std::string input)
: Backtrace(std::move(backtrace))
, Input(std::move(input))
{
+#ifndef CMAKE_BOOTSTRAP
+ auto profilingRAII =
+ cmakeInstance.CreateProfilingEntry("genex_compile", this->Input);
+#endif
+
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
this->NeedsEvaluation = l.GetSawGeneratorExpression();
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 188993f..e22b8ab 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -12,10 +12,11 @@
#include <vector>
#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
+class cmake;
class cmCompiledGeneratorExpression;
class cmGeneratorTarget;
-class cmLocalGenerator;
struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionEvaluator;
@@ -33,7 +34,8 @@ class cmGeneratorExpression
{
public:
/** Construct. */
- cmGeneratorExpression(cmListFileBacktrace backtrace = cmListFileBacktrace());
+ cmGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace = cmListFileBacktrace());
~cmGeneratorExpression();
cmGeneratorExpression(cmGeneratorExpression const&) = delete;
@@ -82,6 +84,7 @@ public:
const std::string& replacement);
private:
+ cmake& CMakeInstance;
cmListFileBacktrace Backtrace;
};
@@ -152,7 +155,8 @@ private:
cmGeneratorExpressionContext& context,
cmGeneratorExpressionDAGChecker* dagChecker) const;
- cmCompiledGeneratorExpression(cmListFileBacktrace backtrace,
+ cmCompiledGeneratorExpression(cmake& cmakeInstance,
+ cmListFileBacktrace backtrace,
std::string input);
friend class cmGeneratorExpression;
@@ -184,7 +188,8 @@ public:
std::string config,
cmGeneratorTarget const* headTarget,
std::string language = std::string())
- : LocalGenerator(localGenerator)
+ : GeneratorExpression(*localGenerator->GetCMakeInstance())
+ , LocalGenerator(localGenerator)
, Config(std::move(config))
, HeadTarget(headTarget)
, Language(std::move(language))
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 8f3ed4d..817437e 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -165,7 +165,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
}
cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
- cmGeneratorExpression contentGE(lfbt);
+ cmGeneratorExpression contentGE(*lg->GetCMakeInstance(), lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> inputExpression =
contentGE.Parse(inputContent);
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index fec309c..b239408 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -4,8 +4,14 @@
#include <sstream>
+#ifndef CMAKE_BOOTSTRAP
+# include <cm3p/json/value.h>
+#endif
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionNode.h"
+#include "cmLocalGenerator.h"
+#include "cmake.h"
GeneratorExpressionContent::GeneratorExpressionContent(
const char* startContent, size_t length)
@@ -61,6 +67,12 @@ std::string GeneratorExpressionContent::Evaluate(
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
+#ifndef CMAKE_BOOTSTRAP
+ auto evalProfilingRAII =
+ context->LG->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_eval", this->GetOriginalExpression());
+#endif
+
std::string identifier;
{
for (const auto& pExprEval : this->IdentifierChildren) {
@@ -101,7 +113,24 @@ std::string GeneratorExpressionContent::Evaluate(
return std::string();
}
- return node->Evaluate(parameters, context, this, dagChecker);
+ {
+#ifndef CMAKE_BOOTSTRAP
+ auto execProfilingRAII =
+ context->LG->GetCMakeInstance()->CreateProfilingEntry(
+ "genex_exec", identifier, [&parameters]() -> Json::Value {
+ Json::Value args = Json::objectValue;
+ if (!parameters.empty()) {
+ args["genexArgs"] = Json::arrayValue;
+ for (auto const& parameter : parameters) {
+ args["genexArgs"].append(parameter);
+ }
+ }
+ return args;
+ });
+#endif
+
+ return node->Evaluate(parameters, context, this, dagChecker);
+ }
}
std::string GeneratorExpressionContent::EvaluateParameters(
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 45d5a83..562c31e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -57,7 +57,7 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget const* currentTarget)
{
- cmGeneratorExpression ge(context->Backtrace);
+ cmGeneratorExpression ge(*lg->GetCMakeInstance(), context->Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
cge->SetQuiet(context->Quiet);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7d43eb1..6065285 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -241,15 +241,16 @@ private:
std::unique_ptr<
cmGeneratorTarget::
- TargetPropertyEntry> static CreateTargetPropertyEntry(const BT<std::
- string>&
+ TargetPropertyEntry> static CreateTargetPropertyEntry(cmake& cmakeInstance,
+ const BT<
+ std::string>&
propertyValue,
bool
evaluateForBuildsystem =
false)
{
if (cmGeneratorExpression::Find(propertyValue.Value) != std::string::npos) {
- cmGeneratorExpression ge(propertyValue.Backtrace);
+ cmGeneratorExpression ge(cmakeInstance, propertyValue.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(propertyValue.Value);
cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
@@ -262,12 +263,13 @@ std::unique_ptr<
}
static void CreatePropertyGeneratorExpressions(
- cmBTStringRange entries,
+ cmake& cmakeInstance, cmBTStringRange entries,
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items,
bool evaluateForBuildsystem = false)
{
for (auto const& entry : entries) {
- items.push_back(CreateTargetPropertyEntry(entry, evaluateForBuildsystem));
+ items.push_back(
+ CreateTargetPropertyEntry(cmakeInstance, entry, evaluateForBuildsystem));
}
}
@@ -343,29 +345,36 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->GlobalGenerator->ComputeTargetObjectDirectory(this);
- CreatePropertyGeneratorExpressions(t->GetIncludeDirectoriesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetIncludeDirectoriesEntries(),
this->IncludeDirectoriesEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileOptionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileOptionsEntries(),
this->CompileOptionsEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileFeaturesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileFeaturesEntries(),
this->CompileFeaturesEntries);
- CreatePropertyGeneratorExpressions(t->GetCompileDefinitionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetCompileDefinitionsEntries(),
this->CompileDefinitionsEntries);
- CreatePropertyGeneratorExpressions(t->GetLinkOptionsEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetLinkOptionsEntries(),
this->LinkOptionsEntries);
- CreatePropertyGeneratorExpressions(t->GetLinkDirectoriesEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetLinkDirectoriesEntries(),
this->LinkDirectoriesEntries);
- CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(),
+ CreatePropertyGeneratorExpressions(*lg->GetCMakeInstance(),
+ t->GetPrecompileHeadersEntries(),
this->PrecompileHeadersEntries);
- CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
- this->SourceEntries, true);
+ CreatePropertyGeneratorExpressions(
+ *lg->GetCMakeInstance(), t->GetSourceEntries(), this->SourceEntries, true);
this->PolicyMap = t->GetPolicyMap();
@@ -753,6 +762,7 @@ void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
this->SourceEntries.insert(
before ? this->SourceEntries.begin() : this->SourceEntries.end(),
CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(),
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
this->ClearSourcesCache();
}
@@ -780,6 +790,7 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
before ? this->IncludeDirectoriesEntries.begin()
: this->IncludeDirectoriesEntries.end(),
CreateTargetPropertyEntry(
+ *this->Makefile->GetCMakeInstance(),
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
}
@@ -1653,7 +1664,8 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
lib.Target);
std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">";
- cmGeneratorExpression ge(lib.Backtrace);
+ cmGeneratorExpression ge(*headTarget->Makefile->GetCMakeInstance(),
+ lib.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
@@ -4192,7 +4204,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
case cmPolicies::OLD: {
std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(*configProp);
+ CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), *configProp);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
} break;
@@ -4778,8 +4791,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
std::vector<std::string> options = cmExpandedList(*linkOptions);
for (const auto& option : options) {
- std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(option);
+ std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), option);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
}
@@ -4931,8 +4944,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
std::vector<std::string> depends = cmExpandedList(*linkDepends);
for (const auto& depend : depends) {
- std::unique_ptr<TargetPropertyEntry> entry =
- CreateTargetPropertyEntry(depend);
+ std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
+ *this->LocalGenerator->GetCMakeInstance(), depend);
entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
this, config, language, &dagChecker, *entry));
}
@@ -5532,7 +5545,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
} else if (cmHasLiteralPrefix(*location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
- flags.MacFolder += strlen("Resources/");
+ flags.MacFolder += cmStrLen("Resources/");
}
} else {
flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
@@ -6756,7 +6769,8 @@ void cmGeneratorTarget::ExpandLinkItems(
cmMakefile const* mf = this->LocalGenerator->GetMakefile();
LookupLinkItemScope scope{ this->LocalGenerator };
for (BT<std::string> const& entry : entries) {
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance(),
+ entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
std::vector<std::string> libs = cmExpandedList(
@@ -8195,7 +8209,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
break;
}
}
- cmGeneratorExpression ge(entry.Backtrace);
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance(),
+ entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
@@ -8515,9 +8530,14 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType(
// lib
// 2. empty propval: add /clr as flag, mixed unmanaged/managed
// target, has import lib
- // 3. any value (safe,pure): add /clr:[propval] as flag, target with
+ // 3. netcore propval: add /clr:netcore as flag, mixed
+ // unmanaged/managed target, has import lib.
+ // 4. any value (safe,pure): add /clr:[propval] as flag, target with
// managed code only, no import lib
- return propval.empty() ? ManagedType::Mixed : ManagedType::Managed;
+ if (propval.empty() || propval == "netcore") {
+ return ManagedType::Mixed;
+ }
+ return ManagedType::Managed;
}
cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index c2bf888..a9485b5 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -827,7 +827,8 @@ void cmGlobalGenerator::EnableLanguage(
"No " << compilerName << " could be found.\n"
;
/* clang-format on */
- } else if ((lang != "RC") && (lang != "ASM_MASM")) {
+ } else if ((lang != "RC") && (lang != "ASM_MARMASM") &&
+ (lang != "ASM_MASM")) {
if (!cmSystemTools::FileIsFullPath(*compilerFile)) {
/* clang-format off */
noCompiler <<
@@ -2943,19 +2944,18 @@ std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const
bool cmGlobalGenerator::UseFolderProperty() const
{
- cmValue prop =
+ const cmValue prop =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
- // If this property is defined, let the setter turn this on or off...
- //
+ // If this property is defined, let the setter turn this on or off.
if (prop) {
return cmIsOn(*prop);
}
- // By default, this feature is OFF, since it is not supported in the
- // Visual Studio Express editions until VS11:
- //
- return false;
+ // If CMP0143 is NEW `treat` "USE_FOLDERS" as ON. Otherwise `treat` it as OFF
+ assert(!this->Makefiles.empty());
+ return (this->Makefiles[0]->GetPolicyStatus(cmPolicies::CMP0143) ==
+ cmPolicies::NEW);
}
void cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 077de42..395372b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1171,7 +1171,8 @@ void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
}
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
- const std::string& commandLine, const std::string& sourceFile)
+ const std::string& commandLine, const std::string& sourceFile,
+ const std::string& objPath)
{
// Compute Ninja's build file path.
std::string buildFileDir =
@@ -1205,7 +1206,9 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
<< R"( "command": ")"
<< cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n"
<< R"( "file": ")"
- << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n"
+ << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\",\n"
+ << R"( "output": ")"
+ << cmGlobalGenerator::EscapeJSON(objPath) << "\"\n"
<< "}";
/* clang-format on */
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index defa264..dac1c52 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -292,7 +292,8 @@ public:
}
void AddCXXCompileCommand(const std::string& commandLine,
- const std::string& sourceFile);
+ const std::string& sourceFile,
+ const std::string& objPath);
/**
* Add a rule to the generated build system.
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 21aa89c..bf9e40e 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -143,7 +143,7 @@ void cmGlobalUnixMakefileGenerator3::Generate()
void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string& sourceFile, const std::string& workingDirectory,
- const std::string& compileCommand)
+ const std::string& compileCommand, const std::string& objPath)
{
if (!this->CommandDatabase) {
std::string commandDatabaseName =
@@ -164,7 +164,9 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
<< "\",\n"
<< R"( "file": ")"
<< cmGlobalGenerator::EscapeJSON(sourceFile)
- << "\"\n}";
+ << "\",\n"
+ << R"( "output": ")"
+ << cmGlobalGenerator::EscapeJSON(objPath) << "\"\n}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index b9d333e..92e567a 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -174,7 +174,8 @@ public:
void AddCXXCompileCommand(const std::string& sourceFile,
const std::string& workingDirectory,
- const std::string& compileCommand);
+ const std::string& compileCommand,
+ const std::string& objPath);
/** Does the make tool tolerate .NOTPARALLEL? */
virtual bool AllowNotParallel() const { return true; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index bea2ae7..266e08d 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -56,6 +56,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
{
this->DefaultCudaFlagTableName = "v10";
this->DefaultCudaHostFlagTableName = "v10";
+ this->DefaultMarmasmFlagTableName = "v10";
this->DefaultNasmFlagTableName = "v10";
}
@@ -1154,8 +1155,6 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
} else {
makeCommand.Add(cmStrCat("/m:", std::to_string(jobs)));
}
- // Having msbuild.exe and cl.exe using multiple jobs is discouraged
- makeCommand.Add("/p:CL_MPCount=1");
}
// Respect the verbosity: 'n' normal will show build commands
@@ -1466,6 +1465,13 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetCudaHostFlagTable()
"CudaHost");
}
+cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMarmasmFlagTable()
+ const
+{
+ return LoadFlagTable(std::string(), this->DefaultMarmasmFlagTableName,
+ "MARMASM");
+}
+
cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetMasmFlagTable() const
{
return LoadFlagTable(this->GetMasmFlagTableName(),
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index b32c0a7..b3d9552 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -163,6 +163,7 @@ public:
cmIDEFlagTable const* GetLinkFlagTable() const;
cmIDEFlagTable const* GetCudaFlagTable() const;
cmIDEFlagTable const* GetCudaHostFlagTable() const;
+ cmIDEFlagTable const* GetMarmasmFlagTable() const;
cmIDEFlagTable const* GetMasmFlagTable() const;
cmIDEFlagTable const* GetNasmFlagTable() const;
@@ -226,6 +227,7 @@ protected:
std::string DefaultLinkFlagTableName;
std::string DefaultCudaFlagTableName;
std::string DefaultCudaHostFlagTableName;
+ std::string DefaultMarmasmFlagTableName;
std::string DefaultMasmFlagTableName;
std::string DefaultNasmFlagTableName;
std::string DefaultRCFlagTableName;
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 086d3af..c53ddf5 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -161,6 +161,18 @@ bool cmGlobalVisualStudio11Generator::MatchesGeneratorName(
return false;
}
+void cmGlobalVisualStudio11Generator::EnableLanguage(
+ std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
+{
+ for (std::string const& it : lang) {
+ if (it == "ASM_MARMASM") {
+ this->MarmasmEnabled = true;
+ }
+ }
+ this->AddPlatformDefinitions(mf);
+ cmGlobalVisualStudio10Generator::EnableLanguage(lang, mf, optional);
+}
+
bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
{
if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 2f8a7f6..fd25984 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -25,6 +25,9 @@ public:
bool MatchesGeneratorName(const std::string& name) const override;
+ void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
+ bool optional) override;
+
bool SupportsCustomCommandDepfile() const override { return true; }
cm::optional<cmDepfileFormat> DepfileFormat() const override
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index ff76762..7431176 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -70,6 +70,7 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
: cmGlobalVisualStudioGenerator(cm, platformInGeneratorName)
{
this->DevEnvCommandInitialized = false;
+ this->MarmasmEnabled = false;
this->MasmEnabled = false;
this->NasmEnabled = false;
this->ExtraFlagTable = cmVS7ExtraFlagTable;
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 288069c..e901ecd 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -106,6 +106,7 @@ public:
bool FindMakeProgram(cmMakefile* mf) override;
/** Is the Microsoft Assembler enabled? */
+ bool IsMarmasmEnabled() const { return this->MarmasmEnabled; }
bool IsMasmEnabled() const { return this->MasmEnabled; }
bool IsNasmEnabled() const { return this->NasmEnabled; }
@@ -176,6 +177,7 @@ protected:
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
std::string CurrentProject;
+ bool MarmasmEnabled;
bool MasmEnabled;
bool NasmEnabled;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 0658021..62e5a1e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -4412,12 +4412,20 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
buildSettings->AddAttribute("CODE_SIGNING_ALLOWED",
this->CreateString("NO"));
}
+ auto debugConfigs = this->GetCMakeInstance()->GetDebugConfigs();
+ std::set<std::string> debugConfigSet(debugConfigs.begin(),
+ debugConfigs.end());
for (auto& config : configs) {
CreateGlobalXCConfigSettings(root, config.second, config.first);
cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
+ if (debugConfigSet.count(cmSystemTools::UpperCase(config.first)) == 0) {
+ buildSettingsForCfg->AddAttribute("SWIFT_COMPILATION_MODE",
+ this->CreateString("wholemodule"));
+ }
+
// Put this last so it can override existing settings
// Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
for (const auto& var : this->CurrentMakefile->GetDefinitions()) {
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 0974eea..5bf8320 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -21,7 +21,7 @@ cmInstalledFile::Property::~Property() = default;
void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(backtrace);
+ cmGeneratorExpression ge(*mf->GetCMakeInstance(), backtrace);
this->Name = name;
this->NameExpression = ge.Parse(name);
@@ -56,7 +56,7 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
bool /*asString*/)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(backtrace);
+ cmGeneratorExpression ge(*mf->GetCMakeInstance(), backtrace);
Property& property = this->Properties[prop];
property.ValueExpressions.push_back(ge.Parse(value));
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index b2b724a..9745142 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -4505,7 +4505,7 @@ std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputGenex(
std::string const& o, cmListFileBacktrace const& bt)
{
std::vector<std::string> allConfigOutputs;
- cmGeneratorExpression ge(bt);
+ cmGeneratorExpression ge(*this->GetCMakeInstance(), bt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(o);
std::vector<std::string> configs =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c11f5b4..1e2ea2a 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -701,7 +701,7 @@ bool cmLocalNinjaGenerator::HasUniqueByproducts(
{
std::vector<std::string> configs =
this->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
- cmGeneratorExpression ge(bt);
+ cmGeneratorExpression ge(*this->GetCMakeInstance(), bt);
for (std::string const& p : byproducts) {
if (cmGeneratorExpression::Find(p) == std::string::npos) {
return false;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index af2d31d..383045d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -842,6 +842,24 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
}
}
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
+ if (gg->IsMarmasmEnabled() && !this->FortranProject) {
+ Options marmasmOptions(this, Options::MarmasmCompiler, 0, 0);
+ /* clang-format off */
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"MARMASM\"\n"
+ ;
+ /* clang-format on */
+ targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "ASM_MARMASM");
+ // Use same preprocessor definitions as VCCLCompilerTool.
+ targetOptions.OutputPreprocessorDefinitions(fout, 4, "ASM_MARMASM");
+ marmasmOptions.OutputFlagMap(fout, 4);
+ /* clang-format off */
+ fout <<
+ "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
+ "\t\t\t/>\n";
+ /* clang-format on */
+ }
if (gg->IsMasmEnabled() && !this->FortranProject) {
Options masmOptions(this, Options::MasmCompiler, 0, 0);
/* clang-format off */
@@ -1720,6 +1738,10 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
aCompilerTool = "VFCustomBuildTool";
}
}
+ if (gg->IsMarmasmEnabled() && !this->FortranProject &&
+ lang == "ASM_MARMASM") {
+ aCompilerTool = "MARMASM";
+ }
if (gg->IsMasmEnabled() && !this->FortranProject &&
lang == "ASM_MASM") {
aCompilerTool = "MASM";
@@ -2050,6 +2072,17 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
/* clang-format on */
+ if (gg->IsMarmasmEnabled()) {
+ /* clang-format off */
+ fout <<
+ "\t<ToolFiles>\n"
+ "\t\t<DefaultToolFile\n"
+ "\t\t\tFileName=\"marmasm.rules\"\n"
+ "\t\t/>\n"
+ "\t</ToolFiles>\n"
+ ;
+ /* clang-format on */
+ }
if (gg->IsMasmEnabled()) {
/* clang-format off */
fout <<
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 6e0d704..db8f785 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -375,19 +375,28 @@ public:
++this->Makefile->RecursionDepth;
this->Makefile->ExecutionStatusStack.push_back(&status);
#if !defined(CMAKE_BOOTSTRAP)
- if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
- this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
- lfc);
- }
+ this->ProfilingDataRAII =
+ this->Makefile->GetCMakeInstance()->CreateProfilingEntry(
+ "script", lff.LowerCaseName(), [&lff, &lfc]() -> Json::Value {
+ Json::Value argsValue = Json::objectValue;
+ if (!lff.Arguments().empty()) {
+ std::string args;
+ for (auto const& a : lff.Arguments()) {
+ args = cmStrCat(args, args.empty() ? "" : " ", a.Value);
+ }
+ argsValue["functionArgs"] = args;
+ }
+ argsValue["location"] =
+ cmStrCat(lfc.FilePath, ':', std::to_string(lfc.Line));
+ return argsValue;
+ });
#endif
}
~cmMakefileCall()
{
#if !defined(CMAKE_BOOTSTRAP)
- if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
- this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
- }
+ this->ProfilingDataRAII.reset();
#endif
this->Makefile->ExecutionStatusStack.pop_back();
--this->Makefile->RecursionDepth;
@@ -399,6 +408,9 @@ public:
private:
cmMakefile* Makefile;
+#if !defined(CMAKE_BOOTSTRAP)
+ cm::optional<cmMakefileProfilingData::RAII> ProfilingDataRAII;
+#endif
};
void cmMakefile::OnExecuteCommand(std::function<void()> callback)
@@ -3584,6 +3596,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
gg->RecursionDepth = this->RecursionDepth;
cm.SetGlobalGenerator(std::move(gg));
+ // copy trace state
+ cm.SetTraceRedirect(this->GetCMakeInstance());
+
// do a configure
cm.SetHomeDirectory(srcdir);
cm.SetHomeOutputDirectory(bindir);
@@ -4470,12 +4485,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0102 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0108 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 ||
- id == cmPolicies::CMP0091)) &&
+ id == cmPolicies::CMP0091 || id == cmPolicies::CMP0104)) &&
(!this->IsSet("CMAKE_WARN_DEPRECATED") ||
this->IsOn("CMAKE_WARN_DEPRECATED"))) {
this->IssueMessage(MessageType::DEPRECATION_WARNING,
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
index 1cd97c9..e903ae1 100644
--- a/Source/cmMakefileProfilingData.cxx
+++ b/Source/cmMakefileProfilingData.cxx
@@ -4,7 +4,8 @@
#include <chrono>
#include <stdexcept>
-#include <vector>
+#include <type_traits>
+#include <utility>
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
@@ -12,7 +13,6 @@
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
-#include "cmListFileCache.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -43,8 +43,9 @@ cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
}
}
-void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
- cmListFileContext const& lfc)
+void cmMakefileProfilingData::StartEntry(const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args)
{
/* Do not try again if we previously failed to write to output. */
if (!this->ProfileStream.good()) {
@@ -58,24 +59,17 @@ void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
cmsys::SystemInformation info;
Json::Value v;
v["ph"] = "B";
- v["name"] = lff.LowerCaseName();
- v["cat"] = "cmake";
+ v["name"] = name;
+ v["cat"] = category;
v["ts"] = static_cast<Json::Value::UInt64>(
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count());
v["pid"] = static_cast<int>(info.GetProcessId());
v["tid"] = 0;
- Json::Value argsValue;
- if (!lff.Arguments().empty()) {
- std::string args;
- for (auto const& a : lff.Arguments()) {
- args += (args.empty() ? "" : " ") + a.Value;
- }
- argsValue["functionArgs"] = args;
+ if (args) {
+ v["args"] = *std::move(args);
}
- argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
- v["args"] = argsValue;
this->JsonWriter->write(v, &this->ProfileStream);
} catch (std::ios_base::failure& fail) {
@@ -112,3 +106,36 @@ void cmMakefileProfilingData::StopEntry()
cmSystemTools::Error("Error writing profiling output!");
}
}
+
+cmMakefileProfilingData::RAII::RAII(cmMakefileProfilingData& data,
+ const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args)
+ : Data(&data)
+{
+ this->Data->StartEntry(category, name, std::move(args));
+}
+
+cmMakefileProfilingData::RAII::RAII(RAII&& other) noexcept
+ : Data(other.Data)
+{
+ other.Data = nullptr;
+}
+
+cmMakefileProfilingData::RAII::~RAII()
+{
+ if (this->Data) {
+ this->Data->StopEntry();
+ }
+}
+
+cmMakefileProfilingData::RAII& cmMakefileProfilingData::RAII::operator=(
+ RAII&& other) noexcept
+{
+ if (this->Data) {
+ this->Data->StopEntry();
+ }
+ this->Data = other.Data;
+ other.Data = nullptr;
+ return *this;
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
index a86764a..4cf0bfa 100644
--- a/Source/cmMakefileProfilingData.h
+++ b/Source/cmMakefileProfilingData.h
@@ -4,23 +4,45 @@
#include <memory>
#include <string>
+#include <cm/optional>
+
+#include <cm3p/json/value.h> // IWYU pragma: keep
+
#include "cmsys/FStream.hxx"
namespace Json {
class StreamWriter;
}
-class cmListFileContext;
-class cmListFileFunction;
-
class cmMakefileProfilingData
{
public:
cmMakefileProfilingData(const std::string&);
~cmMakefileProfilingData() noexcept;
- void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+ void StartEntry(const std::string& category, const std::string& name,
+ cm::optional<Json::Value> args = cm::nullopt);
void StopEntry();
+ class RAII
+ {
+ public:
+ RAII() = delete;
+ RAII(const RAII&) = delete;
+ RAII(RAII&&) noexcept;
+
+ RAII(cmMakefileProfilingData& data, const std::string& category,
+ const std::string& name,
+ cm::optional<Json::Value> args = cm::nullopt);
+
+ ~RAII();
+
+ RAII& operator=(const RAII&) = delete;
+ RAII& operator=(RAII&&) noexcept;
+
+ private:
+ cmMakefileProfilingData* Data = nullptr;
+ };
+
private:
cmsys::ofstream ProfileStream;
std::unique_ptr<Json::StreamWriter> JsonWriter;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index d19bbb9..c5c5490 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1031,7 +1031,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
this->GlobalGenerator->AddCXXCompileCommand(
- source.GetFullPath(), workingDirectory, compileCommand);
+ source.GetFullPath(), workingDirectory, compileCommand, relativeObj);
}
// See if we need to use a compiler launcher like ccache or distcc
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index bda8a5f..895a4c3 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -372,7 +372,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
vars.SwiftModule = "$SWIFT_MODULE";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
- vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP";
vars.SwiftSources = "$SWIFT_SOURCES";
vars.Defines = "$DEFINES";
@@ -1072,12 +1071,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmOutputConverter::SHELL);
}(vars["SWIFT_MODULE_NAME"]);
- const std::string map = cmStrCat(gt->GetSupportDirectory(), '/', config,
- '/', "output-file-map.json");
- vars["SWIFT_OUTPUT_FILE_MAP"] =
- this->GetLocalGenerator()->ConvertToOutputFormat(
- this->ConvertToNinjaPath(map), cmOutputConverter::SHELL);
-
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
std::vector<cmSourceFile const*> sources;
std::stringstream oss;
@@ -1101,6 +1094,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
vars["DEFINES"] = this->GetDefines("Swift", config);
vars["FLAGS"] = this->GetFlags("Swift", config);
vars["INCLUDES"] = this->GetIncludes("Swift", config);
+ this->GenerateSwiftOutputFileMap(config, vars["FLAGS"]);
}
// Compute specific libraries to link with.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index e4427f5..fba0ff9 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1177,30 +1177,42 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
this->GetImplFileStream(fileConfig) << "\n";
+}
- if (!this->Configs[config].SwiftOutputMap.empty()) {
- std::string const mapFilePath =
- cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
- "output-file-map.json");
- std::string const targetSwiftDepsPath = [this, config]() -> std::string {
- cmGeneratorTarget const* target = this->GeneratorTarget;
- if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return *name;
- }
- return this->ConvertToNinjaPath(
- cmStrCat(target->GetSupportDirectory(), '/', config, '/',
- target->GetName(), ".swiftdeps"));
- }();
+void cmNinjaTargetGenerator::GenerateSwiftOutputFileMap(
+ const std::string& config, std::string& flags)
+{
+ if (this->Configs[config].SwiftOutputMap.empty()) {
+ return;
+ }
- // build the global target dependencies
- // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
- Json::Value deps(Json::objectValue);
- deps["swift-dependencies"] = targetSwiftDepsPath;
- this->Configs[config].SwiftOutputMap[""] = deps;
+ std::string const targetSwiftDepsPath = [this, config]() -> std::string {
+ cmGeneratorTarget const* target = this->GeneratorTarget;
+ if (cmValue name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return *name;
+ }
+ return this->ConvertToNinjaPath(cmStrCat(target->GetSupportDirectory(),
+ '/', config, '/',
+ target->GetName(), ".swiftdeps"));
+ }();
- cmGeneratedFileStream output(mapFilePath);
- output << this->Configs[config].SwiftOutputMap;
- }
+ std::string mapFilePath =
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
+ "output-file-map.json");
+
+ // build the global target dependencies
+ // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+ Json::Value deps(Json::objectValue);
+ deps["swift-dependencies"] = targetSwiftDepsPath;
+ this->Configs[config].SwiftOutputMap[""] = deps;
+
+ cmGeneratedFileStream output(mapFilePath);
+ output << this->Configs[config].SwiftOutputMap;
+
+ // Add flag
+ this->LocalGenerator->AppendFlags(flags, "-output-file-map");
+ this->LocalGenerator->AppendFlagEscape(flags,
+ ConvertToNinjaPath(mapFilePath));
}
namespace {
@@ -1998,7 +2010,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine(
compileCmds, outputConfig, outputConfig);
- this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
+ this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName,
+ objectFileName);
}
void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4b4cf8d..c43b650 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -163,6 +163,9 @@ protected:
void EmitSwiftDependencyInfo(cmSourceFile const* source,
const std::string& config);
+ void GenerateSwiftOutputFileMap(const std::string& config,
+ std::string& flags);
+
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 4643868..fa24f57 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -431,7 +431,10 @@ class cmMakefile;
SELECT(POLICY, CMP0142, \
"The Xcode generator does not append per-config suffixes to " \
"library search paths.", \
- 3, 25, 0, cmPolicies::WARN)
+ 3, 25, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0143, \
+ "Global property USE_FOLDERS treated as ON by default", 3, 26, 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 249fe2d..4d1ccfe 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -34,6 +34,15 @@ bool cmProjectCommand(std::vector<std::string> const& args,
}
cmMakefile& mf = status.GetMakefile();
+ if (mf.IsRootMakefile() &&
+ !mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "cmake_minimum_required() should be called prior to this top-level "
+ "project() call. Please see the cmake-commands(7) manual for usage "
+ "documentation of both commands.");
+ }
+
if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) {
return false;
}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 96649ab..6f78a46 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -2095,7 +2095,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Evaluate generator expression
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpression ge(*this->Makefile->GetCMakeInstance(), lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val);
genVars.Executable = cge->Evaluate(this->LocalGen, "");
}
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index b63d11c..638bb42 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -119,11 +119,6 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
return this->ReplaceValues->SwiftModuleName;
}
}
- if (this->ReplaceValues->SwiftOutputFileMap) {
- if (variable == "SWIFT_OUTPUT_FILE_MAP") {
- return this->ReplaceValues->SwiftOutputFileMap;
- }
- }
if (this->ReplaceValues->SwiftSources) {
if (variable == "SWIFT_SOURCES") {
return this->ReplaceValues->SwiftSources;
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 23ec405..5d1f199 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -64,7 +64,7 @@ public:
const char* SwiftLibraryName = nullptr;
const char* SwiftModule = nullptr;
const char* SwiftModuleName = nullptr;
- const char* SwiftOutputFileMap = nullptr;
+ const char* SwiftOutputFileMapOption = nullptr;
const char* SwiftSources = nullptr;
const char* ISPCHeader = nullptr;
const char* CudaCompileMode = nullptr;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index e54ccfc..f12f91f 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -786,6 +786,8 @@ std::string cmState::ModeToString(cmState::Mode mode)
return "CTEST";
case CPack:
return "CPACK";
+ case Help:
+ return "HELP";
case Unknown:
return "UNKNOWN";
}
diff --git a/Source/cmState.h b/Source/cmState.h
index 2d0c521..9a17b22 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -53,6 +53,7 @@ public:
FindPackage,
CTest,
CPack,
+ Help
};
enum class ProjectKind
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index ee74908..78d230e 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1140,7 +1140,7 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
return CopyResult::Success;
}
- cmsys::Status status;
+ cmsys::SystemTools::CopyStatus status;
status = cmsys::SystemTools::CloneFileContent(oldname, newname);
if (!status) {
// if cloning did not succeed, fall back to blockwise copy
@@ -1149,14 +1149,24 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
if (!status) {
if (err) {
*err = status.GetString();
+ switch (status.Path) {
+ case cmsys::SystemTools::CopyStatus::SourcePath:
+ *err = cmStrCat(*err, " (input)");
+ break;
+ case cmsys::SystemTools::CopyStatus::DestPath:
+ *err = cmStrCat(*err, " (output)");
+ break;
+ default:
+ break;
+ }
}
return CopyResult::Failure;
}
if (perms) {
- status = SystemTools::SetPermissions(newname, perm);
- if (!status) {
+ perms = SystemTools::SetPermissions(newname, perm);
+ if (!perms) {
if (err) {
- *err = status.GetString();
+ *err = cmStrCat(perms.GetString(), " (output)");
}
return CopyResult::Failure;
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 874195b..2955d7c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2656,8 +2656,9 @@ cmFileSet* cmTarget::GetFileSet(const std::string& name)
std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
const std::string& name, const std::string& type, cmFileSetVisibility vis)
{
- auto result = this->impl->FileSets.emplace(
- std::make_pair(name, cmFileSet(name, type, vis)));
+ auto result = this->impl->FileSets.emplace(std::make_pair(
+ name,
+ cmFileSet(*this->GetMakefile()->GetCMakeInstance(), name, type, vis)));
if (result.second) {
auto bt = this->impl->Makefile->GetBacktrace();
if (type == this->impl->HeadersFileSets.TypeName) {
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index dbb0876..5e325dd 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -127,7 +127,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
this->TestGenerated = true;
// Set up generator expression evaluation context.
- cmGeneratorExpression ge(this->Test->GetBacktrace());
+ cmGeneratorExpression ge(*this->Test->GetMakefile()->GetCMakeInstance(),
+ this->Test->GetBacktrace());
// Determine if policy CMP0110 is set to NEW.
const bool quote_test_name =
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 677fdb6..7e47b4e 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -128,8 +128,8 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
: static_cast<char>(0);
if (c1 == '%' && c2 != 0) {
- result +=
- this->AddTimestampComponent(c2, timeStruct, timeT, microseconds);
+ result += this->AddTimestampComponent(c2, timeStruct, timeT, utcFlag,
+ microseconds);
++i;
} else {
result += c1;
@@ -179,7 +179,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const
}
std::string cmTimestamp::AddTimestampComponent(
- char flag, struct tm& timeStruct, const time_t timeT,
+ char flag, struct tm& timeStruct, const time_t timeT, const bool utcFlag,
const uint32_t microseconds) const
{
std::string formatString = cmStrCat('%', flag);
@@ -203,6 +203,63 @@ std::string cmTimestamp::AddTimestampComponent(
case 'Y':
case '%':
break;
+ case 'Z':
+#if defined(__GLIBC__)
+ // 'struct tm' has the time zone, so strftime can honor UTC.
+ static_cast<void>(utcFlag);
+#else
+ // 'struct tm' may not have the time zone, so strftime may
+ // use local time. Hard-code the UTC result.
+ if (utcFlag) {
+ return std::string("GMT");
+ }
+#endif
+ break;
+ case 'z': {
+#if defined(__GLIBC__)
+ // 'struct tm' has the time zone, so strftime can honor UTC.
+ static_cast<void>(utcFlag);
+#else
+ // 'struct tm' may not have the time zone, so strftime may
+ // use local time. Hard-code the UTC result.
+ if (utcFlag) {
+ return std::string("+0000");
+ }
+#endif
+#ifndef _AIX
+ break;
+#else
+ std::string xpg_sus_old;
+ bool const xpg_sus_was_set =
+ cmSystemTools::GetEnv("XPG_SUS_ENV", xpg_sus_old);
+ if (xpg_sus_was_set && xpg_sus_old == "ON") {
+ break;
+ }
+ xpg_sus_old = "XPG_SUS_ENV=" + xpg_sus_old;
+
+ // On AIX systems, %z requires XPG_SUS_ENV=ON to work as desired.
+ cmSystemTools::PutEnv("XPG_SUS_ENV=ON");
+ tzset();
+
+ char buffer[16];
+ size_t size = strftime(buffer, sizeof(buffer), "%z", &timeStruct);
+
+# ifndef CMAKE_BOOTSTRAP
+ if (xpg_sus_was_set) {
+ cmSystemTools::PutEnv(xpg_sus_old);
+ } else {
+ cmSystemTools::UnsetEnv("XPG_SUS_ENV");
+ }
+# else
+ // No UnsetEnv during bootstrap. This is good enough for CMake itself.
+ cmSystemTools::PutEnv(xpg_sus_old);
+ static_cast<void>(xpg_sus_was_set);
+# endif
+ tzset();
+
+ return std::string(buffer, size);
+#endif
+ }
case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
{
// Build a time_t for UNIX epoch and subtract from the input "timeT":
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index ada5006..05c6342 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -32,6 +32,6 @@ private:
time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const;
std::string AddTimestampComponent(char flag, struct tm& timeStruct,
- time_t timeT,
- uint32_t microseconds = 0) const;
+ time_t timeT, bool utcFlag,
+ uint32_t microseconds) const;
};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4cfb561..7e43bee 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -406,6 +406,9 @@ void cmVisualStudio10TargetGenerator::Generate()
if (!this->ComputeCudaLinkOptions()) {
return;
}
+ if (!this->ComputeMarmasmOptions()) {
+ return;
+ }
if (!this->ComputeMasmOptions()) {
return;
}
@@ -732,6 +735,11 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
this->GlobalGenerator->GetPlatformToolsetCuda() +
".props");
}
+ if (this->GlobalGenerator->IsMarmasmEnabled()) {
+ Elem(e1, "Import")
+ .Attribute("Project",
+ "$(VCTargetsPath)\\BuildCustomizations\\marmasm.props");
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
Elem(e1, "Import")
.Attribute("Project",
@@ -830,6 +838,11 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
this->GlobalGenerator->GetPlatformToolsetCuda() +
".targets");
}
+ if (this->GlobalGenerator->IsMarmasmEnabled()) {
+ Elem(e1, "Import")
+ .Attribute("Project",
+ "$(VCTargetsPath)\\BuildCustomizations\\marmasm.targets");
+ }
if (this->GlobalGenerator->IsMasmEnabled()) {
Elem(e1, "Import")
.Attribute("Project",
@@ -2077,7 +2090,7 @@ void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
const std::string& settingsPropertyValue, ConfigToSettings& toolSettings)
{
if (!settingsPropertyValue.empty()) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(settingsPropertyValue);
@@ -2177,7 +2190,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if there's any additional flags to use
if (cmValue saf = sf->GetProperty("VS_SHADER_FLAGS")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf);
for (const std::string& config : this->Configurations) {
@@ -2190,7 +2203,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if debug information should be generated
if (cmValue sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed);
for (const std::string& config : this->Configurations) {
@@ -2204,7 +2217,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
}
// Figure out if optimizations should be disabled
if (cmValue sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo);
for (const std::string& config : this->Configurations) {
@@ -2318,7 +2331,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(
this->FinishWritingSource(e2, toolSettings);
if (!deployContent.empty()) {
- cmGeneratorExpression ge;
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(deployContent);
// Deployment location cannot be set on a configuration basis
@@ -2485,6 +2498,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
const std::string& lang = si.Source->GetLanguage();
if (lang == "C" || lang == "CXX") {
tool = "ClCompile";
+ } else if (lang == "ASM_MARMASM" &&
+ this->GlobalGenerator->IsMarmasmEnabled()) {
+ tool = "MARMASM";
} else if (lang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled()) {
tool = "MASM";
@@ -2740,6 +2756,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
const std::string& srclang = source->GetLanguage();
if (srclang == "C" || srclang == "CXX") {
flagtable = gg->GetClFlagTable();
+ } else if (srclang == "ASM_MARMASM" &&
+ this->GlobalGenerator->IsMarmasmEnabled()) {
+ flagtable = gg->GetMarmasmFlagTable();
} else if (srclang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled()) {
flagtable = gg->GetMasmFlagTable();
@@ -3316,9 +3335,12 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
}
- if (this->ProjectType != VsProjectType::csproj && clOptions.IsManaged()) {
+ if (this->ProjectType != VsProjectType::csproj &&
+ (clOptions.IsManaged() || clOptions.HasFlag("CLRSupport"))) {
this->Managed = true;
- std::string managedType = clOptions.GetFlag("CompileAsManaged");
+ std::string managedType = clOptions.HasFlag("CompileAsManaged")
+ ? clOptions.GetFlag("CompileAsManaged")
+ : "Mixed";
if (managedType == "Safe" || managedType == "Pure") {
// force empty calling convention if safe clr is used
clOptions.AddFlag("CallingConvention", "");
@@ -3748,6 +3770,59 @@ void cmVisualStudio10TargetGenerator::WriteCudaLinkOptions(
cudaLinkOptions.OutputFlagMap();
}
+bool cmVisualStudio10TargetGenerator::ComputeMarmasmOptions()
+{
+ if (!this->GlobalGenerator->IsMarmasmEnabled()) {
+ return true;
+ }
+ for (std::string const& c : this->Configurations) {
+ if (!this->ComputeMarmasmOptions(c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmVisualStudio10TargetGenerator::ComputeMarmasmOptions(
+ std::string const& configName)
+{
+ cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+ auto pOptions = cm::make_unique<Options>(
+ this->LocalGenerator, Options::MarmasmCompiler, gg->GetMarmasmFlagTable());
+ Options& marmasmOptions = *pOptions;
+
+ std::string flags;
+ this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ cmBuildStep::Compile, "ASM_MARMASM",
+ configName);
+
+ marmasmOptions.Parse(flags);
+
+ // Get includes for this target
+ marmasmOptions.AddIncludes(this->GetIncludes(configName, "ASM_MARMASM"));
+
+ this->MarmasmOptions[configName] = std::move(pOptions);
+ return true;
+}
+
+void cmVisualStudio10TargetGenerator::WriteMarmasmOptions(
+ Elem& e1, std::string const& configName)
+{
+ if (!this->MSTools || !this->GlobalGenerator->IsMarmasmEnabled()) {
+ return;
+ }
+ Elem e2(e1, "MARMASM");
+
+ // Preprocessor definitions and includes are shared with clOptions.
+ OptionsHelper clOptions(*(this->ClOptions[configName]), e2);
+ clOptions.OutputPreprocessorDefinitions("ASM_MARMASM");
+
+ OptionsHelper marmasmOptions(*(this->MarmasmOptions[configName]), e2);
+ marmasmOptions.OutputAdditionalIncludeDirectories("ASM_MARMASM");
+ marmasmOptions.PrependInheritedString("AdditionalOptions");
+ marmasmOptions.OutputFlagMap();
+}
+
bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
{
if (!this->GlobalGenerator->IsMasmEnabled()) {
@@ -4448,6 +4523,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups(Elem& e0)
// output rc compile flags <ResourceCompile></ResourceCompile>
this->WriteRCOptions(e1, c);
this->WriteCudaOptions(e1, c);
+ this->WriteMarmasmOptions(e1, c);
this->WriteMasmOptions(e1, c);
this->WriteNasmOptions(e1, c);
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 17dcecd..60e9736 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -132,6 +132,9 @@ private:
bool ComputeCudaLinkOptions(std::string const& config);
void WriteCudaLinkOptions(Elem& e1, std::string const& config);
+ bool ComputeMarmasmOptions();
+ bool ComputeMarmasmOptions(std::string const& config);
+ void WriteMarmasmOptions(Elem& e1, std::string const& config);
bool ComputeMasmOptions();
bool ComputeMasmOptions(std::string const& config);
void WriteMasmOptions(Elem& e1, std::string const& config);
@@ -208,6 +211,7 @@ private:
OptionsMap RcOptions;
OptionsMap CudaOptions;
OptionsMap CudaLinkOptions;
+ OptionsMap MarmasmOptions;
OptionsMap MasmOptions;
OptionsMap NasmOptions;
OptionsMap LinkOptions;
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index ed4ee1d..20e2d22 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -24,6 +24,7 @@ public:
Compiler,
ResourceCompiler,
CudaCompiler,
+ MarmasmCompiler,
MasmCompiler,
NasmCompiler,
Linker,
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 013a87b..36c0089 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -196,7 +196,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
this->AddProjectCommands();
}
- if (mode == cmState::Project) {
+ if (mode == cmState::Project || mode == cmState::Help) {
this->LoadEnvironmentPresets();
}
@@ -1542,6 +1542,16 @@ void cmake::PrintTraceFormatVersion()
}
}
+void cmake::SetTraceRedirect(cmake* other)
+{
+ this->Trace = other->Trace;
+ this->TraceExpand = other->TraceExpand;
+ this->TraceFormatVar = other->TraceFormatVar;
+ this->TraceOnlyThisSources = other->TraceOnlyThisSources;
+
+ this->TraceRedirect = other;
+}
+
bool cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -2060,6 +2070,10 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
int cmake::Configure()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "configure");
+#endif
+
DiagLevel diagLevel;
if (this->DiagLevels.count("deprecated") == 1) {
@@ -2572,6 +2586,11 @@ int cmake::Generate()
if (!this->GlobalGenerator) {
return -1;
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+ auto profilingRAII = this->CreateProfilingEntry("project", "generate");
+#endif
+
if (!this->GlobalGenerator->Compute()) {
return -1;
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 3183577..6b585a1 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -33,6 +33,7 @@
# include <cm3p/json/value.h>
# include "cmCMakePresetsGraph.h"
+# include "cmMakefileProfilingData.h"
#endif
class cmExternalMakefileProjectGeneratorFactory;
@@ -41,9 +42,6 @@ class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
-#if !defined(CMAKE_BOOTSTRAP)
-class cmMakefileProfilingData;
-#endif
class cmMessenger;
class cmVariableWatch;
struct cmBuildOptions;
@@ -513,10 +511,19 @@ public:
{
return this->TraceOnlyThisSources;
}
- cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
+ cmGeneratedFileStream& GetTraceFile()
+ {
+ if (this->TraceRedirect) {
+ return this->TraceRedirect->GetTraceFile();
+ }
+ return this->TraceFile;
+ }
void SetTraceFile(std::string const& file);
void PrintTraceFormatVersion();
+ //! Use trace from another ::cmake instance.
+ void SetTraceRedirect(cmake* other);
+
bool GetWarnUninitialized() const { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
@@ -630,6 +637,24 @@ public:
#if !defined(CMAKE_BOOTSTRAP)
cmMakefileProfilingData& GetProfilingOutput();
bool IsProfilingEnabled() const;
+
+ cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
+ const std::string& category, const std::string& name)
+ {
+ return this->CreateProfilingEntry(
+ category, name, []() -> cm::nullopt_t { return cm::nullopt; });
+ }
+
+ template <typename ArgsFunc>
+ cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
+ const std::string& category, const std::string& name, ArgsFunc&& argsFunc)
+ {
+ if (this->IsProfilingEnabled()) {
+ return cm::make_optional<cmMakefileProfilingData::RAII>(
+ this->GetProfilingOutput(), category, name, argsFunc());
+ }
+ return cm::nullopt;
+ }
#endif
protected:
@@ -688,6 +713,7 @@ private:
bool TraceExpand = false;
TraceFormat TraceFormatVar = TRACE_HUMAN;
cmGeneratedFileStream TraceFile;
+ cmake* TraceRedirect = nullptr;
bool WarnUninitialized = false;
bool WarnUnusedCli = true;
bool CheckSystemVars = false;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 723932e..9f23667 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -208,7 +208,7 @@ int do_cmake(int ac, char const* const* av)
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(ac, av, "--")) {
// Construct and print requested documentation.
- cmake hcm(cmake::RoleInternal, cmState::Unknown);
+ cmake hcm(cmake::RoleInternal, cmState::Help);
hcm.SetHomeDirectory("");
hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
@@ -522,25 +522,8 @@ int do_build(int ac, char const* const* av)
if (ac >= 3) {
std::vector<std::string> inputArgs;
- bool hasPreset = false;
- for (int i = 2; i < ac; ++i) {
- if (strcmp(av[i], "--list-presets") == 0 ||
- cmHasLiteralPrefix(av[i], "--preset=") ||
- strcmp(av[i], "--preset") == 0) {
- hasPreset = true;
- break;
- }
- }
-
- if (hasPreset) {
- inputArgs.reserve(ac - 2);
- cm::append(inputArgs, av + 2, av + ac);
- } else {
- dir = cmSystemTools::CollapseFullPath(av[2]);
-
- inputArgs.reserve(ac - 3);
- cm::append(inputArgs, av + 3, av + ac);
- }
+ inputArgs.reserve(ac - 2);
+ cm::append(inputArgs, av + 2, av + ac);
decltype(inputArgs.size()) i = 0;
for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
@@ -555,6 +538,11 @@ int do_build(int ac, char const* const* av)
break;
}
}
+ if (!matched && i == 0) {
+ dir = cmSystemTools::CollapseFullPath(arg);
+ matched = true;
+ parsed = true;
+ }
if (!(matched && parsed)) {
dir.clear();
if (!matched) {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 67394f9..06bceb4 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2,11 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmcmd.h"
+#include <functional>
+
+#include <cm/optional>
#include <cmext/algorithm>
#include <cm3p/uv.h>
#include <fcntl.h>
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
@@ -640,20 +644,59 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
if (args.size() > 1) {
// Copy file
if (args[1] == "copy" && args.size() > 3) {
+ using CommandArgument =
+ cmCommandLineArgument<bool(const std::string& value)>;
+
+ cm::optional<std::string> targetArg;
+ std::vector<CommandArgument> argParsers{
+ { "-t", CommandArgument::Values::One,
+ CommandArgument::setToValue(targetArg) },
+ };
+
+ std::vector<std::string> files;
+ for (decltype(args.size()) i = 2; i < args.size(); i++) {
+ const std::string& arg = args[i];
+ bool matched = false;
+ for (auto const& m : argParsers) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (m.parse(arg, i, args)) {
+ break;
+ }
+ return 1; // failed to parse
+ }
+ }
+ if (!matched) {
+ files.push_back(arg);
+ }
+ }
+
// If multiple source files specified,
// then destination must be directory
- if ((args.size() > 4) &&
- (!cmSystemTools::FileIsDirectory(args.back()))) {
- std::cerr << "Error: Target (for copy command) \"" << args.back()
+ if (files.size() > 2 && !targetArg) {
+ targetArg = files.back();
+ files.pop_back();
+ }
+ if (targetArg && (!cmSystemTools::FileIsDirectory(*targetArg))) {
+ std::cerr << "Error: Target (for copy command) \"" << *targetArg
<< "\" is not a directory.\n";
return 1;
}
+ if (!targetArg) {
+ if (files.size() < 2) {
+ std::cerr
+ << "Error: No files or target specified (for copy command).\n";
+ return 1;
+ }
+ targetArg = files.back();
+ files.pop_back();
+ }
// If error occurs we want to continue copying next files.
bool return_value = false;
- for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
- if (!cmsys::SystemTools::CopyFileAlways(arg, args.back())) {
- std::cerr << "Error copying file \"" << arg << "\" to \""
- << args.back() << "\".\n";
+ for (auto const& file : files) {
+ if (!cmsys::SystemTools::CopyFileAlways(file, *targetArg)) {
+ std::cerr << "Error copying file \"" << file << "\" to \""
+ << *targetArg << "\".\n";
return_value = true;
}
}
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 45a9e6f..b25b258 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -2011,6 +2011,14 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
return 0;
}
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wshorten-64-to-32")
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wshorten-64-to-32"
+# define KWSYSPE_CLANG_DIAG_WSHORTEN
+# endif
+#endif
+
/* Get the length of time before the given timeout time arrives.
Returns 1 if the time has already arrived, and 0 otherwise. */
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -2061,6 +2069,11 @@ static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
return current;
}
+#if defined(KWSYSPE_CLANG_DIAG_WSHORTEN)
+# undef KWSYSPE_CLANG_DIAG_WSHORTEN
+# pragma clang diagnostic pop
+#endif
+
static double kwsysProcessTimeToDouble(kwsysProcessTime t)
{
return (double)t.tv_sec + (double)(t.tv_usec) * 0.000001;
diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in
index 16efaef..7cef029 100644
--- a/Source/kwsys/Status.hxx.in
+++ b/Source/kwsys/Status.hxx.in
@@ -7,6 +7,16 @@
#include <string>
+/*
+ * Detect a symbol collision with the name of this class. X11 headers use
+ * `#define Status int` instead of using `typedef` which poisons any other
+ * usage of this name.
+ */
+#if defined(Status) && defined(_X11_XLIB_H_)
+# error \
+ "Status.hxx must be included *before* any X11 headers to avoid a collision with the `Status` define that is made in its API."
+#endif
+
namespace @KWSYS_NAMESPACE@ {
/** \class Status
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index e6cc48f..20e2edb 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -482,7 +482,7 @@ protected:
unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
- bool RetreiveInformationFromCpuInfoFile();
+ bool RetrieveInformationFromCpuInfoFile();
std::string ExtractValueFromCpuInfoFile(std::string buffer, const char* word,
size_t init = 0);
@@ -1520,7 +1520,7 @@ void SystemInformationImplementation::RunCPUCheck()
#elif defined(__hpux)
this->QueryHPUXProcessor();
#elif defined(__linux) || defined(__CYGWIN__)
- this->RetreiveInformationFromCpuInfoFile();
+ this->RetrieveInformationFromCpuInfoFile();
#else
this->QueryProcessor();
#endif
@@ -3435,7 +3435,7 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
}
/** Query for the cpu status */
-bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
+bool SystemInformationImplementation::RetrieveInformationFromCpuInfoFile()
{
this->NumberOfLogicalCPU = 0;
this->NumberOfPhysicalCPU = 0;
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index a20901c..a3ab51a 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -36,6 +36,7 @@
#ifdef _WIN32
# include <cwchar>
+# include <unordered_map>
#endif
// Work-around CMake dependency scanning limitation. This must
@@ -506,16 +507,39 @@ public:
};
#ifdef _WIN32
-struct SystemToolsPathCaseCmp
+# if defined(_WIN64)
+static constexpr size_t FNV_OFFSET_BASIS = 14695981039346656037ULL;
+static constexpr size_t FNV_PRIME = 1099511628211ULL;
+# else
+static constexpr size_t FNV_OFFSET_BASIS = 2166136261U;
+static constexpr size_t FNV_PRIME = 16777619U;
+# endif
+
+// Case insensitive Fnv1a hash
+struct SystemToolsPathCaseHash
+{
+ size_t operator()(std::string const& path) const
+ {
+ size_t hash = FNV_OFFSET_BASIS;
+ for (auto c : path) {
+ hash ^= static_cast<size_t>(std::tolower(c));
+ hash *= FNV_PRIME;
+ }
+
+ return hash;
+ }
+};
+
+struct SystemToolsPathCaseEqual
{
bool operator()(std::string const& l, std::string const& r) const
{
# ifdef _MSC_VER
- return _stricmp(l.c_str(), r.c_str()) < 0;
+ return _stricmp(l.c_str(), r.c_str()) == 0;
# elif defined(__GNUC__)
- return strcasecmp(l.c_str(), r.c_str()) < 0;
+ return strcasecmp(l.c_str(), r.c_str()) == 0;
# else
- return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+ return SystemTools::Strucmp(l.c_str(), r.c_str()) == 0;
# endif
}
};
@@ -540,8 +564,12 @@ public:
bool const cache);
static std::string GetActualCaseForPathCached(std::string const& path);
static const char* GetEnvBuffered(const char* key);
- std::map<std::string, std::string, SystemToolsPathCaseCmp> FindFileMap;
- std::map<std::string, std::string, SystemToolsPathCaseCmp> PathCaseMap;
+ std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
+ SystemToolsPathCaseEqual>
+ FindFileMap;
+ std::unordered_map<std::string, std::string, SystemToolsPathCaseHash,
+ SystemToolsPathCaseEqual>
+ PathCaseMap;
std::map<std::string, std::string> EnvMap;
#endif
#ifdef __CYGWIN__
@@ -2262,8 +2290,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir)
return new_destination + '/' + SystemTools::GetFilenameName(source);
}
-Status SystemTools::CopyFileIfDifferent(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus 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
@@ -2280,7 +2308,7 @@ Status SystemTools::CopyFileIfDifferent(std::string const& source,
}
}
// at this point the files must be the same so return true
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
#define KWSYS_ST_BUFFER 4096
@@ -2406,13 +2434,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
return false;
}
-Status SystemTools::CopyFileContentBlockwise(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus 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 Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
// try and remove the destination file so that read only destination files
@@ -2424,7 +2452,7 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
if (!fout) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
// This copy loop is very sensitive on certain platforms with
@@ -2453,10 +2481,10 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
fout.close();
if (!fout) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
/**
@@ -2471,13 +2499,13 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
* - The underlying filesystem does not support file cloning
* - An unspecified error occurred
*/
-Status SystemTools::CloneFileContent(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus 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 Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
SystemTools::RemoveFile(destination);
@@ -2485,14 +2513,14 @@ Status SystemTools::CloneFileContent(std::string const& 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();
+ CopyStatus status{ Status::POSIX_errno(), CopyStatus::DestPath };
close(in);
return status;
}
- Status status = Status::Success();
+ CopyStatus status{ Status::Success(), CopyStatus::NoPath };
if (ioctl(out, FICLONE, in) < 0) {
- status = Status::POSIX_errno();
+ status = CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
close(in);
close(out);
@@ -2504,40 +2532,41 @@ Status SystemTools::CloneFileContent(std::string const& source,
// be updated by `copy_file_if_different` and `copy_file`.
if (copyfile(source.c_str(), destination.c_str(), nullptr,
COPYFILE_METADATA | COPYFILE_CLONE) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
# if KWSYS_CXX_HAS_UTIMENSAT
// utimensat is only available on newer Unixes and macOS 10.13+
if (utimensat(AT_FDCWD, destination.c_str(), nullptr, 0) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# else
// fall back to utimes
if (utimes(destination.c_str(), nullptr) < 0) {
- return Status::POSIX_errno();
+ return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# endif
- return Status::Success();
+ return CopyStatus{ Status::Success(), CopyStatus::NoPath };
#else
(void)source;
(void)destination;
- return Status::POSIX(ENOSYS);
+ return CopyStatus{ Status::POSIX(ENOSYS), CopyStatus::NoPath };
#endif
}
/**
* Copy a file named by "source" to the file named by "destination".
*/
-Status SystemTools::CopyFileAlways(std::string const& source,
- std::string const& destination)
+SystemTools::CopyStatus SystemTools::CopyFileAlways(
+ std::string const& source, std::string const& destination)
{
- Status status;
+ CopyStatus status;
mode_t perm = 0;
Status perms = SystemTools::GetPermissions(source, perm);
std::string real_destination = destination;
if (SystemTools::FileIsDirectory(source)) {
- status = SystemTools::MakeDirectory(destination);
+ status = CopyStatus{ SystemTools::MakeDirectory(destination),
+ CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2562,7 +2591,8 @@ Status SystemTools::CopyFileAlways(std::string const& source,
// Create destination directory
if (!destination_dir.empty()) {
- status = SystemTools::MakeDirectory(destination_dir);
+ status = CopyStatus{ SystemTools::MakeDirectory(destination_dir),
+ CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2578,13 +2608,15 @@ Status SystemTools::CopyFileAlways(std::string const& source,
}
}
if (perms) {
- status = SystemTools::SetPermissions(real_destination, perm);
+ status = CopyStatus{ SystemTools::SetPermissions(real_destination, perm),
+ CopyStatus::DestPath };
}
return status;
}
-Status SystemTools::CopyAFile(std::string const& source,
- std::string const& destination, bool always)
+SystemTools::CopyStatus SystemTools::CopyAFile(std::string const& source,
+ std::string const& destination,
+ bool always)
{
if (always) {
return SystemTools::CopyFileAlways(source, destination);
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index acce015..56b65fd 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -566,11 +566,34 @@ public:
const mode_t* mode = nullptr);
/**
+ * Represent the result of a file copy operation.
+ * This is the result 'Status' and, if the operation failed,
+ * an indication of whether the error occurred on the source
+ * or destination path.
+ */
+ struct CopyStatus : public Status
+ {
+ enum WhichPath
+ {
+ NoPath,
+ SourcePath,
+ DestPath,
+ };
+ CopyStatus() = default;
+ CopyStatus(Status s, WhichPath p)
+ : Status(s)
+ , Path(p)
+ {
+ }
+ WhichPath Path = NoPath;
+ };
+
+ /**
* Copy the source file to the destination file only
* if the two files differ.
*/
- static Status CopyFileIfDifferent(std::string const& source,
- std::string const& destination);
+ static CopyStatus CopyFileIfDifferent(std::string const& source,
+ std::string const& destination);
/**
* Compare the contents of two files. Return true if different
@@ -588,13 +611,13 @@ public:
/**
* Blockwise copy source to destination file
*/
- static Status CopyFileContentBlockwise(std::string const& source,
- std::string const& destination);
+ static CopyStatus 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);
+ static CopyStatus CloneFileContent(std::string const& source,
+ std::string const& destination);
/**
* Return true if the two files are the same file
@@ -604,16 +627,17 @@ public:
/**
* Copy a file.
*/
- static Status CopyFileAlways(std::string const& source,
- std::string const& destination);
+ static CopyStatus 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 Status CopyAFile(std::string const& source,
- std::string const& destination, bool always = true);
+ static CopyStatus CopyAFile(std::string const& source,
+ std::string const& destination,
+ bool always = true);
/**
* Copy content directory to another directory with all files and
diff --git a/Templates/MSBuild/FlagTables/v10_MARMASM.json b/Templates/MSBuild/FlagTables/v10_MARMASM.json
new file mode 100644
index 0000000..5c8de1f
--- /dev/null
+++ b/Templates/MSBuild/FlagTables/v10_MARMASM.json
@@ -0,0 +1,149 @@
+[
+ {
+ "name": "16BitThumbInstructions",
+ "switch": "16",
+ "comment": "Assemble source as 16-bit Thumb instructions.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "32BitArmInstructions",
+ "switch": "32",
+ "comment": "Assemble source as 32-bit ARM instructions.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "CoffThumb2Only",
+ "switch": "coff_thumb2_only",
+ "comment": "Allow only Thumb-2 code.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "ErrorReporting",
+ "switch": "errorReport:prompt",
+ "comment": "Prompt to send report immediately (/errorReport:prompt)",
+ "value": "0",
+ "flags": []
+ },
+ {
+ "name": "ErrorReporting",
+ "switch": "errorReport:queue",
+ "comment": "Prompt to send report at the next logon (/errorReport:queue)",
+ "value": "1",
+ "flags": []
+ },
+ {
+ "name": "ErrorReporting",
+ "switch": "errorReport:send",
+ "comment": "Automatically send report (/errorReport:send)",
+ "value": "2",
+ "flags": []
+ },
+ {
+ "name": "ErrorReporting",
+ "switch": "errorReport:none",
+ "comment": "Do not send report (/errorReport:none)",
+ "value": "3",
+ "flags": []
+ },
+ {
+ "name": "Errors",
+ "switch": "errors",
+ "comment": "Redirect error and warning messages.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "FunctionOverride",
+ "switch": "funcOverride",
+ "comment": "Emit function overriding support for the specified function.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "DebugInformation",
+ "switch": "g",
+ "comment": "Generate debugging information.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "Machine",
+ "switch": "machine",
+ "comment": "Specify the machine type to set in the PE header.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "NoEsc",
+ "switch": "noesc",
+ "comment": "Ignore C-style escaped special characters.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "NoLogo",
+ "switch": "nologo",
+ "comment": "Suppress the copyright banner.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "NoWarn",
+ "switch": "nowarn",
+ "comment": "Disable all warning messages.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "ObjectFile",
+ "switch": "o",
+ "comment": "Specify the name of the object (output) file.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "ItBlocks",
+ "switch": "oldit",
+ "comment": "Generate ARMv7-style IT blocks.",
+ "value": "true",
+ "flags": []
+ },
+ {
+ "name": "PredefineDirective",
+ "switch": "predefine",
+ "comment": "Specify a SETA, SETL, or SETS directive to predefine a symbol.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "SourceLink",
+ "switch": "sourcelink",
+ "comment": "Specify the configuration file that contains a simple mapping of local file paths to URLs for source files to display in the debugger.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ },
+ {
+ "name": "CommandLineArgumentsViaFile",
+ "switch": "via",
+ "comment": "Read extra command-line arguments from the specified file.",
+ "value": "",
+ "flags": [
+ "UserValue"
+ ]
+ }
+]
diff --git a/Templates/MSBuild/FlagTables/v142_CL.json b/Templates/MSBuild/FlagTables/v142_CL.json
index c76c040..4f2dce8 100644
--- a/Templates/MSBuild/FlagTables/v142_CL.json
+++ b/Templates/MSBuild/FlagTables/v142_CL.json
@@ -56,6 +56,13 @@
"flags": []
},
{
+ "name": "CLRSupport",
+ "switch": "clr:netcore",
+ "comment": ".NET Core Runtime Support",
+ "value": "NetCore",
+ "flags": []
+ },
+ {
"name": "WarningLevel",
"switch": "W0",
"comment": "Turn Off All Warnings",
diff --git a/Templates/MSBuild/FlagTables/v143_CL.json b/Templates/MSBuild/FlagTables/v143_CL.json
index 993fbf1..119e171 100644
--- a/Templates/MSBuild/FlagTables/v143_CL.json
+++ b/Templates/MSBuild/FlagTables/v143_CL.json
@@ -56,6 +56,13 @@
"flags": []
},
{
+ "name": "CLRSupport",
+ "switch": "clr:netcore",
+ "comment": ".NET Core Runtime Support",
+ "value": "NetCore",
+ "flags": []
+ },
+ {
"name": "WarningLevel",
"switch": "W0",
"comment": "Turn Off All Warnings",
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 6e35df9..d4ef7ee 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -271,14 +271,6 @@ if(BUILD_TESTING)
find_package(Qt5Widgets QUIET NO_MODULE)
endif()
- if(NOT CMake_TEST_EXTERNAL_CMAKE)
- add_subdirectory(CMakeLib)
- endif()
- add_subdirectory(CMakeOnly)
- add_subdirectory(RunCMake)
-
- add_subdirectory(FindPackageModeMakefileTest)
-
# Collect a list of all test build directories.
set(TEST_BUILD_DIRS)
@@ -342,6 +334,27 @@ if(BUILD_TESTING)
endif()
endif()
+ if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT)
+ if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND
+ ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
+ (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
+ if(CMAKE_GENERATOR STREQUAL "Xcode")
+ set(CMake_TEST_XCODE_SWIFT 1)
+ endif()
+ endif()
+ endif()
+ if(NOT DEFINED CMake_TEST_Swift)
+ if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT)
+ set(CMake_TEST_Swift 1)
+ endif()
+ endif()
+
+ if(NOT DEFINED CMake_TEST_OBJC)
+ if(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
+ set(CMake_TEST_OBJC 1)
+ endif()
+ endif()
+
# Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value,
# whichever is greater.
set(CMAKE_LONG_TEST_TIMEOUT 1500)
@@ -352,6 +365,14 @@ if(BUILD_TESTING)
set(CMAKE_LONG_TEST_TIMEOUT 1500)
endif()
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ add_subdirectory(CMakeLib)
+ endif()
+ add_subdirectory(CMakeOnly)
+ add_subdirectory(RunCMake)
+
+ add_subdirectory(FindPackageModeMakefileTest)
+
add_test(NAME CMake.Copyright
COMMAND ${CMAKE_CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeCopyright.cmake)
@@ -380,16 +401,7 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
set_tests_properties(MissingSourceFile PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
- if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT)
- if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND
- ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
- (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
- if(CMAKE_GENERATOR STREQUAL "Xcode")
- set(CMake_TEST_XCODE_SWIFT 1)
- endif()
- endif()
- endif()
- if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT)
+ if(CMake_TEST_Swift)
ADD_TEST_MACRO(SwiftOnly SwiftOnly)
if(CMake_TEST_XCODE_SWIFT)
ADD_TEST_MACRO(SwiftMix SwiftMix)
@@ -432,6 +444,11 @@ if(BUILD_TESTING)
endif()
endif()
+ if(CMake_TEST_OBJC)
+ add_subdirectory(ObjC)
+ add_subdirectory(ObjCXX)
+ endif()
+
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
ADD_TEST_MACRO(CSharpOnly CSharpOnly)
if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
@@ -2144,10 +2161,16 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MFC")
endif()
+ if(MSVC AND NOT MSVC_VERSION LESS 1700
+ AND (CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
+ )
+ ADD_TEST_MACRO(VSMARMASM VSMARMASM)
+ endif()
+
if(MSVC AND NOT MSVC_VERSION LESS 1310
AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 "
OR CMAKE_SIZEOF_VOID_P EQUAL 4)
- AND (NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
+ AND (NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
)
ADD_TEST_MACRO(VSMASM VSMASM)
endif()
@@ -2500,9 +2523,6 @@ if(BUILD_TESTING)
-Dgen=${CMAKE_GENERATOR}
-P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest")
-
- add_subdirectory(ObjC)
- add_subdirectory(ObjCXX)
endif()
endif()
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index 0907d03..c990eb4 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -96,8 +96,8 @@ foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG
check_version_string(${VTEST} ${VTEST}_VERSION_STRING)
endforeach()
-foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2
- HDF5 JPEG LibArchive OPENSCENEGRAPH Ruby RUBY SWIG Protobuf)
+foreach(VTEST BISON Boost BZIP2 CUDA DOXYGEN FLEX GIF GTK2
+ HDF5 JPEG LibArchive LIBLZMA OPENSCENEGRAPH Ruby RUBY SWIG Protobuf ZLIB)
check_version_string(${VTEST} ${VTEST}_VERSION)
endforeach()
diff --git a/Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake b/Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake
new file mode 100644
index 0000000..eb2eb42
--- /dev/null
+++ b/Tests/CMakeTests/String-TIMESTAMP-TimeZone.cmake
@@ -0,0 +1,22 @@
+string(TIMESTAMP output "%z")
+
+STRING(LENGTH output output_length)
+
+message("~${output}~")
+
+set(expected_output_length 6)
+
+if(NOT(${output_length} EQUAL ${expected_output_length}))
+ message(FATAL_ERROR "expected ${expected_output_length} entries in output with all specifiers; found ${output_length}")
+endif()
+
+string(SUBSTRING ${output} 0 1 output0)
+string(SUBSTRING ${output} 4 1 output4)
+
+if(NOT((${output0} STREQUAL "-") OR (${output0} STREQUAL "+")))
+ message(FATAL_ERROR "expected output[0] equ '+' or '-'; found: '${output0}'")
+endif()
+
+if(NOT((${output4} STREQUAL "0") OR (${output4} STREQUAL "5")))
+ message(FATAL_ERROR "expected output[4] equ '0' or '5'; found: '${output4}'")
+endif()
diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in
index 154afa7..5f8b111 100644
--- a/Tests/CMakeTests/StringTest.cmake.in
+++ b/Tests/CMakeTests/StringTest.cmake.in
@@ -44,6 +44,8 @@ set(TIMESTAMP-IncompleteSpecifier-RESULT 0)
set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~")
set(TIMESTAMP-AllSpecifiers-RESULT 0)
set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~")
+set(TIMESTAMP-TimeZone-RESULT 0)
+set(TIMESTAMP-TimeZone-STDERR "~[-,+][0-9][0-9][0-9][0-9]~")
set(TIMESTAMP-MonthWeekNames-RESULT 0)
set(TIMESTAMP-MonthWeekNames-STDERR "~[^%]+;[^%]+~")
set(TIMESTAMP-UnixTime-RESULT 0)
@@ -75,6 +77,7 @@ check_cmake_test(String
TIMESTAMP-IncompleteSpecifier
TIMESTAMP-AllSpecifiers
TIMESTAMP-MonthWeekNames
+ TIMESTAMP-TimeZone
TIMESTAMP-UnixTime
)
diff --git a/Tests/CTestUpdateGIT.cmake.in b/Tests/CTestUpdateGIT.cmake.in
index a3ef4eb..7fddaa3 100644
--- a/Tests/CTestUpdateGIT.cmake.in
+++ b/Tests/CTestUpdateGIT.cmake.in
@@ -34,7 +34,7 @@ endif()
# Adapt to the system default branch name.
execute_process(
- COMMAND ${GIT} config --get init.defaultBranch
+ COMMAND ${GIT} --git-dir= config --get init.defaultBranch
RESULT_VARIABLE defaultBranchFailed
OUTPUT_VARIABLE defaultBranch
ERROR_VARIABLE defaultBranchError
diff --git a/Tests/CheckSourceTree/check.cmake b/Tests/CheckSourceTree/check.cmake
index c2e3529..655e419 100644
--- a/Tests/CheckSourceTree/check.cmake
+++ b/Tests/CheckSourceTree/check.cmake
@@ -3,6 +3,15 @@ if(DEFINED ENV{CTEST_REAL_HOME})
set(ENV{HOME} "$ENV{CTEST_REAL_HOME}")
endif()
+file(GLOB known_files
+ "${CMake_SOURCE_DIR}/Tests/Java/hs_err_pid*.log"
+ "${CMake_SOURCE_DIR}/Tests/JavaExportImport/InstallExport/hs_err_pid*.log"
+ "${CMake_SOURCE_DIR}/Tests/JavaNativeHeaders/hs_err_pid*.log"
+ )
+if(known_files)
+ file(REMOVE ${known_files})
+endif()
+
execute_process(
COMMAND "${GIT_EXECUTABLE}" status
WORKING_DIRECTORY "${CMake_SOURCE_DIR}"
diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt
index 08c897c..e391a6f 100644
--- a/Tests/CustomCommandByproducts/CMakeLists.txt
+++ b/Tests/CustomCommandByproducts/CMakeLists.txt
@@ -149,6 +149,29 @@ set_property(TARGET ExternalLibraryWithSubstitution PROPERTY IMPORTED_LOCATION
${binary_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX})
add_dependencies(ExternalLibraryWithSubstitution ExtTargetSubst)
+# Generate the library file of an imported target as an install byproduct
+# of an external project. The byproduct uses <INSTALL_DIR> that is substituted
+# by the real install path
+if(_isMultiConfig)
+ set(cfg /${CMAKE_CFG_INTDIR})
+else()
+ set(cfg)
+endif()
+include(ExternalProject)
+ExternalProject_Add(ExtTargetInstallSubst
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND
+ "${CMAKE_COMMAND}" -E copy_directory "<BINARY_DIR>${cfg}" "<INSTALL_DIR>${cfg}"
+ BUILD_BYPRODUCTS "<BINARY_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ INSTALL_BYPRODUCTS "<INSTALL_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ )
+ExternalProject_Get_Property(ExtTargetInstallSubst install_dir)
+add_library(ExternalLibraryWithInstallDirSubstitution STATIC IMPORTED)
+set_property(TARGET ExternalLibraryWithInstallDirSubstitution PROPERTY IMPORTED_LOCATION
+ ${install_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX})
+add_dependencies(ExternalLibraryWithInstallDirSubstitution ExtTargetInstallSubst)
+
# Add an executable consuming all the byproducts.
add_executable(CustomCommandByproducts
CustomCommandByproducts.c
@@ -169,6 +192,18 @@ add_dependencies(CustomCommandByproducts Producer2)
target_link_libraries(CustomCommandByproducts ExternalLibrary)
+add_executable(ExternalLibraryByproducts ExternalLibraryByproducts.c)
+target_link_libraries(ExternalLibraryByproducts ExternalLibrary)
+
+add_executable(ExternalLibraryByproducts_WithSubstitution ExternalLibraryByproducts.c)
+target_link_libraries(ExternalLibraryByproducts_WithSubstitution ExternalLibraryWithSubstitution)
+
+add_executable(ExternalLibraryByproducts_WithInstallDirSubstitution ExternalLibraryByproducts.c)
+target_link_libraries(
+ ExternalLibraryByproducts_WithInstallDirSubstitution
+ ExternalLibraryWithInstallDirSubstitution
+)
+
if(CMAKE_GENERATOR STREQUAL "Ninja")
add_custom_target(CheckNinja ALL
COMMENT "Checking build.ninja"
diff --git a/Tests/CustomCommandByproducts/ExternalLibraryByproducts.c b/Tests/CustomCommandByproducts/ExternalLibraryByproducts.c
new file mode 100644
index 0000000..3588e53
--- /dev/null
+++ b/Tests/CustomCommandByproducts/ExternalLibraryByproducts.c
@@ -0,0 +1,5 @@
+extern int ExternalLibrary(void);
+int main(void)
+{
+ return (ExternalLibrary() + 1);
+}
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index ebbe288..6187966 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -261,13 +261,24 @@ else()
set(test_shell_path2 /shell/path /another/path)
endif()
+set(test_shell_path_genex "$<SHELL_PATH:${test_shell_path}>")
+set(test_shell_path2_genex "$<SHELL_PATH:${test_shell_path2}>")
+if(msys1_prefix)
+ # Add a prefix to the value produced by the genex so that the path does
+ # not look absolute, thus suppressing conversion by MSYS 1.0 bash.
+ set(test_shell_path_genex "${msys1_prefix}${test_shell_path_genex}")
+ # There is no way to suppress conversion of the second path in
+ # MSYS 1.0 bash, so do the comparison at generate time instead.
+ set(test_shell_path2_genex "$<STREQUAL:${test_shell_path2_genex},/c/shell/path:/d/another/path>")
+endif()
+
add_custom_target(check-part4 ALL
COMMAND ${msys2_no_conv} ${CMAKE_COMMAND}
# Prefix path to bypass its further conversion when being processed by
# CMake as command-line argument
-Dmsys1_prefix=${msys1_prefix}
- -Dtest_shell_path=${msys1_prefix}$<SHELL_PATH:${test_shell_path}>
- "-Dtest_shell_path2=$<SHELL_PATH:${test_shell_path2}>"
+ "-Dtest_shell_path=${test_shell_path_genex}"
+ "-Dtest_shell_path2=${test_shell_path2_genex}"
-Dif_1=$<IF:1,a,b>
-Dif_2=$<IF:0,a,b>
-Dif_3=$<IF:$<EQUAL:10,30>,a,b>
diff --git a/Tests/GeneratorExpression/check-part4.cmake b/Tests/GeneratorExpression/check-part4.cmake
index a7e0944..28f3699 100644
--- a/Tests/GeneratorExpression/check-part4.cmake
+++ b/Tests/GeneratorExpression/check-part4.cmake
@@ -16,8 +16,13 @@ else()
check(test_shell_path [[/shell/path]])
endif()
if(WIN32)
- if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles" AND NOT msys1_prefix)
- check(test_shell_path2 [[/c/shell/path:/d/another/path]])
+ if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
+ if(msys1_prefix)
+ # The comparison was done at generate time with the STREQUAL genex.
+ check(test_shell_path2 [[1]])
+ else()
+ check(test_shell_path2 [[/c/shell/path:/d/another/path]])
+ endif()
elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
check(test_shell_path2 [[c:/shell/path;d:/another/path]])
else()
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
index fe57d56..024c647 100644
--- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -7,7 +7,7 @@ set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>)
add_library(autoexport3 SHARED cppCLI.cxx)
if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600
- AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
+ AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "")
endif()
@@ -17,7 +17,7 @@ if(MSVC)
add_library(autoexport_for_exec SHARED hello2.c)
target_link_libraries(autoexport_for_exec say)
if(NOT MSVC_VERSION VERSION_LESS 1600 AND
- NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
+ NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
enable_language(ASM_MASM)
target_sources(autoexport PRIVATE nop.asm)
set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt b/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt
new file mode 100644
index 0000000..66d3016
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0104-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0104 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/CMP0106/CMP0106-OLD-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt
new file mode 100644
index 0000000..ef48d5c
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0106-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0106 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/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 3038ed8..1174d0d 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -299,8 +299,8 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(CompilerChange)
endif()
add_RunCMake_test(CompilerNotFound)
-if (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
- list(APPEND CompilerTest_ARGS -DCMake_TEST_OBJC=1)
+if(DEFINED CMake_TEST_OBJC)
+ list(APPEND CompilerTest_ARGS -DCMake_TEST_OBJC=${CMake_TEST_OBJC})
endif()
if(CMAKE_Fortran_COMPILER)
list(APPEND CompilerTest_ARGS -DCMake_TEST_Fortran=1)
@@ -351,6 +351,7 @@ add_RunCMake_test(GenEx-LINK_LIBRARY)
add_RunCMake_test(GenEx-LINK_GROUP)
add_RunCMake_test(GenEx-TARGET_FILE -DLINKER_SUPPORTS_PDB=${LINKER_SUPPORTS_PDB})
add_RunCMake_test(GenEx-GENEX_EVAL)
+add_RunCMake_test(GenEx-TARGET_PROPERTY)
add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS)
add_RunCMake_test(GenEx-PATH)
add_RunCMake_test(GenEx-PATH_EQUAL)
@@ -361,11 +362,10 @@ if(XCODE_VERSION)
set(GeneratorToolset_ARGS -DXCODE_VERSION=${XCODE_VERSION})
endif()
add_RunCMake_test(GeneratorToolset)
-add_RunCMake_test(GetPrerequisites)
+add_RunCMake_test(GetPrerequisites -DSAMPLE_EXE=$<TARGET_FILE:exit_code>)
add_RunCMake_test(GNUInstallDirs -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(GoogleTest) # Note: does not actually depend on Google Test
add_RunCMake_test(Graphviz)
-add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(LinkItemValidation)
add_RunCMake_test(LinkStatic)
@@ -502,64 +502,15 @@ if(APPLE)
endif()
function(add_RunCMake_test_try_compile)
- if(CMAKE_VERSION VERSION_LESS 3.9.20170907 AND "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
- # Older CMake versions do not know about MSVC language standards.
- # Approximate our logic from MSVC-CXX.cmake.
- if ((NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.24215.1 AND
- CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) OR
- NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10.25017)
- set(CMAKE_CXX_STANDARD_DEFAULT 14)
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
- set(CMAKE_CXX_STANDARD_DEFAULT "")
- else()
- unset(CMAKE_CXX_STANDARD_DEFAULT)
- endif()
- endif()
- if(CMAKE_VERSION VERSION_LESS 3.18.20200813 AND "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC")
- # Older CMake versions do not know about MSVC language standards.
- # Approximate our logic from MSVC-C.cmake.
- if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 19.27)
- set(CMAKE_C_STANDARD_DEFAULT 99)
- else()
- 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()
- if(CMAKE_VERSION VERSION_LESS 3.20.6 AND "x${CMAKE_C_COMPILER_ID}" STREQUAL "xIntelLLVM" AND "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
- # Older CMake versions accidentally set the default standards to empty when
- # IntelLLVM targets the MSVC ABI, thus not activating standard selection.
- # Approximate the logic from IntelLLVM-{C,CXX}.cmake.
- if(DEFINED CMAKE_C_STANDARD_DEFAULT AND "${CMAKE_C_STANDARD_DEFAULT}" STREQUAL "")
- set(CMAKE_C_STANDARD_DEFAULT 17)
- endif()
- if(DEFINED CMAKE_CXX_STANDARD_DEFAULT AND "${CMAKE_CXX_STANDARD_DEFAULT}" STREQUAL "")
- set(CMAKE_CXX_STANDARD_DEFAULT 14)
- endif()
- endif()
foreach(
var
IN ITEMS
CMAKE_SYSTEM_NAME
- CMAKE_C_COMPILER_ID
- CMAKE_C_COMPILER_VERSION
- CMAKE_C_STANDARD_DEFAULT
- CMAKE_CXX_COMPILER_ID
- CMAKE_CXX_COMPILER_VERSION
- CMAKE_CXX_STANDARD_DEFAULT
CMake_TEST_CUDA
CMake_TEST_ISPC
CMake_TEST_HIP
+ CMake_TEST_OBJC
CMake_TEST_FILESYSTEM_1S
- CMAKE_OBJC_STANDARD_DEFAULT
- CMAKE_OBJCXX_STANDARD_DEFAULT
)
if(DEFINED ${var})
list(APPEND try_compile_ARGS -D${var}=${${var}})
@@ -752,11 +703,13 @@ add_RunCMake_test(target_sources)
add_RunCMake_test(CheckCompilerFlag -DCMake_TEST_CUDA=${CMake_TEST_CUDA}
-DCMake_TEST_ISPC=${CMake_TEST_ISPC}
-DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}
- -DCMake_TEST_HIP=${CMake_TEST_HIP})
+ -DCMake_TEST_HIP=${CMake_TEST_HIP}
+ -DCMake_TEST_Swift=${CMake_TEST_Swift})
add_RunCMake_test(CheckSourceCompiles -DCMake_TEST_CUDA=${CMake_TEST_CUDA}
-DCMake_TEST_ISPC=${CMake_TEST_ISPC}
-DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}
- -DCMake_TEST_HIP=${CMake_TEST_HIP})
+ -DCMake_TEST_HIP=${CMake_TEST_HIP}
+ -DCMake_TEST_Swift=${CMake_TEST_Swift})
add_RunCMake_test(CheckSourceRuns -DCMake_TEST_CUDA=${CMake_TEST_CUDA}
-DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}
-DCMake_TEST_HIP=${CMake_TEST_HIP})
@@ -896,13 +849,13 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
if(DEFINED CMake_TEST_ISPC)
list(APPEND CompilerLauncher_ARGS -DCMake_TEST_ISPC=${CMake_TEST_ISPC})
endif()
+ if(DEFINED CMake_TEST_OBJC)
+ list(APPEND CompilerLauncher_ARGS -DCMake_TEST_OBJC=${CMake_TEST_OBJC})
+ list(APPEND LinkerLauncher_ARGS -DCMake_TEST_OBJC=${CMake_TEST_OBJC})
+ endif()
if(CMAKE_Fortran_COMPILER)
list(APPEND CompilerLauncher_ARGS -DCMake_TEST_Fortran=1)
endif()
- if (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
- list(APPEND CompilerLauncher_ARGS -DCMake_TEST_OBJC=1)
- list(APPEND LinkerLauncher_ARGS -DCMake_TEST_OBJC=1)
- endif()
add_RunCMake_test(CompilerLauncher)
set_property(TEST RunCMake.CompilerLauncher APPEND
PROPERTY LABELS "CUDA;HIP;ISPC")
diff --git a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
index 1c7b836..5bd0158 100644
--- a/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresetsTest/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
# Presets do not support legacy VS generator name architecture suffix.
if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index df3e82a..8c35fe5 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -3,9 +3,6 @@ include(RunCTest)
set(RunCMake_TEST_TIMEOUT 60)
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
run_cmake_command(repeat-opt-bad1
${CMAKE_CTEST_COMMAND} --repeat until-pass
)
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index 3f17c1f..921fabd 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -120,7 +120,9 @@ function (run_cxx_module_test directory)
if (RunCMake_CXXModules_INSTALL)
run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
endif ()
- run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
+ if (NOT RunCMake_CXXModules_NO_TEST)
+ run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
+ endif ()
endfunction ()
string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
@@ -132,6 +134,10 @@ if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(generated)
run_cxx_module_test(public-req-private)
run_cxx_module_test(deep-chain)
+ run_cxx_module_test(duplicate)
+ set(RunCMake_CXXModules_NO_TEST 1)
+ run_cxx_module_test(circular)
+ unset(RunCMake_CXXModules_NO_TEST)
endif ()
# Tests which use named modules in shared libraries.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt b/Tests/RunCMake/CXXModules/examples/circular-build-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt
+++ b/Tests/RunCMake/CXXModules/examples/circular-build-result.txt
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt b/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt
new file mode 100644
index 0000000..433b461
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt
@@ -0,0 +1 @@
+(Ninja generators)?(build stopped: dependency cycle:)
diff --git a/Tests/RunCMake/CXXModules/examples/circular-stderr.txt b/Tests/RunCMake/CXXModules/examples/circular-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/circular-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt
new file mode 100644
index 0000000..4d1997c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_circular CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(circular STATIC)
+target_sources(circular
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ circular-a.cppm
+ circular-b.cppm)
+target_compile_features(circular PUBLIC cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm b/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm
new file mode 100644
index 0000000..eea842b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm
@@ -0,0 +1,6 @@
+export module a;
+import b;
+
+export int a() {
+ return b();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm b/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm
new file mode 100644
index 0000000..fc6dc42
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm
@@ -0,0 +1,6 @@
+export module b;
+import a;
+
+export int b() {
+ return a();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt b/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/duplicate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt
new file mode 100644
index 0000000..27be7a8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_duplicate CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_executable(duplicate)
+target_sources(duplicate
+ PRIVATE
+ main.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ duplicate.cxx)
+target_compile_features(duplicate PRIVATE cxx_std_20)
+target_compile_definitions(duplicate PRIVATE NDUPLICATE=1)
+
+add_executable(duplicate2)
+target_sources(duplicate2
+ PRIVATE
+ main.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ duplicate.cxx)
+target_compile_features(duplicate2 PRIVATE cxx_std_20)
+target_compile_definitions(duplicate2 PRIVATE NDUPLICATE=2)
+
+add_test(NAME duplicate COMMAND duplicate)
+set_property(TEST duplicate
+ PROPERTY
+ PASS_REGULAR_EXPRESSION "From duplicate #1")
+add_test(NAME duplicate2 COMMAND duplicate2)
+set_property(TEST duplicate2
+ PROPERTY
+ PASS_REGULAR_EXPRESSION "From duplicate #2")
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx b/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx
new file mode 100644
index 0000000..c0c820b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx
@@ -0,0 +1,11 @@
+module;
+
+#include <iostream>
+
+export module duplicate;
+
+export int from_import()
+{
+ std::cerr << "From duplicate #" << NDUPLICATE << std::endl;
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx b/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx
new file mode 100644
index 0000000..c2c0636
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx
@@ -0,0 +1,6 @@
+import duplicate;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CheckCompilerFlag/CheckCompilerFlagSwift.cmake b/Tests/RunCMake/CheckCompilerFlag/CheckCompilerFlagSwift.cmake
new file mode 100644
index 0000000..23b3006
--- /dev/null
+++ b/Tests/RunCMake/CheckCompilerFlag/CheckCompilerFlagSwift.cmake
@@ -0,0 +1,21 @@
+enable_language (Swift)
+include(CheckCompilerFlag)
+
+set(Swift 1)
+
+# test that the check uses an isolated locale
+set(_env_LC_ALL "${LC_ALL}")
+set(ENV{LC_ALL} "BAD")
+
+check_compiler_flag(Swift "-foo-as-blarpy" SHOULD_FAIL)
+if(SHOULD_FAIL)
+ message(SEND_ERROR "invalid Swift compile flag didn't fail.")
+endif()
+
+check_compiler_flag(Swift "-parseable-output" SHOULD_WORK)
+if(NOT SHOULD_WORK)
+ message(SEND_ERROR "Swift compiler flag '-parseable-output' check failed")
+endif()
+
+# Reset locale
+set(ENV{LC_ALL} ${_env_LC_ALL})
diff --git a/Tests/RunCMake/CheckCompilerFlag/RunCMakeTest.cmake b/Tests/RunCMake/CheckCompilerFlag/RunCMakeTest.cmake
index b0e025c..81429a6 100644
--- a/Tests/RunCMake/CheckCompilerFlag/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckCompilerFlag/RunCMakeTest.cmake
@@ -32,3 +32,7 @@ endif()
if(APPLE)
run_cmake(HeaderpadWorkaround)
endif()
+
+if(CMake_TEST_Swift)
+ run_cmake(CheckCompilerFlagSwift)
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake b/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake
new file mode 100644
index 0000000..767fa69
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/CheckSourceCompilesSwift.cmake
@@ -0,0 +1,15 @@
+enable_language(Swift)
+include(CheckSourceCompiles)
+
+set(Swift 1) # test that this is tolerated
+
+check_source_compiles(Swift "baz()" SHOULD_FAIL)
+
+if(SHOULD_FAIL)
+ message(SEND_ERROR "invalid Swift source didn't fail.")
+endif()
+
+check_source_compiles(Swift "print(\"Hello, CMake\")" SHOULD_BUILD)
+if(NOT SHOULD_BUILD)
+ message(SEND_ERROR "Test failed for valid Swift source.")
+endif()
diff --git a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
index df77d3d..2ed3e36 100644
--- a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
@@ -31,3 +31,7 @@ endif()
if(CMake_TEST_HIP)
run_cmake(CheckSourceCompilesHIP)
endif()
+
+if(CMake_TEST_Swift)
+ run_cmake(CheckSourceCompilesSwift)
+endif()
diff --git a/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
index adc125b..ce1cce3 100644
--- a/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
+++ b/Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt
@@ -1,3 +1,5 @@
+set(CMAKE_MINIMUM_REQUIRED_VERSION "" CACHE STRING "")
+
# Used to verify that the values match what is passed via -S and -B, and are retained in cache.
set(INITIAL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "defined in initial.cmake")
set(INITIAL_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "defined in initial.cmake")
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index 1452c9b..969d8be 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":4}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"tls":(true|false),"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":5}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"tls":(true|false),"version":{.*}}$
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt
+++ b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt
new file mode 100644
index 0000000..9504216
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-t-argument-target-is-file-stderr.txt
@@ -0,0 +1 @@
+^Error: Target \(for copy command\).* is not a directory.$
diff --git a/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt b/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt
new file mode 100644
index 0000000..cdfe857
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Envgen-bad-help-stderr.txt
@@ -0,0 +1 @@
+CMake Error: CMAKE_GENERATOR was set but the specified generator doesn't exist. Using CMake default.
diff --git a/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt b/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt
new file mode 100644
index 0000000..075c48c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Envgen-bad-help-stdout.txt
@@ -0,0 +1,2 @@
+Generators.*
+\* (Unix Makefiles|Visual Studio).*
diff --git a/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt b/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt
new file mode 100644
index 0000000..ece6e5d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Envgen-ninja-multi-help-stdout.txt
@@ -0,0 +1 @@
+\* Ninja Multi-Config[ ]+= Generates build-<Config>.ninja files.
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index a2eeddf..08c5a49 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -58,6 +58,8 @@ run_cmake_command(P_fresh ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_fresh.cm
run_cmake_command(build-no-dir
${CMAKE_COMMAND} --build)
+run_cmake_command(build-no-dir2
+ ${CMAKE_COMMAND} --build --target=invalid)
run_cmake_command(build-no-cache
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
run_cmake_command(build-unknown-command-short
@@ -349,6 +351,13 @@ function(run_EnvironmentGenerator)
run_cmake_command(Envgen-bad ${CMAKE_COMMAND} -G)
unset(ENV{CMAKE_GENERATOR})
+ # Honor CMAKE_GENERATOR env var in --help output
+ set(ENV{CMAKE_GENERATOR} "Ninja Multi-Config")
+ run_cmake_command(Envgen-ninja-multi-help ${CMAKE_COMMAND} --help)
+ set(ENV{CMAKE_GENERATOR} "NoSuchGenerator")
+ run_cmake_command(Envgen-bad-help ${CMAKE_COMMAND} --help)
+ unset(ENV{CMAKE_GENERATOR})
+
if(RunCMake_GENERATOR MATCHES "Visual Studio.*")
set(ENV{CMAKE_GENERATOR} "${RunCMake_GENERATOR}")
run_cmake_command(Envgen ${CMAKE_COMMAND} ${source_dir})
@@ -567,6 +576,12 @@ run_cmake_command(E_copy-three-source-files-target-is-file
${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
run_cmake_command(E_copy-two-good-and-one-bad-source-files-target-is-directory
${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/not_existing_file.bad ${in}/f3.txt ${out})
+run_cmake_command(E_copy-t-argument
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt -t ${out} ${in}/f3.txt)
+run_cmake_command(E_copy-t-argument-target-is-file
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt -t ${out}/f1.txt ${in}/f3.txt)
+run_cmake_command(E_copy-t-argument-no-source-files
+ ${CMAKE_COMMAND} -E copy -t ${out})
run_cmake_command(E_copy_if_different-one-source-directory-target-is-directory
${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${out})
run_cmake_command(E_copy_if_different-three-source-files-target-is-directory
@@ -940,6 +955,7 @@ unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS --trace)
run_cmake(trace)
+run_cmake(trace-try_compile)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS --trace-expand)
@@ -952,6 +968,7 @@ unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS --trace-redirect=${RunCMake_BINARY_DIR}/redirected.trace)
run_cmake(trace-redirect)
+run_cmake(trace-try_compile-redirect)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS --trace-redirect=/no/such/file.txt)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt b/Tests/RunCMake/CommandLine/build-no-dir2-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt
+++ b/Tests/RunCMake/CommandLine/build-no-dir2-result.txt
diff --git a/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt b/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt
new file mode 100644
index 0000000..4811bea
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir2-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\]
diff --git a/Tests/RunCMake/CommandLine/compare_files/.gitattributes b/Tests/RunCMake/CommandLine/compare_files/.gitattributes
index 91d5c10..d03da96 100644
--- a/Tests/RunCMake/CommandLine/compare_files/.gitattributes
+++ b/Tests/RunCMake/CommandLine/compare_files/.gitattributes
@@ -1,2 +1,2 @@
-crlf eol=crlf
-lf eol=lf
+crlf -text -whitespace
+lf -text
diff --git a/Tests/RunCMake/CommandLine/compare_files/crlf b/Tests/RunCMake/CommandLine/compare_files/crlf
index a29bdeb..495181c 100644
--- a/Tests/RunCMake/CommandLine/compare_files/crlf
+++ b/Tests/RunCMake/CommandLine/compare_files/crlf
@@ -1 +1 @@
-line1
+line1
diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake b/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake
new file mode 100644
index 0000000..94a7c95
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-try_compile-redirect-check.cmake
@@ -0,0 +1,13 @@
+file(READ ${RunCMake_SOURCE_DIR}/trace-try_compile-stderr.txt expected_content)
+string(REGEX REPLACE "\n+$" "" expected_content "${expected_content}")
+
+file(READ ${RunCMake_BINARY_DIR}/redirected.trace actual_content)
+string(REGEX REPLACE "\r\n" "\n" actual_content "${actual_content}")
+string(REGEX REPLACE "\n+$" "" actual_content "${actual_content}")
+if(NOT "${actual_content}" MATCHES "${expected_content}")
+ set(RunCMake_TEST_FAILED
+ "Trace file content does not match that expected."
+ "Expected to match:\n${expected_content}\n"
+ "Actual content:\n${actual_content}\n"
+ )
+endif()
diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake
new file mode 100644
index 0000000..982cb89
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-try_compile-redirect.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 3.24)
+project(test C)
diff --git a/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt b/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt
new file mode 100644
index 0000000..1674b8f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-try_compile-stderr.txt
@@ -0,0 +1,4 @@
+.*Modules/CMakeDetermineCompilerABI.cmake\([0-9]+\): try_compile\([^)]+\)
+.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): cmake_minimum_required.*
+.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): project\(CMAKE_TRY_COMPILE.*
+.*Tests/RunCMake/CommandLine/trace-try_compile(-redirect)?-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+/CMakeLists.txt\([0-9]+\): add_executable\(cmTC_.*
diff --git a/Tests/RunCMake/CommandLine/trace-try_compile.cmake b/Tests/RunCMake/CommandLine/trace-try_compile.cmake
new file mode 100644
index 0000000..982cb89
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-try_compile.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 3.24)
+project(test C)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index b7623de..fda18b5 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, 4, check_object_codemodel(g))
+ check_index_object(o[0], "codemodel", 2, 5, check_object_codemodel(g))
def check_backtrace(t, b, backtrace):
btg = t["backtraceGraph"]
@@ -291,10 +291,30 @@ def check_target(c):
assert matches(obj["paths"]["build"], expected["build"])
assert matches(obj["paths"]["source"], expected["source"])
+ def check_file_set(actual, expected):
+ assert is_dict(actual)
+ expected_keys = ["name", "type", "visibility", "baseDirectories"]
+
+ assert is_string(actual["name"], expected["name"])
+ assert is_string(actual["type"], expected["type"])
+ assert is_string(actual["visibility"], expected["visibility"])
+
+ check_list_match(lambda a, e: matches(a, e), actual["baseDirectories"],
+ expected["baseDirectories"],
+ check_exception=lambda a, e: "File set base directory (check): %s" % a,
+ missing_exception=lambda e: "File set base directory (missing): %s" % e,
+ extra_exception=lambda a: "File set base directory (extra): %s" % a)
+
+ assert sorted(actual.keys()) == sorted(expected_keys)
+
def check_source(actual, expected):
assert is_dict(actual)
expected_keys = ["path"]
+ if expected["fileSetName"] is not None:
+ expected_keys.append("fileSetIndex")
+ assert is_string(obj["fileSets"][actual["fileSetIndex"]]["name"], expected["fileSetName"])
+
if expected["compileGroupLanguage"] is not None:
expected_keys.append("compileGroupIndex")
assert is_string(obj["compileGroups"][actual["compileGroupIndex"]]["language"], expected["compileGroupLanguage"])
@@ -313,6 +333,14 @@ def check_target(c):
assert sorted(actual.keys()) == sorted(expected_keys)
+ if expected["fileSets"] is not None:
+ expected_keys.append("fileSets")
+ check_list_match(lambda a, e: matches(a["name"], e["name"]), obj["fileSets"],
+ expected["fileSets"], check=check_file_set,
+ check_exception=lambda a, e: "File set: %s" % a["name"],
+ missing_exception=lambda e: "File set: %s" % e["name"],
+ extra_exception=lambda a: "File set: %s" % a["name"])
+
check_list_match(lambda a, e: matches(a["path"], e["path"]), obj["sources"],
expected["sources"], check=check_source,
check_exception=lambda a, e: "Source file: %s" % a["path"],
@@ -824,6 +852,7 @@ def gen_check_targets(c, g, inSource):
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$",
"isGenerated": True,
+ "fileSetName": None,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": None,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
index eabf739..63493c9 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
@@ -5,10 +5,12 @@
"projectName": "Alias",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
index a5ff686..411057c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
@@ -5,10 +5,12 @@
"projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
index 1f443b1..bf36bfe 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
index 017335c..ebda414 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
@@ -5,10 +5,12 @@
"projectName": "External",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
index 2de5b15..579a103 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
index fa2a6e5..ec03531 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
@@ -5,10 +5,12 @@
"projectName": "Interface",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
index 9d8899a..f145896 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
index 0d45d07..46495ac 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
index ac7c94d..a27d328 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
@@ -5,10 +5,12 @@
"projectName": "Alias",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
index 7af74c4..7cfc0f2 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_1.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_1.json
index c189623..715514d 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_1.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_1.json
@@ -5,10 +5,37 @@
"projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": [
+ {
+ "name": "HEADERS",
+ "type": "HEADERS",
+ "visibility": "PUBLIC",
+ "baseDirectories": [".*/Tests/RunCMake/FileAPI/fileset$"]
+ },
+ {
+ "name": "a",
+ "type": "HEADERS",
+ "visibility": "PRIVATE",
+ "baseDirectories": [".*/Tests/RunCMake/FileAPI/fileset$"]
+ },
+ {
+ "name": "b",
+ "type": "HEADERS",
+ "visibility": "PUBLIC",
+ "baseDirectories": [".*/Tests/RunCMake/FileAPI/fileset/dir$"]
+ },
+ {
+ "name": "c",
+ "type": "HEADERS",
+ "visibility": "INTERFACE",
+ "baseDirectories": [".*/Tests/RunCMake/FileAPI/fileset$"]
+ }
+ ],
"sources": [
{
"path": "^fileset/empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
@@ -29,6 +56,7 @@
{
"path": "^fileset/error\\.c$",
"isGenerated": null,
+ "fileSetName": "HEADERS",
"sourceGroupName": "Header Files",
"compileGroupLanguage": null,
"backtrace": [
@@ -49,6 +77,7 @@
{
"path": "^fileset/other\\.c$",
"isGenerated": null,
+ "fileSetName": "HEADERS",
"sourceGroupName": "Source Files",
"compileGroupLanguage": null,
"backtrace": [
@@ -69,6 +98,7 @@
{
"path": "^fileset/h1\\.h$",
"isGenerated": null,
+ "fileSetName": "a",
"sourceGroupName": "Header Files",
"compileGroupLanguage": null,
"backtrace": [
@@ -89,6 +119,7 @@
{
"path": "^fileset/dir/h2\\.h$",
"isGenerated": null,
+ "fileSetName": "b",
"sourceGroupName": "Header Files",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_2.json
index 75fe58c..4757a9c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_2.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_headers_2.json
@@ -5,10 +5,19 @@
"projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": [
+ {
+ "name": "HEADERS",
+ "type": "HEADERS",
+ "visibility": "INTERFACE",
+ "baseDirectories": [".*/Tests/RunCMake/FileAPI/fileset$"]
+ }
+ ],
"sources": [
{
"path": "^fileset/empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
index 0ca1962..2bfc63f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
index 3392404..6342191 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
@@ -29,6 +31,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(object|build/c_object_lib\\.build)/.*/empty(\\.c)?\\.o(bj)?$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "Object Libraries",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
index 1917f92..3e1b03b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "OBJECT_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
index 0d4018a..f7a8db4 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
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 9a210ff..9066053 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
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "SHARED_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
index 5542277..46c5bfe 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
index 4b63897..df28479 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
index 12ec917..4fa62e3 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^subdir/empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
index ab301e9..8d52ab8 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
@@ -5,10 +5,12 @@
"projectName": "Custom",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
index 483ae79..23f8e52 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
@@ -5,10 +5,12 @@
"projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt(-(Debug|Release|RelWithDebInfo|MinSizeRel))?$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -29,6 +31,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt(-\\(CONFIG\\))?\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
index 837f252..b27fc5b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
@@ -5,10 +5,12 @@
"projectName": "Alias",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index 16d074a..12b2551 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
index 5a0f770..3251777 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
@@ -97,6 +97,7 @@
{
"path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -111,6 +112,7 @@
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -131,6 +133,7 @@
{
"path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
index 9455748..0ac40c2 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
@@ -143,6 +143,7 @@
{
"path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -157,6 +158,7 @@
{
"path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -171,6 +173,7 @@
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -191,6 +194,7 @@
{
"path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
@@ -205,6 +209,7 @@
{
"path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
index 9f6ffcc..86168f1 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
@@ -97,6 +97,7 @@
{
"path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -111,6 +112,7 @@
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -131,6 +133,7 @@
{
"path": ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
@@ -145,6 +148,7 @@
{
"path": ".*/Release/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
@@ -159,6 +163,7 @@
{
"path": ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
@@ -173,6 +178,7 @@
{
"path": ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Precompile Header File",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
index 94ac081..f665004 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
index e8d6218..68c5dcc 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
@@ -29,6 +31,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(object|build/cxx_object_lib\\.build)/.*/empty(\\.cxx)?\\.o(bj)?$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "Object Libraries",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
index 24b391b..0438a49 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "OBJECT_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
index 4421c8f..bb9989e 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
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 03f4cb9..d6d59a4 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
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "SHARED_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
index d6d573f..a6bacf7 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
index 9cb2832..fe884e0 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
index 52c42de..d904bd9 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
index 98298be..bced68a 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "STATIC_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.cxx$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
index d41bbb2..4b69682 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
@@ -5,10 +5,12 @@
"projectName": "External",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
@@ -29,6 +31,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "Generated Source Files",
"compileGroupLanguage": "CXX",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
index 97d7ccd..bd698d5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
@@ -5,10 +5,12 @@
"projectName": "Interface",
"type": "INTERFACE_LIBRARY",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
index fe0524c..c0c3e79 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
index 451e8d4..45fb0a5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
index cbd4346..74c179c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
index d92a810..6771747 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
index 1197a73..659e3fb 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
index 42564e0..7bdaffb 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "EXECUTABLE",
"isGeneratorProvided": null,
+ "fileSets": null,
"sources": [
{
"path": "^empty\\.c$",
"isGenerated": null,
+ "fileSetName": null,
"sourceGroupName": "Source Files",
"compileGroupLanguage": "C",
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
index 941c172..7462f7f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
@@ -5,10 +5,12 @@
"projectName": "Alias",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
index 98c6dd9..abc5084 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
@@ -5,10 +5,12 @@
"projectName": "Custom",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
index b72ff82..af4248c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
@@ -5,10 +5,12 @@
"projectName": "Cxx",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
index 9e73806..a7b8bb0 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
@@ -5,10 +5,12 @@
"projectName": "External",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
index 7534c84..ed3da5f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
@@ -5,10 +5,12 @@
"projectName": "Imported",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
index fdd4b2a..178f9ef 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
@@ -5,10 +5,12 @@
"projectName": "Interface",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
index bcd7616..341647b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
@@ -5,10 +5,12 @@
"projectName": "Object",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
index b3030bd..b3827ed 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
@@ -5,10 +5,12 @@
"projectName": "codemodel-v2",
"type": "UTILITY",
"isGeneratorProvided": true,
+ "fileSets": null,
"sources": [
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "",
"compileGroupLanguage": null,
"backtrace": [
@@ -23,6 +25,7 @@
{
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
"isGenerated": true,
+ "fileSetName": null,
"sourceGroupName": "CMake Rules",
"compileGroupLanguage": null,
"backtrace": [
diff --git a/Tests/RunCMake/File_Archive/argument-validation-compression-level-1-stderr.txt b/Tests/RunCMake/File_Archive/argument-validation-compression-level-1-stderr.txt
index d7bc79a..c2d4071 100644
--- a/Tests/RunCMake/File_Archive/argument-validation-compression-level-1-stderr.txt
+++ b/Tests/RunCMake/File_Archive/argument-validation-compression-level-1-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at compression-level.cmake:39 \(file\):
- file compression level 100 should be in range 0 to 9
+ file compression level 100 for GZip should be in range 0 to 9
Call Stack \(most recent call first\):
argument-validation-compression-level-1.cmake:8 \(check_compression_level\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/argument-validation-compression-level-2-stderr.txt b/Tests/RunCMake/File_Archive/argument-validation-compression-level-2-stderr.txt
index 0f7bd9e..d4a4402 100644
--- a/Tests/RunCMake/File_Archive/argument-validation-compression-level-2-stderr.txt
+++ b/Tests/RunCMake/File_Archive/argument-validation-compression-level-2-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at compression-level.cmake:39 \(file\):
- file compression level high should be in range 0 to 9
+ file compression level high for GZip should be in range 0 to 9
Call Stack \(most recent call first\):
argument-validation-compression-level-2.cmake:8 \(check_compression_level\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/pax-zstd-compression-level.cmake b/Tests/RunCMake/File_Archive/pax-zstd-compression-level.cmake
index 73fd84d..7002860 100644
--- a/Tests/RunCMake/File_Archive/pax-zstd-compression-level.cmake
+++ b/Tests/RunCMake/File_Archive/pax-zstd-compression-level.cmake
@@ -8,3 +8,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/compression-level.cmake)
check_compression_level("1")
check_compression_level("5")
check_compression_level("9")
+check_compression_level("12")
+check_compression_level("15")
+check_compression_level("19")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
index f149d99..69ab4da 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
@@ -113,23 +113,33 @@ message(STATUS "Verifying target \"${tgt}\"")
if (NOT TARGET ${tgt})
message(FATAL_ERROR "No import target for fake link options package")
endif()
-get_target_property(link_options ${tgt} INTERFACE_LINK_OPTIONS)
-if (NOT link_options STREQUAL expected_link_options)
- message(FATAL_ERROR
- "Additional link options not present in INTERFACE_LINK_OPTIONS property\n"
- "expected: \"${expected_link_options}\", but got \"${link_options}\""
- )
-endif()
-get_target_property(inc_dirs ${tgt} INTERFACE_INCLUDE_DIRECTORIES)
-set(expected_inc_dirs "/special" "/other" "/more")
+# Some versions of pkg-config on Windows don't parse the Libs and Cflags
+# correctly. The pkg-config that comes with Strawberry perl is one example.
+# It appears to treat the dummymain part of Libs as a library and only returns
+# -e. It also doesn't recognize "-isystem /other", presumably because it doesn't
+# support having a space between "-isystem" and the directory after it (it does
+# give us the "-isystem/more" flag). Since we can't reliably test for these,
+# we don't enable these checks on Windows.
+if(NOT WIN32)
+ get_target_property(link_options ${tgt} INTERFACE_LINK_OPTIONS)
+ if (NOT link_options STREQUAL expected_link_options)
+ message(FATAL_ERROR
+ "Additional link options not present in INTERFACE_LINK_OPTIONS property\n"
+ "expected: \"${expected_link_options}\", but got \"${link_options}\""
+ )
+ endif()
-if (NOT inc_dirs STREQUAL expected_inc_dirs)
- message(FATAL_ERROR
- "Additional include directories not correctly present in INTERFACE_INCLUDE_DIRECTORIES property\n"
- "expected: \"${expected_inc_dirs}\", got \"${inc_dirs}\""
- )
-endif ()
+ get_target_property(inc_dirs ${tgt} INTERFACE_INCLUDE_DIRECTORIES)
+ set(expected_inc_dirs "/special" "/other" "/more")
+
+ if (NOT inc_dirs STREQUAL expected_inc_dirs)
+ message(FATAL_ERROR
+ "Additional include directories not correctly present in INTERFACE_INCLUDE_DIRECTORIES property\n"
+ "expected: \"${expected_inc_dirs}\", got \"${inc_dirs}\""
+ )
+ endif ()
+endif()
get_target_property(c_opts ${tgt} INTERFACE_COMPILE_OPTIONS)
set(expected_c_opts "-DA-isystem/foo") # this is an invalid option, but a good testcase
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_VERSION_OPERATORS.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_VERSION_OPERATORS.cmake
index 2a505c6..f7a9815 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_VERSION_OPERATORS.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_VERSION_OPERATORS.cmake
@@ -20,14 +20,15 @@ Libs: -lcmakeinternalfakepackage
# Always find the .pc file in the calls further below so that we can test that
# the import target find_library() calls handle the NO...PATH options correctly
-set(ENV{PKG_CONFIG_PATH} ${fakePkgDir}/lib/pkgconfig)
+cmake_path(CONVERT "${fakePkgDir}/lib/pkgconfig" TO_NATIVE_PATH_LIST confPath)
+set(ENV{PKG_CONFIG_PATH} "${confPath}")
-pkg_check_modules(FakePackageGE REQUIRED QUIET "cmakeinternalfakepackage >= 8")
+pkg_check_modules(FakePackageGE REQUIRED QUIET "cmakeinternalfakepackage>=8")
if (NOT FakePackageGE_FOUND)
message(FATAL_ERROR "fake package >= 8 not found")
endif()
-pkg_check_modules(FakePackageGE_FAIL QUIET "cmakeinternalfakepackage >= 8.10")
+pkg_check_modules(FakePackageGE_FAIL QUIET "cmakeinternalfakepackage>=8.10")
if (FakePackageGE_FAIL_FOUND)
message(FATAL_ERROR "fake package >= 8.10 found")
endif()
@@ -37,17 +38,17 @@ if (NOT FakePackageLE_FOUND)
message(FATAL_ERROR "fake package <= 9 not found")
endif()
-pkg_check_modules(FakePackageLE_FAIL QUIET "cmakeinternalfakepackage <= 8.1")
+pkg_check_modules(FakePackageLE_FAIL QUIET "cmakeinternalfakepackage<=8.1")
if (FakePackageLE_FAIL_FOUND)
message(FATAL_ERROR "fake package <= 8.1 found")
endif()
-pkg_check_modules(FakePackageGT REQUIRED QUIET "cmakeinternalfakepackage > 8")
+pkg_check_modules(FakePackageGT REQUIRED QUIET "cmakeinternalfakepackage>8")
if (NOT FakePackageGT_FOUND)
message(FATAL_ERROR "fake package > 8 not found")
endif()
-pkg_check_modules(FakePackageGT_FAIL QUIET "cmakeinternalfakepackage > 8.9")
+pkg_check_modules(FakePackageGT_FAIL QUIET "cmakeinternalfakepackage>8.9")
if (FakePackageGT_FAIL_FOUND)
message(FATAL_ERROR "fake package > 8.9 found")
endif()
@@ -57,7 +58,7 @@ if (NOT FakePackageLT_FOUND)
message(FATAL_ERROR "fake package < 9 not found")
endif()
-pkg_check_modules(FakePackageLT_FAIL QUIET "cmakeinternalfakepackage < 8.9")
+pkg_check_modules(FakePackageLT_FAIL QUIET "cmakeinternalfakepackage<8.9")
if (FakePackageLT_FAIL_FOUND)
message(FATAL_ERROR "fake package < 8.9 found")
endif()
@@ -67,17 +68,17 @@ if (NOT FakePackageEQ_FOUND)
message(FATAL_ERROR "fake package = 8.9 not found")
endif()
-pkg_check_modules(FakePackageEQ_FAIL QUIET "cmakeinternalfakepackage = 8.8")
+pkg_check_modules(FakePackageEQ_FAIL QUIET "cmakeinternalfakepackage=8.8")
if (FakePackageEQ_FAIL_FOUND)
message(FATAL_ERROR "fake package = 8.8 found")
endif()
-pkg_check_modules(FakePackageEQ_INV QUIET "cmakeinternalfakepackage == 8.9")
+pkg_check_modules(FakePackageEQ_INV QUIET "cmakeinternalfakepackage==8.9")
if (FakePackageEQ_FAIL_FOUND)
message(FATAL_ERROR "fake package == 8.9 found")
endif()
-pkg_check_modules(FakePackageLLT_INV QUIET "cmakeinternalfakepackage <<= 9")
+pkg_check_modules(FakePackageLLT_INV QUIET "cmakeinternalfakepackage<<=9")
if (FakePackageLLT_FAIL_FOUND)
message(FATAL_ERROR "fake package <<= 9 found")
endif()
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index 661ae3f..6b8e884 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -7,13 +7,18 @@ set(ENV{CMAKE_FRAMEWORK_PATH} "")
run_cmake(PkgConfigDoesNotExist)
-run_cmake(FindPkgConfig_CMP0126_NEW)
-run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
-run_cmake(FindPkgConfig_PKGCONFIG_PATH)
-run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH)
-run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH)
+if(NOT WIN32)
+ # FIXME: The Windows implementation of these tests do not work.
+ # They are disabled until they can be updated to a working state.
+ run_cmake(FindPkgConfig_CMP0126_NEW)
+ run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
+ run_cmake(FindPkgConfig_PKGCONFIG_PATH)
+ run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH)
+ run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH)
+ run_cmake(FindPkgConfig_GET_MATCHING_ARGN)
+endif()
+
run_cmake(FindPkgConfig_extract_frameworks)
-run_cmake(FindPkgConfig_GET_MATCHING_ARGN)
if(APPLE)
run_cmake(FindPkgConfig_extract_frameworks_target)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL-check.cmake
index 0fbf837..0fbf837 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL.cmake
index 212c034..212c034 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/ALIAS_GLOBAL.cmake
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-stderr.txt
index 6da79b7..6da79b7 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName.cmake
index 5f083e2..d3f82aa 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName.cmake
@@ -1,3 +1,4 @@
+enable_language(CXX)
add_subdirectory(BadInvalidName1)
add_subdirectory(BadInvalidName2)
add_subdirectory(BadInvalidName3)
@@ -6,3 +7,6 @@ add_subdirectory(BadInvalidName5)
add_subdirectory(BadInvalidName6)
add_subdirectory(BadInvalidName7)
add_subdirectory(BadInvalidName8)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName1/CMakeLists.txt
index 13e1de7..13e1de7 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName1/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName2/CMakeLists.txt
index 4b78472..4b78472 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName2/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName3/CMakeLists.txt
index 516a049..516a049 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName3/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName4/CMakeLists.txt
index 02f2a1a..02f2a1a 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName4/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName5/CMakeLists.txt
index a653583..a653583 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName5/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName6/CMakeLists.txt
index 614458e..614458e 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName6/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName7/CMakeLists.txt
index 8a9fe80..8a9fe80 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName7/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName8/CMakeLists.txt
index b228159..b228159 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadInvalidName8/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-stderr.txt
index d40b16b..0c9320b 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at BadNonTarget.cmake:7 \(include_directories\):
+CMake Error at BadNonTarget.cmake:6 \(include_directories\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:NonExistent,INCLUDE_DIRECTORIES>
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget.cmake
new file mode 100644
index 0000000..731d758
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadNonTarget.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ "int main(int, char **) { return 0; }\n")
+
+add_executable(main "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+include_directories("$<TARGET_PROPERTY:NonExistent,INCLUDE_DIRECTORIES>")
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-stderr.txt
index fa26861..fa26861 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference.cmake
index 5a99f7a..ee8b9ec 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference.cmake
@@ -1,6 +1,10 @@
+enable_language(CXX)
add_subdirectory(BadSelfReference1)
add_subdirectory(BadSelfReference2)
add_subdirectory(BadSelfReference3)
add_subdirectory(BadSelfReference4)
add_subdirectory(BadSelfReference5)
add_subdirectory(BadSelfReference6)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference1/CMakeLists.txt
index 30c27f5..30c27f5 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference1/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference2/CMakeLists.txt
index c2322f4..c2322f4 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference2/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference3/CMakeLists.txt
index 3e6c30a..3e6c30a 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference3/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference4/CMakeLists.txt
index f79727a..f79727a 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference4/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference5/CMakeLists.txt
index c0badbf..c0badbf 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference5/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference6/CMakeLists.txt
index fcb6b3c..fcb6b3c 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/BadSelfReference6/CMakeLists.txt
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt
new file mode 100644
index 0000000..26a73f9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.3)
+if(RunCMake_TEST STREQUAL "LOCATION")
+ cmake_minimum_required(VERSION 2.8.12) # Leave CMP0026 unset.
+endif()
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES-check.cmake
index ecf7bfe..ecf7bfe 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES.cmake
index e9855be..e9855be 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/INCLUDE_DIRECTORIES.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION-stderr.txt
index a4c8dcd..a4c8dcd 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION.cmake
index 8929cdb..8929cdb 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LOCATION.cmake
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-stderr.txt
index 8bff68e..8bff68e 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1.cmake
index 4b60214..775e5a0 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle1.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 empty.cpp)
add_library(empty2 empty.cpp)
@@ -6,3 +6,6 @@ target_link_libraries(empty1
LINK_PUBLIC
$<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-stderr.txt
index 044b77c..044b77c 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2.cmake
index 557eac1..fc14b48 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle2.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 empty.cpp)
add_library(empty2 empty.cpp)
@@ -6,3 +6,6 @@ target_link_libraries(empty1
LINK_PUBLIC
$<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3-result.txt
index 573541a..573541a 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3-result.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3.cmake
index 0f921d4..e084502 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle3.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 empty.cpp)
add_library(empty2 empty.cpp)
@@ -8,3 +8,6 @@ target_link_libraries(empty1
INTERFACE
$<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-stderr.txt
index d56b199..d56b199 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4.cmake
index ab6d0b2..42290de 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle4.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 empty.cpp)
add_library(empty2 empty.cpp)
@@ -12,3 +12,6 @@ target_link_libraries(empty1
add_library(empty3 empty.cpp)
target_link_libraries(empty3 empty1)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-stderr.txt
index cf4e6d7..cf4e6d7 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5.cmake
index dc180e3..9597176 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle5.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 INTERFACE IMPORTED)
add_library(empty2 INTERFACE IMPORTED)
@@ -8,3 +8,6 @@ set_property(TARGET empty1 PROPERTY INTERFACE_LINK_LIBRARIES
add_library(empty3 empty.cpp)
target_link_libraries(empty3 empty1)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-result.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-stderr.txt
index 93cb573..93cb573 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6-stderr.txt
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6.cmake
index 91252d0..94a5419 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/LinkImplementationCycle6.cmake
@@ -1,4 +1,4 @@
-
+enable_language(CXX)
add_library(empty1 SHARED empty.cpp)
add_library(empty2 SHARED empty.cpp)
@@ -12,3 +12,6 @@ target_link_libraries(empty1
add_library(empty3 SHARED empty.cpp)
target_link_libraries(empty3 empty1)
+
+# Suppress generator-specific targets that might pollute the stderr.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake
index 4294e9f..ac0843e 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake
@@ -1,11 +1,15 @@
include(RunCMake)
-run_cmake(BadSelfReference)
-run_cmake(BadNonTarget)
+run_cmake(ALIAS_GLOBAL)
run_cmake(BadInvalidName)
+run_cmake(BadNonTarget)
+run_cmake(BadSelfReference)
+run_cmake(INCLUDE_DIRECTORIES)
run_cmake(LinkImplementationCycle1)
run_cmake(LinkImplementationCycle2)
run_cmake(LinkImplementationCycle3)
run_cmake(LinkImplementationCycle4)
run_cmake(LinkImplementationCycle5)
run_cmake(LinkImplementationCycle6)
+run_cmake(LOCATION)
+run_cmake(SOURCES)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES-check.cmake
index c1a0f5b..c1a0f5b 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES-check.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES.cmake
index dee7ead..dee7ead 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-SOURCES.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/SOURCES.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/empty3.c b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.c
index e69de29..e69de29 100644
--- a/Tests/RunCMake/GeneratorExpression/empty3.c
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.c
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.cpp
index 11ec041..11ec041 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.cpp
diff --git a/Tests/RunCMake/GeneratorExpression/empty2.c b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.c
index e69de29..e69de29 100644
--- a/Tests/RunCMake/GeneratorExpression/empty2.c
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.c
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.c b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.c
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/main.cpp b/Tests/RunCMake/GenEx-TARGET_PROPERTY/main.cpp
index f8b643a..f8b643a 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/main.cpp
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/main.cpp
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index edeb6bd..8d8c8dc 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -22,10 +22,6 @@ run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
run_cmake(NonValidTarget-Fortran_COMPILER_VERSION)
run_cmake(NonValidTarget-TARGET_PROPERTY)
run_cmake(NonValidTarget-TARGET_POLICY)
-run_cmake(TARGET_PROPERTY-INCLUDE_DIRECTORIES)
-run_cmake(TARGET_PROPERTY-LOCATION)
-run_cmake(TARGET_PROPERTY-SOURCES)
-run_cmake(TARGET_PROPERTY-ALIAS_GLOBAL)
run_cmake(LINK_ONLY-not-linking)
run_cmake(TARGET_EXISTS-no-arg)
run_cmake(TARGET_EXISTS-empty-arg)
diff --git a/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake b/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake
index d1bc9b1..9cc05d0 100644
--- a/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake
+++ b/Tests/RunCMake/GetPrerequisites/ExecutableScripts.cmake
@@ -10,7 +10,9 @@ endfunction()
# Should not throw any errors
# Regular executable
-get_prerequisites(${CMAKE_COMMAND} cmake_prereqs 1 1 "" "")
+if(SAMPLE_EXE)
+ get_prerequisites("${SAMPLE_EXE}" cmake_prereqs 1 1 "" "")
+endif()
# Shell script
check_script(${CMAKE_CURRENT_LIST_DIR}/script.sh)
# Batch script
diff --git a/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake b/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
index a635e38..5550c02 100644
--- a/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GetPrerequisites/RunCMakeTest.cmake
@@ -1,4 +1,4 @@
include(RunCMake)
run_cmake_command(TargetMissing ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/TargetMissing.cmake)
-run_cmake_command(ExecutableScripts ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ExecutableScripts.cmake)
+run_cmake_command(ExecutableScripts ${CMAKE_COMMAND} -DSAMPLE_EXE=${SAMPLE_EXE} -P ${RunCMake_SOURCE_DIR}/ExecutableScripts.cmake)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-skip-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-skip-test-stdout.txt
index 8d7527c..18f133a 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-skip-test-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-skip-test-stdout.txt
@@ -1,10 +1,13 @@
Test project .*
*Start +[0-9]+: skip_test\.test1
*[0-9]+/[0-9]+ +Test +#[0-9]+: skip_test\.test1 \.+\*\*\*Skipped +[0-9.]+ sec
+ *Start +[0-9]+: skip_test\.test1
+ *[0-9]+/[0-9]+ +Test +#[0-9]+: skip_test\.test1 \.+\*\*\*Skipped +[0-9.]+ sec
-100% tests passed, 0 tests failed out of 1
+100% tests passed, 0 tests failed out of 2
Total Test time \(real\) = +[0-9.]+ sec
The following tests did not run:
[ 0-9]+- skip_test\.test1 \(Skipped\)
+[ 0-9]+- skip_test\.test1 \(Skipped\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
index 221d6ad..2ed43fc 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
@@ -78,3 +78,7 @@ xcode_sign_adhoc(skip_test)
gtest_discover_tests(
skip_test
)
+
+gtest_add_tests(
+ TARGET skip_test
+)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 695f562..b494cef 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR
RunCMake_GENERATOR STREQUAL "Watcom WMake")
set(fs_delay 3)
diff --git a/Tests/RunCMake/GoogleTest/skip_test.cpp b/Tests/RunCMake/GoogleTest/skip_test.cpp
index 2bc9fe1..919b1b3 100644
--- a/Tests/RunCMake/GoogleTest/skip_test.cpp
+++ b/Tests/RunCMake/GoogleTest/skip_test.cpp
@@ -1,6 +1,13 @@
#include <iostream>
#include <string>
+/* Having this as comment lets gtest_add_tests recognizes the test we fake
+ here without requiring googletest
+TEST_F( skip_test, test1 )
+{
+}
+*/
+
int main(int argc, char** argv)
{
// Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
diff --git a/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake
index a1ae6ac..30b24bf 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake
@@ -7,7 +7,8 @@ set(expected_compile_commands
]*Debug[^
]*",
"file": "[^
-]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)"
+]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)",
+ "output": "(CMakeFiles/exe\.dir/Debug/main\.c\.o|CMakeFiles\\\\exe\.dir\\\\Debug\\\\main\.c\.obj)"
},
{
"directory": "[^
@@ -16,7 +17,8 @@ set(expected_compile_commands
]*Release[^
]*",
"file": "[^
-]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)"
+]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)",
+ "output": "(CMakeFiles/exe\.dir/Release/main\.c\.o|CMakeFiles\\\\exe\.dir\\\\Release\\\\main\.c\.obj)"
}
]$]==])
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index ba9cc3b..cc754e8 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -155,6 +155,7 @@ function(run_cmake test)
"|BullseyeCoverage"
"|[a-z]+\\([0-9]+\\) malloc:"
"|clang[^:]*: warning: the object size sanitizer has no effect at -O0, but is explicitly enabled:"
+ "|icp?x: remark: Note that use of .-g. without any optimization-level option will turn off most compiler optimizations"
"|lld-link: warning: procedure symbol record for .* refers to PDB item index [0-9A-Fa-fx]+ which is not a valid function ID record"
"|Error kstat returned"
"|Hit xcodebuild bug"
diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake
index 59db395..86f5b3a 100644
--- a/Tests/RunCMake/RunCTest.cmake
+++ b/Tests/RunCMake/RunCTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
function(run_ctest CASE_NAME)
configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in
${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake @ONLY)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget.cmake
deleted file mode 100644
index 97d81e9..0000000
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
- "int main(int, char **) { return 0; }\n")
-
-add_executable(TargetPropertyGeneratorExpressions
- "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
-include_directories("$<TARGET_PROPERTY:NonExistent,INCLUDE_DIRECTORIES>")
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
deleted file mode 100644
index c3922d6..0000000
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-
-cmake_minimum_required(VERSION 3.3)
-project(${RunCMake_TEST} CXX)
-
-# MSVC creates extra targets which pollute the stderr unless we set this.
-set(CMAKE_SUPPRESS_REGENERATION TRUE)
-
-include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index f027e94..ed74896 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -89,3 +89,10 @@ run_cmake(VsDotnetTargetFramework)
run_cmake(VsDotnetTargetFrameworkVersion)
run_cmake(VsNoCompileBatching)
run_cmake(DebugInformationFormat)
+run_cmake(VsCLREmpty)
+run_cmake(VsCLRPure)
+run_cmake(VsCLRSafe)
+
+if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20)
+ run_cmake(VsCLRNetcore)
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCLREmpty-check.cmake b/Tests/RunCMake/VS10Project/VsCLREmpty-check.cmake
new file mode 100644
index 0000000..990da46
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLREmpty-check.cmake
@@ -0,0 +1,24 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(propertyFound FALSE)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<CompileAsManaged>(.*)</CompileAsManaged>$")
+ set(propertyFound TRUE)
+ set(expectedValue "true")
+ set(actualValue ${CMAKE_MATCH_1})
+ if(NOT (${actualValue} STREQUAL ${expectedValue}))
+ set(RunCMake_TEST_FAILED "CompileAsManaged \"${actualValue}\" differs from expected value \"${expectedValue}\".")
+ return()
+ endif()
+ endif()
+endforeach()
+
+if(NOT propertyFound)
+ set(RunCMake_TEST_FAILED "Property CompileAsManaged not found in project file.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCLREmpty.cmake b/Tests/RunCMake/VS10Project/VsCLREmpty.cmake
new file mode 100644
index 0000000..a622f26
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLREmpty.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
+
+set_target_properties(foo PROPERTIES
+ COMMON_LANGUAGE_RUNTIME "")
diff --git a/Tests/RunCMake/VS10Project/VsCLRNetcore-check.cmake b/Tests/RunCMake/VS10Project/VsCLRNetcore-check.cmake
new file mode 100644
index 0000000..a5058d7
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRNetcore-check.cmake
@@ -0,0 +1,24 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(propertyFound FALSE)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<CLRSupport>(.*)</CLRSupport>$")
+ set(propertyFound TRUE)
+ set(expectedValue "NetCore")
+ set(actualValue ${CMAKE_MATCH_1})
+ if(NOT (${actualValue} STREQUAL ${expectedValue}))
+ set(RunCMake_TEST_FAILED "CLRSupport \"${actualValue}\" differs from expected value \"${expectedValue}\".")
+ return()
+ endif()
+ endif()
+endforeach()
+
+if(NOT propertyFound)
+ set(RunCMake_TEST_FAILED "Property CLRSupport not found in project file.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCLRNetcore.cmake b/Tests/RunCMake/VS10Project/VsCLRNetcore.cmake
new file mode 100644
index 0000000..c5ec2bc
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRNetcore.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
+
+set_target_properties(foo PROPERTIES
+ COMMON_LANGUAGE_RUNTIME "netcore")
diff --git a/Tests/RunCMake/VS10Project/VsCLRPure-check.cmake b/Tests/RunCMake/VS10Project/VsCLRPure-check.cmake
new file mode 100644
index 0000000..8ae73eb
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRPure-check.cmake
@@ -0,0 +1,24 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(propertyFound FALSE)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<CompileAsManaged>(.*)</CompileAsManaged>$")
+ set(propertyFound TRUE)
+ set(expectedValue "Pure")
+ set(actualValue ${CMAKE_MATCH_1})
+ if(NOT (${actualValue} STREQUAL ${expectedValue}))
+ set(RunCMake_TEST_FAILED "CompileAsManaged \"${actualValue}\" differs from expected value \"${expectedValue}\".")
+ return()
+ endif()
+ endif()
+endforeach()
+
+if(NOT propertyFound)
+ set(RunCMake_TEST_FAILED "Property CompileAsManaged not found in project file.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCLRPure.cmake b/Tests/RunCMake/VS10Project/VsCLRPure.cmake
new file mode 100644
index 0000000..f919a1c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRPure.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
+
+set_target_properties(foo PROPERTIES
+ COMMON_LANGUAGE_RUNTIME "pure")
diff --git a/Tests/RunCMake/VS10Project/VsCLRSafe-check.cmake b/Tests/RunCMake/VS10Project/VsCLRSafe-check.cmake
new file mode 100644
index 0000000..ebb1f71
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRSafe-check.cmake
@@ -0,0 +1,24 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(propertyFound FALSE)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<CompileAsManaged>(.*)</CompileAsManaged>$")
+ set(propertyFound TRUE)
+ set(expectedValue "Safe")
+ set(actualValue ${CMAKE_MATCH_1})
+ if(NOT (${actualValue} STREQUAL ${expectedValue}))
+ set(RunCMake_TEST_FAILED "CompileAsManaged \"${actualValue}\" differs from expected value \"${expectedValue}\".")
+ return()
+ endif()
+ endif()
+endforeach()
+
+if(NOT propertyFound)
+ set(RunCMake_TEST_FAILED "Property CompileAsManaged not found in project file.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCLRSafe.cmake b/Tests/RunCMake/VS10Project/VsCLRSafe.cmake
new file mode 100644
index 0000000..5f114bf
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCLRSafe.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
+
+set_target_properties(foo PROPERTIES
+ COMMON_LANGUAGE_RUNTIME "safe")
diff --git a/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
new file mode 100644
index 0000000..6dd042b
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+ if(found EQUAL "-1")
+ error("CMakePredefinedTargets should be defined when CMP0143 is NEW!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake b/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
new file mode 100644
index 0000000..2d9829c
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+ if(NOT (found EQUAL "-1"))
+ error("CMakePredefinedTargets should not be defined when CMP0143 is OLD!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake b/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
new file mode 100644
index 0000000..2d9829c
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+ if(NOT (found EQUAL "-1"))
+ error("CMakePredefinedTargets should not be defined when CMP0143 is OLD!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake b/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
index c25833d..134821d 100644
--- a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
@@ -15,4 +15,7 @@ run_cmake(AddPackageToDefault)
if(NOT NO_USE_FOLDERS)
run_cmake(StartupProjectUseFolders)
+ run_cmake(CMP0143-WARN)
+ run_cmake_with_options(CMP0143-OLD "-DCMAKE_POLICY_DEFAULT_CMP0143=OLD")
+ run_cmake_with_options(CMP0143-NEW "-DCMAKE_POLICY_DEFAULT_CMP0143=NEW")
endif()
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt
new file mode 100644
index 0000000..f5247ca
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at duplicate-target-CMP0107-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0107 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/ctest_environment/RunCMakeTest.cmake b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
index 365c9e8..4716c41 100644
--- a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
@@ -1,9 +1,5 @@
include(RunCTest)
-# Isolate our ctest runs from external environment.
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
set(CASE_SOURCE_DIR "${RunCMake_SOURCE_DIR}")
set(RunCTest_VERBOSE_FLAG "-VV")
diff --git a/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake b/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
index 1754203..1c2ad89 100644
--- a/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_fixtures/RunCMakeTest.cmake
@@ -1,9 +1,5 @@
include(RunCTest)
-# Isolate our ctest runs from external environment.
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
function(run_ctest_test CASE_NAME)
set(CASE_CTEST_FIXTURES_ARGS "${ARGN}")
run_ctest(${CASE_NAME})
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
index cb8f696..3f6501e 100644
--- a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -4,8 +4,6 @@ set(SITE test-site)
set(BUILDNAME test-build)
set(COVERAGE_COMMAND "")
-unset(ENV{CTEST_PARALLEL_LEVEL})
-
function(run_mc_test CASE_NAME CHECKER_COMMAND)
run_ctest(${CASE_NAME} ${ARGN})
endfunction()
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index 74ae99c..242a059 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -1,9 +1,6 @@
include(RunCTest)
set(RunCMake_TEST_TIMEOUT 60)
-unset(ENV{CTEST_PARALLEL_LEVEL})
-unset(ENV{CTEST_OUTPUT_ON_FAILURE})
-
set(CASE_CTEST_TEST_ARGS "")
set(CASE_CTEST_TEST_LOAD "")
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt
new file mode 100644
index 0000000..1183f86
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at Repeat-CMP0103-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0103 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/file/COPY_FILE-input-missing-result.txt b/Tests/RunCMake/file/COPY_FILE-input-missing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-input-missing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/COPY_FILE-input-missing-stderr.txt b/Tests/RunCMake/file/COPY_FILE-input-missing-stderr.txt
new file mode 100644
index 0000000..989925d
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-input-missing-stderr.txt
@@ -0,0 +1,14 @@
+^CMake Error at [^
+]*/Tests/RunCMake/file/COPY_FILE-input-missing.cmake:[0-9]+ \(file\):
+ file COPY_FILE failed to copy
+
+ [^
+]*/Tests/RunCMake/file/COPY_FILE-input-missing-build/input-missing
+
+ to
+
+ [^
+]*/Tests/RunCMake/file/COPY_FILE-input-missing-build/output
+
+ because: [^
+]+ \(input\)$
diff --git a/Tests/RunCMake/file/COPY_FILE-input-missing.cmake b/Tests/RunCMake/file/COPY_FILE-input-missing.cmake
new file mode 100644
index 0000000..2d2c55e
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-input-missing.cmake
@@ -0,0 +1,3 @@
+set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input-missing")
+set(newname "${CMAKE_CURRENT_BINARY_DIR}/output")
+file(COPY_FILE "${oldname}" "${newname}")
diff --git a/Tests/RunCMake/file/COPY_FILE-output-missing-result.txt b/Tests/RunCMake/file/COPY_FILE-output-missing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-output-missing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/COPY_FILE-output-missing-stderr.txt b/Tests/RunCMake/file/COPY_FILE-output-missing-stderr.txt
new file mode 100644
index 0000000..0e7d9f7
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-output-missing-stderr.txt
@@ -0,0 +1,14 @@
+^CMake Error at [^
+]*/Tests/RunCMake/file/COPY_FILE-output-missing.cmake:[0-9]+ \(file\):
+ file COPY_FILE failed to copy
+
+ [^
+]*/Tests/RunCMake/file/COPY_FILE-output-missing-build/input
+
+ to
+
+ [^
+]*/Tests/RunCMake/file/COPY_FILE-output-missing-build/output-missing/output
+
+ because: [^
+]+ \(output\)$
diff --git a/Tests/RunCMake/file/COPY_FILE-output-missing.cmake b/Tests/RunCMake/file/COPY_FILE-output-missing.cmake
new file mode 100644
index 0000000..22133e7
--- /dev/null
+++ b/Tests/RunCMake/file/COPY_FILE-output-missing.cmake
@@ -0,0 +1,4 @@
+set(oldname "${CMAKE_CURRENT_BINARY_DIR}/input")
+set(newname "${CMAKE_CURRENT_BINARY_DIR}/output-missing/output")
+file(WRITE "${oldname}" "")
+file(COPY_FILE "${oldname}" "${newname}")
diff --git a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt
index 406e315..7a356c1 100644
--- a/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt
+++ b/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-stderr.txt
@@ -4,7 +4,6 @@
for file: \[.*/Tests/RunCMake/file/DOWNLOAD-hash-mismatch-build/hash-mismatch.txt\]
expected hash: \[0123456789abcdef0123456789abcdef01234567\]
actual hash: \[da39a3ee5e6b4b0d3255bfef95601890afd80709\]
- status: \[0;"No error"\]
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index db88956..4ad00ff 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -65,6 +65,8 @@ 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(COPY_FILE-input-missing)
+run_cmake_script(COPY_FILE-output-missing)
run_cmake_script(RENAME-file-replace)
run_cmake_script(RENAME-file-to-file)
diff --git a/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
index 3a13d32..c11215a 100644
--- a/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at CMP0048-OLD-VERSION.cmake:1 \(project\):
VERSION not allowed unless CMP0048 is set to NEW
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/CMP0048-OLD-stderr.txt b/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
index 1fa70f8..695fb70 100644
--- a/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-OLD-stderr.txt
@@ -7,4 +7,4 @@
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:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/CMP0048-WARN-stderr.txt b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
index 6d29ad2..d9be5d3 100644
--- a/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
+++ b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
@@ -8,5 +8,5 @@ CMake Warning \(dev\) at CMP0048-WARN.cmake:3 \(project\):
PROJECT_VERSION
MyProject_VERSION_TWEAK
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/project/CMakeLists.txt b/Tests/RunCMake/project/CMakeLists.txt
index 4b3de84..fdcaee9 100644
--- a/Tests/RunCMake/project/CMakeLists.txt
+++ b/Tests/RunCMake/project/CMakeLists.txt
@@ -1,3 +1,5 @@
-cmake_minimum_required(VERSION 2.8.12)
+if(NOT "x${RunCMake_TEST}" STREQUAL "xNoMinimumRequired")
+ cmake_minimum_required(VERSION 2.8.12)
+endif()
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/project/LanguagesTwice-stderr.txt b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
index 9c69dd0..6edca2f 100644
--- a/Tests/RunCMake/project/LanguagesTwice-stderr.txt
+++ b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at LanguagesTwice.cmake:1 \(project\):
LANGUAGES may be specified at most once.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/NoMinimumRequired-stderr.txt b/Tests/RunCMake/project/NoMinimumRequired-stderr.txt
new file mode 100644
index 0000000..83e2ac9
--- /dev/null
+++ b/Tests/RunCMake/project/NoMinimumRequired-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+ cmake_minimum_required\(\) should be called prior to this top-level project\(\)
+ call\. Please see the cmake-commands\(7\) manual for usage documentation of
+ both commands\.
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/project/NoMinimumRequired.cmake b/Tests/RunCMake/project/NoMinimumRequired.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/project/NoMinimumRequired.cmake
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 6d9f52f..0f3716f 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -52,3 +52,5 @@ run_cmake(CMP0048-NEW)
run_cmake(CMP0096-WARN)
run_cmake(CMP0096-OLD)
run_cmake(CMP0096-NEW)
+
+run_cmake(NoMinimumRequired)
diff --git a/Tests/RunCMake/project/VersionInvalid-stderr.txt b/Tests/RunCMake/project/VersionInvalid-stderr.txt
index 48358d1..e13a382 100644
--- a/Tests/RunCMake/project/VersionInvalid-stderr.txt
+++ b/Tests/RunCMake/project/VersionInvalid-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VersionInvalid.cmake:2 \(project\):
VERSION "NONE" format invalid.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
index 576ac69..63cbf63 100644
--- a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
+++ b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
@@ -2,4 +2,4 @@ CMake Error at VersionMissingLanguages.cmake:2 \(project\):
project with VERSION, DESCRIPTION or HOMEPAGE_URL must use LANGUAGES before
language names.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/VersionTwice-stderr.txt b/Tests/RunCMake/project/VersionTwice-stderr.txt
index ec07ead..dc05533 100644
--- a/Tests/RunCMake/project/VersionTwice-stderr.txt
+++ b/Tests/RunCMake/project/VersionTwice-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at VersionTwice.cmake:2 \(project\):
VERSION may be specified at most once.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)$
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project_injected/RunCMakeTest.cmake b/Tests/RunCMake/project_injected/RunCMakeTest.cmake
index ba1a003..cf63e12 100644
--- a/Tests/RunCMake/project_injected/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project_injected/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
set(RunCMake_TEST_OPTIONS
+ -DCMAKE_MINIMUM_REQUIRED_VERSION:STATIC=
# Simulate a previous CMake run that used `project(... VERSION ...)`
# in a non-injected call site.
-DCMAKE_PROJECT_VERSION:STATIC=1.2.3
diff --git a/Tests/RunCMake/string/Timestamp-stderr.txt b/Tests/RunCMake/string/Timestamp-stderr.txt
index f162f52..c57bba6 100644
--- a/Tests/RunCMake/string/Timestamp-stderr.txt
+++ b/Tests/RunCMake/string/Timestamp-stderr.txt
@@ -1 +1 @@
-RESULT=2005-08-07 23:19:49.000000 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789
+^RESULT=2005-08-07 23:19:49.000000 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789 TZ=GMT tz=\+0000$
diff --git a/Tests/RunCMake/string/Timestamp.cmake b/Tests/RunCMake/string/Timestamp.cmake
index 531a237..3d68b1a 100644
--- a/Tests/RunCMake/string/Timestamp.cmake
+++ b/Tests/RunCMake/string/Timestamp.cmake
@@ -1,3 +1,3 @@
set(ENV{SOURCE_DATE_EPOCH} "1123456789")
-string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC)
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z" UTC)
message("RESULT=${RESULT}")
diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt
new file mode 100644
index 0000000..07e9a9f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0108-OLD-self-link.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0108 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/test_include_dirs/RunCMakeTest.cmake b/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
index 72056ae..74795c2 100644
--- a/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
+++ b/Tests/RunCMake/test_include_dirs/RunCMakeTest.cmake
@@ -1,5 +1,9 @@
include(RunCMake)
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
function(run_TID)
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TID-build)
diff --git a/Tests/RunCMake/try_compile/Inspect.cmake b/Tests/RunCMake/try_compile/Inspect.cmake
index added41..2977d02 100644
--- a/Tests/RunCMake/try_compile/Inspect.cmake
+++ b/Tests/RunCMake/try_compile/Inspect.cmake
@@ -1,4 +1,25 @@
+enable_language(C)
enable_language(CXX)
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "
-set(CMAKE_CXX_EXTENSIONS_DEFAULT \"${CMAKE_CXX_EXTENSIONS_DEFAULT}\")
-")
+if(CMake_TEST_OBJC)
+ enable_language(OBJC)
+ enable_language(OBJCXX)
+endif()
+
+set(info "")
+foreach(var
+ CMAKE_C_COMPILER_ID
+ CMAKE_C_COMPILER_VERSION
+ CMAKE_C_STANDARD_DEFAULT
+ CMAKE_CXX_COMPILER_ID
+ CMAKE_CXX_COMPILER_VERSION
+ CMAKE_CXX_STANDARD_DEFAULT
+ CMAKE_CXX_EXTENSIONS_DEFAULT
+ CMAKE_OBJC_STANDARD_DEFAULT
+ CMAKE_OBJCXX_STANDARD_DEFAULT
+ )
+ if(DEFINED ${var})
+ string(APPEND info "set(${var} \"${${var}}\")\n")
+ endif()
+endforeach()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index 7245471..ad1cc29 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -1,5 +1,20 @@
include(RunCMake)
+# Detect information from the toolchain:
+# - CMAKE_C_COMPILER_ID
+# - CMAKE_C_COMPILER_VERSION
+# - CMAKE_C_STANDARD_DEFAULT
+# - CMAKE_CXX_COMPILER_ID
+# - CMAKE_CXX_COMPILER_VERSION
+# - CMAKE_CXX_STANDARD_DEFAULT
+# - CMAKE_CXX_EXTENSIONS_DEFAULT
+# - CMAKE_OBJC_STANDARD_DEFAULT
+# - CMAKE_OBJCXX_STANDARD_DEFAULT
+run_cmake_with_options(Inspect
+ -DCMake_TEST_OBJC=${CMake_TEST_OBJC}
+ )
+include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
run_cmake(NoArgs)
run_cmake(OneArg)
run_cmake(TwoArgs)
@@ -88,12 +103,6 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
unset(RunCMake_TEST_NO_CLEAN)
endif()
-# Lookup CMAKE_CXX_EXTENSIONS_DEFAULT.
-# FIXME: Someday we could move this to the top of the file and use it in
-# place of some of the values passed by 'Tests/RunCMake/CMakeLists.txt'.
-run_cmake(Inspect)
-include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
-
# FIXME: Support more compilers and default standard levels.
if (DEFINED CMAKE_CXX_STANDARD_DEFAULT AND
DEFINED CMAKE_CXX_EXTENSIONS_DEFAULT AND (
diff --git a/Tests/SwiftMixLib/CMakeLists.txt b/Tests/SwiftMixLib/CMakeLists.txt
index 40d3498..a52fc94 100644
--- a/Tests/SwiftMixLib/CMakeLists.txt
+++ b/Tests/SwiftMixLib/CMakeLists.txt
@@ -4,3 +4,6 @@ project(SwiftMixLib C CXX Swift)
add_library(SwiftMixedLib lib.c lib.cpp lib.swift)
add_executable(Swifty main.swift)
target_link_libraries(Swifty PUBLIC SwiftMixedLib)
+
+add_executable(c_main main.c)
+target_link_libraries(c_main PUBLIC SwiftMixedLib)
diff --git a/Tests/SwiftMixLib/main.c b/Tests/SwiftMixLib/main.c
new file mode 100644
index 0000000..6ecf984
--- /dev/null
+++ b/Tests/SwiftMixLib/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char* argv[])
+{
+}
diff --git a/Tests/UseSWIG/BasicPerl/CMakeLists.txt b/Tests/UseSWIG/BasicPerl/CMakeLists.txt
index 671d529..1151739 100644
--- a/Tests/UseSWIG/BasicPerl/CMakeLists.txt
+++ b/Tests/UseSWIG/BasicPerl/CMakeLists.txt
@@ -4,7 +4,9 @@ project(TestBasicPerl CXX)
include(CTest)
-set(language "perl")
+if(NOT DEFINED language)
+ set(language "perl")
+endif()
include (../BasicConfiguration.cmake)
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index c76e8a0..7c4925e 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -20,6 +20,16 @@ add_test(NAME UseSWIG.LegacyPerl COMMAND
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+add_test(NAME UseSWIG.LegacyPerl5 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/LegacyPerl"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/LegacyPerl5"
+ ${build_generator_args}
+ --build-project TestLegacyPerl
+ --build-options ${build_options} -Dlanguage=perl5
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
include(CheckLanguage)
check_language(CSharp)
@@ -66,6 +76,16 @@ add_test(NAME UseSWIG.BasicPerl COMMAND
--build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+add_test(NAME UseSWIG.BasicPerl5 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPerl"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPerl5"
+ ${build_generator_args}
+ --build-project TestBasicPerl
+ --build-options ${build_options} -Dlanguage=perl5
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2"
AND CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode|Visual Studio (1[1-9]|[2-9][0-9])")
add_test(NAME UseSWIG.Depfile.BasicPython COMMAND
@@ -89,6 +109,16 @@ if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2"
--build-options ${build_options} -DSWIG_USE_SWIG_DEPENDENCIES=ON
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME UseSWIG.Depfile.BasicPerl5 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPerl"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPerl5.Depfile"
+ ${build_generator_args}
+ --build-project TestBasicPerl
+ --build-options ${build_options} -DSWIG_USE_SWIG_DEPENDENCIES=ON -Dlanguage=perl5
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
endif()
if (CMake_TEST_UseSWIG_Fortran)
diff --git a/Tests/UseSWIG/LegacyPerl/CMakeLists.txt b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt
index 90d92f4..be0b465 100644
--- a/Tests/UseSWIG/LegacyPerl/CMakeLists.txt
+++ b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt
@@ -4,7 +4,9 @@ project(TestLegacyPerl CXX)
include(CTest)
-set(language "perl")
+if(NOT DEFINED language)
+ set(language "perl")
+endif()
include (../LegacyConfiguration.cmake)
diff --git a/Tests/VSMARMASM/CMakeLists.txt b/Tests/VSMARMASM/CMakeLists.txt
new file mode 100644
index 0000000..eb1bfdb
--- /dev/null
+++ b/Tests/VSMARMASM/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(VSMARMASM C ASM_MARMASM)
+add_executable(VSMARMASM main.c foo.asm)
diff --git a/Tests/VSMARMASM/foo.asm b/Tests/VSMARMASM/foo.asm
new file mode 100644
index 0000000..e5b2775
--- /dev/null
+++ b/Tests/VSMARMASM/foo.asm
@@ -0,0 +1,10 @@
+ AREA |.text|, CODE
+
+ EXPORT foo
+
+foo PROC
+ mov w0, #0
+ ret
+ ENDP
+
+ END
diff --git a/Tests/VSMARMASM/main.c b/Tests/VSMARMASM/main.c
new file mode 100644
index 0000000..18ddb78
--- /dev/null
+++ b/Tests/VSMARMASM/main.c
@@ -0,0 +1,5 @@
+extern int foo(void);
+int main(void)
+{
+ return foo();
+}
diff --git a/Utilities/ClangTidyModule/CMakeLists.txt b/Utilities/ClangTidyModule/CMakeLists.txt
new file mode 100644
index 0000000..c51f43a
--- /dev/null
+++ b/Utilities/ClangTidyModule/CMakeLists.txt
@@ -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.
+cmake_minimum_required(VERSION 3.13)
+project(CMakeClangTidyModule C CXX)
+
+get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
+get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
+
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Clang REQUIRED)
+
+add_library(cmake-clang-tidy-module MODULE
+ Module.cxx
+
+ OstringstreamUseCmstrcatCheck.cxx
+ OstringstreamUseCmstrcatCheck.h
+ UseBespokeEnumClassCheck.cxx
+ UseBespokeEnumClassCheck.h
+ UseCmstrlenCheck.cxx
+ UseCmstrlenCheck.h
+ UseCmsysFstreamCheck.cxx
+ UseCmsysFstreamCheck.h
+ )
+target_include_directories(cmake-clang-tidy-module PRIVATE ${CLANG_INCLUDE_DIRS})
+target_link_libraries(cmake-clang-tidy-module PRIVATE clang-tidy)
+
+option(RUN_TESTS "Run the tests for the clang-tidy module" OFF)
+if(RUN_TESTS)
+ enable_testing()
+ add_subdirectory(Tests)
+endif()
diff --git a/Utilities/ClangTidyModule/Module.cxx b/Utilities/ClangTidyModule/Module.cxx
new file mode 100644
index 0000000..7ef8e7d
--- /dev/null
+++ b/Utilities/ClangTidyModule/Module.cxx
@@ -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. */
+#include <clang-tidy/ClangTidyModule.h>
+#include <clang-tidy/ClangTidyModuleRegistry.h>
+
+#include "OstringstreamUseCmstrcatCheck.h"
+#include "UseBespokeEnumClassCheck.h"
+#include "UseCmstrlenCheck.h"
+#include "UseCmsysFstreamCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class CMakeClangTidyModule : public ClangTidyModule
+{
+public:
+ void addCheckFactories(ClangTidyCheckFactories& CheckFactories) override
+ {
+ CheckFactories.registerCheck<UseCmstrlenCheck>("cmake-use-cmstrlen");
+ CheckFactories.registerCheck<UseCmsysFstreamCheck>(
+ "cmake-use-cmsys-fstream");
+ CheckFactories.registerCheck<UseBespokeEnumClassCheck>(
+ "cmake-use-bespoke-enum-class");
+ CheckFactories.registerCheck<OstringstreamUseCmstrcatCheck>(
+ "cmake-ostringstream-use-cmstrcat");
+ }
+};
+
+static ClangTidyModuleRegistry::Add<CMakeClangTidyModule> X(
+ "cmake-clang-tidy", "Adds lint checks for the CMake code base.");
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx
new file mode 100644
index 0000000..920fdf3
--- /dev/null
+++ b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.cxx
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "OstringstreamUseCmstrcatCheck.h"
+
+#include <clang/AST/Type.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+using namespace ast_matchers;
+
+OstringstreamUseCmstrcatCheck::OstringstreamUseCmstrcatCheck(
+ StringRef Name, ClangTidyContext* Context)
+ : ClangTidyCheck(Name, Context)
+{
+}
+
+void OstringstreamUseCmstrcatCheck::registerMatchers(MatchFinder* Finder)
+{
+ Finder->addMatcher(
+ typeLoc(unless(elaboratedTypeLoc()),
+ optionally(hasParent(elaboratedTypeLoc().bind("parentType"))),
+ loc(qualType(
+ hasDeclaration(namedDecl(hasName("::std::ostringstream"))))))
+ .bind("ostringstream"),
+ this);
+}
+
+void OstringstreamUseCmstrcatCheck::check(
+ const MatchFinder::MatchResult& Result)
+{
+ const TypeLoc* ParentTypeNode =
+ Result.Nodes.getNodeAs<TypeLoc>("parentType");
+ const TypeLoc* RootNode = Result.Nodes.getNodeAs<TypeLoc>("ostringstream");
+
+ if (ParentTypeNode != nullptr) {
+ if (ParentTypeNode->getBeginLoc().isValid()) {
+ this->diag(ParentTypeNode->getBeginLoc(),
+ "use strings and cmStrCat() instead of std::ostringstream");
+ }
+
+ } else if (RootNode != nullptr) {
+ if (RootNode->getBeginLoc().isValid()) {
+ this->diag(RootNode->getBeginLoc(),
+ "use strings and cmStrCat() instead of std::ostringstream");
+ }
+ }
+}
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h
new file mode 100644
index 0000000..ecb5616
--- /dev/null
+++ b/Utilities/ClangTidyModule/OstringstreamUseCmstrcatCheck.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class OstringstreamUseCmstrcatCheck : public ClangTidyCheck
+{
+public:
+ OstringstreamUseCmstrcatCheck(StringRef Name, ClangTidyContext* Context);
+ void registerMatchers(ast_matchers::MatchFinder* Finder) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/Tests/CMakeLists.txt b/Utilities/ClangTidyModule/Tests/CMakeLists.txt
new file mode 100644
index 0000000..5bf0e89
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/CMakeLists.txt
@@ -0,0 +1,16 @@
+configure_file("${CMake_SOURCE_DIR}/.clang-format" ".clang-format" COPYONLY)
+
+function(add_run_clang_tidy_test check_name)
+ add_test(NAME "RunClangTidy.${check_name}" COMMAND ${CMAKE_COMMAND}
+ "-DCLANG_TIDY_COMMAND=$<TARGET_FILE:clang-tidy>"
+ "-DCLANG_TIDY_MODULE=$<TARGET_FILE:cmake-clang-tidy-module>"
+ "-DCHECK_NAME=${check_name}"
+ "-DRunClangTidy_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/RunClangTidy.cmake"
+ )
+endfunction()
+
+add_run_clang_tidy_test(cmake-use-cmstrlen)
+add_run_clang_tidy_test(cmake-use-cmsys-fstream)
+add_run_clang_tidy_test(cmake-use-bespoke-enum-class)
+add_run_clang_tidy_test(cmake-ostringstream-use-cmstrcat)
diff --git a/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake
new file mode 100644
index 0000000..7fd7cdd
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake
@@ -0,0 +1,63 @@
+set(config_arg)
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy")
+ set(config_arg "--config-file=${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy")
+endif()
+
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-stdout.txt")
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-stdout.txt" expect_stdout)
+ string(REGEX REPLACE "\n+$" "" expect_stdout "${expect_stdout}")
+else()
+ set(expect_stdout "")
+endif()
+
+set(source_file "${RunClangTidy_BINARY_DIR}/${CHECK_NAME}.cxx")
+configure_file("${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.cxx" "${source_file}" COPYONLY)
+
+set(command
+ "${CLANG_TIDY_COMMAND}"
+ "--load=${CLANG_TIDY_MODULE}"
+ "--checks=-*,${CHECK_NAME}"
+ "--fix"
+ "--format-style=file"
+ ${config_arg}
+ "${source_file}"
+ --
+ )
+execute_process(
+ COMMAND ${command}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE actual_stdout
+ ERROR_VARIABLE actual_stderr
+ )
+string(REPLACE "${RunClangTidy_BINARY_DIR}/" "" actual_stdout "${actual_stdout}")
+
+set(RunClangTidy_TEST_FAILED)
+
+if(NOT result EQUAL 0)
+ string(APPEND RunClangTidy_TEST_FAILED "Expected result: 0, actual result: ${result}\n")
+endif()
+
+string(REGEX REPLACE "\n+$" "" actual_stdout "${actual_stdout}")
+if(NOT actual_stdout STREQUAL expect_stdout)
+ string(REPLACE "\n" "\n " expect_stdout_formatted " ${expect_stdout}")
+ string(REPLACE "\n" "\n " actual_stdout_formatted " ${actual_stdout}")
+ string(APPEND RunClangTidy_TEST_FAILED "Expected stdout:\n${expect_stdout_formatted}\nActual stdout:\n${actual_stdout_formatted}\n")
+endif()
+
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx")
+ set(expect_fixit_file "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx")
+else()
+ set(expect_fixit_file "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.cxx")
+endif()
+file(READ "${expect_fixit_file}" expect_fixit)
+file(READ "${source_file}" actual_fixit)
+if(NOT expect_fixit STREQUAL actual_fixit)
+ string(REPLACE "\n" "\n " expect_fixit_formatted " ${expect_fixit}")
+ string(REPLACE "\n" "\n " actual_fixit_formatted " ${actual_fixit}")
+ string(APPEND RunClangTidy_TEST_FAILED "Expected fixit:\n${expect_fixit_formatted}\nActual fixit:\n${actual_fixit_formatted}\n")
+endif()
+
+if(RunClangTidy_TEST_FAILED)
+ string(REPLACE ";" " " command_formatted "${command}")
+ message(FATAL_ERROR "Command:\n ${command_formatted}\n${RunClangTidy_TEST_FAILED}")
+endif()
diff --git a/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt
new file mode 100644
index 0000000..1b2d6e7
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat-stdout.txt
@@ -0,0 +1,6 @@
+cmake-ostringstream-use-cmstrcat.cxx:5:3: warning: use strings and cmStrCat() instead of std::ostringstream [cmake-ostringstream-use-cmstrcat]
+ std::ostringstream test;
+ ^
+cmake-ostringstream-use-cmstrcat.cxx:8:13: warning: use strings and cmStrCat() instead of std::ostringstream [cmake-ostringstream-use-cmstrcat]
+void check2(std::ostringstream& test2)
+ ^
diff --git a/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx
new file mode 100644
index 0000000..ab749a6
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-ostringstream-use-cmstrcat.cxx
@@ -0,0 +1,10 @@
+#include <sstream>
+
+void check()
+{
+ std::ostringstream test;
+}
+
+void check2(std::ostringstream& test2)
+{
+}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class-stdout.txt
new file mode 100644
index 0000000..5e0acdd
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class-stdout.txt
@@ -0,0 +1,18 @@
+cmake-use-bespoke-enum-class.cxx:3:16: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+bool function1(bool i)
+ ^
+cmake-use-bespoke-enum-class.cxx:8:15: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+int function2(bool i)
+ ^
+cmake-use-bespoke-enum-class.cxx:13:16: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+char function3(bool i)
+ ^
+cmake-use-bespoke-enum-class.cxx:18:16: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+void function4(bool i)
+ ^
+cmake-use-bespoke-enum-class.cxx:22:17: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+float function5(bool i)
+ ^
+cmake-use-bespoke-enum-class.cxx:27:18: warning: use a bespoke enum class instead of booleans as parameters [cmake-use-bespoke-enum-class]
+double function6(bool i)
+ ^
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class.cxx
new file mode 100644
index 0000000..2913e6a
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-bespoke-enum-class.cxx
@@ -0,0 +1,63 @@
+// Correction needed
+
+bool function1(bool i)
+{
+ return true;
+}
+
+int function2(bool i)
+{
+ return 0;
+}
+
+char function3(bool i)
+{
+ return 'a';
+}
+
+void function4(bool i)
+{
+}
+
+float function5(bool i)
+{
+ return 1.0;
+}
+
+double function6(bool i)
+{
+ return 0;
+}
+
+// No correction needed
+bool global;
+
+bool function7(int i)
+{
+ bool l;
+ return true;
+}
+
+int function8(int i)
+{
+ return i;
+}
+
+char function9(char i)
+{
+ return i;
+}
+
+void function10()
+{
+}
+
+float function11(float i)
+{
+ return i;
+}
+
+double function12(double i)
+{
+ return i;
+}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx
new file mode 100644
index 0000000..c93d557
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx
@@ -0,0 +1,37 @@
+#include <cstring>
+
+template <size_t N>
+constexpr size_t cmStrLen(const char (&/*str*/)[N])
+{
+ return N - 1;
+}
+
+namespace ns1 {
+using std::strlen;
+}
+
+namespace ns2 {
+std::size_t strlen(const char* str)
+{
+ return std::strlen(str);
+}
+}
+
+int main()
+{
+ // String variable used for calling strlen() on a variable
+ auto s0 = "howdy";
+
+ // Correction needed
+ (void)cmStrLen("Hello");
+ (void)cmStrLen("Goodbye");
+ (void)cmStrLen("Hola");
+ (void)cmStrLen("Bonjour");
+
+ // No correction needed
+ (void)ns2::strlen("Salve");
+ (void)cmStrLen("Konnichiwa");
+ (void)strlen(s0);
+
+ return 0;
+}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt
new file mode 100644
index 0000000..6c52ad5
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt
@@ -0,0 +1,20 @@
+cmake-use-cmstrlen.cxx:26:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)strlen("Hello");
+ ^~~~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:26:9: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:27:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)::strlen("Goodbye");
+ ^~~~~~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:27:9: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:28:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)std::strlen("Hola");
+ ^~~~~~~~~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:28:9: note: FIX-IT applied suggested code changes
+cmake-use-cmstrlen.cxx:29:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen]
+ (void)ns1::strlen("Bonjour");
+ ^~~~~~~~~~~
+ cmStrLen
+cmake-use-cmstrlen.cxx:29:9: note: FIX-IT applied suggested code changes
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx
new file mode 100644
index 0000000..f36262b
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx
@@ -0,0 +1,37 @@
+#include <cstring>
+
+template <size_t N>
+constexpr size_t cmStrLen(const char (&/*str*/)[N])
+{
+ return N - 1;
+}
+
+namespace ns1 {
+using std::strlen;
+}
+
+namespace ns2 {
+std::size_t strlen(const char* str)
+{
+ return std::strlen(str);
+}
+}
+
+int main()
+{
+ // String variable used for calling strlen() on a variable
+ auto s0 = "howdy";
+
+ // Correction needed
+ (void)strlen("Hello");
+ (void)::strlen("Goodbye");
+ (void)std::strlen("Hola");
+ (void)ns1::strlen("Bonjour");
+
+ // No correction needed
+ (void)ns2::strlen("Salve");
+ (void)cmStrLen("Konnichiwa");
+ (void)strlen(s0);
+
+ return 0;
+}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx
new file mode 100644
index 0000000..5c7c123
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx
@@ -0,0 +1,81 @@
+#include <fstream>
+#include <vector>
+
+namespace cmsys {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+}
+
+namespace ns {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+
+namespace ns {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+}
+
+class cl
+{
+public:
+ using ifstream = cmsys::ifstream;
+ using ofstream = cmsys::ofstream;
+ using fstream = cmsys::fstream;
+};
+
+using ifs = cmsys::ifstream;
+using ofs = cmsys::ofstream;
+using fs = cmsys::fstream;
+}
+
+int main()
+{
+ using std::ifstream;
+ using std::ofstream;
+ using std::fstream;
+
+ // Correction needed
+ cmsys::ifstream ifsUnqual;
+ cmsys::ifstream ifsQual;
+ cmsys::ifstream ifsNS;
+ cmsys::ifstream ifsNested;
+ cmsys::ifstream ifsClass;
+ cmsys::ifstream ifsRenamed;
+
+ cmsys::ofstream ofsUnqual;
+ cmsys::ofstream ofsQual;
+ cmsys::ofstream ofsNS;
+ cmsys::ofstream ofsNested;
+ cmsys::ofstream ofsClass;
+ cmsys::ofstream ofsRenamed;
+
+ cmsys::fstream fsUnqual;
+ cmsys::fstream fsQual;
+ cmsys::fstream fsNS;
+ cmsys::fstream fsNested;
+ cmsys::fstream fsClass;
+ cmsys::fstream fsRenamed;
+
+ cmsys::ifstream::off_type offsetQual = 0;
+ cmsys::ifstream::off_type offsetUnqual = 0;
+ cmsys::ifstream::off_type offsetNS = 0;
+ cmsys::ifstream::off_type offsetNested = 0;
+ cmsys::ifstream::traits_type::off_type offsetTraitsNested = 0;
+ cmsys::ifstream::traits_type::off_type offsetTraitsClass = 0;
+
+ std::vector<cmsys::ifstream> ifsVectorUnqual;
+
+ // No correction needed
+ cmsys::ifstream ifsCmsys;
+ cmsys::ofstream ofsCmsys;
+ cmsys::fstream fsCmsys;
+ cmsys::ifstream::off_type offsetCmsys = 0;
+ cmsys::ifstream::traits_type::off_type offsetTraitsCmsys = 0;
+ std::vector<cmsys::ifstream> ifsVectorCmsys;
+ std::basic_ifstream<wchar_t> ifsWchar;
+
+ return 0;
+}
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt
new file mode 100644
index 0000000..d2c45f2
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt
@@ -0,0 +1,155 @@
+cmake-use-cmsys-fstream.cxx:24:20: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ using ifstream = std::ifstream;
+ ^~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:24:20: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:25:20: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ using ofstream = std::ofstream;
+ ^~~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:25:20: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:26:19: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ using fstream = std::fstream;
+ ^~~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:26:19: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:29:13: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+using ifs = std::ifstream;
+ ^~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:29:13: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:30:13: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+using ofs = std::ofstream;
+ ^~~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:30:13: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:31:12: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+using fs = std::fstream;
+ ^~~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:31:12: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:41:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ifstream ifsUnqual;
+ ^~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:41:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:42:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ std::ifstream ifsQual;
+ ^~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:42:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:43:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ifstream ifsNS;
+ ^~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:43:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:44:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ns::ifstream ifsNested;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:44:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:45:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::cl::ifstream ifsClass;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:45:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:46:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ifs ifsRenamed;
+ ^~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:46:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:48:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ ofstream ofsUnqual;
+ ^~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:48:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:49:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ std::ofstream ofsQual;
+ ^~~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:49:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:50:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ ns::ofstream ofsNS;
+ ^~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:50:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:51:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ ns::ns::ofstream ofsNested;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:51:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:52:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ ns::cl::ofstream ofsClass;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:52:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:53:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream]
+ ns::ofs ofsRenamed;
+ ^~~~~~~
+ cmsys::ofstream
+cmake-use-cmsys-fstream.cxx:53:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:55:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ fstream fsUnqual;
+ ^~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:55:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:56:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ std::fstream fsQual;
+ ^~~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:56:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:57:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ ns::fstream fsNS;
+ ^~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:57:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:58:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ ns::ns::fstream fsNested;
+ ^~~~~~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:58:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:59:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ ns::ns::fstream fsClass;
+ ^~~~~~~~~~~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:59:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:60:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream]
+ ns::fs fsRenamed;
+ ^~~~~~
+ cmsys::fstream
+cmake-use-cmsys-fstream.cxx:60:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:62:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ std::ifstream::off_type offsetQual = 0;
+ ^~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:62:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:63:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ifstream::off_type offsetUnqual = 0;
+ ^~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:63:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:64:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ifstream::off_type offsetNS = 0;
+ ^~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:64:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:65:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ns::ifstream::off_type offsetNested = 0;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:65:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:66:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::ns::ifstream::traits_type::off_type offsetTraitsNested = 0;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:66:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:67:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ ns::cl::ifstream::traits_type::off_type offsetTraitsClass = 0;
+ ^~~~~~~~~~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:67:3: note: FIX-IT applied suggested code changes
+cmake-use-cmsys-fstream.cxx:69:15: warning: use cmsys::ifstream [cmake-use-cmsys-fstream]
+ std::vector<ifstream> ifsVectorUnqual;
+ ^~~~~~~~
+ cmsys::ifstream
+cmake-use-cmsys-fstream.cxx:69:15: note: FIX-IT applied suggested code changes
diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx
new file mode 100644
index 0000000..56a7611
--- /dev/null
+++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx
@@ -0,0 +1,81 @@
+#include <fstream>
+#include <vector>
+
+namespace cmsys {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+}
+
+namespace ns {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+
+namespace ns {
+using std::ifstream;
+using std::ofstream;
+using std::fstream;
+}
+
+class cl
+{
+public:
+ using ifstream = std::ifstream;
+ using ofstream = std::ofstream;
+ using fstream = std::fstream;
+};
+
+using ifs = std::ifstream;
+using ofs = std::ofstream;
+using fs = std::fstream;
+}
+
+int main()
+{
+ using std::ifstream;
+ using std::ofstream;
+ using std::fstream;
+
+ // Correction needed
+ ifstream ifsUnqual;
+ std::ifstream ifsQual;
+ ns::ifstream ifsNS;
+ ns::ns::ifstream ifsNested;
+ ns::cl::ifstream ifsClass;
+ ns::ifs ifsRenamed;
+
+ ofstream ofsUnqual;
+ std::ofstream ofsQual;
+ ns::ofstream ofsNS;
+ ns::ns::ofstream ofsNested;
+ ns::cl::ofstream ofsClass;
+ ns::ofs ofsRenamed;
+
+ fstream fsUnqual;
+ std::fstream fsQual;
+ ns::fstream fsNS;
+ ns::ns::fstream fsNested;
+ ns::ns::fstream fsClass;
+ ns::fs fsRenamed;
+
+ std::ifstream::off_type offsetQual = 0;
+ ifstream::off_type offsetUnqual = 0;
+ ns::ifstream::off_type offsetNS = 0;
+ ns::ns::ifstream::off_type offsetNested = 0;
+ ns::ns::ifstream::traits_type::off_type offsetTraitsNested = 0;
+ ns::cl::ifstream::traits_type::off_type offsetTraitsClass = 0;
+
+ std::vector<ifstream> ifsVectorUnqual;
+
+ // No correction needed
+ cmsys::ifstream ifsCmsys;
+ cmsys::ofstream ofsCmsys;
+ cmsys::fstream fsCmsys;
+ cmsys::ifstream::off_type offsetCmsys = 0;
+ cmsys::ifstream::traits_type::off_type offsetTraitsCmsys = 0;
+ std::vector<cmsys::ifstream> ifsVectorCmsys;
+ std::basic_ifstream<wchar_t> ifsWchar;
+
+ return 0;
+}
diff --git a/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.cxx b/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.cxx
new file mode 100644
index 0000000..26f3749
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.cxx
@@ -0,0 +1,35 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "UseBespokeEnumClassCheck.h"
+
+#include <clang/AST/Type.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+using namespace ast_matchers;
+
+UseBespokeEnumClassCheck::UseBespokeEnumClassCheck(StringRef Name,
+ ClangTidyContext* Context)
+ : ClangTidyCheck(Name, Context)
+{
+}
+
+void UseBespokeEnumClassCheck::registerMatchers(MatchFinder* Finder)
+{
+ Finder->addMatcher(
+ parmVarDecl(
+ hasTypeLoc(typeLoc(loc(qualType(asString("_Bool")))).bind("type"))),
+ this);
+}
+
+void UseBespokeEnumClassCheck::check(const MatchFinder::MatchResult& Result)
+{
+ const TypeLoc* Node = Result.Nodes.getNodeAs<TypeLoc>("type");
+ this->diag(Node->getBeginLoc(),
+ "use a bespoke enum class instead of booleans as parameters");
+}
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.h b/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.h
new file mode 100644
index 0000000..be76db0
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseBespokeEnumClassCheck.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class UseBespokeEnumClassCheck : public ClangTidyCheck
+{
+public:
+ UseBespokeEnumClassCheck(StringRef Name, ClangTidyContext* Context);
+ void registerMatchers(ast_matchers::MatchFinder* Finder) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx
new file mode 100644
index 0000000..590d260
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx
@@ -0,0 +1,34 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "UseCmstrlenCheck.h"
+
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+using namespace ast_matchers;
+
+UseCmstrlenCheck::UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context)
+ : ClangTidyCheck(Name, Context)
+{
+}
+
+void UseCmstrlenCheck::registerMatchers(MatchFinder* Finder)
+{
+ Finder->addMatcher(callExpr(callee(functionDecl(hasName("::strlen"))),
+ callee(expr().bind("callee")),
+ hasArgument(0, stringLiteral())),
+ this);
+}
+
+void UseCmstrlenCheck::check(const MatchFinder::MatchResult& Result)
+{
+ const Expr* Node = Result.Nodes.getNodeAs<Expr>("callee");
+
+ this->diag(Node->getBeginLoc(), "use cmStrLen() for string literals")
+ << FixItHint::CreateReplacement(Node->getSourceRange(), "cmStrLen");
+}
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.h b/Utilities/ClangTidyModule/UseCmstrlenCheck.h
new file mode 100644
index 0000000..08f77c2
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class UseCmstrlenCheck : public ClangTidyCheck
+{
+public:
+ UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context);
+ void registerMatchers(ast_matchers::MatchFinder* Finder) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
+};
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx
new file mode 100644
index 0000000..95a0a4d
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx
@@ -0,0 +1,101 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "UseCmsysFstreamCheck.h"
+
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+using namespace ast_matchers;
+
+UseCmsysFstreamCheck::UseCmsysFstreamCheck(StringRef Name,
+ ClangTidyContext* Context)
+ : ClangTidyCheck(Name, Context)
+{
+}
+
+void UseCmsysFstreamCheck::registerMatchers(MatchFinder* Finder)
+{
+ this->createMatcher("::std::basic_ifstream", "::cmsys::ifstream", Finder,
+ "ifstream");
+ this->createMatcher("::std::basic_ofstream", "::cmsys::ofstream", Finder,
+ "ofstream");
+ this->createMatcher("::std::basic_fstream", "::cmsys::fstream", Finder,
+ "fstream");
+}
+
+void UseCmsysFstreamCheck::check(const MatchFinder::MatchResult& Result)
+{
+ const TypeLoc* ParentTypeNode =
+ Result.Nodes.getNodeAs<TypeLoc>("parentType");
+ const NestedNameSpecifierLoc* ParentNameNode =
+ Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("parentName");
+ const TypeLoc* RootNode = nullptr;
+ StringRef BindName;
+ StringRef Warning;
+
+ if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("ifstream")) != nullptr) {
+ BindName = "cmsys::ifstream";
+ Warning = "use cmsys::ifstream";
+ } else if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("ofstream")) !=
+ nullptr) {
+ BindName = "cmsys::ofstream";
+ Warning = "use cmsys::ofstream";
+ } else if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("fstream")) !=
+ nullptr) {
+ BindName = "cmsys::fstream";
+ Warning = "use cmsys::fstream";
+ }
+
+ if (ParentTypeNode != nullptr) {
+ if (ParentTypeNode->getBeginLoc().isValid()) {
+ this->diag(ParentTypeNode->getBeginLoc(), Warning)
+ << FixItHint::CreateReplacement(ParentTypeNode->getSourceRange(),
+ BindName);
+ }
+ } else if (ParentNameNode != nullptr) {
+ if (ParentNameNode->getBeginLoc().isValid()) {
+ this->diag(ParentNameNode->getBeginLoc(), Warning)
+ << FixItHint::CreateReplacement(
+ SourceRange(ParentNameNode->getBeginLoc(), RootNode->getEndLoc()),
+ BindName);
+ }
+ } else if (RootNode != nullptr) {
+ if (RootNode->getBeginLoc().isValid()) {
+ this->diag(RootNode->getBeginLoc(), Warning)
+ << FixItHint::CreateReplacement(RootNode->getSourceRange(), BindName);
+ }
+ }
+}
+
+void UseCmsysFstreamCheck::createMatcher(StringRef StdName,
+ StringRef CmsysName,
+ ast_matchers::MatchFinder* Finder,
+ StringRef Bind)
+{
+ TypeLocMatcher IsStd = loc(qualType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(classTemplateSpecializationDecl(
+ hasName(StdName),
+ hasTemplateArgument(
+ 0, templateArgument(refersToType(asString("char"))))))))));
+
+ // TODO This only checks to see if the type directly refers to
+ // cmsys::fstream. There are some corner cases involving template parameters
+ // that refer to cmsys::fstream that are missed by this matcher, resulting in
+ // a false positive. Figure out how to find these indirect references to
+ // cmsys::fstream and filter them out. In the meantime, such false positives
+ // can be silenced with NOLINT(cmake-use-cmsys-fstream).
+ TypeLocMatcher IsCmsys =
+ loc(usingType(throughUsingDecl(namedDecl(hasName(CmsysName)))));
+
+ Finder->addMatcher(
+ typeLoc(IsStd, unless(IsCmsys), unless(elaboratedTypeLoc()),
+ optionally(hasParent(elaboratedTypeLoc().bind("parentType"))),
+ optionally(hasParent(nestedNameSpecifierLoc().bind("parentName"))))
+ .bind(Bind),
+ this);
+}
+}
+}
+}
diff --git a/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h
new file mode 100644
index 0000000..782123c
--- /dev/null
+++ b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h
@@ -0,0 +1,24 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <clang-tidy/ClangTidyCheck.h>
+#include <clang/ASTMatchers/ASTMatchFinder.h>
+
+namespace clang {
+namespace tidy {
+namespace cmake {
+class UseCmsysFstreamCheck : public ClangTidyCheck
+{
+public:
+ UseCmsysFstreamCheck(StringRef Name, ClangTidyContext* Context);
+ void registerMatchers(ast_matchers::MatchFinder* Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
+
+private:
+ void createMatcher(StringRef name, StringRef CmsysName,
+ ast_matchers::MatchFinder* Finder, StringRef bind);
+};
+}
+}
+}
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index bc16350..b084dd5 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.13...3.23 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.24 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/Scripts/update-nghttp2.bash b/Utilities/Scripts/update-nghttp2.bash
index 07a8f13..bc76377 100755
--- a/Utilities/Scripts/update-nghttp2.bash
+++ b/Utilities/Scripts/update-nghttp2.bash
@@ -8,7 +8,7 @@ readonly name="nghttp2"
readonly ownership="nghttp2 upstream <kwrobot@kitware.com>"
readonly subtree="Utilities/cmnghttp2"
readonly repo="https://github.com/nghttp2/nghttp2.git"
-readonly tag="v1.40.0"
+readonly tag="v1.50.0"
readonly shortlog=false
readonly paths="
COPYING
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 886f4e0..a9aa47d 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.13...3.23 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.24 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_INFO "Build Info manual with Sphinx" OFF)
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_LINKCHECK "Check external links mentioned in documentation" 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)
@@ -35,7 +36,15 @@ 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 AND NOT SPHINX_LATEXPDF)
+if(NOT (SPHINX_INFO
+ OR SPHINX_MAN
+ OR SPHINX_HTML
+ OR SPHINX_SINGLEHTML
+ OR SPHINX_LINKCHECK
+ OR SPHINX_QTHELP
+ OR SPHINX_TEXT
+ OR SPHINX_LATEXPDF
+ ))
return()
elseif(NOT SPHINX_EXECUTABLE)
message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!")
@@ -79,6 +88,13 @@ endif()
if(SPHINX_SINGLEHTML)
list(APPEND doc_formats singlehtml)
endif()
+if(SPHINX_LINKCHECK)
+ list(APPEND doc_formats linkcheck)
+ #
+ set(linkcheck_post_commands
+ COMMAND ${CMAKE_COMMAND} -E echo "sphinx-build linkcheck: see checking status in file://${CMAKE_CURRENT_BINARY_DIR}/linkcheck/output.txt"
+ )
+endif()
if(SPHINX_TEXT)
list(APPEND doc_formats text)
endif()
@@ -159,11 +175,41 @@ if(CMake_SPHINX_CMAKE_ORG)
)
endif()
+# Redirect `sphinx-build` output to `build-<format>.log` file?
+set(sphinx_use_build_log TRUE)
+set(sphinx_verbose_levels "DEBUG;TRACE")
+set(sphinx_no_redirect_levels "VERBOSE;${sphinx_verbose_levels}")
+# NOTE There is no generic verbosity level for all supported generators,
+# so lets use CMake verbosity level to control if `sphinx-build` should
+# redirect it's output to a file or a user wants to see it at build time.
+if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25)
+ cmake_language(GET_MESSAGE_LOG_LEVEL verbose_level)
+else()
+ # If building under CMake < 3.25, fallback to `CMAKE_MESSAGE_LOG_LEVEL`
+ # variable. It was added in 3.17 but it's OK to set it even for older
+ # versions (w/o any effect on `message()` command of course).
+ set(verbose_level ${CMAKE_MESSAGE_LOG_LEVEL})
+endif()
+if(DEFINED ENV{VERBOSE} OR CMAKE_VERBOSE_MAKEFILE OR verbose_level IN_LIST sphinx_no_redirect_levels)
+ set(sphinx_use_build_log FALSE)
+ if(verbose_level IN_LIST sphinx_verbose_levels)
+ # NOTE Sphinx accept multiple `-v` options for more verbosity
+ # but the output mostly for Sphinx developers...
+ list(APPEND sphinx_flags "-v")
+ endif()
+endif()
+
set(doc_format_outputs "")
set(doc_format_last "")
foreach(format IN LISTS doc_formats)
set(doc_format_output "doc_format_${format}")
- set(doc_format_log "build-${format}.log")
+ set(doc_format_log "")
+ set(build_comment_tail " ...")
+ if(sphinx_use_build_log)
+ set(doc_format_log "build-${format}.log")
+ set(build_comment_tail ": see Utilities/Sphinx/${doc_format_log}")
+ list(PREPEND doc_format_log ">")
+ endif()
if(CMake_SPHINX_CMAKE_ORG)
set(doctrees "doctrees/${format}")
else()
@@ -172,43 +218,37 @@ foreach(format IN LISTS doc_formats)
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}
- ${${format}_pre_commands}
- 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}_opts}
- > ${doc_format_log} # log stdout, pass stderr
- ${${format}_post_commands}
- DEPENDS ${doc_format_last}
- COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}"
- VERBATIM
+ set(_args
+ -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}_opts}
)
else()
# other formats use standard builder (-b) mode
- add_custom_command(
- OUTPUT ${doc_format_output}
- ${${format}_pre_commands}
- COMMAND ${SPHINX_EXECUTABLE}
- -c ${CMAKE_CURRENT_BINARY_DIR}
- -d ${CMAKE_CURRENT_BINARY_DIR}/${doctrees}
- -b ${format}
- ${sphinx_flags}
- ${doc_${format}_opts}
- ${CMake_SOURCE_DIR}/Help
- ${CMAKE_CURRENT_BINARY_DIR}/${format}
- > ${doc_format_log} # log stdout, pass stderr
- ${${format}_post_commands}
- DEPENDS ${doc_format_last}
- COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}"
- VERBATIM
+ set(_args
+ -c ${CMAKE_CURRENT_BINARY_DIR}
+ -d ${CMAKE_CURRENT_BINARY_DIR}/${doctrees}
+ -b ${format}
+ ${sphinx_flags}
+ ${doc_${format}_opts}
+ ${CMake_SOURCE_DIR}/Help
+ ${CMAKE_CURRENT_BINARY_DIR}/${format}
)
endif()
+
+ add_custom_command(
+ OUTPUT ${doc_format_output}
+ ${${format}_pre_commands}
+ COMMAND ${SPHINX_EXECUTABLE} ${_args} ${doc_format_log}
+ ${${format}_post_commands}
+ DEPENDS ${doc_format_last}
+ COMMENT "sphinx-build ${format}${build_comment_tail}"
+ VERBATIM
+ )
set_property(SOURCE ${doc_format_output} PROPERTY SYMBOLIC 1)
list(APPEND doc_format_outputs ${doc_format_output})
if(NOT CMake_SPHINX_CMAKE_ORG)
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py
index c7b1233..47e4909 100644
--- a/Utilities/Sphinx/cmake.py
+++ b/Utilities/Sphinx/cmake.py
@@ -475,3 +475,4 @@ def setup(app):
app.add_transform(CMakeTransform)
app.add_transform(CMakeXRefTransform)
app.add_domain(CMakeDomain)
+ return {"parallel_read_safe": True}
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
index 2b3083b..fc3ecb5 100644
--- a/Utilities/Sphinx/conf.py.in
+++ b/Utilities/Sphinx/conf.py.in
@@ -87,3 +87,5 @@ html_favicon = '@conf_path@/static/cmake-favicon.ico'
# https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
# qthelp_namespace = "org.cmake"
# qthelp_qch_name = "CMake.qch"
+
+linkcheck_ignore = [r'about:|https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack']
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt
index 9002ab6..6d0c76f 100644
--- a/Utilities/cmnghttp2/CMakeLists.txt
+++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -19,6 +19,7 @@ add_library(cmnghttp2 STATIC
lib/nghttp2_buf.c
lib/nghttp2_callbacks.c
lib/nghttp2_debug.c
+ lib/nghttp2_extpri.c
lib/nghttp2_frame.c
lib/nghttp2_hd.c
lib/nghttp2_hd_huffman.c
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
index e3aeb9f..61a14d9 100644
--- a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
+++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
@@ -229,6 +229,13 @@ typedef struct {
#define NGHTTP2_CLIENT_MAGIC_LEN 24
/**
+ * @macro
+ *
+ * The default max number of settings per SETTINGS frame
+ */
+#define NGHTTP2_DEFAULT_MAX_SETTINGS 32
+
+/**
* @enum
*
* Error codes used in this library. The code range is [-999, -500],
@@ -399,12 +406,17 @@ typedef enum {
*/
NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
/**
- * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
- * under unexpected condition and processing was terminated (e.g.,
- * out of memory). If application receives this error code, it must
- * stop using that :type:`nghttp2_session` object and only allowed
- * operation for that object is deallocate it using
- * `nghttp2_session_del()`.
+ * When a local endpoint receives too many settings entries
+ * in a single SETTINGS frame.
+ */
+ NGHTTP2_ERR_TOO_MANY_SETTINGS = -537,
+ /**
+ * The errors < :enum:`nghttp2_error.NGHTTP2_ERR_FATAL` mean that
+ * the library is under unexpected condition and processing was
+ * terminated (e.g., out of memory). If application receives this
+ * error code, it must stop using that :type:`nghttp2_session`
+ * object and only allowed operation for that object is deallocate
+ * it using `nghttp2_session_del()`.
*/
NGHTTP2_ERR_FATAL = -900,
/**
@@ -533,9 +545,9 @@ typedef struct {
* :type:`nghttp2_on_frame_send_callback`, and
* :type:`nghttp2_on_frame_not_send_callback`), it may not be
* NULL-terminated if header field is passed from application with
- * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`). When application
- * is constructing this struct, |name| is not required to be
- * NULL-terminated.
+ * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`).
+ * When application is constructing this struct, |name| is not
+ * required to be NULL-terminated.
*/
uint8_t *name;
/**
@@ -546,9 +558,9 @@ typedef struct {
* :type:`nghttp2_on_frame_send_callback`, and
* :type:`nghttp2_on_frame_not_send_callback`), it may not be
* NULL-terminated if header field is passed from application with
- * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE`). When
- * application is constructing this struct, |value| is not required
- * to be NULL-terminated.
+ * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE`).
+ * When application is constructing this struct, |value| is not
+ * required to be NULL-terminated.
*/
uint8_t *value;
/**
@@ -622,7 +634,11 @@ typedef enum {
* The ORIGIN frame, which is defined by `RFC 8336
* <https://tools.ietf.org/html/rfc8336>`_.
*/
- NGHTTP2_ORIGIN = 0x0c
+ NGHTTP2_ORIGIN = 0x0c,
+ /**
+ * The PRIORITY_UPDATE frame, which is defined by :rfc:`9218`.
+ */
+ NGHTTP2_PRIORITY_UPDATE = 0x10
} nghttp2_frame_type;
/**
@@ -691,7 +707,11 @@ typedef enum {
* SETTINGS_ENABLE_CONNECT_PROTOCOL
* (`RFC 8441 <https://tools.ietf.org/html/rfc8441>`_)
*/
- NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08
+ NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
+ /**
+ * SETTINGS_NO_RFC7540_PRIORITIES (:rfc:`9218`)
+ */
+ NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES = 0x09
} nghttp2_settings_id;
/* Note: If we add SETTINGS, update the capacity of
NGHTTP2_INBOUND_NUM_IV as well */
@@ -705,8 +725,8 @@ typedef enum {
*
* Default maximum number of incoming concurrent streams. Use
* `nghttp2_submit_settings()` with
- * :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
- * maximum number of incoming concurrent streams.
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS`
+ * to change the maximum number of incoming concurrent streams.
*
* .. note::
*
@@ -860,38 +880,41 @@ typedef enum {
* The implementation of this function must read at most |length|
* bytes of data from |source| (or possibly other places) and store
* them in |buf| and return number of data stored in |buf|. If EOF is
- * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|.
+ * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag
+ * in |*data_flags|.
*
* Sometime it is desirable to avoid copying data into |buf| and let
* application to send data directly. To achieve this, set
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` to |*data_flags| (and possibly
- * other flags, just like when we do copy), and return the number of
- * bytes to send without copying data into |buf|. The library, seeing
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to
+ * |*data_flags| (and possibly other flags, just like when we do
+ * copy), and return the number of bytes to send without copying data
+ * into |buf|. The library, seeing
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
* :type:`nghttp2_send_data_callback`. The application must send
* complete DATA frame in that callback.
*
* If this callback is set by `nghttp2_submit_request()`,
* `nghttp2_submit_response()` or `nghttp2_submit_headers()` and
* `nghttp2_submit_data()` with flag parameter
- * :enum:`NGHTTP2_FLAG_END_STREAM` set, and
- * :enum:`NGHTTP2_DATA_FLAG_EOF` flag is set to |*data_flags|, DATA
- * frame will have END_STREAM flag set. Usually, this is expected
- * behaviour and all are fine. One exception is send trailer fields.
- * You cannot send trailer fields after sending frame with END_STREAM
- * set. To avoid this problem, one can set
- * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM` along with
- * :enum:`NGHTTP2_DATA_FLAG_EOF` to signal the library not to set
- * END_STREAM in DATA frame. Then application can use
- * `nghttp2_submit_trailer()` to send trailer fields.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to
+ * |*data_flags|, DATA frame will have END_STREAM flag set. Usually,
+ * this is expected behaviour and all are fine. One exception is send
+ * trailer fields. You cannot send trailer fields after sending frame
+ * with END_STREAM set. To avoid this problem, one can set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along
+ * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the
+ * library not to set END_STREAM in DATA frame. Then application can
+ * use `nghttp2_submit_trailer()` to send trailer fields.
* `nghttp2_submit_trailer()` can be called inside this callback.
*
* If the application wants to postpone DATA frames (e.g.,
* asynchronous I/O, or reading data blocks for long time), it is
- * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
- * any data in this invocation. The library removes DATA frame from
- * the outgoing queue temporarily. To move back deferred DATA frame
- * to outgoing queue, call `nghttp2_session_resume_data()`.
+ * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED`
+ * without reading any data in this invocation. The library removes
+ * DATA frame from the outgoing queue temporarily. To move back
+ * deferred DATA frame to outgoing queue, call
+ * `nghttp2_session_resume_data()`.
*
* By default, |length| is limited to 16KiB at maximum. If peer
* allows larger frames, application can enlarge transmission buffer
@@ -900,16 +923,17 @@ typedef enum {
*
* If the application just wants to return from
* `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
- * sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
+ * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.
*
* In case of error, there are 2 choices. Returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
- * by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a
- * different error code is desirable, use
- * `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
- * failure.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream by issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different
+ * error code is desirable, use `nghttp2_submit_rst_stream()` with a
+ * desired error code and then return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will
+ * signal the entire session failure.
*/
typedef ssize_t (*nghttp2_data_source_read_callback)(
nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
@@ -1289,8 +1313,9 @@ typedef union {
* |length| bytes of data stored in |data|. The |flags| is currently
* not used and always 0. It must return the number of bytes sent if
* it succeeds. If it cannot send any single byte without blocking,
- * it must return :enum:`NGHTTP2_ERR_WOULDBLOCK`. For other errors,
- * it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. The
+ * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For
+ * other errors, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The
* |user_data| pointer is the third argument passed in to the call to
* `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
*
@@ -1318,9 +1343,10 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
/**
* @functypedef
*
- * Callback function invoked when :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is
- * used in :type:`nghttp2_data_source_read_callback` to send complete
- * DATA frame.
+ * Callback function invoked when
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
+ * :type:`nghttp2_data_source_read_callback` to send complete DATA
+ * frame.
*
* The |frame| is a DATA frame to send. The |framehd| is the
* serialized frame header (9 bytes). The |length| is the length of
@@ -1338,21 +1364,22 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
* If all data were written successfully, return 0.
*
* If it cannot send any data at all, just return
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
- * with the same parameters later (It is recommended to send complete
- * DATA frame at once in this function to deal with error; if partial
- * frame data has already sent, it is impossible to send another data
- * in that state, and all we can do is tear down connection). When
- * data is fully processed, but application wants to make
- * `nghttp2_session_mem_send()` or `nghttp2_session_send()` return
- * immediately without processing next frames, return
- * :enum:`NGHTTP2_ERR_PAUSE`. If application decided to reset this
- * stream, return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`; the library will call
+ * this callback with the same parameters later (It is recommended to
+ * send complete DATA frame at once in this function to deal with
+ * error; if partial frame data has already sent, it is impossible to
+ * send another data in that state, and all we can do is tear down
+ * connection). When data is fully processed, but application wants
+ * to make `nghttp2_session_mem_send()` or `nghttp2_session_send()`
+ * return immediately without processing next frames, return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. If application decided to
+ * reset this stream, return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
* the library will send RST_STREAM with INTERNAL_ERROR as error code.
* The application can also return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in
- * connection closure. Returning any other value is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which will
+ * result in connection closure. Returning any other value is treated
+ * as :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
*/
typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
nghttp2_frame *frame,
@@ -1369,11 +1396,13 @@ typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
* currently not used and always 0. It must return the number of
* bytes written in |buf| if it succeeds. If it cannot read any
* single byte without blocking, it must return
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF before it reads any
- * single byte, it must return :enum:`NGHTTP2_ERR_EOF`. For other
- * errors, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
- * Returning 0 is treated as :enum:`NGHTTP2_ERR_WOULDBLOCK`. The
- * |user_data| pointer is the third argument passed in to the call to
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF
+ * before it reads any single byte, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data|
+ * pointer is the third argument passed in to the call to
* `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
*
* This callback is required if the application uses
@@ -1417,7 +1446,8 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
* The implementation of this function must return 0 if it succeeds.
* If nonzero value is returned, it is treated as fatal error and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_frame_recv_callback()`.
@@ -1445,7 +1475,8 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session,
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`.
@@ -1468,9 +1499,9 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)(
* `nghttp2_session_server_new()`.
*
* If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
- * return without processing further input bytes. The memory by
- * pointed by the |data| is retained until
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv()` return without processing further
+ * input bytes. The memory by pointed by the |data| is retained until
* `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
* The application must retain the input bytes which was used to
* produce the |data| parameter, because it may refer to the memory
@@ -1479,7 +1510,8 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)(
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error, and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`.
@@ -1499,19 +1531,20 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
* `nghttp2_session_server_new()`.
*
* The implementation of this function must return 0 if it succeeds.
- * It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
- * transmission of the given frame.
+ * It can also return :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` to
+ * cancel the transmission of the given frame.
*
* If there is a fatal error while executing this callback, the
- * implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
- * which makes `nghttp2_session_send()` and
- * `nghttp2_session_mem_send()` functions immediately return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * implementation should return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* If the other value is returned, it is treated as if
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. But the
- * implementation should not rely on this since the library may define
- * new return value to extend its capability.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+ * But the implementation should not rely on this since the library
+ * may define new return value to extend its capability.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
@@ -1530,7 +1563,8 @@ typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session,
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_frame_send_callback()`.
@@ -1552,7 +1586,8 @@ typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session,
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* `nghttp2_session_get_stream_user_data()` can be used to get
* associated data.
@@ -1583,7 +1618,8 @@ typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session,
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`,
* `nghttp2_session_send()`, and `nghttp2_session_mem_send()`
- * functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_stream_close_callback()`.
@@ -1601,10 +1637,11 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
* will be emitted by :type:`nghttp2_on_header_callback`.
*
* The ``frame->hd.flags`` may not have
- * :enum:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one
- * or more CONTINUATION frames are involved. But the application does
- * not need to care about that because the header name/value pairs are
- * emitted transparently regardless of CONTINUATION frames.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_HEADERS` flag set, which
+ * indicates that one or more CONTINUATION frames are involved. But
+ * the application does not need to care about that because the header
+ * name/value pairs are emitted transparently regardless of
+ * CONTINUATION frames.
*
* The server applications probably create an object to store
* information about new stream if ``frame->hd.type ==
@@ -1627,26 +1664,31 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
* trailer fields also has ``frame->headers.cat ==
* NGHTTP2_HCAT_HEADERS`` which does not contain any status code.
*
- * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
- * the stream (promised stream if frame is PUSH_PROMISE) by issuing
- * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. In this case,
+ * Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream (promised stream if frame is PUSH_PROMISE) by
+ * issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case,
* :type:`nghttp2_on_header_callback` and
* :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a
* different error code is desirable, use
* `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Again, use
- * ``frame->push_promise.promised_stream_id`` as stream_id parameter
- * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+ * parameter in `nghttp2_submit_rst_stream()` if frame is
+ * PUSH_PROMISE.
*
* The implementation of this function must return 0 if it succeeds.
- * It can return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
+ * It can return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
* reset the stream (promised stream if frame is PUSH_PROMISE). For
* critical errors, it must return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the other value is
- * returned, it is treated as if :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
- * is returned. If :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * value is returned, it is treated as if
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
* `nghttp2_session_mem_recv()` function will immediately return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_begin_headers_callback()`.
@@ -1663,16 +1705,17 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
* The |value| of length |valuelen| is header value. The |flags| is
* bitwise OR of one or more of :type:`nghttp2_nv_flag`.
*
- * If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver
- * must not index this name/value pair when forwarding it to the next
- * hop. More specifically, "Literal Header Field never Indexed"
- * representation must be used in HPACK encoding.
+ * If :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_INDEX` is set in
+ * |flags|, the receiver must not index this name/value pair when
+ * forwarding it to the next hop. More specifically, "Literal Header
+ * Field never Indexed" representation must be used in HPACK encoding.
*
* When this callback is invoked, ``frame->hd.type`` is either
- * :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`. After all
- * header name/value pairs are processed with this callback, and no
- * error has been detected, :type:`nghttp2_on_frame_recv_callback`
- * will be invoked. If there is an error in decompression,
+ * :enum:`nghttp2_frame_type.NGHTTP2_HEADERS` or
+ * :enum:`nghttp2_frame_type.NGHTTP2_PUSH_PROMISE`. After all header
+ * name/value pairs are processed with this callback, and no error has
+ * been detected, :type:`nghttp2_on_frame_recv_callback` will be
+ * invoked. If there is an error in decompression,
* :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be
* invoked.
*
@@ -1690,34 +1733,39 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
* explained in :ref:`http-messaging` section.
*
* If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
- * return without processing further input bytes. The memory pointed
- * by |frame|, |name| and |value| parameters are retained until
- * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
- * The application must retain the input bytes which was used to
- * produce these parameters, because it may refer to the memory region
- * included in the input bytes.
- *
- * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
- * the stream (promised stream if frame is PUSH_PROMISE) by issuing
- * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv()` return without processing further
+ * input bytes. The memory pointed by |frame|, |name| and |value|
+ * parameters are retained until `nghttp2_session_mem_recv()` or
+ * `nghttp2_session_recv()` is called. The application must retain
+ * the input bytes which was used to produce these parameters, because
+ * it may refer to the memory region included in the input bytes.
+ *
+ * Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream (promised stream if frame is PUSH_PROMISE) by
+ * issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case,
* :type:`nghttp2_on_header_callback` and
* :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a
* different error code is desirable, use
* `nghttp2_submit_rst_stream()` with a desired error code and then
- * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Again, use
- * ``frame->push_promise.promised_stream_id`` as stream_id parameter
- * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Again, use ``frame->push_promise.promised_stream_id`` as stream_id
+ * parameter in `nghttp2_submit_rst_stream()` if frame is
+ * PUSH_PROMISE.
*
* The implementation of this function must return 0 if it succeeds.
- * It may return :enum:`NGHTTP2_ERR_PAUSE` or
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For other critical
- * failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
- * the other nonzero value is returned, it is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * It may return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For
+ * other critical failures, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * nonzero value is returned, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_header_callback()`.
@@ -1784,11 +1832,12 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
*
* With this callback, application inspects the incoming invalid
* field, and it also can reset stream from this callback by returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
- * error code is :enum:`NGHTTP2_PROTOCOL_ERROR`. To change the error
- * code, call `nghttp2_submit_rst_stream()` with the error code of
- * choice in addition to returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By
+ * default, the error code is
+ * :enum:`nghttp2_error_code.NGHTTP2_PROTOCOL_ERROR`. To change the
+ * error code, call `nghttp2_submit_rst_stream()` with the error code
+ * of choice in addition to returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
*
* If 0 is returned, the header field is ignored, and the stream is
* not reset.
@@ -1819,11 +1868,12 @@ typedef int (*nghttp2_on_invalid_header_callback)(
*
* With this callback, application inspects the incoming invalid
* field, and it also can reset stream from this callback by returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
- * error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
- * code, call `nghttp2_submit_rst_stream()` with the error code of
- * choice in addition to returning
- * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By
+ * default, the error code is
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. To change the
+ * error code, call `nghttp2_submit_rst_stream()` with the error code
+ * of choice in addition to returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_on_invalid_header_callback2)(
nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
@@ -1837,11 +1887,12 @@ typedef int (*nghttp2_on_invalid_header_callback2)(
* |frame|. The application must choose the total length of payload
* including padded bytes in range [frame->hd.length, max_payloadlen],
* inclusive. Choosing number not in this range will be treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning
* ``frame->hd.length`` means no padding is added. Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_select_padding_callback()`.
@@ -1861,16 +1912,17 @@ typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session,
* |remote_max_frame_size|)]. If a value greater than this range is
* returned than the max allow value will be used. Returning a value
* smaller than this range is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. The |frame_type| is provided
- * for future extensibility and identifies the type of frame (see
- * :type:`nghttp2_frame_type`) for which to get the length for.
- * Currently supported frame types are: :enum:`NGHTTP2_DATA`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The
+ * |frame_type| is provided for future extensibility and identifies
+ * the type of frame (see :type:`nghttp2_frame_type`) for which to get
+ * the length for. Currently supported frame types are:
+ * :enum:`nghttp2_frame_type.NGHTTP2_DATA`.
*
* This callback can be used to control the length in bytes for which
* :type:`nghttp2_data_source_read_callback` is allowed to send to the
* remote endpoint. This callback is optional. Returning
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
- * failure.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the
+ * entire session failure.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_data_source_read_length_callback()`.
@@ -1897,7 +1949,8 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)(
* The implementation of this function must return 0 if it succeeds.
* If nonzero value is returned, it is treated as fatal error and
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_begin_frame_callback()`.
@@ -1916,14 +1969,15 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session,
* The implementation of this function must return 0 if it succeeds.
*
* To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
*
* If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_on_extension_chunk_recv_callback)(
nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data,
@@ -1953,14 +2007,15 @@ typedef int (*nghttp2_on_extension_chunk_recv_callback)(
* |*payload|, and do its own mechanism to process extension frames.
*
* To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`.
*
* If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
void **payload,
@@ -1982,17 +2037,18 @@ typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
* bytes written into |buf| when it succeeds.
*
* To abort processing this extension frame, return
- * :enum:`NGHTTP2_ERR_CANCEL`, and
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and
* :type:`nghttp2_on_frame_not_send_callback` will be invoked.
*
* If fatal error occurred, application should return
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
- * other values are returned, currently they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the return value is
- * strictly larger than |len|, it is treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return
+ * value is strictly larger than |len|, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
uint8_t *buf, size_t len,
@@ -2017,12 +2073,12 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
*
* Normally, application should return 0 from this callback. If fatal
* error occurred while doing something in this callback, application
- * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
- * library will return immediately with return value
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value
- * is returned from this callback, they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
- * rely on this details.
+ * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * In this case, library will return immediately with return value
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if
+ * nonzero value is returned from this callback, they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+ * should not rely on this details.
*/
typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
size_t len, void *user_data);
@@ -2043,12 +2099,12 @@ typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
*
* Normally, application should return 0 from this callback. If fatal
* error occurred while doing something in this callback, application
- * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
- * library will return immediately with return value
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value
- * is returned from this callback, they are treated as
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
- * rely on this details.
+ * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * In this case, library will return immediately with return value
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if
+ * nonzero value is returned from this callback, they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application
+ * should not rely on this details.
*/
typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
int lib_error_code, const char *msg,
@@ -2078,7 +2134,7 @@ typedef struct nghttp2_session_callbacks nghttp2_session_callbacks;
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -2275,7 +2331,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback(
* @function
*
* Sets callback function invoked when
- * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is used in
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
* :type:`nghttp2_data_source_read_callback` to avoid data copy.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback(
@@ -2458,7 +2514,7 @@ typedef struct nghttp2_option nghttp2_option;
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_option_new(nghttp2_option **option_ptr);
@@ -2519,7 +2575,8 @@ nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
* If this option is not used or used with zero value, if MAGIC does
* not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
* and `nghttp2_session_mem_recv()` will return error
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal
+ * error.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val);
@@ -2604,8 +2661,8 @@ nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
* received. If this option is set to nonzero, the library won't send
* PING frame with ACK flag set in the response for incoming PING
* frame. The application can send PING frame with ACK flag set using
- * `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags
- * parameter.
+ * `nghttp2_submit_ping()` with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK`
+ * as flags parameter.
*/
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
int val);
@@ -2619,7 +2676,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
* `nghttp2_hd_deflate_bound()`. The default value is 64KiB. If
* application attempts to send header fields larger than this limit,
* the transmission of the frame fails with error code
- * :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FRAME_SIZE_ERROR`.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
@@ -2644,6 +2701,11 @@ nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
* This option prevents the library from retaining closed streams to
* maintain the priority tree. If this option is set to nonzero,
* applications can discard closed stream completely to save memory.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is submitted via `nghttp2_submit_settings()`, any
+ * closed streams are not retained regardless of this option.
*/
NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
int val);
@@ -2662,6 +2724,47 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
/**
* @function
*
+ * This function sets the maximum number of SETTINGS entries per
+ * SETTINGS frame that will be accepted. If more than those entries
+ * are received, the peer is considered to be misbehaving and session
+ * will be closed. The default value is 32.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
+ size_t val);
+
+/**
+ * @function
+ *
+ * This option, if set to nonzero, allows server to fallback to
+ * :rfc:`7540` priorities if SETTINGS_NO_RFC7540_PRIORITIES was not
+ * received from client, and server submitted
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * = 1 via `nghttp2_submit_settings()`. Most of the advanced
+ * functionality for RFC 7540 priorities are still disabled. This
+ * fallback only enables the minimal feature set of RFC 7540
+ * priorities to deal with priority signaling from client.
+ *
+ * Client session ignores this option.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option,
+ int val);
+
+/**
+ * @function
+ *
+ * This option, if set to nonzero, turns off RFC 9113 leading and
+ * trailing white spaces validation against HTTP field value. Some
+ * important fields, such as HTTP/2 pseudo header fields, are
+ * validated more strictly and this option does not apply to them.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
+ nghttp2_option *option, int val);
+
+/**
+ * @function
+ *
* Initializes |*session_ptr| for client use. The all members of
* |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
* does not store |callbacks|. The |user_data| is an arbitrary user
@@ -2677,7 +2780,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -2703,7 +2806,7 @@ nghttp2_session_client_new(nghttp2_session **session_ptr,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -2729,7 +2832,7 @@ nghttp2_session_server_new(nghttp2_session **session_ptr,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -2755,7 +2858,7 @@ nghttp2_session_client_new2(nghttp2_session **session_ptr,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -2781,7 +2884,7 @@ nghttp2_session_server_new2(nghttp2_session **session_ptr,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_session_client_new3(
@@ -2806,7 +2909,7 @@ NGHTTP2_EXTERN int nghttp2_session_client_new3(
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_session_server_new3(
@@ -2828,12 +2931,14 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
*
* This function retrieves the highest prioritized frame from the
* outbound queue and sends it to the remote peer. It does this as
- * many as possible until the user callback
+ * many times as possible until the user callback
* :type:`nghttp2_send_callback` returns
- * :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
- * This function calls several callback functions which are passed
- * when initializing the |session|. Here is the simple time chart
- * which tells when each callback is invoked:
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue
+ * becomes empty or flow control is triggered (remote window size
+ * becomes depleted or maximum number of concurrent streams is
+ * reached). This function calls several callback functions which are
+ * passed when initializing the |session|. Here is the simple time
+ * chart which tells when each callback is invoked:
*
* 1. Get the next frame to send from outbound queue.
*
@@ -2851,7 +2956,7 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
*
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
*
- * 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
+ * 7. If :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` is returned from
* :type:`nghttp2_before_frame_send_callback`, the current frame
* transmission is canceled, and
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
@@ -2869,9 +2974,9 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
* The callback function failed.
*/
NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
@@ -2903,7 +3008,7 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
* |*data_ptr| if it succeeds, or one of the following negative error
* codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*
* .. note::
@@ -2925,8 +3030,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
*
* This function receives as many frames as possible until the user
* callback :type:`nghttp2_recv_callback` returns
- * :enum:`NGHTTP2_ERR_WOULDBLOCK`. This function calls several
- * callback functions which are passed when initializing the
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. This function calls
+ * several callback functions which are passed when initializing the
* |session|. Here is the simple time chart which tells when each
* callback is invoked:
*
@@ -2971,18 +3076,18 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_EOF`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`
* The remote peer did shutdown on the connection.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
* The callback function failed.
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
* Invalid client magic was detected. This error only returns
* when |session| was configured as server and
* `nghttp2_option_set_no_recv_client_magic()` is not used with
* nonzero value.
- * :enum:`NGHTTP2_ERR_FLOODED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED`
* Flooding was detected in this HTTP/2 session, and it must be
* closed. This is most likely caused by misbehaviour of peer.
*/
@@ -2992,7 +3097,7 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
* @function
*
* Processes data |in| as an input from the remote endpoint. The
- * |inlen| indicates the number of bytes in the |in|.
+ * |inlen| indicates the number of bytes to receive in the |in|.
*
* This function behaves like `nghttp2_session_recv()` except that it
* does not use :type:`nghttp2_recv_callback` to receive data; the
@@ -3001,27 +3106,27 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
* are called in the same way as they are in `nghttp2_session_recv()`.
*
* In the current implementation, this function always tries to
- * processes all input data unless either an error occurs or
- * :enum:`NGHTTP2_ERR_PAUSE` is returned from
+ * processes |inlen| bytes of input data unless either an error occurs or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from
* :type:`nghttp2_on_header_callback` or
* :type:`nghttp2_on_data_chunk_recv_callback`. If
- * :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
- * number of bytes which was used to produce the data or frame for the
- * callback.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value
+ * includes the number of bytes which was used to produce the data or
+ * frame for the callback.
*
* This function returns the number of processed bytes, or one of the
* following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
* The callback function failed.
- * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
* Invalid client magic was detected. This error only returns
* when |session| was configured as server and
* `nghttp2_option_set_no_recv_client_magic()` is not used with
* nonzero value.
- * :enum:`NGHTTP2_ERR_FLOODED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED`
* Flooding was detected in this HTTP/2 session, and it must be
* closed. This is most likely caused by misbehaviour of peer.
*/
@@ -3038,9 +3143,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The stream does not exist; or no deferred data exist.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_session_resume_data(nghttp2_session *session,
@@ -3101,7 +3206,7 @@ nghttp2_session_get_stream_user_data(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The stream does not exist
*/
NGHTTP2_EXTERN int
@@ -3318,7 +3423,7 @@ nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session,
@@ -3345,9 +3450,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |last_stream_id| is invalid.
*/
NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
@@ -3362,7 +3467,7 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
*
* This function is only usable for server. If this function is
* called with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
*
* To gracefully shutdown HTTP/2 session, server should call this
* function to send GOAWAY with last_stream_id (1u << 31) - 1. And
@@ -3384,9 +3489,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* The |session| is initialized as client.
*/
NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
@@ -3421,7 +3526,7 @@ NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |next_stream_id| is strictly less than the value
* `nghttp2_session_get_next_stream_id()` returns; or
* |next_stream_id| is invalid (e.g., even integer for client, or
@@ -3456,11 +3561,11 @@ nghttp2_session_get_next_stream_id(nghttp2_session *session);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* Automatic WINDOW_UPDATE is not disabled.
*/
NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session,
@@ -3477,9 +3582,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* Automatic WINDOW_UPDATE is not disabled.
*/
NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session,
@@ -3496,11 +3601,11 @@ NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* Automatic WINDOW_UPDATE is not disabled.
*/
NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
@@ -3527,12 +3632,17 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
* found, we use default priority instead of given |pri_spec|. That
* is make stream depend on root stream with weight 16.
*
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is submitted via `nghttp2_submit_settings()`, this
+ * function does nothing and returns 0.
+ *
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Attempted to depend on itself; or no stream exist for the given
* |stream_id|; or |stream_id| is 0
*/
@@ -3570,12 +3680,17 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
* found, we use default priority instead of given |pri_spec|. That
* is make stream depend on root stream with weight 16.
*
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is submitted via `nghttp2_submit_settings()`, this
+ * function does nothing and returns 0.
+ *
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Attempted to depend on itself; or stream denoted by |stream_id|
* already exists; or |stream_id| cannot be used to create idle
* stream (in other words, local endpoint has already opened
@@ -3626,11 +3741,11 @@ nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |settings_payload| is badly formed.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The stream ID 1 is already used or closed; or is not available.
*/
NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session,
@@ -3670,11 +3785,11 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |settings_payload| is badly formed.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The stream ID 1 is already used or closed; or is not available.
*/
NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
@@ -3698,10 +3813,10 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
* This function returns the number of bytes written in |buf|, or one
* of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |iv| contains duplicate settings ID or invalid value.
*
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
@@ -3732,8 +3847,8 @@ NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code);
* on with |weight| and its exclusive flag. If |exclusive| is
* nonzero, exclusive flag is set.
*
- * The |weight| must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.
+ * The |weight| must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.
*/
NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
int32_t stream_id,
@@ -3768,11 +3883,17 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members.
*
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is received by a remote endpoint, |pri_spec| is
+ * ignored, and treated as if ``NULL`` is specified.
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include
@@ -3783,12 +3904,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
* |nva| is preserved. For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively. With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase. The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
* :type:`nghttp2_on_frame_send_callback` or
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
@@ -3810,15 +3931,15 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* This function returns assigned stream ID if it succeeds, or one of
* the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was
* reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* Trying to depend on itself (new stream ID equals
* ``pri_spec->stream_id``).
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is server session.
*
* .. warning::
@@ -3853,12 +3974,12 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
* |nva| is preserved. For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively. With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase. The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
* :type:`nghttp2_on_frame_send_callback` or
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
@@ -3884,16 +4005,16 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully
* processed yet. Normally, this does not happen, but when
* application wrongly calls `nghttp2_submit_response()` twice,
* this may happen.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |session| is client session.
*
* .. warning::
@@ -3919,12 +4040,12 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
* |nva| is preserved. For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively. With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase. The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
* :type:`nghttp2_on_frame_send_callback` or
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
@@ -3936,16 +4057,16 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* |nva| will be sent as response headers, which will result in error.
*
* This function has the same effect with `nghttp2_submit_headers()`,
- * with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
- * stream_user_data to NULL.
+ * with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both
+ * pri_spec and stream_user_data to NULL.
*
* To submit trailer fields after `nghttp2_submit_response()` is
* called, the application has to specify
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
* Inside of :type:`nghttp2_data_source_read_callback`, when setting
- * :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
- * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the
- * application can send trailer fields using
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`. After
+ * that, the application can send trailer fields using
* `nghttp2_submit_trailer()`. `nghttp2_submit_trailer()` can be used
* inside :type:`nghttp2_data_source_read_callback`.
*
@@ -3953,9 +4074,9 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* Otherwise, this function returns 0 if it succeeds, or one of the
* following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
*/
NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
@@ -3968,10 +4089,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* Submits HEADERS frame. The |flags| is bitwise OR of the
* following values:
*
- * * :enum:`NGHTTP2_FLAG_END_STREAM`
+ * * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`
*
- * If |flags| includes :enum:`NGHTTP2_FLAG_END_STREAM`, this frame has
- * END_STREAM flag set.
+ * If |flags| includes :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`,
+ * this frame has END_STREAM flag set.
*
* The library handles the CONTINUATION frame internally and it
* correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
@@ -3988,11 +4109,16 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members.
*
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is received by a remote endpoint, |pri_spec| is
+ * ignored, and treated as if ``NULL`` is specified.
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible to include
@@ -4003,12 +4129,12 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
* |nva| is preserved. For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively. With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase. The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
* :type:`nghttp2_on_frame_send_callback` or
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
@@ -4026,19 +4152,19 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* |stream_id| is -1. Otherwise, this function returns 0 if it
* succeeds, or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was
* reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; or trying to depend on itself (stream ID
* equals ``pri_spec->stream_id``).
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully
* processed yet. This happens if stream denoted by |stream_id|
* is in reserved state.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* The |stream_id| is -1, and |session| is server session.
*
* .. warning::
@@ -4060,8 +4186,8 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
*
* Submits one or more DATA frames to the stream |stream_id|. The
* data to be sent are provided by |data_prd|. If |flags| contains
- * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM
- * flag set.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
+ * has END_STREAM flag set.
*
* This function does not take ownership of the |data_prd|. The
* function copies the members of the |data_prd|.
@@ -4069,27 +4195,28 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully
* processed yet.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
- * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
* The stream was already closed; or the |stream_id| is invalid.
*
* .. note::
*
* Currently, only one DATA or HEADERS is allowed for a stream at a
* time. Submitting these frames more than once before first DATA
- * or HEADERS is finished results in :enum:`NGHTTP2_ERR_DATA_EXIST`
- * error code. The earliest callback which tells that previous
- * frame is done is :type:`nghttp2_on_frame_send_callback`. In side
- * that callback, new data can be submitted using
- * `nghttp2_submit_data()`. Of course, all data except for last one
- * must not have :enum:`NGHTTP2_FLAG_END_STREAM` flag set in
- * |flags|. This sounds a bit complicated, and we recommend to use
+ * or HEADERS is finished results in
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The
+ * earliest callback which tells that previous frame is done is
+ * :type:`nghttp2_on_frame_send_callback`. In side that callback,
+ * new data can be submitted using `nghttp2_submit_data()`. Of
+ * course, all data except for last one must not have
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|.
+ * This sounds a bit complicated, and we recommend to use
* `nghttp2_submit_request()` and `nghttp2_submit_response()` to
* avoid this cascading issue. The experience shows that for HTTP
* use, these two functions are enough to implement both client and
@@ -4106,25 +4233,31 @@ NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
* to the priority specification |pri_spec|.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |pri_spec| is priority specification of this request. ``NULL``
* is not allowed for this function. To specify the priority, use
* `nghttp2_priority_spec_init()`. This function will copy its data
* members.
*
- * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
- * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is
- * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
- * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is received by a remote endpoint, this function does
+ * nothing and returns 0.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
* depend on itself.
*/
@@ -4134,6 +4267,61 @@ nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
const nghttp2_priority_spec *pri_spec);
/**
+ * @macro
+ *
+ * :macro:`NGHTTP2_EXTPRI_DEFAULT_URGENCY` is the default urgency
+ * level for :rfc:`9218` extensible priorities.
+ */
+#define NGHTTP2_EXTPRI_DEFAULT_URGENCY 3
+
+/**
+ * @macro
+ *
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_HIGH` is the highest urgency level
+ * for :rfc:`9218` extensible priorities.
+ */
+#define NGHTTP2_EXTPRI_URGENCY_HIGH 0
+
+/**
+ * @macro
+ *
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW` is the lowest urgency level for
+ * :rfc:`9218` extensible priorities.
+ */
+#define NGHTTP2_EXTPRI_URGENCY_LOW 7
+
+/**
+ * @macro
+ *
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LEVELS` is the number of urgency
+ * levels for :rfc:`9218` extensible priorities.
+ */
+#define NGHTTP2_EXTPRI_URGENCY_LEVELS (NGHTTP2_EXTPRI_URGENCY_LOW + 1)
+
+/**
+ * @struct
+ *
+ * :type:`nghttp2_extpri` is :rfc:`9218` extensible priorities
+ * specification for a stream.
+ */
+typedef struct nghttp2_extpri {
+ /**
+ * :member:`urgency` is the urgency of a stream, it must be in
+ * [:macro:`NGHTTP2_EXTPRI_URGENCY_HIGH`,
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`], inclusive, and 0 is the
+ * highest urgency.
+ */
+ uint32_t urgency;
+ /**
+ * :member:`inc` indicates that a content can be processed
+ * incrementally or not. If inc is 0, it cannot be processed
+ * incrementally. If inc is 1, it can be processed incrementally.
+ * Other value is not permitted.
+ */
+ int inc;
+} nghttp2_extpri;
+
+/**
* @function
*
* Submits RST_STREAM frame to cancel/reject the stream |stream_id|
@@ -4142,14 +4330,14 @@ nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
* The pre-defined error code is one of :enum:`nghttp2_error_code`.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
*/
NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
@@ -4164,7 +4352,7 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
* indicates the number of :type:`nghttp2_settings_entry`.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* This function does not take ownership of the |iv|. This function
* copies all the elements in the |iv|.
@@ -4173,16 +4361,17 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
* size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
* RST_STREAM is issued against such a stream.
*
- * SETTINGS with :enum:`NGHTTP2_FLAG_ACK` is automatically submitted
- * by the library and application could not send it at its will.
+ * SETTINGS with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` is
+ * automatically submitted by the library and application could not
+ * send it at its will.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |iv| contains invalid value (e.g., initial window size
* strictly greater than (1 << 31) - 1.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
@@ -4210,12 +4399,12 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
* |nva| is preserved. For header fields with
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
- * and value are not copied respectively. With
- * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
- * pass header field name in lowercase. The application should
- * maintain the references to them until
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
* :type:`nghttp2_on_frame_send_callback` or
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
@@ -4234,18 +4423,18 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
* This function returns assigned promised stream ID if it succeeds,
* or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_PROTO`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
* This function was invoked when |session| is initialized as
* client.
- * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
* No stream ID is available because maximum stream ID was
* reached.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0; The |stream_id| does not designate stream
* that peer initiated.
- * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
* The stream was already closed; or the |stream_id| is invalid.
*
* .. warning::
@@ -4274,10 +4463,10 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
*
* The |flags| is bitwise OR of 0 or more of the following value.
*
- * * :enum:`NGHTTP2_FLAG_ACK`
+ * * :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK`
*
* Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags|
- * should be :enum:`NGHTTP2_FLAG_NONE`.
+ * should be :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* If the |opaque_data| is non ``NULL``, then it should point to the 8
* bytes array of memory to specify opaque data to send with PING
@@ -4287,7 +4476,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
@@ -4302,7 +4491,7 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
* The pre-defined error code is one of :enum:`nghttp2_error_code`.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |last_stream_id| is peer's stream ID or 0. So if |session| is
* initialized as client, |last_stream_id| must be even or 0. If
@@ -4332,9 +4521,9 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |opaque_data_len| is too large; the |last_stream_id| is
* invalid.
*/
@@ -4390,7 +4579,7 @@ nghttp2_session_check_server_session(nghttp2_session *session);
* Submits WINDOW_UPDATE frame.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |stream_id| is the stream ID to send this WINDOW_UPDATE. To
* send connection level WINDOW_UPDATE, specify 0 to |stream_id|.
@@ -4417,9 +4606,9 @@ nghttp2_session_check_server_session(nghttp2_session *session);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_FLOW_CONTROL`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOW_CONTROL`
* The local window size overflow or gets negative.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
@@ -4437,7 +4626,7 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
* to transmission queue.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* This sounds similar to `nghttp2_submit_window_update()`, but there
* are 2 differences. The first difference is that this function
@@ -4456,9 +4645,9 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is negative.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -4489,18 +4678,19 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
*
* The standard HTTP/2 frame cannot be sent with this function, so
* |type| must be strictly grater than 0x9. Otherwise, this function
- * will fail with error code :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`.
+ * will fail with error code
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* If :type:`nghttp2_pack_extension_callback` is not set.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* If |type| specifies standard HTTP/2 frame type. The frame
* types in the rage [0x0, 0x9], both inclusive, are standard
* HTTP/2 frame type, and cannot be sent using this function.
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory
*/
NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
@@ -4514,8 +4704,8 @@ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
* extension to HTTP/2. If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_builtin_recv_extension_type()` is set for
- * :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
- * this struct.
+ * :enum:`nghttp2_frame_type.NGHTTP2_ALTSVC`,
+ * ``nghttp2_extension.payload`` will point to this struct.
*
* It has the following members:
*/
@@ -4549,7 +4739,7 @@ typedef struct {
* `RFC 7383 <https://tools.ietf.org/html/rfc7838#section-4>`_.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |origin| points to the origin this alternative service is
* associated with. The |origin_len| is the length of the origin. If
@@ -4559,16 +4749,16 @@ typedef struct {
*
* The ALTSVC frame is only usable from server side. If this function
* is invoked with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* The function is called from client side session
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* The sum of |origin_len| and |field_value_len| is larger than
* 16382; or |origin_len| is 0 while |stream_id| is 0; or
* |origin_len| is not 0 while |stream_id| is not 0.
@@ -4607,8 +4797,8 @@ typedef struct {
* If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_builtin_recv_extension_type()` is set for
- * :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
- * this struct.
+ * :enum:`nghttp2_frame_type.NGHTTP2_ORIGIN`,
+ * ``nghttp2_extension.payload`` will point to this struct.
*
* It has the following members:
*/
@@ -4632,7 +4822,7 @@ typedef struct {
* `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
*
* The |flags| is currently ignored and should be
- * :enum:`NGHTTP2_FLAG_NONE`.
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
* The |ov| points to the array of origins. The |nov| specifies the
* number of origins included in |ov|. This function creates copies
@@ -4640,13 +4830,13 @@ typedef struct {
*
* The ORIGIN frame is only usable by a server. If this function is
* invoked with client side session, this function returns
- * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* The function is called from client side session.
- * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* There are too many origins, or an origin is too large to fit
* into a default frame payload.
*/
@@ -4656,6 +4846,108 @@ NGHTTP2_EXTERN int nghttp2_submit_origin(nghttp2_session *session,
size_t nov);
/**
+ * @struct
+ *
+ * The payload of PRIORITY_UPDATE frame. PRIORITY_UPDATE frame is a
+ * non-critical extension to HTTP/2. If this frame is received, and
+ * `nghttp2_option_set_user_recv_extension_type()` is not set, and
+ * `nghttp2_option_set_builtin_recv_extension_type()` is set for
+ * :enum:`nghttp2_frame_type.NGHTTP2_PRIORITY_UPDATE`,
+ * ``nghttp2_extension.payload`` will point to this struct.
+ *
+ * It has the following members:
+ */
+typedef struct {
+ /**
+ * The stream ID of the stream whose priority is updated.
+ */
+ int32_t stream_id;
+ /**
+ * The pointer to Priority field value. It is not necessarily
+ * NULL-terminated.
+ */
+ uint8_t *field_value;
+ /**
+ * The length of the :member:`field_value`.
+ */
+ size_t field_value_len;
+} nghttp2_ext_priority_update;
+
+/**
+ * @function
+ *
+ * Submits PRIORITY_UPDATE frame.
+ *
+ * PRIORITY_UPDATE frame is a non-critical extension to HTTP/2, and
+ * defined in :rfc:`9218#section-7.1`.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
+ *
+ * The |stream_id| is the ID of stream which is prioritized. The
+ * |field_value| points to the Priority field value. The
+ * |field_value_len| is the length of the Priority field value.
+ *
+ * If this function is called by server,
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` is returned.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 0 is received by a remote endpoint (or it is omitted),
+ * this function does nothing and returns 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
+ * The function is called from server side session
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |field_value_len| is larger than 16380; or |stream_id| is
+ * 0.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_priority_update(nghttp2_session *session,
+ uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *field_value,
+ size_t field_value_len);
+
+/**
+ * @function
+ *
+ * Changes the priority of the existing stream denoted by |stream_id|.
+ * The new priority is |extpri|. This function is meant to be used by
+ * server for :rfc:`9218` extensible prioritization scheme.
+ *
+ * If |session| is initialized as client, this function returns
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. For client, use
+ * `nghttp2_submit_priority_update()` instead.
+ *
+ * If :member:`extpri->urgency <nghttp2_extpri.urgency>` is out of
+ * bound, it is set to :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`.
+ *
+ * If |ignore_client_signal| is nonzero, server starts to ignore
+ * client priority signals for this stream.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is not submitted via `nghttp2_submit_settings()`,
+ * this function does nothing and returns 0.
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
+ * The |session| is initialized as client.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * |stream_id| is zero; or a stream denoted by |stream_id| is not
+ * found.
+ */
+NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority(
+ nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri,
+ int ignore_client_signal);
+
+/**
* @function
*
* Compares ``lhs->name`` of length ``lhs->namelen`` bytes and
@@ -4766,13 +5058,51 @@ NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len);
* Returns nonzero if HTTP header field value |value| of length |len|
* is valid according to
* http://tools.ietf.org/html/rfc7230#section-3.2
+ *
+ * This function is considered obsolete, and application should
+ * consider to use `nghttp2_check_header_value_rfc9113()` instead.
*/
NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len);
/**
* @function
*
- * Returns nonzero if the |value| which is supposed to the value of
+ * Returns nonzero if HTTP header field value |value| of length |len|
+ * is valid according to
+ * http://tools.ietf.org/html/rfc7230#section-3.2, plus
+ * https://datatracker.ietf.org/doc/html/rfc9113#section-8.2.1
+ */
+NGHTTP2_EXTERN int nghttp2_check_header_value_rfc9113(const uint8_t *value,
+ size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to be the value of
+ * the :method header field is valid according to
+ * https://datatracker.ietf.org/doc/html/rfc7231#section-4 and
+ * https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
+ */
+NGHTTP2_EXTERN int nghttp2_check_method(const uint8_t *value, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to be the value of
+ * the :path header field is valid according to
+ * https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.3
+ *
+ * |value| is valid if it merely consists of the allowed characters.
+ * In particular, it does not check whether |value| follows the syntax
+ * of path. The allowed characters are all characters valid by
+ * `nghttp2_check_header_value` minus SPC and HT.
+ */
+NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to be the value of the
* :authority or host header field is valid according to
* https://tools.ietf.org/html/rfc3986#section-3.2
*
@@ -4806,7 +5136,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -4860,7 +5190,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
@@ -4874,24 +5204,24 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
* the |buf| of length |buflen|.
*
* If |buf| is not large enough to store the deflated header block,
- * this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The
- * caller should use `nghttp2_hd_deflate_bound()` to know the upper
- * bound of buffer size required to deflate given header name/value
- * pairs.
+ * this function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
+ * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+ * buffer size required to deflate given header name/value pairs.
*
* Once this function fails, subsequent call of this function always
- * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
*
* After this function returns, it is safe to delete the |nva|.
*
* This function returns the number of bytes written to |buf| if it
* succeeds, or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
* Deflation process has failed.
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
@@ -4907,23 +5237,24 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
* must be set in len field of :type:`nghttp2_vec`. If and only if
* one chunk is filled up completely, next chunk will be used. If
* |vec| is not large enough to store the deflated header block, this
- * function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
+ * function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
* should use `nghttp2_hd_deflate_bound()` to know the upper bound of
* buffer size required to deflate given header name/value pairs.
*
* Once this function fails, subsequent call of this function always
- * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
*
* After this function returns, it is safe to delete the |nva|.
*
* This function returns the number of bytes written to |vec| if it
* succeeds, or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
* Deflation process has failed.
- * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
@@ -5003,7 +5334,7 @@ typedef struct nghttp2_hd_inflater nghttp2_hd_inflater;
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
@@ -5052,9 +5383,9 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
* The function is called while header block is being inflated.
* Probably, application missed to call
* `nghttp2_hd_inflate_end_headers()`.
@@ -5092,7 +5423,8 @@ typedef enum {
*
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
- * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * header name/value pair,
+ * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
* |*inflate_flags| and name/value pair is assigned to the |nv_out|
* and the function returns. The caller must not free the members of
* |nv_out|.
@@ -5115,11 +5447,11 @@ typedef enum {
* This function returns the number of bytes processed if it succeeds,
* or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
* Inflation process has failed.
- * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
* The header field name or value is too large.
*
* Example follows::
@@ -5174,7 +5506,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
*
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
- * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * header name/value pair,
+ * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
* |*inflate_flags| and name/value pair is assigned to the |nv_out|
* and the function returns. The caller must not free the members of
* |nv_out|.
@@ -5190,8 +5523,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
* for the next header block input.
*
* In other words, if |in_final| is nonzero, and this function returns
- * |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
- * set in |*inflate_flags|.
+ * |inlen|, you can assert that
+ * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in
+ * |*inflate_flags|.
*
* The caller can feed complete compressed header block. It also can
* feed it in several chunks. The caller must set |in_final| to
@@ -5201,11 +5535,11 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
* This function returns the number of bytes processed if it succeeds,
* or one of the following negative error codes:
*
- * :enum:`NGHTTP2_ERR_NOMEM`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
* Out of memory.
- * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
* Inflation process has failed.
- * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
* The header field name or value is too large.
*
* Example follows::
@@ -5376,7 +5710,7 @@ typedef enum {
*
* Returns state of |stream|. The root stream retrieved by
* `nghttp2_session_get_root_stream()` will have stream state
- * :enum:`NGHTTP2_STREAM_STATE_IDLE`.
+ * :enum:`nghttp2_stream_proto_state.NGHTTP2_STREAM_STATE_IDLE`.
*/
NGHTTP2_EXTERN nghttp2_stream_proto_state
nghttp2_stream_get_state(nghttp2_stream *stream);
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.c b/Utilities/cmnghttp2/lib/nghttp2_buf.c
index 2a435be..a328447 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_buf.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.c
@@ -82,8 +82,10 @@ void nghttp2_buf_reset(nghttp2_buf *buf) {
}
void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len) {
- buf->begin = buf->pos = buf->last = buf->mark = begin;
- buf->end = begin + len;
+ buf->begin = buf->pos = buf->last = buf->mark = buf->end = begin;
+ if (len) {
+ buf->end += len;
+ }
}
static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length,
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.h b/Utilities/cmnghttp2/lib/nghttp2_buf.h
index 06cce67..45f62f1 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_buf.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.h
@@ -99,7 +99,7 @@ void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem);
* |new_cap|. If extensions took place, buffer pointers in |buf| will
* change.
*
- * This function returns 0 if it succeeds, or one of the followings
+ * This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.c b/Utilities/cmnghttp2/lib/nghttp2_extpri.c
new file mode 100644
index 0000000..3fd9b78
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.c
@@ -0,0 +1,35 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2022 nghttp3 contributors
+ * Copyright (c) 2022 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_extpri.h"
+
+uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) {
+ return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency);
+}
+
+void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri) {
+ extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri);
+ extpri->inc = nghttp2_extpri_uint8_inc(u8extpri);
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.h b/Utilities/cmnghttp2/lib/nghttp2_extpri.h
new file mode 100644
index 0000000..23c6ddc
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.h
@@ -0,0 +1,65 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2022 nghttp3 contributors
+ * Copyright (c) 2022 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_EXTPRI_H
+#define NGHTTP2_EXTPRI_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/*
+ * NGHTTP2_EXTPRI_INC_MASK is a bit mask to retrieve incremental bit
+ * from a value produced by nghttp2_extpri_to_uint8.
+ */
+#define NGHTTP2_EXTPRI_INC_MASK (1 << 7)
+
+/*
+ * nghttp2_extpri_to_uint8 encodes |pri| into uint8_t variable.
+ */
+uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri);
+
+/*
+ * nghttp2_extpri_from_uint8 decodes |u8extpri|, which is produced by
+ * nghttp2_extpri_to_uint8, intto |extpri|.
+ */
+void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
+
+/*
+ * nghttp2_extpri_uint8_urgency extracts urgency from |PRI| which is
+ * supposed to be constructed by nghttp2_extpri_to_uint8.
+ */
+#define nghttp2_extpri_uint8_urgency(PRI) \
+ ((uint32_t)((PRI) & ~NGHTTP2_EXTPRI_INC_MASK))
+
+/*
+ * nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to
+ * be constructed by nghttp2_extpri_to_uint8.
+ */
+#define nghttp2_extpri_uint8_inc(PRI) (((PRI)&NGHTTP2_EXTPRI_INC_MASK) != 0)
+
+#endif /* NGHTTP2_EXTPRI_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.c b/Utilities/cmnghttp2/lib/nghttp2_frame.c
index 4821de4..35072c1 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_frame.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.c
@@ -253,6 +253,31 @@ void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_mem_free(mem, origin->ov);
}
+void nghttp2_frame_priority_update_init(nghttp2_extension *frame,
+ int32_t stream_id, uint8_t *field_value,
+ size_t field_value_len) {
+ nghttp2_ext_priority_update *priority_update;
+
+ nghttp2_frame_hd_init(&frame->hd, 4 + field_value_len,
+ NGHTTP2_PRIORITY_UPDATE, NGHTTP2_FLAG_NONE, 0);
+
+ priority_update = frame->payload;
+ priority_update->stream_id = stream_id;
+ priority_update->field_value = field_value;
+ priority_update->field_value_len = field_value_len;
+}
+
+void nghttp2_frame_priority_update_free(nghttp2_extension *frame,
+ nghttp2_mem *mem) {
+ nghttp2_ext_priority_update *priority_update;
+
+ priority_update = frame->payload;
+ if (priority_update == NULL) {
+ return;
+ }
+ nghttp2_mem_free(mem, priority_update->field_value);
+}
+
size_t nghttp2_frame_priority_len(uint8_t flags) {
if (flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_PRIORITY_SPECLEN;
@@ -654,8 +679,6 @@ int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
var_gift_payloadlen = 0;
}
- payloadlen -= var_gift_payloadlen;
-
if (!var_gift_payloadlen) {
var_gift_payload = NULL;
} else {
@@ -818,8 +841,10 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
size_t len = 0;
origin = frame->payload;
- p = payload;
- end = p + payloadlen;
+ p = end = payload;
+ if (payloadlen) {
+ end += payloadlen;
+ }
for (; p != end;) {
if (end - p < 2) {
@@ -876,6 +901,57 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
return 0;
}
+int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
+ nghttp2_extension *frame) {
+ int rv;
+ nghttp2_buf *buf;
+ nghttp2_ext_priority_update *priority_update;
+
+ /* This is required with --disable-assert. */
+ (void)rv;
+
+ priority_update = frame->payload;
+
+ buf = &bufs->head->buf;
+
+ assert(nghttp2_buf_avail(buf) >= 4 + priority_update->field_value_len);
+
+ buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+ nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+ nghttp2_put_uint32be(buf->last, (uint32_t)priority_update->stream_id);
+ buf->last += 4;
+
+ rv = nghttp2_bufs_add(bufs, priority_update->field_value,
+ priority_update->field_value_len);
+
+ assert(rv == 0);
+
+ return 0;
+}
+
+void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
+ uint8_t *payload,
+ size_t payloadlen) {
+ nghttp2_ext_priority_update *priority_update;
+
+ assert(payloadlen >= 4);
+
+ priority_update = frame->payload;
+
+ priority_update->stream_id =
+ nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
+
+ if (payloadlen > 4) {
+ priority_update->field_value = payload + 4;
+ priority_update->field_value_len = payloadlen - 4;
+ } else {
+ priority_update->field_value = NULL;
+ priority_update->field_value_len = 0;
+ }
+}
+
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) {
nghttp2_settings_entry *iv_copy;
@@ -897,9 +973,25 @@ nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
}
int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b) {
- return a->namelen == b->namelen && a->valuelen == b->valuelen &&
- memcmp(a->name, b->name, a->namelen) == 0 &&
- memcmp(a->value, b->value, a->valuelen) == 0;
+ if (a->namelen != b->namelen || a->valuelen != b->valuelen) {
+ return 0;
+ }
+
+ if (a->name == NULL || b->name == NULL) {
+ assert(a->namelen == 0);
+ assert(b->namelen == 0);
+ } else if (memcmp(a->name, b->name, a->namelen) != 0) {
+ return 0;
+ }
+
+ if (a->value == NULL || b->value == NULL) {
+ assert(a->valuelen == 0);
+ assert(b->valuelen == 0);
+ } else if (memcmp(a->value, b->value, a->valuelen) != 0) {
+ return 0;
+ }
+
+ return 1;
}
void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem) {
@@ -1055,6 +1147,11 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) {
return 0;
}
break;
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
+ if (iv[i].value != 0 && iv[i].value != 1) {
+ return 0;
+ }
+ break;
}
}
return 1;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.h b/Utilities/cmnghttp2/lib/nghttp2_frame.h
index 615bbf3..5f6152b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_frame.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.h
@@ -46,7 +46,7 @@
#define NGHTTP2_MAX_FRAME_SIZE_MIN (1 << 14)
#define NGHTTP2_MAX_PAYLOADLEN 16384
-/* The one frame buffer length for tranmission. We may use several of
+/* The one frame buffer length for transmission. We may use several of
them to support CONTINUATION. To account for Pad Length field, we
allocate extra 1 byte, which saves extra large memcopying. */
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
@@ -57,7 +57,7 @@
/* Maximum headers block size to send, calculated using
nghttp2_hd_deflate_bound(). This is the default value, and can be
- overridden by nghttp2_option_set_max_send_header_block_size(). */
+ overridden by nghttp2_option_set_max_send_header_block_length(). */
#define NGHTTP2_MAX_HEADERSLEN 65536
/* The number of bytes for each SETTINGS entry */
@@ -73,6 +73,7 @@
typedef union {
nghttp2_ext_altsvc altsvc;
nghttp2_ext_origin origin;
+ nghttp2_ext_priority_update priority_update;
} nghttp2_ext_frame_payload;
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
@@ -423,6 +424,31 @@ int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *ext);
int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem);
+
+/*
+ * Packs PRIORITY_UPDATE frame |frame| in wire frame format and store
+ * it in |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
+ nghttp2_extension *ext);
+
+/*
+ * Unpacks PRIORITY_UPDATE wire format into |frame|. The |payload| of
+ * |payloadlen| bytes contains frame payload. This function assumes
+ * that frame->payload points to the nghttp2_ext_priority_update
+ * object.
+ *
+ * This function always succeeds and returns 0.
+ */
+void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
+ uint8_t *payload,
+ size_t payloadlen);
+
/*
* Initializes HEADERS frame |frame| with given values. |frame| takes
* ownership of |nva|, so caller must not free it. If |stream_id| is
@@ -539,6 +565,25 @@ void nghttp2_frame_origin_init(nghttp2_extension *frame,
void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem);
/*
+ * Initializes PRIORITY_UPDATE frame |frame| with given values. This
+ * function assumes that frame->payload points to
+ * nghttp2_ext_priority_update object. On success, this function
+ * takes ownership of |field_value|, so caller must not free it.
+ */
+void nghttp2_frame_priority_update_init(nghttp2_extension *frame,
+ int32_t stream_id, uint8_t *field_value,
+ size_t field_value_len);
+
+/*
+ * Frees up resources under |frame|. This function does not free
+ * nghttp2_ext_priority_update object pointed by frame->payload. This
+ * function only frees field_value pointed by
+ * nghttp2_ext_priority_update.field_value.
+ */
+void nghttp2_frame_priority_update_free(nghttp2_extension *frame,
+ nghttp2_mem *mem);
+
+/*
* Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does
* not include the Pad Length field. If |padlen| is 0, this function
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.c b/Utilities/cmnghttp2/lib/nghttp2_hd.c
index 5e86931..8a2bda6 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.c
@@ -269,6 +269,11 @@ static int32_t lookup_token(const uint8_t *name, size_t namelen) {
return NGHTTP2_TOKEN_LOCATION;
}
break;
+ case 'y':
+ if (memeq("priorit", name, 7)) {
+ return NGHTTP2_TOKEN_PRIORITY;
+ }
+ break;
}
break;
case 9:
@@ -1263,6 +1268,8 @@ int nghttp2_hd_inflate_change_table_size(
return NGHTTP2_ERR_INVALID_STATE;
}
+ inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
+
/* It seems that encoder is not required to send dynamic table size
update if the table size is not changed after applying
SETTINGS_HEADER_TABLE_SIZE. RFC 7541 is ambiguous here, but this
@@ -1275,13 +1282,12 @@ int nghttp2_hd_inflate_change_table_size(
/* Remember minimum value, and validate that encoder sends the
value less than or equal to this. */
inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size;
- }
- inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
+ inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size;
- inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size;
+ hd_context_shrink_table_size(&inflater->ctx, NULL);
+ }
- hd_context_shrink_table_size(&inflater->ctx, NULL);
return 0;
}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.h b/Utilities/cmnghttp2/lib/nghttp2_hd.h
index 2674028..6de0052 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.h
@@ -112,6 +112,7 @@ typedef enum {
NGHTTP2_TOKEN_PROXY_CONNECTION,
NGHTTP2_TOKEN_UPGRADE,
NGHTTP2_TOKEN__PROTOCOL,
+ NGHTTP2_TOKEN_PRIORITY,
} nghttp2_token;
struct nghttp2_hd_entry;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.c b/Utilities/cmnghttp2/lib/nghttp2_helper.c
index 91136a6..93dd475 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_helper.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_helper.c
@@ -334,6 +334,8 @@ const char *nghttp2_strerror(int error_code) {
case NGHTTP2_ERR_FLOODED:
return "Flooding was detected in this HTTP/2 session, and it must be "
"closed";
+ case NGHTTP2_ERR_TOO_MANY_SETTINGS:
+ return "SETTINGS frame contained more than the maximum allowed entries";
default:
return "Unknown error code";
}
@@ -505,7 +507,179 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
return 1;
}
-/* Generated by genauthroitychartbl.py */
+int nghttp2_check_header_value_rfc9113(const uint8_t *value, size_t len) {
+ if (len == 0) {
+ return 1;
+ }
+
+ if (*value == ' ' || *value == '\t' || *(value + len - 1) == ' ' ||
+ *(value + len - 1) == '\t') {
+ return 0;
+ }
+
+ return nghttp2_check_header_value(value, len);
+}
+
+/* Generated by genmethodchartbl.py */
+static char VALID_METHOD_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
+ 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
+ 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
+ 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
+ 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
+ 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
+ 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
+ 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
+ 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
+ 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
+ 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
+ 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
+ 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
+ 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
+ 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
+ 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
+ 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
+ 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
+ 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
+ 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */,
+ 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
+ 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
+ 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
+ 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
+ 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
+ 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
+ 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
+ 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
+ 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
+ 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
+ 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
+ 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
+ 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
+ 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
+ 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
+ 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
+ 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
+ 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
+ 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
+ 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
+ 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
+ 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
+ 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
+ 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
+ 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
+ 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
+ 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
+ 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
+ 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
+ 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
+ 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
+ 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
+ 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
+};
+
+int nghttp2_check_method(const uint8_t *value, size_t len) {
+ const uint8_t *last;
+ if (len == 0) {
+ return 0;
+ }
+ for (last = value + len; value != last; ++value) {
+ if (!VALID_METHOD_CHARS[*value]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Generated by genpathchartbl.py */
+static char VALID_PATH_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
+ 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
+ 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
+ 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
+ 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
+ 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
+ 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
+ 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
+ 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
+ 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
+ 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
+ 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
+ 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
+ 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
+ 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
+ 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
+ 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
+ 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
+ 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
+ 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
+ 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
+ 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
+ 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
+ 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
+ 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
+ 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
+ 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
+ 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
+ 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
+ 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
+ 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
+ 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
+ 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
+ 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
+ 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
+ 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
+ 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
+ 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
+ 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
+ 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
+ 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
+ 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
+ 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
+ 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
+ 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
+ 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
+ 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
+ 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
+ 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
+ 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
+ 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
+ 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
+ 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
+ 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
+ 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
+ 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
+ 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
+ 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
+ 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
+};
+
+int nghttp2_check_path(const uint8_t *value, size_t len) {
+ const uint8_t *last;
+ for (last = value + len; value != last; ++value) {
+ if (!VALID_PATH_CHARS[*value]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Generated by genauthoritychartbl.py */
static char VALID_AUTHORITY_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.c b/Utilities/cmnghttp2/lib/nghttp2_http.c
index 62f57b6..83e5e66 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_http.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.c
@@ -30,6 +30,7 @@
#include "nghttp2_hd.h"
#include "nghttp2_helper.h"
+#include "nghttp2_extpri.h"
static uint8_t downcase(uint8_t c) {
return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c;
@@ -72,25 +73,12 @@ static int64_t parse_uint(const uint8_t *s, size_t len) {
return n;
}
-static int lws(const uint8_t *s, size_t n) {
- size_t i;
- for (i = 0; i < n; ++i) {
- if (s[i] != ' ' && s[i] != '\t') {
- return 0;
- }
- }
- return 1;
-}
-
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
- int flag) {
- if (stream->http_flags & flag) {
- return 0;
- }
- if (lws(nv->value->base, nv->value->len)) {
+ uint32_t flag) {
+ if ((stream->http_flags & flag) || nv->value->len == 0) {
return 0;
}
- stream->http_flags = (uint16_t)(stream->http_flags | flag);
+ stream->http_flags = stream->http_flags | flag;
return 1;
}
@@ -114,6 +102,8 @@ static int check_path(nghttp2_stream *stream) {
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer, int connect_protocol) {
+ nghttp2_extpri extpri;
+
if (nv->name->base[0] == ':') {
if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
@@ -212,6 +202,23 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
+ case NGHTTP2_TOKEN_PRIORITY:
+ if (!trailer &&
+ /* Do not parse the header field in PUSH_PROMISE. */
+ (stream->stream_id & 1) &&
+ (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
+ !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) {
+ nghttp2_extpri_from_uint8(&extpri, stream->http_extpri);
+ if (nghttp2_http_parse_priority(&extpri, nv->value->base,
+ nv->value->len) == 0) {
+ stream->http_extpri = nghttp2_extpri_to_uint8(&extpri);
+ stream->http_flags |= NGHTTP2_HTTP_FLAG_PRIORITY;
+ } else {
+ stream->http_flags &= (uint32_t)~NGHTTP2_HTTP_FLAG_PRIORITY;
+ stream->http_flags |= NGHTTP2_HTTP_FLAG_BAD_PRIORITY;
+ }
+ }
+ break;
default:
if (nv->name->base[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
@@ -329,6 +336,16 @@ static int check_scheme(const uint8_t *value, size_t len) {
return 1;
}
+static int lws(const uint8_t *s, size_t n) {
+ size_t i;
+ for (i = 0; i < n; ++i) {
+ if (s[i] != ' ' && s[i] != '\t') {
+ return 0;
+ }
+ }
+ return 1;
+}
+
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
int trailer) {
@@ -360,13 +377,46 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
return NGHTTP2_ERR_IGN_HTTP_HEADER;
}
- if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
- nv->token == NGHTTP2_TOKEN_HOST) {
- rv = nghttp2_check_authority(nv->value->base, nv->value->len);
- } else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
+ switch (nv->token) {
+ case NGHTTP2_TOKEN__METHOD:
+ rv = nghttp2_check_method(nv->value->base, nv->value->len);
+ break;
+ case NGHTTP2_TOKEN__PATH:
+ rv = nghttp2_check_path(nv->value->base, nv->value->len);
+ break;
+ case NGHTTP2_TOKEN__AUTHORITY:
+ case NGHTTP2_TOKEN_HOST:
+ if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+ rv = nghttp2_check_authority(nv->value->base, nv->value->len);
+ } else if (
+ stream->flags &
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
+ rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
+ } else {
+ rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len);
+ }
+ break;
+ case NGHTTP2_TOKEN__SCHEME:
rv = check_scheme(nv->value->base, nv->value->len);
- } else {
- rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
+ break;
+ case NGHTTP2_TOKEN__PROTOCOL:
+ /* Check the value consists of just white spaces, which was done
+ in check_pseudo_header before
+ nghttp2_check_header_value_rfc9113 has been introduced. */
+ if ((stream->flags &
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) &&
+ lws(nv->value->base, nv->value->len)) {
+ rv = 0;
+ break;
+ }
+ /* fall through */
+ default:
+ if (stream->flags &
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
+ rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
+ } else {
+ rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len);
+ }
}
if (rv == 0) {
@@ -434,16 +484,15 @@ int nghttp2_http_on_response_headers(nghttp2_stream *stream) {
if (stream->status_code / 100 == 1) {
/* non-final response */
- stream->http_flags =
- (uint16_t)((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) |
- NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
+ stream->http_flags = (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) |
+ NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
stream->content_length = -1;
stream->status_code = -1;
return 0;
}
stream->http_flags =
- (uint16_t)(stream->http_flags & ~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
+ stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
if (!expect_response_body(stream)) {
stream->content_length = 0;
@@ -528,3 +577,715 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
return;
}
}
+
+/* Generated by genchartbl.py */
+static const int SF_KEY_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
+ 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
+ 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
+ 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
+ 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
+ 0 /* RS */, 0 /* US */, 0 /* SPC */, 0 /* ! */, 0 /* " */,
+ 0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */,
+ 0 /* ( */, 0 /* ) */, 1 /* * */, 0 /* + */, 0 /* , */,
+ 1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
+ 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
+ 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
+ 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
+ 0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
+ 0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
+ 0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
+ 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
+ 0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
+ 0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 0 /* ^ */,
+ 1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
+ 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
+ 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
+ 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
+ 0 /* } */, 0 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
+ 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
+ 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
+ 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
+ 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
+ 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
+ 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
+ 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
+ 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
+ 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
+ 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
+ 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
+ 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
+ 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
+ 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
+ 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
+ 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
+ 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
+ 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
+ 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
+ 0 /* 0xff */,
+};
+
+static ssize_t sf_parse_key(const uint8_t *begin, const uint8_t *end) {
+ const uint8_t *p = begin;
+
+ if ((*p < 'a' || 'z' < *p) && *p != '*') {
+ return -1;
+ }
+
+ for (; p != end && SF_KEY_CHARS[*p]; ++p)
+ ;
+
+ return p - begin;
+}
+
+static ssize_t sf_parse_integer_or_decimal(nghttp2_sf_value *dest,
+ const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+ int sign = 1;
+ int64_t value = 0;
+ int type = NGHTTP2_SF_VALUE_TYPE_INTEGER;
+ size_t len = 0;
+ size_t fpos = 0;
+ size_t i;
+
+ if (*p == '-') {
+ if (++p == end) {
+ return -1;
+ }
+
+ sign = -1;
+ }
+
+ if (*p < '0' || '9' < *p) {
+ return -1;
+ }
+
+ for (; p != end; ++p) {
+ switch (*p) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ value *= 10;
+ value += *p - '0';
+
+ if (++len > 15) {
+ return -1;
+ }
+
+ break;
+ case '.':
+ if (type != NGHTTP2_SF_VALUE_TYPE_INTEGER) {
+ goto fin;
+ }
+
+ if (len > 12) {
+ return -1;
+ }
+ fpos = len;
+ type = NGHTTP2_SF_VALUE_TYPE_DECIMAL;
+
+ break;
+ default:
+ goto fin;
+ };
+ }
+
+fin:
+ switch (type) {
+ case NGHTTP2_SF_VALUE_TYPE_INTEGER:
+ if (dest) {
+ dest->type = (uint8_t)type;
+ dest->i = value * sign;
+ }
+
+ return p - begin;
+ case NGHTTP2_SF_VALUE_TYPE_DECIMAL:
+ if (fpos == len || len - fpos > 3) {
+ return -1;
+ }
+
+ if (dest) {
+ dest->type = (uint8_t)type;
+ dest->d = (double)value;
+ for (i = len - fpos; i > 0; --i) {
+ dest->d /= (double)10;
+ }
+ dest->d *= sign;
+ }
+
+ return p - begin;
+ default:
+ assert(0);
+ abort();
+ }
+}
+
+/* Generated by genchartbl.py */
+static const int SF_DQUOTE_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
+ 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
+ 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
+ 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
+ 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
+ 0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 0 /* " */,
+ 1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
+ 1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
+ 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
+ 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
+ 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
+ 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
+ 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
+ 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
+ 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
+ 1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 1 /* ^ */,
+ 1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
+ 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
+ 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
+ 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
+ 1 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
+ 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
+ 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
+ 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
+ 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
+ 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
+ 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
+ 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
+ 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
+ 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
+ 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
+ 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
+ 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
+ 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
+ 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
+ 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
+ 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
+ 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
+ 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
+ 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
+ 0 /* 0xff */,
+};
+
+static ssize_t sf_parse_string(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+
+ if (*p++ != '"') {
+ return -1;
+ }
+
+ for (; p != end; ++p) {
+ switch (*p) {
+ case '\\':
+ if (++p == end) {
+ return -1;
+ }
+
+ switch (*p) {
+ case '"':
+ case '\\':
+ break;
+ default:
+ return -1;
+ }
+
+ break;
+ case '"':
+ if (dest) {
+ dest->type = NGHTTP2_SF_VALUE_TYPE_STRING;
+ dest->s.base = begin + 1;
+ dest->s.len = (size_t)(p - dest->s.base);
+ }
+
+ ++p;
+
+ return p - begin;
+ default:
+ if (!SF_DQUOTE_CHARS[*p]) {
+ return -1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* Generated by genchartbl.py */
+static const int SF_TOKEN_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
+ 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
+ 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
+ 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
+ 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
+ 0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
+ 1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
+ 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
+ 1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
+ 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
+ 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 0 /* ; */,
+ 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
+ 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
+ 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
+ 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
+ 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
+ 1 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
+ 1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
+ 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
+ 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
+ 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
+ 0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
+ 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
+ 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
+ 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
+ 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
+ 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
+ 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
+ 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
+ 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
+ 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
+ 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
+ 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
+ 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
+ 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
+ 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
+ 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
+ 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
+ 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
+ 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
+ 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
+ 0 /* 0xff */,
+};
+
+static ssize_t sf_parse_token(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+
+ if ((*p < 'A' || 'Z' < *p) && (*p < 'a' || 'z' < *p) && *p != '*') {
+ return -1;
+ }
+
+ for (; p != end && SF_TOKEN_CHARS[*p]; ++p)
+ ;
+
+ if (dest) {
+ dest->type = NGHTTP2_SF_VALUE_TYPE_TOKEN;
+ dest->s.base = begin;
+ dest->s.len = (size_t)(p - begin);
+ }
+
+ return p - begin;
+}
+
+/* Generated by genchartbl.py */
+static const int SF_BYTESEQ_CHARS[] = {
+ 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
+ 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
+ 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
+ 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
+ 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
+ 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
+ 0 /* RS */, 0 /* US */, 0 /* SPC */, 0 /* ! */, 0 /* " */,
+ 0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */,
+ 0 /* ( */, 0 /* ) */, 0 /* * */, 1 /* + */, 0 /* , */,
+ 0 /* - */, 0 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
+ 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
+ 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
+ 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
+ 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
+ 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
+ 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
+ 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
+ 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
+ 1 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 0 /* ^ */,
+ 0 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
+ 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
+ 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
+ 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
+ 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
+ 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
+ 0 /* } */, 0 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
+ 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
+ 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+ 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
+ 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
+ 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
+ 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+ 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
+ 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
+ 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
+ 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+ 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
+ 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
+ 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
+ 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+ 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
+ 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
+ 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
+ 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+ 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
+ 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
+ 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
+ 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+ 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
+ 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
+ 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
+ 0 /* 0xff */,
+};
+
+static ssize_t sf_parse_byteseq(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+
+ if (*p++ != ':') {
+ return -1;
+ }
+
+ for (; p != end; ++p) {
+ switch (*p) {
+ case ':':
+ if (dest) {
+ dest->type = NGHTTP2_SF_VALUE_TYPE_BYTESEQ;
+ dest->s.base = begin + 1;
+ dest->s.len = (size_t)(p - dest->s.base);
+ }
+
+ ++p;
+
+ return p - begin;
+ default:
+ if (!SF_BYTESEQ_CHARS[*p]) {
+ return -1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static ssize_t sf_parse_boolean(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+ int b;
+
+ if (*p++ != '?') {
+ return -1;
+ }
+
+ if (p == end) {
+ return -1;
+ }
+
+ switch (*p++) {
+ case '0':
+ b = 0;
+ break;
+ case '1':
+ b = 1;
+ break;
+ default:
+ return -1;
+ }
+
+ if (dest) {
+ dest->type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN;
+ dest->b = b;
+ }
+
+ return p - begin;
+}
+
+static ssize_t sf_parse_bare_item(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ switch (*begin) {
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return sf_parse_integer_or_decimal(dest, begin, end);
+ case '"':
+ return sf_parse_string(dest, begin, end);
+ case '*':
+ return sf_parse_token(dest, begin, end);
+ case ':':
+ return sf_parse_byteseq(dest, begin, end);
+ case '?':
+ return sf_parse_boolean(dest, begin, end);
+ default:
+ if (('A' <= *begin && *begin <= 'Z') || ('a' <= *begin && *begin <= 'z')) {
+ return sf_parse_token(dest, begin, end);
+ }
+ return -1;
+ }
+}
+
+#define sf_discard_sp_end_err(BEGIN, END, ERR) \
+ for (;; ++(BEGIN)) { \
+ if ((BEGIN) == (END)) { \
+ return (ERR); \
+ } \
+ if (*(BEGIN) != ' ') { \
+ break; \
+ } \
+ }
+
+static ssize_t sf_parse_params(const uint8_t *begin, const uint8_t *end) {
+ const uint8_t *p = begin;
+ ssize_t slen;
+
+ for (; p != end && *p == ';';) {
+ ++p;
+
+ sf_discard_sp_end_err(p, end, -1);
+
+ slen = sf_parse_key(p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+
+ if (p == end || *p != '=') {
+ /* Boolean true */
+ } else if (++p == end) {
+ return -1;
+ } else {
+ slen = sf_parse_bare_item(NULL, p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+ }
+ }
+
+ return p - begin;
+}
+
+static ssize_t sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+ ssize_t slen;
+
+ slen = sf_parse_bare_item(dest, p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+
+ slen = sf_parse_params(p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+
+ return p - begin;
+}
+
+ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ return sf_parse_item(dest, begin, end);
+}
+
+static ssize_t sf_parse_inner_list(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end) {
+ const uint8_t *p = begin;
+ ssize_t slen;
+
+ if (*p++ != '(') {
+ return -1;
+ }
+
+ for (;;) {
+ sf_discard_sp_end_err(p, end, -1);
+
+ if (*p == ')') {
+ ++p;
+
+ slen = sf_parse_params(p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+
+ if (dest) {
+ dest->type = NGHTTP2_SF_VALUE_TYPE_INNER_LIST;
+ }
+
+ return p - begin;
+ }
+
+ slen = sf_parse_item(NULL, p, end);
+ if (slen < 0) {
+ return -1;
+ }
+
+ p += slen;
+
+ if (p == end || (*p != ' ' && *p != ')')) {
+ return -1;
+ }
+ }
+}
+
+ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest,
+ const uint8_t *begin, const uint8_t *end) {
+ return sf_parse_inner_list(dest, begin, end);
+}
+
+static ssize_t sf_parse_item_or_inner_list(nghttp2_sf_value *dest,
+ const uint8_t *begin,
+ const uint8_t *end) {
+ if (*begin == '(') {
+ return sf_parse_inner_list(dest, begin, end);
+ }
+
+ return sf_parse_item(dest, begin, end);
+}
+
+#define sf_discard_ows(BEGIN, END) \
+ for (;; ++(BEGIN)) { \
+ if ((BEGIN) == (END)) { \
+ goto fin; \
+ } \
+ if (*(BEGIN) != ' ' && *(BEGIN) != '\t') { \
+ break; \
+ } \
+ }
+
+#define sf_discard_ows_end_err(BEGIN, END, ERR) \
+ for (;; ++(BEGIN)) { \
+ if ((BEGIN) == (END)) { \
+ return (ERR); \
+ } \
+ if (*(BEGIN) != ' ' && *(BEGIN) != '\t') { \
+ break; \
+ } \
+ }
+
+int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
+ size_t valuelen) {
+ const uint8_t *p = value, *end = value + valuelen;
+ ssize_t slen;
+ nghttp2_sf_value val;
+ nghttp2_extpri pri = *dest;
+ const uint8_t *key;
+ size_t keylen;
+
+ for (; p != end && *p == ' '; ++p)
+ ;
+
+ for (; p != end;) {
+ slen = sf_parse_key(p, end);
+ if (slen < 0) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ key = p;
+ keylen = (size_t)slen;
+
+ p += slen;
+
+ if (p == end || *p != '=') {
+ /* Boolean true */
+ val.type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN;
+ val.b = 1;
+
+ slen = sf_parse_params(p, end);
+ if (slen < 0) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+ } else if (++p == end) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ } else {
+ slen = sf_parse_item_or_inner_list(&val, p, end);
+ if (slen < 0) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+ }
+
+ p += slen;
+
+ if (keylen == 1) {
+ switch (key[0]) {
+ case 'i':
+ if (val.type != NGHTTP2_SF_VALUE_TYPE_BOOLEAN) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ pri.inc = val.b;
+
+ break;
+ case 'u':
+ if (val.type != NGHTTP2_SF_VALUE_TYPE_INTEGER ||
+ val.i < NGHTTP2_EXTPRI_URGENCY_HIGH ||
+ NGHTTP2_EXTPRI_URGENCY_LOW < val.i) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ pri.urgency = (uint32_t)val.i;
+
+ break;
+ }
+ }
+
+ sf_discard_ows(p, end);
+
+ if (*p++ != ',') {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ sf_discard_ows_end_err(p, end, NGHTTP2_ERR_INVALID_ARGUMENT);
+ }
+
+fin:
+ *dest = pri;
+
+ return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.h b/Utilities/cmnghttp2/lib/nghttp2_http.h
index dd057cd..0c3a78e 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_http.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.h
@@ -94,4 +94,55 @@ int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n);
void nghttp2_http_record_request_method(nghttp2_stream *stream,
nghttp2_frame *frame);
+/*
+ * RFC 8941 Structured Field Values.
+ */
+typedef enum nghttp2_sf_value_type {
+ NGHTTP2_SF_VALUE_TYPE_BOOLEAN,
+ NGHTTP2_SF_VALUE_TYPE_INTEGER,
+ NGHTTP2_SF_VALUE_TYPE_DECIMAL,
+ NGHTTP2_SF_VALUE_TYPE_STRING,
+ NGHTTP2_SF_VALUE_TYPE_TOKEN,
+ NGHTTP2_SF_VALUE_TYPE_BYTESEQ,
+ NGHTTP2_SF_VALUE_TYPE_INNER_LIST,
+} nghttp2_sf_value_type;
+
+/*
+ * nghttp2_sf_value stores Structured Field Values item. For Inner
+ * List, only type is set to NGHTTP2_SF_VALUE_TYPE_INNER_LIST.
+ */
+typedef struct nghttp2_sf_value {
+ uint8_t type;
+ union {
+ int b;
+ int64_t i;
+ double d;
+ struct {
+ const uint8_t *base;
+ size_t len;
+ } s;
+ };
+} nghttp2_sf_value;
+
+/*
+ * nghttp2_sf_parse_item parses the input sequence [|begin|, |end|)
+ * and stores the parsed an Item in |dest|. It returns the number of
+ * bytes consumed if it succeeds, or -1. This function is declared
+ * here for unit tests.
+ */
+ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
+ const uint8_t *end);
+
+/*
+ * nghttp2_sf_parse_inner_list parses the input sequence [|begin|, |end|)
+ * and stores the parsed an Inner List in |dest|. It returns the number of
+ * bytes consumed if it succeeds, or -1. This function is declared
+ * here for unit tests.
+ */
+ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest,
+ const uint8_t *begin, const uint8_t *end);
+
+int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
+ size_t valuelen);
+
#endif /* NGHTTP2_HTTP_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.c b/Utilities/cmnghttp2/lib/nghttp2_map.c
index 4d9f97b..e5db168 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_map.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.c
@@ -1,7 +1,8 @@
/*
* nghttp2 - HTTP/2 C Library
*
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -25,14 +26,19 @@
#include "nghttp2_map.h"
#include <string.h>
+#include <assert.h>
+#include <stdio.h>
-#define INITIAL_TABLE_LENGTH 256
+#include "nghttp2_helper.h"
+
+#define NGHTTP2_INITIAL_TABLE_LENBITS 8
int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
map->mem = mem;
- map->tablelen = INITIAL_TABLE_LENGTH;
+ map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS;
+ map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS;
map->table =
- nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_entry *));
+ nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
if (map->table == NULL) {
return NGHTTP2_ERR_NOMEM;
}
@@ -43,112 +49,188 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
}
void nghttp2_map_free(nghttp2_map *map) {
+ if (!map) {
+ return;
+ }
+
nghttp2_mem_free(map->mem, map->table);
}
-void nghttp2_map_each_free(nghttp2_map *map,
- int (*func)(nghttp2_map_entry *entry, void *ptr),
+void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
uint32_t i;
+ nghttp2_map_bucket *bkt;
+
for (i = 0; i < map->tablelen; ++i) {
- nghttp2_map_entry *entry;
- for (entry = map->table[i]; entry;) {
- nghttp2_map_entry *next = entry->next;
- func(entry, ptr);
- entry = next;
+ bkt = &map->table[i];
+
+ if (bkt->data == NULL) {
+ continue;
}
- map->table[i] = NULL;
+
+ func(bkt->data, ptr);
}
}
-int nghttp2_map_each(nghttp2_map *map,
- int (*func)(nghttp2_map_entry *entry, void *ptr),
+int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
int rv;
uint32_t i;
+ nghttp2_map_bucket *bkt;
+
for (i = 0; i < map->tablelen; ++i) {
- nghttp2_map_entry *entry;
- for (entry = map->table[i]; entry; entry = entry->next) {
- rv = func(entry, ptr);
- if (rv != 0) {
- return rv;
- }
+ bkt = &map->table[i];
+
+ if (bkt->data == NULL) {
+ continue;
+ }
+
+ rv = func(bkt->data, ptr);
+ if (rv != 0) {
+ return rv;
}
}
+
return 0;
}
-void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
- entry->key = key;
- entry->next = NULL;
+static uint32_t hash(nghttp2_map_key_type key) {
+ return (uint32_t)key * 2654435769u;
}
-/* Same hash function in android HashMap source code. */
-/* The |mod| must be power of 2 */
-static uint32_t hash(int32_t key, uint32_t mod) {
- uint32_t h = (uint32_t)key;
- h ^= (h >> 20) ^ (h >> 12);
- h ^= (h >> 7) ^ (h >> 4);
- return h & (mod - 1);
+static size_t h2idx(uint32_t hash, uint32_t bits) {
+ return hash >> (32 - bits);
}
-static int insert(nghttp2_map_entry **table, uint32_t tablelen,
- nghttp2_map_entry *entry) {
- uint32_t h = hash(entry->key, tablelen);
- if (table[h] == NULL) {
- table[h] = entry;
- } else {
- nghttp2_map_entry *p;
- /* We won't allow duplicated key, so check it out. */
- for (p = table[h]; p; p = p->next) {
- if (p->key == entry->key) {
- return NGHTTP2_ERR_INVALID_ARGUMENT;
- }
+static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
+ nghttp2_map_bucket *bkt, size_t idx) {
+ return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
+}
+
+static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash,
+ nghttp2_map_key_type *pkey, void **pdata) {
+ uint32_t h = bkt->hash;
+ nghttp2_map_key_type key = bkt->key;
+ void *data = bkt->data;
+
+ bkt->hash = *phash;
+ bkt->key = *pkey;
+ bkt->data = *pdata;
+
+ *phash = h;
+ *pkey = key;
+ *pdata = data;
+}
+
+static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash,
+ nghttp2_map_key_type key, void *data) {
+ bkt->hash = hash;
+ bkt->key = key;
+ bkt->data = data;
+}
+
+void nghttp2_map_print_distance(nghttp2_map *map) {
+ uint32_t i;
+ size_t idx;
+ nghttp2_map_bucket *bkt;
+
+ for (i = 0; i < map->tablelen; ++i) {
+ bkt = &map->table[i];
+
+ if (bkt->data == NULL) {
+ fprintf(stderr, "@%u <EMPTY>\n", i);
+ continue;
}
- entry->next = table[h];
- table[h] = entry;
+
+ idx = h2idx(bkt->hash, map->tablelenbits);
+ fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i,
+ bkt->hash, bkt->key, idx,
+ distance(map->tablelen, map->tablelenbits, bkt, idx));
+ }
+}
+
+static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
+ uint32_t tablelenbits, uint32_t hash,
+ nghttp2_map_key_type key, void *data) {
+ size_t idx = h2idx(hash, tablelenbits);
+ size_t d = 0, dd;
+ nghttp2_map_bucket *bkt;
+
+ for (;;) {
+ bkt = &table[idx];
+
+ if (bkt->data == NULL) {
+ map_bucket_set_data(bkt, hash, key, data);
+ return 0;
+ }
+
+ dd = distance(tablelen, tablelenbits, bkt, idx);
+ if (d > dd) {
+ map_bucket_swap(bkt, &hash, &key, &data);
+ d = dd;
+ } else if (bkt->key == key) {
+ /* TODO This check is just a waste after first swap or if this
+ function is called from map_resize. That said, there is no
+ difference with or without this conditional in performance
+ wise. */
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ ++d;
+ idx = (idx + 1) & (tablelen - 1);
}
- return 0;
}
-/* new_tablelen must be power of 2 */
-static int resize(nghttp2_map *map, uint32_t new_tablelen) {
+/* new_tablelen must be power of 2 and new_tablelen == (1 <<
+ new_tablelenbits) must hold. */
+static int map_resize(nghttp2_map *map, uint32_t new_tablelen,
+ uint32_t new_tablelenbits) {
uint32_t i;
- nghttp2_map_entry **new_table;
+ nghttp2_map_bucket *new_table;
+ nghttp2_map_bucket *bkt;
+ int rv;
+ (void)rv;
new_table =
- nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_entry *));
+ nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket));
if (new_table == NULL) {
return NGHTTP2_ERR_NOMEM;
}
for (i = 0; i < map->tablelen; ++i) {
- nghttp2_map_entry *entry;
- for (entry = map->table[i]; entry;) {
- nghttp2_map_entry *next = entry->next;
- entry->next = NULL;
- /* This function must succeed */
- insert(new_table, new_tablelen, entry);
- entry = next;
+ bkt = &map->table[i];
+ if (bkt->data == NULL) {
+ continue;
}
+ rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
+ bkt->data);
+
+ assert(0 == rv);
}
+
nghttp2_mem_free(map->mem, map->table);
map->tablelen = new_tablelen;
+ map->tablelenbits = new_tablelenbits;
map->table = new_table;
return 0;
}
-int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
int rv;
+
+ assert(data);
+
/* Load factor is 0.75 */
if ((map->size + 1) * 4 > map->tablelen * 3) {
- rv = resize(map, map->tablelen * 2);
+ rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
if (rv != 0) {
return rv;
}
}
- rv = insert(map->table, map->tablelen, new_entry);
+
+ rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
+ data);
if (rv != 0) {
return rv;
}
@@ -156,34 +238,76 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
return 0;
}
-nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
- uint32_t h;
- nghttp2_map_entry *entry;
- h = hash(key, map->tablelen);
- for (entry = map->table[h]; entry; entry = entry->next) {
- if (entry->key == key) {
- return entry;
+void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
+ uint32_t h = hash(key);
+ size_t idx = h2idx(h, map->tablelenbits);
+ nghttp2_map_bucket *bkt;
+ size_t d = 0;
+
+ for (;;) {
+ bkt = &map->table[idx];
+
+ if (bkt->data == NULL ||
+ d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+ return NULL;
}
+
+ if (bkt->key == key) {
+ return bkt->data;
+ }
+
+ ++d;
+ idx = (idx + 1) & (map->tablelen - 1);
}
- return NULL;
}
-int nghttp2_map_remove(nghttp2_map *map, key_type key) {
- uint32_t h;
- nghttp2_map_entry **dst;
+int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
+ uint32_t h = hash(key);
+ size_t idx = h2idx(h, map->tablelenbits), didx;
+ nghttp2_map_bucket *bkt;
+ size_t d = 0;
- h = hash(key, map->tablelen);
+ for (;;) {
+ bkt = &map->table[idx];
- for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
- if ((*dst)->key != key) {
- continue;
+ if (bkt->data == NULL ||
+ d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ if (bkt->key == key) {
+ map_bucket_set_data(bkt, 0, 0, NULL);
+
+ didx = idx;
+ idx = (idx + 1) & (map->tablelen - 1);
+
+ for (;;) {
+ bkt = &map->table[idx];
+ if (bkt->data == NULL ||
+ distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
+ break;
+ }
+
+ map->table[didx] = *bkt;
+ map_bucket_set_data(bkt, 0, 0, NULL);
+ didx = idx;
+
+ idx = (idx + 1) & (map->tablelen - 1);
+ }
+
+ --map->size;
+
+ return 0;
}
- *dst = (*dst)->next;
- --map->size;
- return 0;
+ ++d;
+ idx = (idx + 1) & (map->tablelen - 1);
}
- return NGHTTP2_ERR_INVALID_ARGUMENT;
+}
+
+void nghttp2_map_clear(nghttp2_map *map) {
+ memset(map->table, 0, sizeof(*map->table) * map->tablelen);
+ map->size = 0;
}
size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.h b/Utilities/cmnghttp2/lib/nghttp2_map.h
index f6e29e3..1419a09 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_map.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.h
@@ -1,7 +1,8 @@
/*
* nghttp2 - HTTP/2 C Library
*
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2017 ngtcp2 contributors
+ * Copyright (c) 2012 nghttp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -30,27 +31,25 @@
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
-#include "nghttp2_int.h"
+
#include "nghttp2_mem.h"
/* Implementation of unordered map */
-typedef int32_t key_type;
+typedef int32_t nghttp2_map_key_type;
-typedef struct nghttp2_map_entry {
- struct nghttp2_map_entry *next;
- key_type key;
-#if SIZEOF_INT_P == 4
- /* we requires 8 bytes aligment */
- int64_t pad;
-#endif
-} nghttp2_map_entry;
+typedef struct nghttp2_map_bucket {
+ uint32_t hash;
+ nghttp2_map_key_type key;
+ void *data;
+} nghttp2_map_bucket;
-typedef struct {
- nghttp2_map_entry **table;
+typedef struct nghttp2_map {
+ nghttp2_map_bucket *table;
nghttp2_mem *mem;
size_t size;
uint32_t tablelen;
+ uint32_t tablelenbits;
} nghttp2_map;
/*
@@ -74,21 +73,14 @@ void nghttp2_map_free(nghttp2_map *map);
/*
* Deallocates each entries using |func| function and any resources
* allocated for |map|. The |func| function is responsible for freeing
- * given the |entry| object. The |ptr| will be passed to the |func| as
+ * given the |data| object. The |ptr| will be passed to the |func| as
* send argument. The return value of the |func| will be ignored.
*/
-void nghttp2_map_each_free(nghttp2_map *map,
- int (*func)(nghttp2_map_entry *entry, void *ptr),
+void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
/*
- * Initializes the |entry| with the |key|. All entries to be inserted
- * to the map must be initialized with this function.
- */
-void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
-
-/*
- * Inserts the new |entry| with the key |entry->key| to the map |map|.
+ * Inserts the new |data| with the |key| to the map |map|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -98,25 +90,30 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
-int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
/*
- * Returns the entry associated by the key |key|. If there is no such
- * entry, this function returns NULL.
+ * Returns the data associated by the key |key|. If there is no such
+ * data, this function returns NULL.
*/
-nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
+void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
/*
- * Removes the entry associated by the key |key| from the |map|. The
- * removed entry is not freed by this function.
+ * Removes the data associated by the key |key| from the |map|. The
+ * removed data is not freed by this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
- * The entry associated by |key| does not exist.
+ * The data associated by |key| does not exist.
*/
-int nghttp2_map_remove(nghttp2_map *map, key_type key);
+int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
+
+/*
+ * Removes all entries from |map|.
+ */
+void nghttp2_map_clear(nghttp2_map *map);
/*
* Returns the number of items stored in the map |map|.
@@ -124,21 +121,22 @@ int nghttp2_map_remove(nghttp2_map *map, key_type key);
size_t nghttp2_map_size(nghttp2_map *map);
/*
- * Applies the function |func| to each entry in the |map| with the
+ * Applies the function |func| to each data in the |map| with the
* optional user supplied pointer |ptr|.
*
* If the |func| returns 0, this function calls the |func| with the
- * next entry. If the |func| returns nonzero, it will not call the
+ * next data. If the |func| returns nonzero, it will not call the
* |func| for further entries and return the return value of the
* |func| immediately. Thus, this function returns 0 if all the
* invocations of the |func| return 0, or nonzero value which the last
* invocation of |func| returns.
*
- * Don't use this function to free each entry. Use
+ * Don't use this function to free each data. Use
* nghttp2_map_each_free() instead.
*/
-int nghttp2_map_each(nghttp2_map *map,
- int (*func)(nghttp2_map_entry *entry, void *ptr),
+int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
+void nghttp2_map_print_distance(nghttp2_map *map);
+
#endif /* NGHTTP2_MAP_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_net.h b/Utilities/cmnghttp2/lib/nghttp2_net.h
index 95ffee7..345f6c8 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_net.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_net.h
@@ -42,7 +42,7 @@
#if defined(WIN32)
/* Windows requires ws2_32 library for ntonl family functions. We
define inline functions for those function so that we don't have
- dependeny on that lib. */
+ dependency on that lib. */
# ifdef _MSC_VER
# define STIN static __inline
@@ -53,7 +53,7 @@
STIN uint32_t htonl(uint32_t hostlong) {
uint32_t res;
unsigned char *p = (unsigned char *)&res;
- *p++ = hostlong >> 24;
+ *p++ = (unsigned char)(hostlong >> 24);
*p++ = (hostlong >> 16) & 0xffu;
*p++ = (hostlong >> 8) & 0xffu;
*p = hostlong & 0xffu;
@@ -63,7 +63,7 @@ STIN uint32_t htonl(uint32_t hostlong) {
STIN uint16_t htons(uint16_t hostshort) {
uint16_t res;
unsigned char *p = (unsigned char *)&res;
- *p++ = hostshort >> 8;
+ *p++ = (unsigned char)(hostshort >> 8);
*p = hostshort & 0xffu;
return res;
}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.c b/Utilities/cmnghttp2/lib/nghttp2_option.c
index e53f22d..ee0cd0f 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_option.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.c
@@ -90,6 +90,10 @@ void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ORIGIN;
return;
+ case NGHTTP2_PRIORITY_UPDATE:
+ option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
+ option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_PRIORITY_UPDATE;
+ return;
default:
return;
}
@@ -121,3 +125,21 @@ void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
option->max_outbound_ack = val;
}
+
+void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
+ option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
+ option->max_settings = val;
+}
+
+void nghttp2_option_set_server_fallback_rfc7540_priorities(
+ nghttp2_option *option, int val) {
+ option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES;
+ option->server_fallback_rfc7540_priorities = val;
+}
+
+void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
+ nghttp2_option *option, int val) {
+ option->opt_set_mask |=
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+ option->no_rfc9113_leading_and_trailing_ws_validation = val;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.h b/Utilities/cmnghttp2/lib/nghttp2_option.h
index 1f740aa..b228a07 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_option.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.h
@@ -67,6 +67,9 @@ typedef enum {
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
+ NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
+ NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13,
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
} nghttp2_option_flag;
/**
@@ -86,6 +89,10 @@ struct nghttp2_option {
*/
size_t max_outbound_ack;
/**
+ * NGHTTP2_OPT_MAX_SETTINGS
+ */
+ size_t max_settings;
+ /**
* Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified.
*/
@@ -123,6 +130,14 @@ struct nghttp2_option {
*/
int no_closed_streams;
/**
+ * NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES
+ */
+ int server_fallback_rfc7540_priorities;
+ /**
+ * NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION
+ */
+ int no_rfc9113_leading_and_trailing_ws_validation;
+ /**
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
*/
uint8_t user_recv_ext_types[32];
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
index f651c80..2a3041d 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
@@ -89,6 +89,9 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
case NGHTTP2_ORIGIN:
nghttp2_frame_origin_free(&frame->ext, mem);
break;
+ case NGHTTP2_PRIORITY_UPDATE:
+ nghttp2_frame_priority_update_free(&frame->ext, mem);
+ break;
default:
assert(0);
break;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
index b5f503a..bd4611b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
@@ -111,7 +111,7 @@ struct nghttp2_outbound_item {
to this structure to avoid frequent memory allocation. */
nghttp2_ext_frame_payload ext_frame_payload;
nghttp2_aux_data aux_data;
- /* The priority used in priority comparion. Smaller is served
+ /* The priority used in priority comparison. Smaller is served
earlier. For PING, SETTINGS and non-DATA frames (excluding
response HEADERS frame) have dedicated cycle value defined above.
For DATA frame, cycle is computed by taking into account of
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.c b/Utilities/cmnghttp2/lib/nghttp2_pq.c
index bebccc7..64353ac 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_pq.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.c
@@ -29,13 +29,12 @@
#include "nghttp2_helper.h"
-int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) {
+void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) {
pq->mem = mem;
pq->capacity = 0;
pq->q = NULL;
pq->length = 0;
pq->less = less;
- return 0;
}
void nghttp2_pq_free(nghttp2_pq *pq) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.h b/Utilities/cmnghttp2/lib/nghttp2_pq.h
index 2d7b702..c8d90ef 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_pq.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.h
@@ -55,14 +55,8 @@ typedef struct {
/*
* Initializes priority queue |pq| with compare function |cmp|.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
*/
-int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
+void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
/*
* Deallocates any resources allocated for |pq|. The stored items are
@@ -114,7 +108,7 @@ typedef int (*nghttp2_pq_item_cb)(nghttp2_pq_entry *item, void *arg);
void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
/*
- * Applys |fun| to each item in |pq|. The |arg| is passed as arg
+ * Applies |fun| to each item in |pq|. The |arg| is passed as arg
* parameter to callback function. This function must not change the
* ordering key. If the return value from callback is nonzero, this
* function returns 1 immediately without iterating remaining items.
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.c b/Utilities/cmnghttp2/lib/nghttp2_session.c
index 9df3d6f..93f3f07 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_session.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.c
@@ -36,6 +36,7 @@
#include "nghttp2_option.h"
#include "nghttp2_http.h"
#include "nghttp2_pq.h"
+#include "nghttp2_extpri.h"
#include "nghttp2_debug.h"
/*
@@ -143,6 +144,11 @@ static int session_detect_idle_stream(nghttp2_session *session,
return 0;
}
+static int session_no_rfc7540_pri_no_fallback(nghttp2_session *session) {
+ return session->pending_no_rfc7540_priorities == 1 &&
+ !session->fallback_rfc7540_priorities;
+}
+
static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
return (ext_types[type / 8] & (1 << (type & 0x7))) > 0;
}
@@ -354,6 +360,14 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
}
nghttp2_frame_origin_free(&iframe->frame.ext, mem);
break;
+ case NGHTTP2_PRIORITY_UPDATE:
+ if ((session->builtin_recv_ext_types &
+ NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
+ break;
+ }
+ /* Do not call nghttp2_frame_priority_update_free, because all
+ fields point to sbuf. */
+ break;
}
}
@@ -385,6 +399,7 @@ static void init_settings(nghttp2_settings_storage *settings) {
settings->initial_window_size = NGHTTP2_INITIAL_WINDOW_SIZE;
settings->max_frame_size = NGHTTP2_MAX_FRAME_SIZE_MIN;
settings->max_header_list_size = UINT32_MAX;
+ settings->no_rfc7540_priorities = UINT32_MAX;
}
static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
@@ -398,6 +413,21 @@ static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
aob->state = NGHTTP2_OB_POP_ITEM;
}
+#define NGHTTP2_STREAM_MAX_CYCLE_GAP ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX)
+
+static int stream_less(const void *lhsx, const void *rhsx) {
+ const nghttp2_stream *lhs, *rhs;
+
+ lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry);
+ rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry);
+
+ if (lhs->cycle == rhs->cycle) {
+ return lhs->seq < rhs->seq;
+ }
+
+ return rhs->cycle - lhs->cycle <= NGHTTP2_STREAM_MAX_CYCLE_GAP;
+}
+
int nghttp2_enable_strict_preface = 1;
static int session_new(nghttp2_session **session_ptr,
@@ -408,6 +438,7 @@ static int session_new(nghttp2_session **session_ptr,
size_t nbuffer;
size_t max_deflate_dynamic_table_size =
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
+ size_t i;
if (mem == NULL) {
mem = nghttp2_mem_default();
@@ -442,6 +473,7 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->pending_local_max_concurrent_stream =
NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
(*session_ptr)->pending_enable_push = 1;
+ (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX;
if (server) {
(*session_ptr)->server = 1;
@@ -458,6 +490,7 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
(*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
+ (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
@@ -521,6 +554,25 @@ static int session_new(nghttp2_session **session_ptr,
if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
(*session_ptr)->max_outbound_ack = option->max_outbound_ack;
}
+
+ if ((option->opt_set_mask & NGHTTP2_OPT_MAX_SETTINGS) &&
+ option->max_settings) {
+ (*session_ptr)->max_settings = option->max_settings;
+ }
+
+ if ((option->opt_set_mask &
+ NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) &&
+ option->server_fallback_rfc7540_priorities) {
+ (*session_ptr)->opt_flags |=
+ NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES;
+ }
+
+ if ((option->opt_set_mask &
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) &&
+ option->no_rfc9113_leading_and_trailing_ws_validation) {
+ (*session_ptr)->opt_flags |=
+ NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -578,6 +630,10 @@ static int session_new(nghttp2_session **session_ptr,
}
}
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
+ nghttp2_pq_init(&(*session_ptr)->sched[i].ob_data, stream_less, mem);
+ }
+
return 0;
fail_aob_framebuf:
@@ -660,7 +716,7 @@ int nghttp2_session_server_new3(nghttp2_session **session_ptr,
return 0;
}
-static int free_streams(nghttp2_map_entry *entry, void *ptr) {
+static int free_streams(void *entry, void *ptr) {
nghttp2_session *session;
nghttp2_stream *stream;
nghttp2_outbound_item *item;
@@ -729,6 +785,7 @@ static void inflight_settings_del(nghttp2_inflight_settings *settings,
void nghttp2_session_del(nghttp2_session *session) {
nghttp2_mem *mem;
nghttp2_inflight_settings *settings;
+ size_t i;
if (session == NULL) {
return;
@@ -742,6 +799,9 @@ void nghttp2_session_del(nghttp2_session *session) {
settings = next;
}
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
+ nghttp2_pq_free(&session->sched[i].ob_data);
+ }
nghttp2_stream_free(&session->root);
/* Have to free streams first, so that we can check
@@ -769,6 +829,8 @@ int nghttp2_session_reprioritize_stream(
nghttp2_priority_spec pri_spec_default;
const nghttp2_priority_spec *pri_spec = pri_spec_in;
+ assert((!session->server && session->pending_no_rfc7540_priorities != 1) ||
+ (session->server && !session_no_rfc7540_pri_no_fallback(session)));
assert(pri_spec->stream_id != stream->stream_id);
if (!nghttp2_stream_in_dep_tree(stream)) {
@@ -836,6 +898,214 @@ int nghttp2_session_reprioritize_stream(
return 0;
}
+static uint64_t pq_get_first_cycle(nghttp2_pq *pq) {
+ nghttp2_stream *stream;
+
+ if (nghttp2_pq_empty(pq)) {
+ return 0;
+ }
+
+ stream = nghttp2_struct_of(nghttp2_pq_top(pq), nghttp2_stream, pq_entry);
+ return stream->cycle;
+}
+
+static int session_ob_data_push(nghttp2_session *session,
+ nghttp2_stream *stream) {
+ int rv;
+ uint32_t urgency;
+ int inc;
+ nghttp2_pq *pq;
+
+ assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
+ assert(stream->queued == 0);
+
+ urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
+ inc = nghttp2_extpri_uint8_inc(stream->extpri);
+
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
+
+ pq = &session->sched[urgency].ob_data;
+
+ stream->cycle = pq_get_first_cycle(pq);
+ if (inc) {
+ stream->cycle += stream->last_writelen;
+ }
+
+ rv = nghttp2_pq_push(pq, &stream->pq_entry);
+ if (rv != 0) {
+ return rv;
+ }
+
+ stream->queued = 1;
+
+ return 0;
+}
+
+static int session_ob_data_remove(nghttp2_session *session,
+ nghttp2_stream *stream) {
+ uint32_t urgency;
+
+ assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
+ assert(stream->queued == 1);
+
+ urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
+
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
+
+ nghttp2_pq_remove(&session->sched[urgency].ob_data, &stream->pq_entry);
+
+ stream->queued = 0;
+
+ return 0;
+}
+
+static int session_attach_stream_item(nghttp2_session *session,
+ nghttp2_stream *stream,
+ nghttp2_outbound_item *item) {
+ int rv;
+
+ rv = nghttp2_stream_attach_item(stream, item);
+ if (rv != 0) {
+ return rv;
+ }
+
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
+ return 0;
+ }
+
+ return session_ob_data_push(session, stream);
+}
+
+static int session_detach_stream_item(nghttp2_session *session,
+ nghttp2_stream *stream) {
+ int rv;
+
+ rv = nghttp2_stream_detach_item(stream);
+ if (rv != 0) {
+ return rv;
+ }
+
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
+ !stream->queued) {
+ return 0;
+ }
+
+ return session_ob_data_remove(session, stream);
+}
+
+static int session_defer_stream_item(nghttp2_session *session,
+ nghttp2_stream *stream, uint8_t flags) {
+ int rv;
+
+ rv = nghttp2_stream_defer_item(stream, flags);
+ if (rv != 0) {
+ return rv;
+ }
+
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
+ !stream->queued) {
+ return 0;
+ }
+
+ return session_ob_data_remove(session, stream);
+}
+
+static int session_resume_deferred_stream_item(nghttp2_session *session,
+ nghttp2_stream *stream,
+ uint8_t flags) {
+ int rv;
+
+ rv = nghttp2_stream_resume_deferred_item(stream, flags);
+ if (rv != 0) {
+ return rv;
+ }
+
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
+ (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL)) {
+ return 0;
+ }
+
+ return session_ob_data_push(session, stream);
+}
+
+static nghttp2_outbound_item *
+session_sched_get_next_outbound_item(nghttp2_session *session) {
+ size_t i;
+ nghttp2_pq_entry *ent;
+ nghttp2_stream *stream;
+
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
+ ent = nghttp2_pq_top(&session->sched[i].ob_data);
+ if (!ent) {
+ continue;
+ }
+
+ stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
+ return stream->item;
+ }
+
+ return NULL;
+}
+
+static int session_sched_empty(nghttp2_session *session) {
+ size_t i;
+
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
+ if (!nghttp2_pq_empty(&session->sched[i].ob_data)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void session_sched_reschedule_stream(nghttp2_session *session,
+ nghttp2_stream *stream) {
+ nghttp2_pq *pq;
+ uint32_t urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
+ int inc = nghttp2_extpri_uint8_inc(stream->extpri);
+ uint64_t penalty = (uint64_t)stream->last_writelen;
+ int rv;
+
+ (void)rv;
+
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
+
+ pq = &session->sched[urgency].ob_data;
+
+ if (!inc || nghttp2_pq_size(pq) == 1) {
+ return;
+ }
+
+ nghttp2_pq_remove(pq, &stream->pq_entry);
+
+ stream->cycle += penalty;
+
+ rv = nghttp2_pq_push(pq, &stream->pq_entry);
+
+ assert(0 == rv);
+}
+
+static int session_update_stream_priority(nghttp2_session *session,
+ nghttp2_stream *stream,
+ uint8_t u8extpri) {
+ if (stream->extpri == u8extpri) {
+ return 0;
+ }
+
+ if (stream->queued) {
+ session_ob_data_remove(session, stream);
+
+ stream->extpri = u8extpri;
+
+ return session_ob_data_push(session, stream);
+ }
+
+ stream->extpri = u8extpri;
+
+ return 0;
+}
+
int nghttp2_session_add_item(nghttp2_session *session,
nghttp2_outbound_item *item) {
/* TODO Return error if stream is not found for the frame requiring
@@ -857,7 +1127,7 @@ int nghttp2_session_add_item(nghttp2_session *session,
return NGHTTP2_ERR_DATA_EXIST;
}
- rv = nghttp2_stream_attach_item(stream, item);
+ rv = session_attach_stream_item(session, stream, item);
if (rv != 0) {
return rv;
@@ -953,6 +1223,18 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
return 0;
}
+ /* Sending RST_STREAM to an idle stream is subject to protocol
+ violation. Historically, nghttp2 allows this. In order not to
+ disrupt the existing applications, we don't error out this case
+ and simply ignore it. */
+ if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+ if ((uint32_t)stream_id >= session->next_stream_id) {
+ return 0;
+ }
+ } else if (session->last_recv_stream_id < stream_id) {
+ return 0;
+ }
+
/* Cancel pending request HEADERS in ob_syn if this RST_STREAM
refers to that stream. */
if (!session->server && nghttp2_session_is_my_stream_id(session, stream_id) &&
@@ -963,8 +1245,7 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
headers_frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
assert(headers_frame->hd.type == NGHTTP2_HEADERS);
- if (headers_frame->hd.stream_id <= stream_id &&
- (uint32_t)stream_id < session->next_stream_id) {
+ if (headers_frame->hd.stream_id <= stream_id) {
for (item = session->ob_syn.head; item; item = item->qnext) {
aux_data = &item->aux_data.headers;
@@ -1022,13 +1303,27 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
mem = &session->mem;
stream = nghttp2_session_get_stream_raw(session, stream_id);
+ if (session->opt_flags &
+ NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
+ flags |= NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+ }
+
if (stream) {
assert(stream->state == NGHTTP2_STREAM_IDLE);
- assert(nghttp2_stream_in_dep_tree(stream));
- nghttp2_session_detach_idle_stream(session, stream);
- rv = nghttp2_stream_dep_remove(stream);
- if (rv != 0) {
- return NULL;
+ assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
+ nghttp2_stream_in_dep_tree(stream));
+
+ if (nghttp2_stream_in_dep_tree(stream)) {
+ assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES));
+ nghttp2_session_detach_idle_stream(session, stream);
+ rv = nghttp2_stream_dep_remove(stream);
+ if (rv != 0) {
+ return NULL;
+ }
+
+ if (session_no_rfc7540_pri_no_fallback(session)) {
+ stream->flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
+ }
}
} else {
stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream));
@@ -1039,7 +1334,21 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
stream_alloc = 1;
}
- if (pri_spec->stream_id != 0) {
+ if (session_no_rfc7540_pri_no_fallback(session) ||
+ session->remote_settings.no_rfc7540_priorities == 1) {
+ /* For client which has not received server
+ SETTINGS_NO_RFC7540_PRIORITIES = 1, send a priority signal
+ opportunistically. */
+ if (session->server ||
+ session->remote_settings.no_rfc7540_priorities == 1) {
+ nghttp2_priority_spec_default_init(&pri_spec_default);
+ pri_spec = &pri_spec_default;
+ }
+
+ if (session->pending_no_rfc7540_priorities == 1) {
+ flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
+ }
+ } else if (pri_spec->stream_id != 0) {
dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id);
if (!dep_stream &&
@@ -1085,7 +1394,11 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
(int32_t)session->local_settings.initial_window_size,
stream_user_data, mem);
- rv = nghttp2_map_insert(&session->streams, &stream->map_entry);
+ if (session_no_rfc7540_pri_no_fallback(session)) {
+ stream->seq = session->stream_seq++;
+ }
+
+ rv = nghttp2_map_insert(&session->streams, stream_id, stream);
if (rv != 0) {
nghttp2_stream_free(stream);
nghttp2_mem_free(mem, stream);
@@ -1124,6 +1437,10 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
}
}
+ if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
+ return stream;
+ }
+
if (pri_spec->stream_id == 0) {
dep_stream = &session->root;
}
@@ -1163,7 +1480,7 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
item = stream->item;
- rv = nghttp2_stream_detach_item(stream);
+ rv = session_detach_stream_item(session, stream);
if (rv != 0) {
return rv;
@@ -1213,6 +1530,10 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
/* Closes both directions just in case they are not closed yet */
stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED;
+ if (session->pending_no_rfc7540_priorities == 1) {
+ return nghttp2_session_destroy_stream(session, stream);
+ }
+
if ((session->opt_flags & NGHTTP2_OPTMASK_NO_CLOSED_STREAMS) == 0 &&
session->server && !is_my_stream_id &&
nghttp2_stream_in_dep_tree(stream)) {
@@ -1767,6 +2088,28 @@ static int session_predicate_origin_send(nghttp2_session *session) {
return 0;
}
+static int session_predicate_priority_update_send(nghttp2_session *session,
+ int32_t stream_id) {
+ nghttp2_stream *stream;
+
+ if (session_is_closing(session)) {
+ return NGHTTP2_ERR_SESSION_CLOSING;
+ }
+
+ stream = nghttp2_session_get_stream(session, stream_id);
+ if (stream == NULL) {
+ return 0;
+ }
+ if (stream->state == NGHTTP2_STREAM_CLOSING) {
+ return NGHTTP2_ERR_STREAM_CLOSING;
+ }
+ if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+ return NGHTTP2_ERR_INVALID_STREAM_STATE;
+ }
+
+ return 0;
+}
+
/* Take into account settings max frame size and both connection-level
flow control here */
static ssize_t
@@ -1996,7 +2339,7 @@ static int session_prep_frame(nghttp2_session *session,
if (stream) {
int rv2;
- rv2 = nghttp2_stream_detach_item(stream);
+ rv2 = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
@@ -2015,7 +2358,7 @@ static int session_prep_frame(nghttp2_session *session,
queue when session->remote_window_size > 0 */
assert(session->remote_window_size > 0);
- rv = nghttp2_stream_defer_item(stream,
+ rv = session_defer_stream_item(session, stream,
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
if (nghttp2_is_fatal(rv)) {
@@ -2034,7 +2377,8 @@ static int session_prep_frame(nghttp2_session *session,
return rv;
}
if (rv == NGHTTP2_ERR_DEFERRED) {
- rv = nghttp2_stream_defer_item(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
+ rv = session_defer_stream_item(session, stream,
+ NGHTTP2_STREAM_FLAG_DEFERRED_USER);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -2045,7 +2389,7 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_DEFERRED;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
- rv = nghttp2_stream_detach_item(stream);
+ rv = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -2061,7 +2405,7 @@ static int session_prep_frame(nghttp2_session *session,
if (rv != 0) {
int rv2;
- rv2 = nghttp2_stream_detach_item(stream);
+ rv2 = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
@@ -2311,6 +2655,18 @@ static int session_prep_frame(nghttp2_session *session,
}
return 0;
+ case NGHTTP2_PRIORITY_UPDATE: {
+ nghttp2_ext_priority_update *priority_update = frame->ext.payload;
+ rv = session_predicate_priority_update_send(session,
+ priority_update->stream_id);
+ if (rv != 0) {
+ return rv;
+ }
+
+ nghttp2_frame_pack_priority_update(&session->aob.framebufs, &frame->ext);
+
+ return 0;
+ }
default:
/* Unreachable here */
assert(0);
@@ -2322,6 +2678,8 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_outbound_item *
nghttp2_session_get_next_ob_item(nghttp2_session *session) {
+ nghttp2_outbound_item *item;
+
if (nghttp2_outbound_queue_top(&session->ob_urgent)) {
return nghttp2_outbound_queue_top(&session->ob_urgent);
}
@@ -2337,7 +2695,12 @@ nghttp2_session_get_next_ob_item(nghttp2_session *session) {
}
if (session->remote_window_size > 0) {
- return nghttp2_stream_next_outbound_item(&session->root);
+ item = nghttp2_stream_next_outbound_item(&session->root);
+ if (item) {
+ return item;
+ }
+
+ return session_sched_get_next_outbound_item(session);
}
return NULL;
@@ -2371,7 +2734,12 @@ nghttp2_session_pop_next_ob_item(nghttp2_session *session) {
}
if (session->remote_window_size > 0) {
- return nghttp2_stream_next_outbound_item(&session->root);
+ item = nghttp2_stream_next_outbound_item(&session->root);
+ if (item) {
+ return item;
+ }
+
+ return session_sched_get_next_outbound_item(session);
}
return NULL;
@@ -2407,7 +2775,7 @@ static int session_call_on_frame_send(nghttp2_session *session,
return 0;
}
-static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) {
+static int find_stream_on_goaway_func(void *entry, void *ptr) {
nghttp2_close_stream_on_goaway_arg *arg;
nghttp2_stream *stream;
@@ -2481,10 +2849,20 @@ static int session_close_stream_on_goaway(nghttp2_session *session,
return 0;
}
-static void reschedule_stream(nghttp2_stream *stream) {
+static void session_reschedule_stream(nghttp2_session *session,
+ nghttp2_stream *stream) {
stream->last_writelen = stream->item->frame.hd.length;
- nghttp2_stream_reschedule(stream);
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
+ nghttp2_stream_reschedule(stream);
+ return;
+ }
+
+ if (!session->server) {
+ return;
+ }
+
+ session_sched_reschedule_stream(session, stream);
}
static int session_update_stream_consumed_size(nghttp2_session *session,
@@ -2494,14 +2872,6 @@ static int session_update_stream_consumed_size(nghttp2_session *session,
static int session_update_connection_consumed_size(nghttp2_session *session,
size_t delta_size);
-static int session_update_recv_connection_window_size(nghttp2_session *session,
- size_t delta_size);
-
-static int session_update_recv_stream_window_size(nghttp2_session *session,
- nghttp2_stream *stream,
- size_t delta_size,
- int send_window_update);
-
/*
* Called after a frame is sent. This function runs
* on_frame_send_callback and handles stream closure upon END_STREAM
@@ -2541,7 +2911,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
if (stream && aux_data->eof) {
- rv = nghttp2_stream_detach_item(stream);
+ rv = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -2666,9 +3036,8 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
}
case NGHTTP2_PRIORITY:
- if (session->server) {
+ if (session->server || session->pending_no_rfc7540_priorities == 1) {
return 0;
- ;
}
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
@@ -2735,7 +3104,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
rv = session_update_connection_consumed_size(session, 0);
} else {
- rv = session_update_recv_connection_window_size(session, 0);
+ rv = nghttp2_session_update_recv_connection_window_size(session, 0);
}
if (nghttp2_is_fatal(rv)) {
@@ -2761,7 +3130,8 @@ static int session_after_frame_sent1(nghttp2_session *session) {
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
rv = session_update_stream_consumed_size(session, stream, 0);
} else {
- rv = session_update_recv_stream_window_size(session, stream, 0, 1);
+ rv =
+ nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1);
}
if (nghttp2_is_fatal(rv)) {
@@ -2842,7 +3212,7 @@ static int session_after_frame_sent2(nghttp2_session *session) {
further data. */
if (nghttp2_session_predicate_data_send(session, stream) != 0) {
if (stream) {
- rv = nghttp2_stream_detach_item(stream);
+ rv = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -3140,7 +3510,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
- rv = nghttp2_stream_detach_item(stream);
+ rv = session_detach_stream_item(session, stream);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -3720,6 +4090,21 @@ static int session_end_stream_headers_received(nghttp2_session *session,
nghttp2_frame *frame,
nghttp2_stream *stream) {
int rv;
+
+ assert(frame->hd.type == NGHTTP2_HEADERS);
+
+ if (session->server && session_enforce_http_messaging(session) &&
+ frame->headers.cat == NGHTTP2_HCAT_REQUEST &&
+ (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
+ !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) &&
+ (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) {
+ rv = session_update_stream_priority(session, stream, stream->http_extpri);
+ if (rv != 0) {
+ assert(nghttp2_is_fatal(rv));
+ return rv;
+ }
+ }
+
if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
return 0;
}
@@ -4081,6 +4466,8 @@ int nghttp2_session_on_priority_received(nghttp2_session *session,
int rv;
nghttp2_stream *stream;
+ assert(!session_no_rfc7540_pri_no_fallback(session));
+
if (frame->hd.stream_id == 0) {
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
"PRIORITY: stream_id == 0");
@@ -4138,6 +4525,8 @@ static int session_process_priority_frame(nghttp2_session *session) {
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
+ assert(!session_no_rfc7540_pri_no_fallback(session));
+
nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos);
return nghttp2_session_on_priority_received(session, frame);
@@ -4184,8 +4573,7 @@ static int session_process_rst_stream_frame(nghttp2_session *session) {
return nghttp2_session_on_rst_stream_received(session, frame);
}
-static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
- void *ptr) {
+static int update_remote_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
@@ -4205,8 +4593,8 @@ static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
if (stream->remote_window_size > 0 &&
nghttp2_stream_check_deferred_by_flow_control(stream)) {
- rv = nghttp2_stream_resume_deferred_item(
- stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+ rv = session_resume_deferred_stream_item(
+ arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -4238,8 +4626,7 @@ session_update_remote_initial_window_size(nghttp2_session *session,
update_remote_initial_window_size_func, &arg);
}
-static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
- void *ptr) {
+static int update_local_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
@@ -4251,9 +4638,16 @@ static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
}
- if (!(arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
- stream->window_update_queued == 0 &&
- nghttp2_should_send_window_update(stream->local_window_size,
+
+ if (stream->window_update_queued) {
+ return 0;
+ }
+
+ if (arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
+ return session_update_stream_consumed_size(arg->session, stream, 0);
+ }
+
+ if (nghttp2_should_send_window_update(stream->local_window_size,
stream->recv_window_size)) {
rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE,
@@ -4374,6 +4768,9 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
session->local_settings.enable_connect_protocol = iv[i].value;
break;
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
+ session->local_settings.no_rfc7540_priorities = iv[i].value;
+ break;
}
}
@@ -4533,6 +4930,34 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
session->remote_settings.enable_connect_protocol = entry->value;
break;
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
+
+ if (entry->value != 0 && entry->value != 1) {
+ return session_handle_invalid_connection(
+ session, frame, NGHTTP2_ERR_PROTO,
+ "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES");
+ }
+
+ if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX &&
+ session->remote_settings.no_rfc7540_priorities != entry->value) {
+ return session_handle_invalid_connection(
+ session, frame, NGHTTP2_ERR_PROTO,
+ "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed");
+ }
+
+ session->remote_settings.no_rfc7540_priorities = entry->value;
+
+ break;
+ }
+ }
+
+ if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) {
+ session->remote_settings.no_rfc7540_priorities = 0;
+
+ if (session->server && session->pending_no_rfc7540_priorities &&
+ (session->opt_flags &
+ NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES)) {
+ session->fallback_rfc7540_priorities = 1;
}
}
@@ -4818,8 +5243,8 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
if (stream->remote_window_size > 0 &&
nghttp2_stream_check_deferred_by_flow_control(stream)) {
- rv = nghttp2_stream_resume_deferred_item(
- stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+ rv = session_resume_deferred_stream_item(
+ session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
if (nghttp2_is_fatal(rv)) {
return rv;
@@ -4890,6 +5315,80 @@ int nghttp2_session_on_origin_received(nghttp2_session *session,
return session_call_on_frame_received(session, frame);
}
+int nghttp2_session_on_priority_update_received(nghttp2_session *session,
+ nghttp2_frame *frame) {
+ nghttp2_ext_priority_update *priority_update;
+ nghttp2_stream *stream;
+ nghttp2_priority_spec pri_spec;
+ nghttp2_extpri extpri;
+ int rv;
+
+ assert(session->server);
+
+ priority_update = frame->ext.payload;
+
+ if (frame->hd.stream_id != 0) {
+ return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+ "PRIORITY_UPDATE: stream_id == 0");
+ }
+
+ if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) {
+ if (session_detect_idle_stream(session, priority_update->stream_id)) {
+ return session_handle_invalid_connection(
+ session, frame, NGHTTP2_ERR_PROTO,
+ "PRIORITY_UPDATE: prioritizing idle push is not allowed");
+ }
+
+ /* TODO Ignore priority signal to a push stream for now */
+ return session_call_on_frame_received(session, frame);
+ }
+
+ stream = nghttp2_session_get_stream_raw(session, priority_update->stream_id);
+ if (stream) {
+ /* Stream already exists. */
+ if (stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) {
+ return session_call_on_frame_received(session, frame);
+ }
+ } else if (session_detect_idle_stream(session, priority_update->stream_id)) {
+ if (session->num_idle_streams + session->num_incoming_streams >=
+ session->local_settings.max_concurrent_streams) {
+ return session_handle_invalid_connection(
+ session, frame, NGHTTP2_ERR_PROTO,
+ "PRIORITY_UPDATE: max concurrent streams exceeded");
+ }
+
+ nghttp2_priority_spec_default_init(&pri_spec);
+ stream = nghttp2_session_open_stream(session, priority_update->stream_id,
+ NGHTTP2_FLAG_NONE, &pri_spec,
+ NGHTTP2_STREAM_IDLE, NULL);
+ if (!stream) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+ } else {
+ return session_call_on_frame_received(session, frame);
+ }
+
+ extpri.urgency = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
+ extpri.inc = 0;
+
+ rv = nghttp2_http_parse_priority(&extpri, priority_update->field_value,
+ priority_update->field_value_len);
+ if (rv != 0) {
+ /* Just ignore field_value if it cannot be parsed. */
+ return session_call_on_frame_received(session, frame);
+ }
+
+ rv = session_update_stream_priority(session, stream,
+ nghttp2_extpri_to_uint8(&extpri));
+ if (rv != 0) {
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+ }
+
+ return session_call_on_frame_received(session, frame);
+}
+
static int session_process_altsvc_frame(nghttp2_session *session) {
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
@@ -4924,6 +5423,16 @@ static int session_process_origin_frame(nghttp2_session *session) {
return nghttp2_session_on_origin_received(session, frame);
}
+static int session_process_priority_update_frame(nghttp2_session *session) {
+ nghttp2_inbound_frame *iframe = &session->iframe;
+ nghttp2_frame *frame = &iframe->frame;
+
+ nghttp2_frame_unpack_priority_update_payload(&frame->ext, iframe->sbuf.pos,
+ nghttp2_buf_len(&iframe->sbuf));
+
+ return nghttp2_session_on_priority_update_received(session, frame);
+}
+
static int session_process_extension_frame(nghttp2_session *session) {
int rv;
nghttp2_inbound_frame *iframe = &session->iframe;
@@ -5019,22 +5528,10 @@ static int adjust_recv_window_size(int32_t *recv_window_size_ptr, size_t delta,
return 0;
}
-/*
- * Accumulates received bytes |delta_size| for stream-level flow
- * control and decides whether to send WINDOW_UPDATE to that stream.
- * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
- * be sent.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
- */
-static int session_update_recv_stream_window_size(nghttp2_session *session,
- nghttp2_stream *stream,
- size_t delta_size,
- int send_window_update) {
+int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
+ nghttp2_stream *stream,
+ size_t delta_size,
+ int send_window_update) {
int rv;
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
stream->local_window_size);
@@ -5063,20 +5560,8 @@ static int session_update_recv_stream_window_size(nghttp2_session *session,
return 0;
}
-/*
- * Accumulates received bytes |delta_size| for connection-level flow
- * control and decides whether to send WINDOW_UPDATE to the
- * connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
- * WINDOW_UPDATE will not be sent.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
- */
-static int session_update_recv_connection_window_size(nghttp2_session *session,
- size_t delta_size) {
+int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session,
+ size_t delta_size) {
int rv;
rv = adjust_recv_window_size(&session->recv_window_size, delta_size,
session->local_window_size);
@@ -5285,6 +5770,7 @@ static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
break;
default:
DEBUGF("recv: unknown settings id=0x%02x\n", iv.settings_id);
@@ -5357,7 +5843,7 @@ static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
/*
* This function returns the effective payload length in the data of
- * length |readlen| when the remaning payload is |payloadleft|. The
+ * length |readlen| when the remaining payload is |payloadleft|. The
* |payloadleft| does not include |readlen|. If padding was started
* strictly before this data chunk, this function returns -1.
*/
@@ -5378,9 +5864,11 @@ static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
return (ssize_t)(readlen);
}
+static const uint8_t static_in[] = {0};
+
ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
size_t inlen) {
- const uint8_t *first = in, *last = in + inlen;
+ const uint8_t *first, *last;
nghttp2_inbound_frame *iframe = &session->iframe;
size_t readlen;
ssize_t padlen;
@@ -5391,6 +5879,14 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
size_t pri_fieldlen;
nghttp2_mem *mem;
+ if (in == NULL) {
+ assert(inlen == 0);
+ in = static_in;
+ }
+
+ first = in;
+ last = in + inlen;
+
DEBUGF("recv: connection recv_window_size=%d, local_window=%d\n",
session->recv_window_size, session->local_window_size);
@@ -5678,6 +6174,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
}
+ /* Check the settings flood counter early to be safe */
+ if (session->obq_flood_counter_ >= session->max_outbound_ack &&
+ !(iframe->frame.hd.flags & NGHTTP2_FLAG_ACK)) {
+ return NGHTTP2_ERR_FLOODED;
+ }
+
iframe->state = NGHTTP2_IB_READ_SETTINGS;
if (iframe->payloadleft) {
@@ -5688,6 +6190,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->max_niv =
iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
+ if (iframe->max_niv - 1 > session->max_settings) {
+ rv = nghttp2_session_terminate_session_with_reason(
+ session, NGHTTP2_ENHANCE_YOUR_CALM,
+ "SETTINGS: too many setting entries");
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+ return (ssize_t)inlen;
+ }
+
iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
iframe->max_niv);
@@ -5873,6 +6385,49 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->state = NGHTTP2_IB_READ_ORIGIN_PAYLOAD;
break;
+ case NGHTTP2_PRIORITY_UPDATE:
+ if ((session->builtin_recv_ext_types &
+ NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
+ busy = 1;
+ iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+ break;
+ }
+
+ DEBUGF("recv: PRIORITY_UPDATE\n");
+
+ iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+ iframe->frame.ext.payload =
+ &iframe->ext_frame_payload.priority_update;
+
+ if (!session->server) {
+ rv = nghttp2_session_terminate_session_with_reason(
+ session, NGHTTP2_PROTOCOL_ERROR,
+ "PRIORITY_UPDATE is received from server");
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+ return (ssize_t)inlen;
+ }
+
+ if (iframe->payloadleft < 4) {
+ busy = 1;
+ iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+ break;
+ }
+
+ if (!session_no_rfc7540_pri_no_fallback(session) ||
+ iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
+ busy = 1;
+ iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+ break;
+ }
+
+ busy = 1;
+
+ iframe->state = NGHTTP2_IB_READ_NBYTE;
+ inbound_frame_set_mark(iframe, iframe->payloadleft);
+
+ break;
default:
busy = 1;
@@ -5978,13 +6533,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
case NGHTTP2_PRIORITY:
- rv = session_process_priority_frame(session);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
+ if (!session_no_rfc7540_pri_no_fallback(session) &&
+ session->remote_settings.no_rfc7540_priorities != 1) {
+ rv = session_process_priority_frame(session);
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
- if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+ return (ssize_t)inlen;
+ }
}
session_inbound_frame_reset(session);
@@ -6141,6 +6699,18 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->state = NGHTTP2_IB_READ_ALTSVC_PAYLOAD;
break;
+ case NGHTTP2_PRIORITY_UPDATE:
+ DEBUGF("recv: prioritized_stream_id=%d\n",
+ nghttp2_get_uint32(iframe->sbuf.pos) & NGHTTP2_STREAM_ID_MASK);
+
+ rv = session_process_priority_update_frame(session);
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+
+ session_inbound_frame_reset(session);
+
+ break;
}
default:
/* This is unknown frame */
@@ -6420,8 +6990,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
/* CONTINUATION won't bear NGHTTP2_PADDED flag */
- iframe->frame.hd.flags = (uint8_t)(
- iframe->frame.hd.flags | (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
+ iframe->frame.hd.flags =
+ (uint8_t)(iframe->frame.hd.flags |
+ (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
iframe->frame.hd.length += cont_hd.length;
busy = 1;
@@ -6454,7 +7025,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
/* Pad Length field is subject to flow control */
- rv = session_update_recv_connection_window_size(session, readlen);
+ rv = nghttp2_session_update_recv_connection_window_size(session, readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6477,7 +7048,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
if (stream) {
- rv = session_update_recv_stream_window_size(
+ rv = nghttp2_session_update_recv_stream_window_size(
session, stream, readlen,
iframe->payloadleft ||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
@@ -6524,7 +7095,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (readlen > 0) {
ssize_t data_readlen;
- rv = session_update_recv_connection_window_size(session, readlen);
+ rv = nghttp2_session_update_recv_connection_window_size(session,
+ readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6533,7 +7105,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
return (ssize_t)inlen;
}
- rv = session_update_recv_stream_window_size(
+ rv = nghttp2_session_update_recv_stream_window_size(
session, stream, readlen,
iframe->payloadleft ||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
@@ -6634,7 +7206,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (readlen > 0) {
/* Update connection-level flow control window for ignored
DATA frame too */
- rv = session_update_recv_connection_window_size(session, readlen);
+ rv = nghttp2_session_update_recv_connection_window_size(session,
+ readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6850,7 +7423,8 @@ int nghttp2_session_want_write(nghttp2_session *session) {
*/
return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) ||
nghttp2_outbound_queue_top(&session->ob_reg) ||
- (!nghttp2_pq_empty(&session->root.obq) &&
+ ((!nghttp2_pq_empty(&session->root.obq) ||
+ !session_sched_empty(session)) &&
session->remote_window_size > 0) ||
(nghttp2_outbound_queue_top(&session->ob_syn) &&
!session_is_outgoing_concurrent_streams_max(session));
@@ -7003,6 +7577,7 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
int rv;
nghttp2_mem *mem;
nghttp2_inflight_settings *inflight_settings = NULL;
+ uint8_t no_rfc7540_pri = session->pending_no_rfc7540_priorities;
mem = &session->mem;
@@ -7020,6 +7595,21 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
+ for (i = 0; i < niv; ++i) {
+ if (iv[i].settings_id != NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES) {
+ continue;
+ }
+
+ if (no_rfc7540_pri == UINT8_MAX) {
+ no_rfc7540_pri = (uint8_t)iv[i].value;
+ continue;
+ }
+
+ if (iv[i].value != (uint32_t)no_rfc7540_pri) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+ }
+
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
return NGHTTP2_ERR_NOMEM;
@@ -7094,6 +7684,12 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
}
}
+ if (no_rfc7540_pri == UINT8_MAX) {
+ session->pending_no_rfc7540_priorities = 0;
+ } else {
+ session->pending_no_rfc7540_priorities = no_rfc7540_pri;
+ }
+
return 0;
}
@@ -7222,7 +7818,7 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
return rv;
}
- reschedule_stream(stream);
+ session_reschedule_stream(session, stream);
if (frame->hd.length == 0 && (data_flags & NGHTTP2_DATA_FLAG_EOF) &&
(data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM)) {
@@ -7296,7 +7892,7 @@ int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
- rv = nghttp2_stream_resume_deferred_item(stream,
+ rv = session_resume_deferred_stream_item(session, stream,
NGHTTP2_STREAM_FLAG_DEFERRED_USER);
if (nghttp2_is_fatal(rv)) {
@@ -7404,6 +8000,8 @@ uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
return session->remote_settings.max_header_list_size;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
return session->remote_settings.enable_connect_protocol;
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
+ return session->remote_settings.no_rfc7540_priorities;
}
assert(0);
@@ -7427,6 +8025,8 @@ uint32_t nghttp2_session_get_local_settings(nghttp2_session *session,
return session->local_settings.max_header_list_size;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
return session->local_settings.enable_connect_protocol;
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
+ return session->local_settings.no_rfc7540_priorities;
}
assert(0);
@@ -7454,6 +8054,11 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
+ /* SETTINGS frame contains too many settings */
+ if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH >
+ session->max_settings) {
+ return NGHTTP2_ERR_TOO_MANY_SETTINGS;
+ }
rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
settings_payloadlen, mem);
if (rv != 0) {
@@ -7705,6 +8310,10 @@ int nghttp2_session_change_stream_priority(
nghttp2_stream *stream;
nghttp2_priority_spec pri_spec_copy;
+ if (session->pending_no_rfc7540_priorities == 1) {
+ return 0;
+ }
+
if (stream_id == 0 || stream_id == pri_spec->stream_id) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
@@ -7737,6 +8346,10 @@ int nghttp2_session_create_idle_stream(nghttp2_session *session,
nghttp2_stream *stream;
nghttp2_priority_spec pri_spec_copy;
+ if (session->pending_no_rfc7540_priorities == 1) {
+ return 0;
+ }
+
if (stream_id == 0 || stream_id == pri_spec->stream_id ||
!session_detect_idle_stream(session, stream_id)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
@@ -7778,3 +8391,38 @@ nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session) {
void nghttp2_session_set_user_data(nghttp2_session *session, void *user_data) {
session->user_data = user_data;
}
+
+int nghttp2_session_change_extpri_stream_priority(
+ nghttp2_session *session, int32_t stream_id,
+ const nghttp2_extpri *extpri_in, int ignore_client_signal) {
+ nghttp2_stream *stream;
+ nghttp2_extpri extpri = *extpri_in;
+
+ if (!session->server) {
+ return NGHTTP2_ERR_INVALID_STATE;
+ }
+
+ if (session->pending_no_rfc7540_priorities != 1) {
+ return 0;
+ }
+
+ if (stream_id == 0) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ stream = nghttp2_session_get_stream_raw(session, stream_id);
+ if (!stream) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ if (extpri.urgency > NGHTTP2_EXTPRI_URGENCY_LOW) {
+ extpri.urgency = NGHTTP2_EXTPRI_URGENCY_LOW;
+ }
+
+ if (ignore_client_signal) {
+ stream->flags |= NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES;
+ }
+
+ return session_update_stream_priority(session, stream,
+ nghttp2_extpri_to_uint8(&extpri));
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.h b/Utilities/cmnghttp2/lib/nghttp2_session.h
index 90ead9c..34d2d58 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_session.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.h
@@ -52,7 +52,9 @@ typedef enum {
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3,
- NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4
+ NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4,
+ NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5,
+ NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6,
} nghttp2_optmask;
/*
@@ -62,7 +64,8 @@ typedef enum {
typedef enum {
NGHTTP2_TYPEMASK_NONE = 0,
NGHTTP2_TYPEMASK_ALTSVC = 1 << 0,
- NGHTTP2_TYPEMASK_ORIGIN = 1 << 1
+ NGHTTP2_TYPEMASK_ORIGIN = 1 << 1,
+ NGHTTP2_TYPEMASK_PRIORITY_UPDATE = 1 << 2
} nghttp2_typemask;
typedef enum {
@@ -151,10 +154,8 @@ typedef struct {
/* padding length for the current frame */
size_t padlen;
nghttp2_inbound_state state;
- /* Small buffer. Currently the largest contiguous chunk to buffer
- is frame header. We buffer part of payload, but they are smaller
- than frame header. */
- uint8_t raw_sbuf[NGHTTP2_FRAME_HDLEN];
+ /* Small fixed sized buffer. */
+ uint8_t raw_sbuf[32];
} nghttp2_inbound_frame;
typedef struct {
@@ -165,6 +166,7 @@ typedef struct {
uint32_t max_frame_size;
uint32_t max_header_list_size;
uint32_t enable_connect_protocol;
+ uint32_t no_rfc7540_priorities;
} nghttp2_settings_storage;
typedef enum {
@@ -202,6 +204,12 @@ struct nghttp2_session {
response) frame, which are subject to
SETTINGS_MAX_CONCURRENT_STREAMS limit. */
nghttp2_outbound_queue ob_syn;
+ /* Queues for DATA frames which is used when
+ SETTINGS_NO_RFC7540_PRIORITIES is enabled. This implements RFC
+ 9218 extensible prioritization scheme. */
+ struct {
+ nghttp2_pq ob_data;
+ } sched[NGHTTP2_EXTPRI_URGENCY_LEVELS];
nghttp2_active_outbound_item aob;
nghttp2_inbound_frame iframe;
nghttp2_hd_deflater hd_deflater;
@@ -227,6 +235,9 @@ struct nghttp2_session {
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
considered as in-flight. */
nghttp2_inflight_settings *inflight_settings_head;
+ /* Sequential number across all streams to process streams in
+ FIFO. */
+ uint64_t stream_seq;
/* The number of outgoing streams. This will be capped by
remote_settings.max_concurrent_streams. */
size_t num_outgoing_streams;
@@ -267,6 +278,8 @@ struct nghttp2_session {
/* The maximum length of header block to send. Calculated by the
same way as nghttp2_hd_deflate_bound() does. */
size_t max_send_header_block_length;
+ /* The maximum number of settings accepted per SETTINGS frame. */
+ size_t max_settings;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,
@@ -326,6 +339,11 @@ struct nghttp2_session {
/* Unacked local ENABLE_CONNECT_PROTOCOL value. We use this to
accept :protocol header field before SETTINGS_ACK is received. */
uint8_t pending_enable_connect_protocol;
+ /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is
+ effective before it is acknowledged. */
+ uint8_t pending_no_rfc7540_priorities;
+ /* Turn on fallback to RFC 7540 priorities; for server use only. */
+ uint8_t fallback_rfc7540_priorities;
/* Nonzero if the session is server side. */
uint8_t server;
/* Flags indicating GOAWAY is sent and/or received. The flags are
@@ -406,7 +424,7 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
uint32_t error_code);
/*
- * Adds PING frame. This is a convenient functin built on top of
+ * Adds PING frame. This is a convenient function built on top of
* nghttp2_session_add_frame() to add PING easily.
*
* If the |opaque_data| is not NULL, it must point to 8 bytes memory
@@ -772,6 +790,19 @@ int nghttp2_session_on_origin_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
+ * Called when PRIORITY_UPDATE is received, assuming |frame| is
+ * properly initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ * The callback function failed.
+ */
+int nghttp2_session_on_priority_update_received(nghttp2_session *session,
+ nghttp2_frame *frame);
+
+/*
* Called when DATA is received, assuming |frame| is properly
* initialized.
*
@@ -898,4 +929,36 @@ int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
uint32_t error_code,
const char *reason);
+/*
+ * Accumulates received bytes |delta_size| for connection-level flow
+ * control and decides whether to send WINDOW_UPDATE to the
+ * connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
+ * WINDOW_UPDATE will not be sent.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session,
+ size_t delta_size);
+
+/*
+ * Accumulates received bytes |delta_size| for stream-level flow
+ * control and decides whether to send WINDOW_UPDATE to that stream.
+ * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
+ * be sent.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ * Out of memory.
+ */
+int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
+ nghttp2_stream *stream,
+ size_t delta_size,
+ int send_window_update);
+
#endif /* NGHTTP2_SESSION_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.c b/Utilities/cmnghttp2/lib/nghttp2_stream.c
index dc3a6b1..b3614a0 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_stream.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.c
@@ -33,7 +33,7 @@
#include "nghttp2_frame.h"
/* Maximum distance between any two stream's cycle in the same
- prirority queue. Imagine stream A's cycle is A, and stream B's
+ priority queue. Imagine stream A's cycle is A, and stream B's
cycle is B, and A < B. The cycle is unsigned 32 bit integer, it
may get overflow. Because of how we calculate the next cycle
value, if B - A is less than or equals to
@@ -62,7 +62,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
int32_t weight, int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem) {
- nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id);
nghttp2_pq_init(&stream->obq, stream_less, mem);
stream->stream_id = stream_id;
@@ -101,6 +100,8 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream->descendant_next_seq = 0;
stream->seq = 0;
stream->last_writelen = 0;
+
+ stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
}
void nghttp2_stream_free(nghttp2_stream *stream) {
@@ -485,6 +486,10 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
stream->item = item;
+ if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
+ return 0;
+ }
+
rv = stream_update_dep_on_attach_item(stream);
if (rv != 0) {
/* This may relave stream->queued == 1, but stream->item == NULL.
@@ -504,6 +509,10 @@ int nghttp2_stream_detach_item(nghttp2_stream *stream) {
stream->item = NULL;
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
+ if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
+ return 0;
+ }
+
return stream_update_dep_on_detach_item(stream);
}
@@ -515,6 +524,10 @@ int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
stream->flags |= flags;
+ if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
+ return 0;
+ }
+
return stream_update_dep_on_detach_item(stream);
}
@@ -530,6 +543,10 @@ int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
return 0;
}
+ if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
+ return 0;
+ }
+
return stream_update_dep_on_attach_item(stream);
}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.h b/Utilities/cmnghttp2/lib/nghttp2_stream.h
index a1b807d..7a8e4c6 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_stream.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.h
@@ -90,8 +90,15 @@ typedef enum {
NGHTTP2_STREAM_FLAG_DEFERRED_USER = 0x08,
/* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
- NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c
-
+ NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c,
+ /* Indicates that this stream is not subject to RFC7540
+ priorities scheme. */
+ NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10,
+ /* Ignore client RFC 9218 priority signal. */
+ NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20,
+ /* Indicates that RFC 9113 leading and trailing white spaces
+ validation against a field value is not performed. */
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 0x40,
} nghttp2_stream_flag;
/* HTTP related flags to enforce HTTP semantics */
@@ -132,11 +139,14 @@ typedef enum {
/* set if final response is expected */
NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14,
NGHTTP2_HTTP_FLAG__PROTOCOL = 1 << 15,
+ /* set if priority header field is received */
+ NGHTTP2_HTTP_FLAG_PRIORITY = 1 << 16,
+ /* set if an error is encountered while parsing priority header
+ field */
+ NGHTTP2_HTTP_FLAG_BAD_PRIORITY = 1 << 17,
} nghttp2_http_flag;
struct nghttp2_stream {
- /* Intrusive Map */
- nghttp2_map_entry map_entry;
/* Entry for dep_prev->obq */
nghttp2_pq_entry pq_entry;
/* Priority Queue storing direct descendant (nghttp2_stream). Only
@@ -206,7 +216,7 @@ struct nghttp2_stream {
/* status code from remote server */
int16_t status_code;
/* Bitwise OR of zero or more nghttp2_http_flag values */
- uint16_t http_flags;
+ uint32_t http_flags;
/* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */
uint8_t flags;
/* Bitwise OR of zero or more nghttp2_shut_flag values */
@@ -220,6 +230,12 @@ struct nghttp2_stream {
this stream. The nonzero does not necessarily mean WINDOW_UPDATE
is not queued. */
uint8_t window_update_queued;
+ /* extpri is a stream priority produced by nghttp2_extpri_to_uint8
+ used by RFC 9218 extensible priorities. */
+ uint8_t extpri;
+ /* http_extpri is a stream priority received in HTTP request header
+ fields and produced by nghttp2_extpri_to_uint8. */
+ uint8_t http_extpri;
};
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.c b/Utilities/cmnghttp2/lib/nghttp2_submit.c
index f604eff..f5554eb 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_submit.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_submit.c
@@ -196,7 +196,8 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
flags &= NGHTTP2_FLAG_END_STREAM;
- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
+ if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
+ session->remote_settings.no_rfc7540_priorities != 1) {
rv = detect_self_dependency(session, stream_id, pri_spec);
if (rv != 0) {
return rv;
@@ -229,6 +230,10 @@ int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
mem = &session->mem;
+ if (session->remote_settings.no_rfc7540_priorities == 1) {
+ return 0;
+ }
+
if (stream_id == 0 || pri_spec == NULL) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
@@ -450,6 +455,13 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
if (rv != 0) {
return rv;
}
+
+ if (window_size_increment > 0) {
+ return nghttp2_session_add_window_update(session, 0, stream_id,
+ window_size_increment);
+ }
+
+ return nghttp2_session_update_recv_connection_window_size(session, 0);
} else {
stream = nghttp2_session_get_stream(session, stream_id);
@@ -476,14 +488,15 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
if (rv != 0) {
return rv;
}
- }
- if (window_size_increment > 0) {
- return nghttp2_session_add_window_update(session, 0, stream_id,
- window_size_increment);
- }
+ if (window_size_increment > 0) {
+ return nghttp2_session_add_window_update(session, 0, stream_id,
+ window_size_increment);
+ }
- return 0;
+ return nghttp2_session_update_recv_stream_window_size(session, stream, 0,
+ 1);
+ }
}
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
@@ -654,6 +667,78 @@ fail_item_malloc:
return rv;
}
+int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *field_value,
+ size_t field_value_len) {
+ nghttp2_mem *mem;
+ uint8_t *buf, *p;
+ nghttp2_outbound_item *item;
+ nghttp2_frame *frame;
+ nghttp2_ext_priority_update *priority_update;
+ int rv;
+ (void)flags;
+
+ mem = &session->mem;
+
+ if (session->server) {
+ return NGHTTP2_ERR_INVALID_STATE;
+ }
+
+ if (session->remote_settings.no_rfc7540_priorities == 0) {
+ return 0;
+ }
+
+ if (stream_id == 0 || 4 + field_value_len > NGHTTP2_MAX_PAYLOADLEN) {
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+ }
+
+ if (field_value_len) {
+ buf = nghttp2_mem_malloc(mem, field_value_len + 1);
+ if (buf == NULL) {
+ return NGHTTP2_ERR_NOMEM;
+ }
+
+ p = nghttp2_cpymem(buf, field_value, field_value_len);
+ *p = '\0';
+ } else {
+ buf = NULL;
+ }
+
+ item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+ if (item == NULL) {
+ rv = NGHTTP2_ERR_NOMEM;
+ goto fail_item_malloc;
+ }
+
+ nghttp2_outbound_item_init(item);
+
+ item->aux_data.ext.builtin = 1;
+
+ priority_update = &item->ext_frame_payload.priority_update;
+
+ frame = &item->frame;
+ frame->ext.payload = priority_update;
+
+ nghttp2_frame_priority_update_init(&frame->ext, stream_id, buf,
+ field_value_len);
+
+ rv = nghttp2_session_add_item(session, item);
+ if (rv != 0) {
+ nghttp2_frame_priority_update_free(&frame->ext, mem);
+ nghttp2_mem_free(mem, item);
+
+ return rv;
+ }
+
+ return 0;
+
+fail_item_malloc:
+ free(buf);
+
+ return rv;
+}
+
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
const nghttp2_data_provider *data_prd) {
uint8_t flags = NGHTTP2_FLAG_NONE;
@@ -680,7 +765,8 @@ int32_t nghttp2_submit_request(nghttp2_session *session,
return NGHTTP2_ERR_PROTO;
}
- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
+ if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
+ session->remote_settings.no_rfc7540_priorities != 1) {
rv = detect_self_dependency(session, -1, pri_spec);
if (rv != 0) {
return rv;