From 88ee9316f52102fed3f7567569a04c14327c514e Mon Sep 17 00:00:00 2001 From: Alexander Neumann <30894796+Neumann-A@users.noreply.github.com> Date: Thu, 25 Jul 2024 22:53:34 +0200 Subject: [PATCH] Add VCPKG_POST_PORTFILE_INCLUDES (#1417) --- .../invalid.extension | 0 .../post-portfile-includes.cmake | 9 +++++ .../portfile.cmake | 1 + .../vcpkg-post-portfile-includes/vcpkg.json | 5 +++ .../post-portfile-includes.cmake | 9 +++++ .../post-portfile-includes/test1.cmake | 2 ++ .../post-portfile-includes/test2.cmake | 10 ++++++ .../portfile.cmake | 35 +++++++++++++++++++ .../vcpkg-post-portfile-includes/vcpkg.json | 5 +++ .../post-portfile-includes.ps1 | 23 ++++++++++++ include/vcpkg/base/contractual-constants.h | 2 ++ include/vcpkg/base/message-data.inc.h | 5 +++ include/vcpkg/commands.build.h | 1 + locales/messages.json | 2 ++ src/vcpkg/cmakevars.cpp | 1 + src/vcpkg/commands.build.cpp | 28 +++++++++++++++ 16 files changed, 138 insertions(+) create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes-fail/invalid.extension create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes-fail/post-portfile-includes.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/portfile.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/vcpkg.json create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes/post-portfile-includes.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes/test1.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes/test2.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/portfile.cmake create mode 100644 azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/vcpkg.json create mode 100644 azure-pipelines/end-to-end-tests-dir/post-portfile-includes.ps1 diff --git a/azure-pipelines/e2e-ports/post-portfile-includes-fail/invalid.extension b/azure-pipelines/e2e-ports/post-portfile-includes-fail/invalid.extension new file mode 100644 index 0000000000..e69de29bb2 diff --git a/azure-pipelines/e2e-ports/post-portfile-includes-fail/post-portfile-includes.cmake b/azure-pipelines/e2e-ports/post-portfile-includes-fail/post-portfile-includes.cmake new file mode 100644 index 0000000000..b1c0ae4cc5 --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes-fail/post-portfile-includes.cmake @@ -0,0 +1,9 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) +if(APPLE) +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +elseif(UNIX) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +endif() +set(VCPKG_POST_PORTFILE_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/invalid.extension") diff --git a/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/portfile.cmake b/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/vcpkg.json b/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/vcpkg.json new file mode 100644 index 0000000000..415862a95c --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes-fail/vcpkg-post-portfile-includes/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "vcpkg-post-portfile-includes", + "version": "0", + "description": "A port to test post portfile includes" +} diff --git a/azure-pipelines/e2e-ports/post-portfile-includes/post-portfile-includes.cmake b/azure-pipelines/e2e-ports/post-portfile-includes/post-portfile-includes.cmake new file mode 100644 index 0000000000..2730c5c44d --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes/post-portfile-includes.cmake @@ -0,0 +1,9 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) +if(APPLE) +set(VCPKG_CMAKE_SYSTEM_NAME Darwin) +elseif(UNIX) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +endif() +set(VCPKG_POST_PORTFILE_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/test1.cmake;${CMAKE_CURRENT_LIST_DIR}/test2.cmake") diff --git a/azure-pipelines/e2e-ports/post-portfile-includes/test1.cmake b/azure-pipelines/e2e-ports/post-portfile-includes/test1.cmake new file mode 100644 index 0000000000..f07492d765 --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes/test1.cmake @@ -0,0 +1,2 @@ +# Just a random comment +set(VCPKG_POST_INCLUDE_CHECK_TEST2 ON) diff --git a/azure-pipelines/e2e-ports/post-portfile-includes/test2.cmake b/azure-pipelines/e2e-ports/post-portfile-includes/test2.cmake new file mode 100644 index 0000000000..f7c444cf0c --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes/test2.cmake @@ -0,0 +1,10 @@ + +if(NOT VCPKG_POST_INCLUDE_CHECK_TEST1) + message(FATAL_ERROR "VCPKG_POST_INCLUDE_CHECK_TEST1 failed") +endif() + +if(NOT VCPKG_POST_INCLUDE_CHECK_TEST2) + message(FATAL_ERROR "VCPKG_POST_INCLUDE_CHECK_TEST2 failed") +endif() + +message(STATUS "VCPKG_POST_INCLUDE_CHECK_TEST successful") diff --git a/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/portfile.cmake b/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/portfile.cmake new file mode 100644 index 0000000000..fdb9d01e11 --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/portfile.cmake @@ -0,0 +1,35 @@ +file(STRINGS "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}.vcpkg_abi_info.txt" lines) +list(FILTER lines INCLUDE REGEX "post_portfile_include_(0|1)") +list(GET lines 0 first_line) +list(GET lines 1 second_line) + +set(expected1 "post_portfile_include_0 ad6ac07ed1e066eaf23af161afb36b25a3ec03af49cd3e52ceb3a91d388f23f8") +set(expected2 "post_portfile_include_1 f8b37330094530b0fc7a5606fea7b491ec0e67edd1fd8f7e1a5607f7be0a3ff2") + +if(first_line STREQUAL "${expected1}") + message(STATUS "ABI hash succesful!") +else() + message(FATAL_ERROR "First line in abi info is not the post include file to be hashed but:\n first_line: '${first_line}'\n expected: '${expected1}' ") +endif() +if(second_line STREQUAL "${expected2}") + message(STATUS "ABI hash succesful!") +else() + message(FATAL_ERROR "Second line in abi info is not the second post include file to be hashed but:\n second_line: '${second_line}'\n expected: '${expected2}' ") +endif() + +if(NOT Z_VCPKG_POST_PORTFILE_INCLUDES) + message(FATAL_ERROR "Variable Z_VCPKG_POST_PORTFILE_INCLUDES not set by vcpkg-tool!") +endif() + +set(path1 "${CMAKE_CURRENT_LIST_DIR}/../test1.cmake") +cmake_path(NORMAL_PATH path1) +set(path2 "${CMAKE_CURRENT_LIST_DIR}/../test2.cmake") +cmake_path(NORMAL_PATH path2) + +if(NOT Z_VCPKG_POST_PORTFILE_INCLUDES STREQUAL "${path1};${path2}") + message(FATAL_ERROR "Z_VCPKG_POST_PORTFILE_INCLUDES ist not equal to '${path1};${path2}' (Z_VCPKG_POST_PORTFILE_INCLUDES:'${Z_VCPKG_POST_PORTFILE_INCLUDES}') ") +endif() + +set(VCPKG_POST_INCLUDE_CHECK_TEST1 ON) + +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/vcpkg.json b/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/vcpkg.json new file mode 100644 index 0000000000..415862a95c --- /dev/null +++ b/azure-pipelines/e2e-ports/post-portfile-includes/vcpkg-post-portfile-includes/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "vcpkg-post-portfile-includes", + "version": "0", + "description": "A port to test post portfile includes" +} diff --git a/azure-pipelines/end-to-end-tests-dir/post-portfile-includes.ps1 b/azure-pipelines/end-to-end-tests-dir/post-portfile-includes.ps1 new file mode 100644 index 0000000000..a13e2aa061 --- /dev/null +++ b/azure-pipelines/end-to-end-tests-dir/post-portfile-includes.ps1 @@ -0,0 +1,23 @@ +. $PSScriptRoot/../end-to-end-tests-prelude.ps1 + +Run-Vcpkg @directoryArgs ` + "--overlay-triplets=$PSScriptRoot/../e2e-ports/post-portfile-includes" ` + "--overlay-ports=$PSScriptRoot/../e2e-ports/post-portfile-includes" ` + x-set-installed ` + vcpkg-post-portfile-includes ` + --host-triplet post-portfile-includes ` + --binarysource=clear +Throw-IfFailed + +$output = Run-VcpkgAndCaptureOutput @directoryArgs ` + "--overlay-triplets=$PSScriptRoot/../e2e-ports/post-portfile-includes-fail" ` + "--overlay-ports=$PSScriptRoot/../e2e-ports/post-portfile-includes-fail" ` + x-set-installed ` + vcpkg-post-portfile-includes ` + --host-triplet post-portfile-includes ` + --binarysource=clear +Throw-IfNotFailed +if ($output -notmatch "Variable VCPKG_POST_PORTFILE_INCLUDES contains invalid file path") +{ + throw "Expected to fail since VCPKG_POST_PORTFILE_INCLUDES is set to a relative path" +} diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index 4df94fa7d2..e637a800db 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -409,6 +409,7 @@ namespace vcpkg inline constexpr StringLiteral CMakeVariablePolicySkipUsageInstallCheck = "VCPKG_POLICY_SKIP_USAGE_INSTALL_CHECK"; inline constexpr StringLiteral CMakeVariablePort = "PORT"; inline constexpr StringLiteral CMakeVariablePortConfigs = "VCPKG_PORT_CONFIGS"; + inline constexpr StringLiteral CMakeVariablePostPortfileIncludes = "VCPKG_POST_PORTFILE_INCLUDES"; inline constexpr StringLiteral CMakeVariableProhibitBackcompatFeatures = "_VCPKG_PROHIBIT_BACKCOMPAT_FEATURES"; inline constexpr StringLiteral CMakeVariablePublicAbiOverride = "VCPKG_PUBLIC_ABI_OVERRIDE"; inline constexpr StringLiteral CMakeVariableRef = "REF"; @@ -425,6 +426,7 @@ namespace vcpkg inline constexpr StringLiteral CMakeVariableXBoxConsoleTarget = "VCPKG_XBOX_CONSOLE_TARGET"; inline constexpr StringLiteral CMakeVariableZChainloadToolchainFile = "Z_VCPKG_CHAINLOAD_TOOLCHAIN_FILE"; inline constexpr StringLiteral CMakeVariableZVcpkgGameDKLatest = "Z_VCPKG_GameDKLatest"; + inline constexpr StringLiteral CMakeVariableZPostPortfileIncludes = "Z_VCPKG_POST_PORTFILE_INCLUDES"; // Policies are PascalCase inline constexpr StringLiteral PolicyAllowDebugInclude = "PolicyAllowDebugInclude"; diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index ba588a3469..8b9f9b10d9 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1913,6 +1913,11 @@ DECLARE_MESSAGE(InvalidValueHashAdditionalFiles, "", "Variable VCPKG_HASH_ADDITIONAL_FILES contains invalid file path: '{path}'. The value must be " "an absolute path to an existent file.") +DECLARE_MESSAGE(InvalidValuePostPortfileIncludes, + (msg::path), + "", + "Variable VCPKG_POST_PORTFILE_INCLUDES contains invalid file path: '{path}'. The value must be " + "an absolute path to an existent cmake file.") DECLARE_MESSAGE(IrregularFile, (msg::path), "", "path was not a regular file: {path}") DECLARE_MESSAGE(JsonErrorMustBeAnObject, (msg::path), "", "Expected \"{path}\" to be an object.") DECLARE_MESSAGE(JsonFieldNotObject, (msg::json_field), "", "value of [\"{json_field}\"] must be an object") diff --git a/include/vcpkg/commands.build.h b/include/vcpkg/commands.build.h index c976e682ed..747c130141 100644 --- a/include/vcpkg/commands.build.h +++ b/include/vcpkg/commands.build.h @@ -132,6 +132,7 @@ namespace vcpkg std::vector passthrough_env_vars; std::vector passthrough_env_vars_tracked; std::vector hash_additional_files; + std::vector post_portfile_includes; Optional gamedk_latest_path; Path toolchain_file() const; diff --git a/locales/messages.json b/locales/messages.json index 4139c7d9c1..aa72058691 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -1061,6 +1061,8 @@ "_InvalidUri.comment": "{value} is the URI we attempted to parse.", "InvalidValueHashAdditionalFiles": "Variable VCPKG_HASH_ADDITIONAL_FILES contains invalid file path: '{path}'. The value must be an absolute path to an existent file.", "_InvalidValueHashAdditionalFiles.comment": "An example of {path} is /foo/bar.", + "InvalidValuePostPortfileIncludes": "Variable VCPKG_POST_PORTFILE_INCLUDES contains invalid file path: '{path}'. The value must be an absolute path to an existent cmake file.", + "_InvalidValuePostPortfileIncludes.comment": "An example of {path} is /foo/bar.", "IrregularFile": "path was not a regular file: {path}", "_IrregularFile.comment": "An example of {path} is /foo/bar.", "JsonErrorMustBeAnObject": "Expected \"{path}\" to be an object.", diff --git a/src/vcpkg/cmakevars.cpp b/src/vcpkg/cmakevars.cpp index 1c321a0d78..6e9f5abbda 100644 --- a/src/vcpkg/cmakevars.cpp +++ b/src/vcpkg/cmakevars.cpp @@ -152,6 +152,7 @@ VCPKG_ENV_PASSTHROUGH_UNTRACKED=${VCPKG_ENV_PASSTHROUGH_UNTRACKED} VCPKG_LOAD_VCVARS_ENV=${VCPKG_LOAD_VCVARS_ENV} VCPKG_DISABLE_COMPILER_TRACKING=${VCPKG_DISABLE_COMPILER_TRACKING} VCPKG_HASH_ADDITIONAL_FILES=${VCPKG_HASH_ADDITIONAL_FILES} +VCPKG_POST_PORTFILE_INCLUDES=${VCPKG_POST_PORTFILE_INCLUDES} VCPKG_XBOX_CONSOLE_TARGET=${VCPKG_XBOX_CONSOLE_TARGET} Z_VCPKG_GameDKLatest=$ENV{GameDKLatest} e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index a0a5c3fbad..68b963be13 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -36,6 +36,8 @@ #include #include +#include + using namespace vcpkg; namespace @@ -774,6 +776,10 @@ namespace vcpkg all_features.append(feature->name + ";"); } + auto& post_portfile_includes = action.pre_build_info(VCPKG_LINE_INFO).post_portfile_includes; + std::string all_post_portfile_includes = + Strings::join(";", Util::fmap(post_portfile_includes, [](const Path& p) { return p.generic_u8string(); })); + std::vector variables{ {CMakeVariableAllFeatures, all_features}, {CMakeVariableCurrentPortDir, scfl.port_directory()}, @@ -786,6 +792,7 @@ namespace vcpkg {CMakeVariableEditable, Util::Enum::to_bool(action.editable) ? "1" : "0"}, {CMakeVariableNoDownloads, !Util::Enum::to_bool(build_options.allow_downloads) ? "1" : "0"}, {CMakeVariableZChainloadToolchainFile, action.pre_build_info(VCPKG_LINE_INFO).toolchain_file()}, + {CMakeVariableZPostPortfileIncludes, all_post_portfile_includes}, }; if (build_options.download_tool == DownloadTool::Aria2) @@ -1215,11 +1222,25 @@ namespace vcpkg { Checks::msg_exit_with_message(VCPKG_LINE_INFO, msgInvalidValueHashAdditionalFiles, msg::path = file); } + abi_tag_entries.emplace_back( fmt::format("additional_file_{}", i), Hash::get_file_hash(fs, file, Hash::Algorithm::Sha256).value_or_exit(VCPKG_LINE_INFO)); } + for (size_t i = 0; i < abi_info.pre_build_info->post_portfile_includes.size(); ++i) + { + auto& file = abi_info.pre_build_info->post_portfile_includes[i]; + if (file.is_relative() || !fs.is_regular_file(file) || file.extension() != ".cmake") + { + Checks::msg_exit_with_message(VCPKG_LINE_INFO, msgInvalidValuePostPortfileIncludes, msg::path = file); + } + + abi_tag_entries.emplace_back( + fmt::format("post_portfile_include_{}", i), + Hash::get_file_hash(fs, file, Hash::Algorithm::Sha256).value_or_exit(VCPKG_LINE_INFO)); + } + auto&& scfl = action.source_control_file_and_location.value_or_exit(VCPKG_LINE_INFO); auto port_dir = scfl.port_directory(); auto raw_files = fs.get_regular_files_recursive_lexically_proximate(port_dir, VCPKG_LINE_INFO); @@ -1863,6 +1884,13 @@ namespace vcpkg hash_additional_files = Util::fmap(Strings::split(*value, ';'), [](auto&& str) { return Path(std::move(str)); }); } + + if (auto value = Util::value_if_set_and_nonempty(cmakevars, CMakeVariablePostPortfileIncludes)) + { + post_portfile_includes = + Util::fmap(Strings::split(*value, ';'), [](auto&& str) { return Path(std::move(str)); }); + } + // Note that this value must come after CMakeVariableChainloadToolchainFile because its default depends upon it load_vcvars_env = !external_toolchain_file.has_value(); if (auto value = Util::value_if_set_and_nonempty(cmakevars, CMakeVariableLoadVcvarsEnv))