diff --git a/toolsrc/cmake/utilities.cmake b/toolsrc/cmake/utilities.cmake index 9523b9d9782..4b434a9c76a 100644 --- a/toolsrc/cmake/utilities.cmake +++ b/toolsrc/cmake/utilities.cmake @@ -204,7 +204,13 @@ function(vcpkg_target_add_warning_options TARGET) if(VCPKG_DEVELOPMENT_WARNINGS) target_compile_options(${TARGET} PRIVATE -W4) if(VCPKG_COMPILER STREQUAL "clang") - target_compile_options(${TARGET} PRIVATE -Wmissing-prototypes -Wno-missing-field-initializers) + # -Wno-range-loop-analysis is due to an LLVM bug which will be fixed in a + # future version of clang https://reviews.llvm.org/D73007 + target_compile_options(${TARGET} PRIVATE + -Wmissing-prototypes + -Wno-missing-field-initializers + -Wno-range-loop-analysis + ) else() target_compile_options(${TARGET} PRIVATE -analyze) endif() @@ -219,13 +225,21 @@ function(vcpkg_target_add_warning_options TARGET) if(VCPKG_DEVELOPMENT_WARNINGS) target_compile_options(${TARGET} PRIVATE -Wall -Wextra -Wpedantic - -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-redundant-move) + -Wno-unknown-pragmas + -Wno-missing-field-initializers + -Wno-redundant-move + ) # GCC and clang have different names for the same warning if(VCPKG_COMPILER STREQUAL "gcc") - target_compile_options(${TARGET} PRIVATE -Wmissing-declarations) + target_compile_options(${TARGET} PRIVATE + -Wmissing-declarations + ) elseif(VCPKG_COMPILER STREQUAL "clang") - target_compile_options(${TARGET} PRIVATE -Wmissing-prototypes) + target_compile_options(${TARGET} PRIVATE + -Wmissing-prototypes + -Wno-range-loop-analysis + ) endif() endif() diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index 13e70057d3d..f24366c4a69 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -229,7 +229,7 @@ namespace vcpkg if (m_s.has_error()) { System::print2(System::Color::error, m_s.to_string(), "\n"); - Checks::unreachable(line_info); + Checks::exit_fail(line_info); } } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 365f892a0bc..14208e926be 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -212,7 +212,6 @@ namespace vcpkg } bool output_json() const { return json.value_or(false); } - bool is_recursive_invocation() const { return m_is_recursive_invocation; } std::string command; std::vector command_arguments; @@ -221,13 +220,16 @@ namespace vcpkg void imbue_from_environment(); + // Applies recursive settings from the environment or sets a global environment variable + // to be consumed by subprocesses; may only be called once per process. + static void imbue_or_apply_process_recursion(VcpkgCmdArguments& args); + void check_feature_flag_consistency() const; void debug_print_feature_flags() const; void track_feature_flag_metrics() const; private: - bool m_is_recursive_invocation = false; std::unordered_set command_switches; std::unordered_map> command_options; }; diff --git a/toolsrc/src/vcpkg-test/binarycaching.cpp b/toolsrc/src/vcpkg-test/binarycaching.cpp index 3cede064c58..8a1a28d237b 100644 --- a/toolsrc/src/vcpkg-test/binarycaching.cpp +++ b/toolsrc/src/vcpkg-test/binarycaching.cpp @@ -58,7 +58,11 @@ TEST_CASE ("generate_nuspec", "[generate_nuspec]") { auto& fsWrapper = Files::get_real_filesystem(); VcpkgCmdArguments args = VcpkgCmdArguments::create_from_arg_sequence(nullptr, nullptr); + args.imbue_from_environment(); args.packages_root_dir = std::make_unique("/"); + auto pkgPath = fsWrapper.absolute(VCPKG_LINE_INFO, fs::u8path("/zlib2_x64-windows")) / fs::u8path("**"); + pkgPath.make_preferred(); + const auto pkgPathStr = fs::u8string(pkgPath); VcpkgPaths paths(fsWrapper, args); auto pghs = Paragraphs::parse_paragraphs(R"( @@ -101,11 +105,6 @@ Build-Depends: bzip { auto nuspec = generate_nuspec(paths, ipa, ref, {}); -#ifdef _WIN32 -#define PKGPATH "C:\\zlib2_x64-windows\\**" -#else -#define PKGPATH "/zlib2_x64-windows/**" -#endif std::string expected = R"( zlib2_x64-windows @@ -125,7 +124,8 @@ Dependencies: - + )"; REQUIRE_EQUAL_TEXT(nuspec, expected); @@ -133,11 +133,6 @@ Dependencies: { auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue"}); -#ifdef _WIN32 -#define PKGPATH "C:\\zlib2_x64-windows\\**" -#else -#define PKGPATH "/zlib2_x64-windows/**" -#endif std::string expected = R"( zlib2_x64-windows @@ -158,18 +153,14 @@ Dependencies: - + )"; REQUIRE_EQUAL_TEXT(nuspec, expected); } { auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue", "branchvalue", "commitvalue"}); -#ifdef _WIN32 -#define PKGPATH "C:\\zlib2_x64-windows\\**" -#else -#define PKGPATH "/zlib2_x64-windows/**" -#endif std::string expected = R"( zlib2_x64-windows @@ -190,7 +181,8 @@ Dependencies: - + )"; REQUIRE_EQUAL_TEXT(nuspec, expected); diff --git a/toolsrc/src/vcpkg-test/manifests.cpp b/toolsrc/src/vcpkg-test/manifests.cpp index 7cf92818eb3..bbbe0c96c51 100644 --- a/toolsrc/src/vcpkg-test/manifests.cpp +++ b/toolsrc/src/vcpkg-test/manifests.cpp @@ -681,6 +681,7 @@ TEST_CASE ("Serialize all the ports", "[manifests]") std::vector args_list = {"format-manifest"}; auto& fs = Files::get_real_filesystem(); auto args = VcpkgCmdArguments::create_from_arg_sequence(args_list.data(), args_list.data() + args_list.size()); + args.imbue_from_environment(); VcpkgPaths paths{fs, args}; std::vector scfs; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ccc951f101e..f25a0c3b602 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -226,6 +226,7 @@ int main(const int argc, const char* const* const argv) VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(fs, argc, argv); if (const auto p = args.debug.get()) Debug::g_debugging = *p; args.imbue_from_environment(); + VcpkgCmdArguments::imbue_or_apply_process_recursion(args); args.check_feature_flag_consistency(); { diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index e5e8e5aad48..6ac05e53807 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -648,13 +648,6 @@ namespace vcpkg void VcpkgCmdArguments::imbue_from_environment() { - static bool s_reentrancy_guard = false; - Checks::check_exit(VCPKG_LINE_INFO, - !s_reentrancy_guard, - "VcpkgCmdArguments::imbue_from_environment() modifies global state and thus may only be " - "called once per process."); - s_reentrancy_guard = true; - if (!disable_metrics) { const auto vcpkg_disable_metrics_env = System::get_environment_variable(DISABLE_METRICS_ENV); @@ -701,46 +694,52 @@ namespace vcpkg parse_feature_flags(flags, *this); } } + } + void VcpkgCmdArguments::imbue_or_apply_process_recursion(VcpkgCmdArguments& args) + { + static bool s_reentrancy_guard = false; + Checks::check_exit( + VCPKG_LINE_INFO, + !s_reentrancy_guard, + "VcpkgCmdArguments::imbue_or_apply_process_recursion() modifies global state and thus may only be " + "called once per process."); + s_reentrancy_guard = true; + + auto maybe_vcpkg_recursive_data = System::get_environment_variable(RECURSIVE_DATA_ENV); + if (auto vcpkg_recursive_data = maybe_vcpkg_recursive_data.get()) { - auto maybe_vcpkg_recursive_data = System::get_environment_variable(RECURSIVE_DATA_ENV); - if (auto vcpkg_recursive_data = maybe_vcpkg_recursive_data.get()) + auto rec_doc = Json::parse(*vcpkg_recursive_data).value_or_exit(VCPKG_LINE_INFO).first; + const auto& obj = rec_doc.object(); + + if (auto entry = obj.get(DOWNLOADS_ROOT_DIR_ENV)) { - m_is_recursive_invocation = true; - - auto rec_doc = Json::parse(*vcpkg_recursive_data).value_or_exit(VCPKG_LINE_INFO).first; - const auto& obj = rec_doc.object(); - - if (auto entry = obj.get(DOWNLOADS_ROOT_DIR_ENV)) - { - downloads_root_dir = std::make_unique(entry->string().to_string()); - } - - if (obj.get(DISABLE_METRICS_ENV)) - { - disable_metrics = true; - } - - // Setting the recursive data to 'poison' prevents more than one level of recursion because - // Json::parse() will fail. - System::set_environment_variable(RECURSIVE_DATA_ENV, "poison"); + args.downloads_root_dir = std::make_unique(entry->string().to_string()); } - else + + if (obj.get(DISABLE_METRICS_ENV)) { - Json::Object obj; - if (downloads_root_dir) - { - obj.insert(DOWNLOADS_ROOT_DIR_ENV, Json::Value::string(*downloads_root_dir.get())); - } - - if (disable_metrics) - { - obj.insert(DISABLE_METRICS_ENV, Json::Value::boolean(true)); - } - - System::set_environment_variable(RECURSIVE_DATA_ENV, - Json::stringify(obj, Json::JsonStyle::with_spaces(0))); + args.disable_metrics = true; } + + // Setting the recursive data to 'poison' prevents more than one level of recursion because + // Json::parse() will fail. + System::set_environment_variable(RECURSIVE_DATA_ENV, "poison"); + } + else + { + Json::Object obj; + if (args.downloads_root_dir) + { + obj.insert(DOWNLOADS_ROOT_DIR_ENV, Json::Value::string(*args.downloads_root_dir.get())); + } + + if (args.disable_metrics) + { + obj.insert(DISABLE_METRICS_ENV, Json::Value::boolean(true)); + } + + System::set_environment_variable(RECURSIVE_DATA_ENV, Json::stringify(obj, Json::JsonStyle::with_spaces(0))); } }