diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 4534b5665e..c103c7363d 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1668,6 +1668,7 @@ DECLARE_MESSAGE(HelpTxtOptManifestFeature, (), "", "Additional features from the top-level manifest to install (manifest mode)") +DECLARE_MESSAGE(HelpTxtBuildType, (), "", "Build type (debug, release or both if not specified) (manifest mode)") DECLARE_MESSAGE(HelpTxtOptManifestNoDefault, (), "", diff --git a/include/vcpkg/cmakevars.h b/include/vcpkg/cmakevars.h index 097cd99f3c..c063a00df6 100644 --- a/include/vcpkg/cmakevars.h +++ b/include/vcpkg/cmakevars.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -35,5 +36,6 @@ namespace vcpkg::CMakeVars virtual void load_tag_vars(const ActionPlan& action_plan, Triplet host_triplet) const = 0; }; - std::unique_ptr make_triplet_cmake_var_provider(const VcpkgPaths& paths); + std::unique_ptr make_triplet_cmake_var_provider( + const VcpkgPaths& paths, ConfigurationType default_build_type = ConfigurationType::BOTH); } diff --git a/include/vcpkg/commands.build.h b/include/vcpkg/commands.build.h index 5a4e2efe46..c0cdad90fa 100644 --- a/include/vcpkg/commands.build.h +++ b/include/vcpkg/commands.build.h @@ -60,6 +60,9 @@ namespace vcpkg StringLiteral to_string_view(DownloadTool tool); std::string to_string(DownloadTool tool); + StringLiteral to_string_view(ConfigurationType config_type); + std::string to_string(ConfigurationType config_type); + struct BuildPackageOptions { BuildMissing build_missing; @@ -74,6 +77,7 @@ namespace vcpkg Editable editable; BackcompatFeatures backcompat_features; PrintUsage print_usage; + ConfigurationType build_type; }; static constexpr BuildPackageOptions default_build_package_options{ @@ -89,6 +93,7 @@ namespace vcpkg Editable::NO, BackcompatFeatures::ALLOW, PrintUsage::YES, + ConfigurationType::BOTH, }; static constexpr BuildPackageOptions backcompat_prohibiting_package_options{ @@ -104,6 +109,7 @@ namespace vcpkg Editable::NO, BackcompatFeatures::PROHIBIT, PrintUsage::YES, + ConfigurationType::BOTH, }; struct BuildResultCounts @@ -157,7 +163,7 @@ namespace vcpkg Optional platform_toolset_version; Optional visual_studio_path; Optional external_toolchain_file; - Optional build_type; + ConfigurationType build_type; Optional public_abi_override; std::vector passthrough_env_vars; std::vector passthrough_env_vars_tracked; diff --git a/include/vcpkg/fwd/build.h b/include/vcpkg/fwd/build.h index c65ca91036..594e606947 100644 --- a/include/vcpkg/fwd/build.h +++ b/include/vcpkg/fwd/build.h @@ -53,6 +53,7 @@ namespace vcpkg enum class ConfigurationType { + BOTH, DEBUG, RELEASE, }; diff --git a/locales/messages.json b/locales/messages.json index 18c764cce4..19a8e7bf0c 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -948,6 +948,7 @@ "HelpTextOptFullDesc": "Does not truncate long text", "HelpTopicCommand": "Displays specific help topic", "HelpTopicsCommand": "Displays full list of help topics", + "HelpTxtBuildType": "Build type (debug, release or both if not specified) (manifest mode)", "HelpTxtOptAllowUnsupportedPort": "Continues with a warning on unsupported ports, rather than failing", "HelpTxtOptCleanAfterBuild": "Cleans buildtrees, packages and downloads after building each package", "HelpTxtOptCleanBuildTreesAfterBuild": "Cleans buildtrees after building each package", diff --git a/src/vcpkg/cmakevars.cpp b/src/vcpkg/cmakevars.cpp index 5d1c199b5e..614b572e59 100644 --- a/src/vcpkg/cmakevars.cpp +++ b/src/vcpkg/cmakevars.cpp @@ -31,7 +31,10 @@ namespace vcpkg::CMakeVars { struct TripletCMakeVarProvider : CMakeVarProvider { - explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) { } + explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths, ConfigurationType default_build_type) + : paths(paths), default_build_type(default_build_type) + { + } TripletCMakeVarProvider(const TripletCMakeVarProvider&) = delete; TripletCMakeVarProvider& operator=(const TripletCMakeVarProvider&) = delete; @@ -60,26 +63,32 @@ namespace vcpkg::CMakeVars std::vector>>& vars) const; const VcpkgPaths& paths; + const ConfigurationType default_build_type; mutable std::unordered_map> dep_resolution_vars; mutable std::unordered_map> tag_vars; mutable std::unordered_map> generic_triplet_vars; }; } - std::unique_ptr make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths) + std::unique_ptr make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths, + ConfigurationType default_build_type) { - return std::make_unique(paths); + return std::make_unique(paths, default_build_type); } static std::string create_extraction_file_prelude(const VcpkgPaths& paths, - const std::map& emitted_triplets) + const std::map& emitted_triplets, + ConfigurationType default_build_type) { const auto& fs = paths.get_filesystem(); std::string extraction_file; - extraction_file.append("cmake_minimum_required(VERSION 3.5)\n" - "macro(vcpkg_triplet_file VCPKG_TRIPLET_ID)\n" - "set(_vcpkg_triplet_file_BACKUP_CURRENT_LIST_FILE \"${CMAKE_CURRENT_LIST_FILE}\")\n"); + fmt::format_to(std::back_inserter(extraction_file), + "cmake_minimum_required(VERSION 3.5)\n" + "macro(vcpkg_triplet_file VCPKG_TRIPLET_ID)\n" + "set(VCPKG_BUILD_TYPE \"{}\")\n" + "set(_vcpkg_triplet_file_BACKUP_CURRENT_LIST_FILE \"${{CMAKE_CURRENT_LIST_FILE}}\")\n", + to_string(default_build_type)); for (auto&& p : emitted_triplets) { @@ -116,7 +125,7 @@ endmacro() { emitted_triplets[spec_abi_setting.first.package_spec.triplet()] = emitted_triplet_id++; } - std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets); + std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets, default_build_type); // The variables collected here are those necessary to perform builds. extraction_file.append(R"( @@ -196,7 +205,7 @@ endfunction() emitted_triplets[spec.triplet()] = emitted_triplet_id++; } - std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets); + std::string extraction_file = create_extraction_file_prelude(paths, emitted_triplets, default_build_type); // The variables collected here are those necessary to perform dependency resolution. // If a value affects platform expressions, it must be here. diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index 27e7f6b216..f13b045e6f 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -282,6 +282,18 @@ namespace vcpkg std::string to_string(DownloadTool tool) { return to_string_view(tool).to_string(); } + StringLiteral to_string_view(ConfigurationType config_type) + { + switch (config_type) + { + case ConfigurationType::DEBUG: return "debug"; + case ConfigurationType::RELEASE: return "release"; + default: return ""; + } + } + + std::string to_string(ConfigurationType config_type) { return to_string_view(config_type).to_string(); } + Optional to_linkage_type(StringView str) { if (str == "dynamic") return LinkageType::DYNAMIC; @@ -777,6 +789,11 @@ namespace vcpkg variables.emplace_back("ARIA2", paths.get_tool_exe(Tools::ARIA2, stdout_sink)); } + if (action.build_options.build_type != ConfigurationType::BOTH) + { + variables.emplace_back("VCPKG_DEFAULT_BUILD_TYPE", to_string(action.build_options.build_type)); + } + if (auto cmake_debug = args.cmake_debug.get()) { if (cmake_debug->is_port_affected(scf.core_paragraph->name)) @@ -1166,6 +1183,10 @@ namespace vcpkg const auto& triplet_canonical_name = action.spec.triplet().canonical_name(); abi_tag_entries.emplace_back("triplet", triplet_canonical_name); abi_tag_entries.emplace_back("triplet_abi", triplet_abi); + if (action.build_options.build_type != ConfigurationType::BOTH) + { + abi_tag_entries.emplace_back("build_type", to_string(action.build_options.build_type)); + } auto& fs = paths.get_filesystem(); abi_entries_from_pre_build_info(fs, grdk_cache, pre_build_info, abi_tag_entries); @@ -1789,7 +1810,7 @@ namespace vcpkg break; case VcpkgTripletVar::BUILD_TYPE: if (variable_value.empty()) - build_type = nullopt; + build_type = ConfigurationType::BOTH; else if (Strings::case_insensitive_ascii_equals(variable_value, "debug")) build_type = ConfigurationType::DEBUG; else if (Strings::case_insensitive_ascii_equals(variable_value, "release")) diff --git a/src/vcpkg/commands.install.cpp b/src/vcpkg/commands.install.cpp index 8ccd17875d..9ce09ed14c 100644 --- a/src/vcpkg/commands.install.cpp +++ b/src/vcpkg/commands.install.cpp @@ -618,6 +618,7 @@ namespace vcpkg static constexpr StringLiteral OPTION_ENFORCE_PORT_CHECKS = "enforce-port-checks"; static constexpr StringLiteral OPTION_ALLOW_UNSUPPORTED_PORT = "allow-unsupported"; static constexpr StringLiteral OPTION_NO_PRINT_USAGE = "no-print-usage"; + static constexpr StringLiteral OPTION_DEFAULT_BUILD_TYPE = "x-build-type"; static constexpr CommandSwitch INSTALL_SWITCHES[] = { {OPTION_DRY_RUN, msgHelpTxtOptDryRun}, @@ -643,6 +644,7 @@ namespace vcpkg static constexpr CommandSetting INSTALL_SETTINGS[] = { {OPTION_XUNIT, {}}, // internal use {OPTION_WRITE_PACKAGES_CONFIG, msgHelpTxtOptWritePkgConfig}, + {OPTION_DEFAULT_BUILD_TYPE, msgHelpTxtBuildType}, }; static constexpr CommandMultiSetting INSTALL_MULTISETTINGS[] = { @@ -1017,6 +1019,7 @@ namespace vcpkg : UnsupportedPortAction::Error; const PrintUsage print_cmake_usage = Util::Sets::contains(options.switches, OPTION_NO_PRINT_USAGE) ? PrintUsage::NO : PrintUsage::YES; + ConfigurationType build_type = ConfigurationType::BOTH; get_global_metrics_collector().track_bool(BoolMetric::InstallManifestMode, paths.manifest_mode_enabled()); @@ -1039,6 +1042,27 @@ namespace vcpkg msg::println_error(msgErrorInvalidManifestModeOption, msg::option = OPTION_EDITABLE); failure = true; } + if (auto it = options.settings.find(OPTION_DEFAULT_BUILD_TYPE); it != options.settings.end()) + { + auto& str = it->second; + if (str.empty()) + { + build_type = ConfigurationType::BOTH; + } + else if (Strings::case_insensitive_ascii_equals(str, "debug")) + { + build_type = ConfigurationType::DEBUG; + } + else if (Strings::case_insensitive_ascii_equals(str, "release")) + { + build_type = ConfigurationType::RELEASE; + } + else + { + msg::println_error(msgUnknownSettingForBuildType, msg::option = str); + failure = true; + } + } if (failure) { msg::println(msgUsingManifestAt, msg::path = p->path); @@ -1066,6 +1090,11 @@ namespace vcpkg msg::println_error(msgErrorInvalidClassicModeOption, msg::option = OPTION_MANIFEST_FEATURE); failure = true; } + if (Util::Sets::contains(options.settings, OPTION_DEFAULT_BUILD_TYPE)) + { + msg::println_error(msgErrorInvalidClassicModeOption, msg::option = OPTION_DEFAULT_BUILD_TYPE); + failure = true; + } if (failure) { print_usage(CommandInstallMetadataClassic); @@ -1090,9 +1119,10 @@ namespace vcpkg PurgeDecompressFailure::NO, Util::Enum::to_enum(is_editable), prohibit_backcompat_features ? BackcompatFeatures::PROHIBIT : BackcompatFeatures::ALLOW, - print_cmake_usage}; + print_cmake_usage, + build_type}; - auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths, build_type); auto& var_provider = *var_provider_storage; const CreateInstallPlanOptions create_options{host_triplet, paths.packages(), unsupported_port_action}; diff --git a/src/vcpkg/postbuildlint.cpp b/src/vcpkg/postbuildlint.cpp index 49f46681a1..36066f6873 100644 --- a/src/vcpkg/postbuildlint.cpp +++ b/src/vcpkg/postbuildlint.cpp @@ -1392,7 +1392,8 @@ namespace vcpkg std::vector release_libs = fs.get_regular_files_recursive(release_lib_dir, IgnoreErrors{}); Util::erase_remove_if(release_libs, lib_filter); - if (!pre_build_info.build_type && !build_info.policies.is_enabled(BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES)) + if (pre_build_info.build_type == ConfigurationType::BOTH && + !build_info.policies.is_enabled(BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES)) { error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs, msg_sink); } @@ -1424,7 +1425,7 @@ namespace vcpkg { case LinkageType::DYNAMIC: { - if (!pre_build_info.build_type && + if (pre_build_info.build_type == ConfigurationType::BOTH && !build_info.policies.is_enabled(BuildPolicy::MISMATCHED_NUMBER_OF_BINARIES)) error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls, msg_sink);