Workaround failures of filesystem::canonical
* Apply alternate workaround for canonical failures of fixing case and normalizing.
Fixes:
*
*
*
MODIFY
include/vcpkg/base/files.h
include/vcpkg/base/files.h
@@ -238,9 +238,14 @@ namespace vcpkg::Files
fs::file_status symlink_status(const fs::path& p, ignore_errors_t) const noexcept;
virtual fs::path absolute(const fs::path& path, std::error_code& ec) const = 0;
fs::path absolute(LineInfo li, const fs::path& path) const;
- virtual fs::path canonical(const fs::path& path, std::error_code& ec) const = 0;
- fs::path canonical(LineInfo li, const fs::path& path) const;
- fs::path canonical(const fs::path& path, ignore_errors_t) const;
+ // absolute/system_complete + lexically_normal + fixup_win32_path_case
+ // we don't use real canonical due to issues like:
+ // https://github.com/microsoft/vcpkg/issues/16614 (canonical breaking on some older Windows Server containers)
+ // https://github.com/microsoft/vcpkg/issues/18208 (canonical removing subst despite our recommendation to use
+ // subst)
+ virtual fs::path almost_canonical(const fs::path& path, std::error_code& ec) const = 0;
+ fs::path almost_canonical(LineInfo li, const fs::path& path) const;
+ fs::path almost_canonical(const fs::path& path, ignore_errors_t) const;
virtual fs::path current_path(std::error_code&) const = 0;
fs::path current_path(LineInfo li) const;
virtual void current_path(const fs::path& path, std::error_code&) = 0;

MODIFY
src/vcpkg/base/files.cpp
src/vcpkg/base/files.cpp
@@ -745,10 +745,10 @@ namespace vcpkg::Files
return result;
}
- fs::path Filesystem::canonical(LineInfo li, const fs::path& path) const
+ fs::path Filesystem::almost_canonical(LineInfo li, const fs::path& path) const
{
std::error_code ec;
- const auto result = this->canonical(path, ec);
+ const auto result = this->almost_canonical(path, ec);
if (ec)
{
Checks::exit_with_message(li, "Error getting canonicalization of %s: %s", path.string(), ec.message());
@@ -756,10 +756,10 @@ namespace vcpkg::Files
return result;
}
- fs::path Filesystem::canonical(const fs::path& path, ignore_errors_t) const
+ fs::path Filesystem::almost_canonical(const fs::path& path, ignore_errors_t) const
{
std::error_code ec;
- return this->canonical(path, ec);
+ return this->almost_canonical(path, ec);
}
fs::path Filesystem::current_path(LineInfo li) const
{
@@ -1301,9 +1301,19 @@ namespace vcpkg::Files
#endif // ^^^ !VCPKG_USE_STD_FILESYSTEM
}
- virtual fs::path canonical(const fs::path& path, std::error_code& ec) const override
+ virtual fs::path almost_canonical(const fs::path& path, std::error_code& ec) const override
{
- return fs::stdfs::canonical(path, ec);
+ auto result = this->absolute(path, ec);
+ if (ec)
+ {
+ return result;
+ }
+
+ result = fs::lexically_normal(result);
+#if defined(_WIN32)
+ result = vcpkg::Files::win32_fix_path_case(result);
+#endif // _WIN32
+ return result;
}
virtual fs::path current_path(std::error_code& ec) const override { return fs::stdfs::current_path(ec); }

MODIFY
src/vcpkg/commands.ci.cpp
src/vcpkg/commands.ci.cpp
@@ -492,7 +492,7 @@ namespace vcpkg::Commands::CI
auto raw_path = fs::u8path(it_failure_logs->second);
System::printf("Creating failure logs output directory %s\n", it_failure_logs->second);
filesystem.create_directories(raw_path, VCPKG_LINE_INFO);
- build_logs_recorder_storage = filesystem.canonical(VCPKG_LINE_INFO, raw_path);
+ build_logs_recorder_storage = filesystem.almost_canonical(VCPKG_LINE_INFO, raw_path);
}
}

MODIFY
src/vcpkg/vcpkgpaths.cpp
src/vcpkg/vcpkgpaths.cpp
@@ -31,7 +31,7 @@ namespace
if (option)
{
// input directories must exist, so we use canonical
- return filesystem.canonical(li, fs::u8path(*option));
+ return filesystem.almost_canonical(li, fs::u8path(*option));
}
else
{
@@ -293,7 +293,7 @@ namespace vcpkg
if (args.vcpkg_root_dir)
{
- root = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.vcpkg_root_dir));
+ root = filesystem.almost_canonical(VCPKG_LINE_INFO, fs::u8path(*args.vcpkg_root_dir));
}
else
{
@@ -301,7 +301,8 @@ namespace vcpkg
if (root.empty())
{
root = filesystem.find_file_recursively_up(
- filesystem.canonical(VCPKG_LINE_INFO, System::get_exe_path_of_current_process()), ".vcpkg-root");
+ filesystem.almost_canonical(VCPKG_LINE_INFO, System::get_exe_path_of_current_process()),
+ ".vcpkg-root");
}
}
@@ -313,7 +314,7 @@ namespace vcpkg
{
if (args.manifest_root_dir)
{
- manifest_root_dir = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.manifest_root_dir));
+ manifest_root_dir = filesystem.almost_canonical(VCPKG_LINE_INFO, fs::u8path(*args.manifest_root_dir));
}
else
{
@@ -408,11 +409,11 @@ namespace vcpkg
if (args.default_visual_studio_path)
{
m_pimpl->default_vs_path =
- filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.default_visual_studio_path));
+ filesystem.almost_canonical(VCPKG_LINE_INFO, fs::u8path(*args.default_visual_studio_path));
}
- triplets = filesystem.canonical(VCPKG_LINE_INFO, root / fs::u8path("triplets"));
- community_triplets = filesystem.canonical(VCPKG_LINE_INFO, triplets / fs::u8path("community"));
+ triplets = filesystem.almost_canonical(VCPKG_LINE_INFO, root / fs::u8path("triplets"));
+ community_triplets = filesystem.almost_canonical(VCPKG_LINE_INFO, triplets / fs::u8path("community"));
tools = downloads / fs::u8path("tools");
buildsystems = scripts / fs::u8path("buildsystems");
@@ -436,12 +437,12 @@ namespace vcpkg
versions_work_tree = versioning_tmp / fs::u8path("versions-worktree");
versions_output = versioning_output / fs::u8path("versions");
- ports_cmake = filesystem.canonical(VCPKG_LINE_INFO, scripts / fs::u8path("ports.cmake"));
+ ports_cmake = filesystem.almost_canonical(VCPKG_LINE_INFO, scripts / fs::u8path("ports.cmake"));
for (auto&& overlay_triplets_dir : args.overlay_triplets)
{
m_pimpl->triplets_dirs.emplace_back(
- filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir)));
+ filesystem.almost_canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir)));
}
m_pimpl->triplets_dirs.emplace_back(triplets);
m_pimpl->triplets_dirs.emplace_back(community_triplets);

Workaround failures of filesystem::canonical (#88)

* Apply alternate workaround for canonical failures of fixing case and normalizing.

Fixes:
* https://github.com/microsoft/vcpkg/issues/18326
* https://github.com/microsoft/vcpkg/issues/18208
* https://github.com/microsoft/vcpkg/issues/16614