diff --git a/docs/maintainers/control-files.md b/docs/maintainers/control-files.md index 43c1c70a7..e20669b33 100644 --- a/docs/maintainers/control-files.md +++ b/docs/maintainers/control-files.md @@ -13,13 +13,14 @@ The first paragraph in a `CONTROL` file is the Source paragraph. It must have a ### Examples: ```no-highlight Source: ace -Version: 6.5.5-1 +Version: 6.5.5 Description: The ADAPTIVE Communication Environment ``` ```no-highlight Source: vtk -Version: 8.2.0-2 +Version: 8.2.0 +Port-Version: 2 Description: Software system for 3D computer graphics, image processing, and visualization Build-Depends: zlib, libpng, tiff, libxml2, jsoncpp, glew, freetype, expat, hdf5, libjpeg-turbo, proj4, lz4, libtheora, atlmfc (windows), eigen3, double-conversion, pugixml, libharu, sqlite3, netcdf-c ``` @@ -39,7 +40,7 @@ Package collections to check for conflicts: + [Packages search](https://pkgs.org/) #### Version -The port version. +The library version. This field is an alphanumeric string that may also contain `.`, `_`, or `-`. No attempt at ordering versions is made; all versions are treated as bit strings and are only evaluated for equality. @@ -47,7 +48,6 @@ For tagged-release ports, we follow the following convention: 1. If the port follows a scheme like `va.b.c`, we remove the leading `v`. In this case, it becomes `a.b.c`. 2. If the port includes its own name in the version like `curl-7_65_1`, we remove the leading name: `7_65_1` -3. If the port has been modified, we append a `-N` to distinguish the versions: `1.2.1-4` For rolling-release ports, we use the date that the _commit was accessed by you_, formatted as `YYYY-MM-DD`. Stated another way: if someone had a time machine and went to that date, they would see this commit as the latest master. @@ -56,11 +56,17 @@ For example, given: 2. The current version string is `2019-02-14-1` 3. Today's date is 2019-06-01. -Then if you update the source version today, you should give it version `2019-06-01`. If you need to make a change which doesn't adjust the source version, you should give it version `2019-02-14-2`. +Then if you update the source version today, you should give it version `2019-06-01`. + +#### Port-Version +The version of the port. + +This field is a non-negative integer. It allows one to version the port file separately from the version of the underlying library; if you make a change to a port, without changing the underlying version of the library, you should increment this field by one (starting at `0`, which is equivalent to no `Port-Version` field). When the version of the underlying library is upgraded, this field should be set back to `0` (i.e., delete the `Port-Version` field). ##### Examples: ```no-highlight -Version: 1.0.5-2 +Version: 1.0.5 +Port-Version: 2 ``` ```no-highlight Version: 2019-03-21 @@ -77,7 +83,7 @@ Description: C++ header-only JSON library ``` ```no-highlight Description: Mosquitto is an open source message broker that implements the MQ Telemetry Transport protocol versions 3.1 and 3.1.1. - MQTT provides a lightweight method of carrying out messaging using a publish/subscribe model. This makes it suitable for "machine + MQTT provides a lightweight method of carrying out messaging using a publish/subscribe model. This makes it suitable for "machine to machine" messaging such as with low power sensors or mobile devices such as phones, embedded computers or microcontrollers like the Arduino. ```` diff --git a/scripts/azure-pipelines/azure-pipelines.yml b/scripts/azure-pipelines/azure-pipelines.yml index 9c66be5a3..80c547633 100644 --- a/scripts/azure-pipelines/azure-pipelines.yml +++ b/scripts/azure-pipelines/azure-pipelines.yml @@ -11,6 +11,8 @@ stages: pool: $(windows-pool) jobs: - job: + workspace: + clean: resources steps: - task: Powershell@2 displayName: 'Check C++ Formatting' @@ -23,6 +25,8 @@ stages: dependsOn: [] jobs: - job: + workspace: + clean: resources steps: - task: Powershell@2 displayName: 'Check port manifest Formatting' diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake index 96f847190..4ee79d179 100644 --- a/scripts/buildsystems/vcpkg.cmake +++ b/scripts/buildsystems/vcpkg.cmake @@ -6,10 +6,6 @@ option(VCPKG_VERBOSE "Enables messages from the VCPKG toolchain for debugging pu mark_as_advanced(VCPKG_VERBOSE) function(_vcpkg_get_directory_name_of_file_above OUT DIRECTORY FILENAME) - if(DEFINED ${OUT}) - return() - endif() - set(_vcpkg_get_dir_candidate ${DIRECTORY}) while(IS_DIRECTORY ${_vcpkg_get_dir_candidate} AND NOT DEFINED _vcpkg_get_dir_out) if(EXISTS ${_vcpkg_get_dir_candidate}/${FILENAME}) @@ -28,22 +24,28 @@ function(_vcpkg_get_directory_name_of_file_above OUT DIRECTORY FILENAME) endfunction() _vcpkg_get_directory_name_of_file_above(_VCPKG_MANIFEST_DIR ${CMAKE_CURRENT_SOURCE_DIR} "vcpkg.json") -if(_VCPKG_MANIFEST_DIR) - set(_VCPKG_MANIFEST_MODE_DEFAULT ON) -else() - set(_VCPKG_MANIFEST_MODE_DEFAULT OFF) -endif() - -option(VCPKG_MANIFEST_MODE "Set vcpkg to manifest mode" ${_VCPKG_MANIFEST_MODE_DEFAULT}) - -if(NOT _VCPKG_MANIFEST_DIR AND VCPKG_MANIFEST_MODE) +if(NOT DEFINED VCPKG_MANIFEST_MODE) + if(_VCPKG_MANIFEST_DIR) + set(VCPKG_MANIFEST_MODE ON) + else() + set(VCPKG_MANIFEST_MODE OFF) + endif() +elseif(VCPKG_MANIFEST_MODE AND NOT _VCPKG_MANIFEST_DIR) message(FATAL_ERROR "vcpkg manifest mode was enabled, but we couldn't find a manifest file (vcpkg.json) " "in any directories above ${CMAKE_CURRENT_SOURCE_DIR}. Please add a manifest, or " "disable manifests by turning off VCPKG_MANIFEST_MODE.") endif() -option(VCPKG_MANIFEST_INSTALL "Install packages from the manifest" ON) +if(VCPKG_MANIFEST_MODE) + option(VCPKG_MANIFEST_INSTALL +[[ +Install the dependencies listed in your manifest: + If this is off, you will have to manually install your dependencies. + See https://github.com/microsoft/vcpkg/tree/master/docs/specifications/manifests.md for more info. +]] + ON) +endif() # Determine whether the toolchain is loaded during a try-compile configuration get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) @@ -198,7 +200,7 @@ endif() if (NOT DEFINED _VCPKG_INSTALLED_DIR) if(_VCPKG_MANIFEST_DIR) - set(_VCPKG_INSTALLED_DIR ${_VCPKG_MANIFEST_DIR}/vcpkg_installed) + set(_VCPKG_INSTALLED_DIR ${CMAKE_BINARY_DIR}/vcpkg_installed) else() set(_VCPKG_INSTALLED_DIR ${_VCPKG_ROOT_DIR}/installed) endif() @@ -230,11 +232,11 @@ else() #Release build: Put Release paths before Debug paths. Debug Paths are req ) endif() -# If one CMAKE_FIND_ROOT_PATH_MODE_* variables is set to ONLY, to make sure that ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET} +# If one CMAKE_FIND_ROOT_PATH_MODE_* variables is set to ONLY, to make sure that ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET} # and ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug are searched, it is not sufficient to just add them to CMAKE_FIND_ROOT_PATH, -# as CMAKE_FIND_ROOT_PATH specify "one or more directories to be prepended to all other search directories", so to make sure that +# as CMAKE_FIND_ROOT_PATH specify "one or more directories to be prepended to all other search directories", so to make sure that # the libraries are searched as they are, it is necessary to add "/" to the CMAKE_PREFIX_PATH -if(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE STREQUAL "ONLY" OR +if(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE STREQUAL "ONLY" OR CMAKE_FIND_ROOT_PATH_MODE_LIBRARY STREQUAL "ONLY" OR CMAKE_FIND_ROOT_PATH_MODE_PACKAGE STREQUAL "ONLY") list(APPEND CMAKE_PREFIX_PATH "/") @@ -280,23 +282,45 @@ endforeach() # CMAKE_EXECUTABLE_SUFFIX is not yet defined if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") - set(_VCPKG_EXECUTABLE_SUFFIX ".exe") + set(_VCPKG_EXECUTABLE "${_VCPKG_ROOT_DIR}/vcpkg.exe") + set(_VCPKG_BOOTSTRAP_SCRIPT "${_VCPKG_ROOT_DIR}/bootstrap-vcpkg.bat") else() - set(_VCPKG_EXECUTABLE_SUFFIX "") + set(_VCPKG_EXECUTABLE "${_VCPKG_ROOT_DIR}/vcpkg") + set(_VCPKG_BOOTSTRAP_SCRIPT "${_VCPKG_ROOT_DIR}/bootstrap-vcpkg.sh") endif() if(VCPKG_MANIFEST_MODE AND VCPKG_MANIFEST_INSTALL AND NOT _CMAKE_IN_TRY_COMPILE) + if(NOT EXISTS "${_VCPKG_EXECUTABLE}") + message(STATUS "Bootstrapping vcpkg before install") + + execute_process( + COMMAND "${_VCPKG_BOOTSTRAP_SCRIPT}" + RESULT_VARIABLE _VCPKG_BOOTSTRAP_RESULT) + + if (NOT _VCPKG_BOOTSTRAP_RESULT EQUAL 0) + message(FATAL_ERROR "Bootstrapping vcpkg before install - failed") + endif() + + message(STATUS "Bootstrapping vcpkg before install - done") + endif() + + message(STATUS "Running vcpkg install") + execute_process( - COMMAND "${_VCPKG_ROOT_DIR}/vcpkg${_VCPKG_EXECUTABLE_SUFFIX}" install + COMMAND "${_VCPKG_EXECUTABLE}" install --triplet ${VCPKG_TARGET_TRIPLET} --vcpkg-root ${_VCPKG_ROOT_DIR} --x-manifest-root=${_VCPKG_MANIFEST_DIR} --x-install-root=${_VCPKG_INSTALLED_DIR} --binarycaching RESULT_VARIABLE _VCPKG_INSTALL_RESULT) + if (NOT _VCPKG_INSTALL_RESULT EQUAL 0) - message(FATAL_ERROR "vcpkg install failed") + message(FATAL_ERROR "Running vcpkg install - failed") endif() + + message(STATUS "Running vcpkg install - done") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_VCPKG_MANIFEST_DIR}/vcpkg.json" "${_VCPKG_INSTALLED_DIR}/vcpkg/status") diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index 68ef2dbcd..a202bfdef 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -190,6 +190,9 @@ namespace vcpkg::Files virtual void current_path(const fs::path& path, std::error_code&) = 0; void current_path(const fs::path& path, LineInfo li); + // waits forever for the file lock + virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0; + // waits, at most, 1.5 seconds, for the file lock virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0; virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code&) = 0; diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 0ab5917b5..bcbf10619 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -149,6 +149,9 @@ namespace vcpkg constexpr static StringLiteral PRINT_METRICS_SWITCH = "printmetrics"; Optional print_metrics = nullopt; + constexpr static StringLiteral WAIT_FOR_LOCK_SWITCH = "x-wait-for-lock"; + Optional wait_for_lock = nullopt; + // feature flags constexpr static StringLiteral FEATURE_FLAGS_ENV = "VCPKG_FEATURE_FLAGS"; constexpr static StringLiteral FEATURE_FLAGS_ARG = "feature-flags"; @@ -175,6 +178,7 @@ namespace vcpkg void check_feature_flag_consistency() const; + void debug_print_feature_flags() const; void track_feature_flag_metrics() const; private: diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h index e893f1abc..768ca0c47 100644 --- a/toolsrc/include/vcpkg/versiont.h +++ b/toolsrc/include/vcpkg/versiont.h @@ -6,18 +6,19 @@ namespace vcpkg struct VersionT { VersionT() noexcept; - VersionT(std::string&& value); - VersionT(const std::string& value); + VersionT(std::string&& value, int port_version); + VersionT(const std::string& value, int port_version); - const std::string& to_string() const; + std::string to_string() const; + + friend bool operator==(const VersionT& left, const VersionT& right); + friend bool operator!=(const VersionT& left, const VersionT& right); private: std::string value; + int port_version; }; - bool operator==(const VersionT& left, const VersionT& right); - bool operator!=(const VersionT& left, const VersionT& right); - struct VersionDiff { VersionT left; diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index b6f0782fa..003ae1024 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -250,6 +250,7 @@ int main(const int argc, const char* const* const argv) "Warning: passed either --printmetrics or --no-printmetrics, but metrics are disabled.\n"); } + args.debug_print_feature_flags(); args.track_feature_flag_metrics(); if (Debug::g_debugging) diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 551938990..f119edace 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -874,15 +874,22 @@ namespace vcpkg::Files fs::stdfs::current_path(path, ec); } - virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override + struct TakeExclusiveFileLockHelper { - fs::SystemHandle res; + fs::SystemHandle& res; + const fs::path::string_type& native; + TakeExclusiveFileLockHelper(fs::SystemHandle& res, const fs::path::string_type& native) + : res(res), native(native) + { + } - const auto system_file_name = path.native(); #if defined(WIN32) - constexpr static auto busy_error = ERROR_BUSY; - const auto system_try_take_file_lock = [&] { - auto handle = CreateFileW(system_file_name.c_str(), + void assign_busy_error(std::error_code& ec) { ec.assign(ERROR_BUSY, std::system_category()); } + + bool operator()(std::error_code& ec) + { + ec.clear(); + auto handle = CreateFileW(native.c_str(), GENERIC_READ, 0 /* no sharing */, nullptr /* no security attributes */, @@ -901,31 +908,77 @@ namespace vcpkg::Files res.system_handle = reinterpret_cast(handle); return true; - }; -#else // ^^^ WIN32 / !WIN32 vvv - constexpr static auto busy_error = EBUSY; - int fd = open(system_file_name.c_str(), 0); - if (fd < 0) - { - ec.assign(errno, std::system_category()); - return res; } - const auto system_try_take_file_lock = [&] { - if (flock(fd, LOCK_EX | LOCK_NB) != 0) +#else // ^^^ WIN32 / !WIN32 vvv + int fd = -1; + + void assign_busy_error(std::error_code& ec) { ec.assign(EBUSY, std::generic_category()); } + + bool operator()(std::error_code& ec) + { + ec.clear(); + if (fd == -1) + { + fd = ::open(native.c_str(), 0); + if (fd < 0) + { + ec.assign(errno, std::generic_category()); + return false; + } + } + + if (::flock(fd, LOCK_EX | LOCK_NB) != 0) { if (errno != EWOULDBLOCK) { - ec.assign(errno, std::system_category()); + ec.assign(errno, std::generic_category()); } return false; } res.system_handle = fd; + fd = -1; return true; }; -#endif - if (system_try_take_file_lock() || ec) + ~TakeExclusiveFileLockHelper() + { + if (fd != -1) + { + ::close(fd); + } + } +#endif + }; + + virtual fs::SystemHandle take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override + { + fs::SystemHandle res; + TakeExclusiveFileLockHelper helper(res, path.native()); + + if (helper(ec) || ec) + { + return res; + } + + System::printf("Waiting to take filesystem lock on %s...\n", path.u8string()); + const auto wait = std::chrono::milliseconds(1000); + for (;;) + { + std::this_thread::sleep_for(wait); + if (helper(ec) || ec) + { + return res; + } + } + } + + virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override + { + fs::SystemHandle res; + TakeExclusiveFileLockHelper helper(res, path.native()); + + if (helper(ec) || ec) { return res; } @@ -936,19 +989,17 @@ namespace vcpkg::Files while (wait < std::chrono::milliseconds(1000)) { std::this_thread::sleep_for(wait); - if (system_try_take_file_lock() || ec) + if (helper(ec) || ec) { return res; } wait *= 2; } -#if !defined(WIN32) - close(fd); -#endif - ec.assign(busy_error, std::system_category()); + helper.assign_busy_error(ec); return res; } + virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code& ec) override { #if defined(WIN32) @@ -959,7 +1010,7 @@ namespace vcpkg::Files #else if (flock(handle.system_handle, LOCK_UN) != 0 || close(handle.system_handle) != 0) { - ec.assign(errno, std::system_category()); + ec.assign(errno, std::generic_category()); } #endif } diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index e95b02623..257e4f941 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace vcpkg::Commands::List { @@ -12,11 +13,12 @@ namespace vcpkg::Commands::List static void do_print(const StatusParagraph& pgh, const bool full_desc) { + auto full_version = VersionT(pgh.package.version, pgh.package.port_version).to_string(); if (full_desc) { System::printf("%-50s %-16s %s\n", pgh.package.displayname(), - pgh.package.version, + full_version, Strings::join("\n ", pgh.package.description)); } else @@ -28,7 +30,7 @@ namespace vcpkg::Commands::List } System::printf("%-50s %-16s %s\n", vcpkg::shorten_text(pgh.package.displayname(), 50), - vcpkg::shorten_text(pgh.package.version, 16), + vcpkg::shorten_text(full_version, 16), vcpkg::shorten_text(description, 51)); } } diff --git a/toolsrc/src/vcpkg/commands.porthistory.cpp b/toolsrc/src/vcpkg/commands.porthistory.cpp index 0f4d9716f..7e04cbd01 100644 --- a/toolsrc/src/vcpkg/commands.porthistory.cpp +++ b/toolsrc/src/vcpkg/commands.porthistory.cpp @@ -35,8 +35,14 @@ namespace vcpkg::Commands::PortHistory const std::string cmd = Strings::format(R"(show %s:ports/%s/CONTROL)", commit_id, port_name); auto output = run_git_command(paths, cmd); - const auto version = Strings::find_at_most_one_enclosed(output.output, "Version: ", "\n"); + const auto version = Strings::find_at_most_one_enclosed(output.output, "\nVersion: ", "\n"); + const auto port_version = Strings::find_at_most_one_enclosed(output.output, "\nPort-Version: ", "\n"); Checks::check_exit(VCPKG_LINE_INFO, version.has_value(), "CONTROL file does not have a 'Version' field"); + if (auto pv = port_version.get()) + { + return Strings::format("%s#%s", version.get()->to_string(), pv->to_string()); + } + return version.get()->to_string(); } diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp index ed5044a60..562917e80 100644 --- a/toolsrc/src/vcpkg/commands.portsdiff.cpp +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -103,7 +103,10 @@ namespace vcpkg::Commands::PortsDiff Paragraphs::load_all_ports(paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); std::map names_and_versions; for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + { + const auto& core_pgh = *port->core_paragraph; + names_and_versions.emplace(port->core_paragraph->name, VersionT(core_pgh.version, core_pgh.port_version)); + } fs.remove_all(temp_checkout_path, VCPKG_LINE_INFO); return names_and_versions; } diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index c234c3ab9..126c74dc0 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using vcpkg::PortFileProvider::PathsPortFileProvider; @@ -18,11 +19,12 @@ namespace vcpkg::Commands::Search static void do_print(const SourceParagraph& source_paragraph, bool full_desc) { + auto full_version = VersionT(source_paragraph.version, source_paragraph.port_version).to_string(); if (full_desc) { System::printf("%-20s %-16s %s\n", source_paragraph.name, - source_paragraph.version, + full_version, Strings::join("\n ", source_paragraph.description)); } else @@ -34,7 +36,7 @@ namespace vcpkg::Commands::Search } System::printf("%-20s %-16s %s\n", vcpkg::shorten_text(source_paragraph.name, 20), - vcpkg::shorten_text(source_paragraph.version, 16), + vcpkg::shorten_text(full_version, 16), vcpkg::shorten_text(description, 81)); } } diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 3be938215..f27b2ffae 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -726,8 +726,10 @@ namespace vcpkg::Install { for (auto& dep : (*val)->core_paragraph->dependencies) { - specs.push_back(Input::check_and_get_full_package_spec( - std::move(dep.name), default_triplet, COMMAND_STRUCTURE.example_text)); + specs.push_back(FullPackageSpec{ + {std::move(dep.name), default_triplet}, + std::move(dep.features), + }); } } else diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index aa8d654e3..85241e438 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -26,11 +26,13 @@ namespace vcpkg::Update auto maybe_scfl = provider.get_control_file(pgh->package.spec.name()); if (auto p_scfl = maybe_scfl.get()) { - auto&& port_version = p_scfl->source_control_file->core_paragraph->version; - auto&& installed_version = pgh->package.version; - if (installed_version != port_version) + const auto& latest_pgh = *p_scfl->source_control_file->core_paragraph; + auto latest_version = VersionT(latest_pgh.version, latest_pgh.port_version); + auto installed_version = VersionT(pgh->package.version, pgh->package.port_version); + if (latest_version != installed_version) { - output.push_back({pgh->package.spec, VersionDiff(installed_version, port_version)}); + output.push_back( + {pgh->package.spec, VersionDiff(std::move(installed_version), std::move(latest_version))}); } } else diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 75632541d..6bc14309e 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -297,6 +297,7 @@ namespace vcpkg {PRINT_METRICS_SWITCH, &VcpkgCmdArguments::print_metrics}, {FEATURE_PACKAGES_SWITCH, &VcpkgCmdArguments::feature_packages}, {BINARY_CACHING_SWITCH, &VcpkgCmdArguments::binary_caching}, + {WAIT_FOR_LOCK_SWITCH, &VcpkgCmdArguments::wait_for_lock}, }; bool found = false; @@ -677,13 +678,41 @@ namespace vcpkg } } + void VcpkgCmdArguments::debug_print_feature_flags() const + { + struct + { + StringView name; + Optional flag; + } flags[] = { + {BINARY_CACHING_FEATURE, binary_caching}, + {MANIFEST_MODE_FEATURE, manifest_mode}, + {COMPILER_TRACKING_FEATURE, compiler_tracking}, + }; + + for (const auto& flag : flags) + { + if (auto r = flag.flag.get()) + { + Debug::print("Feature flag '", flag.name, "' = ", *r ? "on" : "off", "\n"); + } + else + { + Debug::print("Feature flag '", flag.name, "' unset\n"); + } + } + } + void VcpkgCmdArguments::track_feature_flag_metrics() const { struct { StringView flag; bool enabled; - } flags[] = {{BINARY_CACHING_FEATURE, binary_caching_enabled()}}; + } flags[] = { + {BINARY_CACHING_FEATURE, binary_caching_enabled()}, + {COMPILER_TRACKING_FEATURE, compiler_tracking_enabled()}, + }; for (const auto& flag : flags) { diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index a957cb27c..0349db1b8 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -125,16 +125,7 @@ namespace vcpkg Debug::print("Using vcpkg-root: ", root.u8string(), '\n'); std::error_code ec; - const auto vcpkg_lock = root / ".vcpkg-root"; - m_pimpl->file_lock_handle = filesystem.try_take_exclusive_file_lock(vcpkg_lock, ec); - if (ec) - { - System::printf(System::Color::error, "Failed to take the filesystem lock on %s:\n", vcpkg_lock.u8string()); - System::printf(System::Color::error, " %s\n", ec.message()); - System::print2(System::Color::error, "Exiting now.\n"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - + bool manifest_mode_on = args.manifest_mode.value_or(args.manifest_root_dir != nullptr); if (args.manifest_root_dir) { manifest_root_dir = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.manifest_root_dir)); @@ -145,12 +136,28 @@ namespace vcpkg } uppercase_win32_drive_letter(manifest_root_dir); - if (!manifest_root_dir.empty() && args.manifest_mode.value_or(true)) + if (!manifest_root_dir.empty() && manifest_mode_on) { - Debug::print("Using manifest-root: ", root.u8string(), '\n'); + Debug::print("Using manifest-root: ", manifest_root_dir.u8string(), '\n'); installed = process_output_directory( filesystem, manifest_root_dir, args.install_root_dir.get(), "vcpkg_installed", VCPKG_LINE_INFO); + const auto vcpkg_lock = root / ".vcpkg-root"; + if (args.wait_for_lock.value_or(false)) + { + m_pimpl->file_lock_handle = filesystem.take_exclusive_file_lock(vcpkg_lock, ec); + } + else + { + m_pimpl->file_lock_handle = filesystem.try_take_exclusive_file_lock(vcpkg_lock, ec); + } + if (ec) + { + System::printf( + System::Color::error, "Failed to take the filesystem lock on %s:\n", vcpkg_lock.u8string()); + System::printf(System::Color::error, " %s\n", ec.message()); + Checks::exit_fail(VCPKG_LINE_INFO); + } } else { @@ -404,10 +411,13 @@ If you wish to silence this error and use classic mode, you can: VcpkgPaths::~VcpkgPaths() { std::error_code ec; - m_pimpl->fs_ptr->unlock_file_lock(m_pimpl->file_lock_handle, ec); - if (ec) + if (m_pimpl->file_lock_handle.is_valid()) { - Debug::print("Failed to unlock filesystem lock: ", ec.message(), '\n'); + m_pimpl->fs_ptr->unlock_file_lock(m_pimpl->file_lock_handle, ec); + if (ec) + { + Debug::print("Failed to unlock filesystem lock: ", ec.message(), '\n'); + } } } } diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp index 209a473c6..d6ee6e93b 100644 --- a/toolsrc/src/vcpkg/versiont.cpp +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -5,12 +5,20 @@ namespace vcpkg { - VersionT::VersionT() noexcept : value("0.0.0") { } - VersionT::VersionT(std::string&& value) : value(std::move(value)) { } - VersionT::VersionT(const std::string& value) : value(value) { } - const std::string& VersionT::to_string() const { return value; } - bool operator==(const VersionT& left, const VersionT& right) { return left.to_string() == right.to_string(); } - bool operator!=(const VersionT& left, const VersionT& right) { return left.to_string() != right.to_string(); } + VersionT::VersionT() noexcept : value("0.0.0"), port_version(0) { } + VersionT::VersionT(std::string&& value, int port_version) : value(std::move(value)), port_version(port_version) { } + VersionT::VersionT(const std::string& value, int port_version) : value(value), port_version(port_version) { } + + std::string VersionT::to_string() const + { + return port_version == 0 ? value : Strings::format("%s#%d", value, port_version); + } + + bool operator==(const VersionT& left, const VersionT& right) + { + return left.port_version == right.port_version && left.value == right.value; + } + bool operator!=(const VersionT& left, const VersionT& right) { return !(left == right); } VersionDiff::VersionDiff() noexcept : left(), right() { } VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) { }