Handle symlink when installing or removing a library
MODIFY
include/vcpkg/base/files.h
include/vcpkg/base/files.h
@@ -20,6 +20,7 @@ namespace fs
inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); }
inline bool is_directory(file_status s) { return stdfs::is_directory(s); }
+ inline bool is_symlink(file_status s) { return stdfs::is_symlink(s); }
}
namespace vcpkg::Files
@@ -54,7 +55,9 @@ namespace vcpkg::Files
const fs::path& newpath,
fs::copy_options opts,
std::error_code& ec) = 0;
+ virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) = 0;
virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0;
+ virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const = 0;
virtual std::vector<fs::path> find_from_PATH(const std::string& name) const = 0;

MODIFY
src/vcpkg/base/files.cpp
src/vcpkg/base/files.cpp
@@ -216,11 +216,19 @@ namespace vcpkg::Files
{
return fs::stdfs::copy_file(oldpath, newpath, opts, ec);
}
+ virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec)
+ {
+ return fs::stdfs::copy_symlink(oldpath, newpath, ec);
+ }
virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override
{
return fs::stdfs::status(path, ec);
}
+ virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const override
+ {
+ return fs::stdfs::symlink_status(path, ec);
+ }
virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) override
{
ec.clear();

MODIFY
src/vcpkg/install.cpp
src/vcpkg/install.cpp
@@ -62,7 +62,7 @@ namespace vcpkg::Install
auto files = fs.get_files_recursive(source_dir);
for (auto&& file : files)
{
- const auto status = fs.status(file, ec);
+ const auto status = fs.symlink_status(file, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message());
@@ -111,6 +111,23 @@ namespace vcpkg::Install
output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix));
break;
}
+ case fs::file_type::symlink:
+ {
+ if (fs.exists(target))
+ {
+ System::println(System::Color::warning,
+ "File %s was already present and will be overwritten",
+ target.u8string(),
+ ec.message());
+ }
+ fs.copy_symlink(file, target, ec);
+ if (ec)
+ {
+ System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message());
+ }
+ output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix));
+ break;
+ }
default:
System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string());
break;

MODIFY
src/vcpkg/remove.cpp
src/vcpkg/remove.cpp
@@ -55,7 +55,7 @@ namespace vcpkg::Remove
auto target = paths.installed / suffix;
- const auto status = fs.status(target, ec);
+ const auto status = fs.symlink_status(target, ec);
if (ec)
{
System::println(System::Color::error, "failed: status(%s): %s", target.u8string(), ec.message());
@@ -66,7 +66,7 @@ namespace vcpkg::Remove
{
dirs_touched.push_back(target);
}
- else if (fs::is_regular_file(status))
+ else if (fs::is_regular_file(status) || fs::is_symlink(status))
{
fs.remove(target, ec);
if (ec)

Handle symlink when installing or removing a library (#4479)