mirror of
https://git.mirrors.martin98.com/https://github.com/gulrak/filesystem
synced 2025-07-21 11:04:25 +08:00
Refactored builds with std::fs to a CMake macro, added du example, added behaviour switch
This commit is contained in:
parent
624a6f63e5
commit
2ac1352b4a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/build*/
|
||||
.vscode/
|
||||
|
@ -25,7 +25,10 @@ target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-
|
||||
|
||||
get_directory_property(hasParent PARENT_DIRECTORY)
|
||||
if(NOT hasParent)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(examples)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
include(GhcHelper)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
36
cmake/GhcHelper.cmake
Normal file
36
cmake/GhcHelper.cmake
Normal file
@ -0,0 +1,36 @@
|
||||
macro(AddExecutableWithStdFS targetName)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
||||
if(APPLE)
|
||||
include_directories(/usr/local/opt/llvm/include)
|
||||
link_directories(/usr/local/opt/llvm/lib)
|
||||
endif()
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
if(APPLE)
|
||||
target_link_libraries(${targetName} -lc++fs)
|
||||
else()
|
||||
target_compile_options(${targetName} PRIVATE "-stdlib=libc++")
|
||||
target_link_libraries(${targetName} -stdlib=libc++ -lc++fs)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${targetName} -lc++fs)
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0))
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
target_link_libraries(${targetName} -lstdc++fs)
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 19.15 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.15))
|
||||
add_executable(${targetName} ${ARGN})
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET ${targetName} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
target_compile_options(${targetName} PRIVATE "/Zc:__cplusplus")
|
||||
target_compile_definitions(${targetName} PRIVATE USE_STD_FS _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
endmacro()
|
@ -4,34 +4,9 @@ target_link_libraries(fs_dir ghc_filesystem)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
target_compile_definitions(fs_dir PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
AddExecutableWithStdFS(std_fs_dir dir.cpp)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
||||
if(APPLE)
|
||||
include_directories(/usr/local/opt/llvm/include)
|
||||
link_directories(/usr/local/opt/llvm/lib)
|
||||
endif()
|
||||
add_executable(std_fs_dir dir.cpp)
|
||||
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||
if(APPLE)
|
||||
target_link_libraries(std_fs_dir -lc++fs)
|
||||
else()
|
||||
target_compile_options(std_fs_dir PRIVATE "-stdlib=libc++")
|
||||
target_link_libraries(std_fs_dir -stdlib=libc++ -lc++fs)
|
||||
endif()
|
||||
add_executable(fs_du du.cpp)
|
||||
target_link_libraries(fs_du ghc_filesystem)
|
||||
AddExecutableWithStdFS(std_fs_du du.cpp)
|
||||
|
||||
target_link_libraries(std_fs_dir -lc++fs)
|
||||
endif()
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0))
|
||||
add_executable(std_fs_dir dir.cpp)
|
||||
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||
target_link_libraries(std_fs_dir -lstdc++fs)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 19.15 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.15))
|
||||
add_executable(std_fs_dir dir.cpp)
|
||||
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
target_compile_options(std_fs_dir PRIVATE "/Zc:__cplusplus")
|
||||
target_compile_definitions(std_fs_dir PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
46
examples/du.cpp
Normal file
46
examples/du.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) && __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs = ghc::filesystem;
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef GHC_FILESYSTEM_VERSION
|
||||
fs::u8arguments u8guard(argc, argv);
|
||||
if(!u8guard.valid()) {
|
||||
std::cerr << "Invalid character encoding, UTF-8 based encoding needed." << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
if(argc > 2) {
|
||||
std::cerr << "USAGE: du <path>" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
fs::path dir{"."};
|
||||
if(argc == 2) {
|
||||
dir = fs::u8path(argv[1]);
|
||||
}
|
||||
|
||||
uint64_t totalSize = 0;
|
||||
|
||||
try {
|
||||
for(auto de : fs::recursive_directory_iterator(dir)) {
|
||||
if(de.is_regular_file()) {
|
||||
totalSize += de.file_size();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(fs::filesystem_error fe) {
|
||||
std::cerr << "Error: " << fe.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cout << totalSize << std::endl;
|
||||
return 0;
|
||||
}
|
@ -144,6 +144,7 @@
|
||||
#endif // GHC_EXPAND_IMPL
|
||||
|
||||
// configure LWG conformance (see README.md)
|
||||
#define LWG_2682_BEHAVIOUR
|
||||
// #define LWG_2935_BEHAVIOUR
|
||||
#define LWG_2937_BEHAVIOUR
|
||||
|
||||
@ -1007,6 +1008,7 @@ enum class portable_error {
|
||||
not_supported,
|
||||
not_implemented,
|
||||
invalid_argument,
|
||||
is_a_directory,
|
||||
};
|
||||
GHC_FS_API std::error_code make_error_code(portable_error err);
|
||||
} // namespace detail
|
||||
@ -1031,6 +1033,8 @@ GHC_INLINE std::error_code make_error_code(portable_error err)
|
||||
return std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category());
|
||||
case portable_error::invalid_argument:
|
||||
return std::error_code(ERROR_INVALID_PARAMETER, std::system_category());
|
||||
case portable_error::is_a_directory:
|
||||
return std::error_code(ERROR_DIRECTORY_NOT_SUPPORTED, std::system_category());
|
||||
}
|
||||
#else
|
||||
switch (err) {
|
||||
@ -1046,6 +1050,8 @@ GHC_INLINE std::error_code make_error_code(portable_error err)
|
||||
return std::error_code(ENOSYS, std::system_category());
|
||||
case portable_error::invalid_argument:
|
||||
return std::error_code(EINVAL, std::system_category());
|
||||
case portable_error::is_a_directory:
|
||||
return std::error_code(EISDIR, std::system_category());
|
||||
}
|
||||
#endif
|
||||
return std::error_code();
|
||||
@ -1641,9 +1647,9 @@ GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::er
|
||||
GHC_INLINE bool is_not_found_error(std::error_code& ec)
|
||||
{
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
return ec.value() == ERROR_FILE_NOT_FOUND || ec.value() == ERROR_PATH_NOT_FOUND;
|
||||
return ec.value() == ERROR_FILE_NOT_FOUND || ec.value() == ERROR_PATH_NOT_FOUND || ec.value() == ERROR_INVALID_NAME;
|
||||
#else
|
||||
return ec.value() == ENOENT;
|
||||
return ec.value() == ENOENT || ec.value() == ENOTDIR;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1665,7 +1671,7 @@ GHC_INLINE file_status symlink_status_ex(const path& p, std::error_code& ec, uin
|
||||
fs.type(file_type::symlink);
|
||||
}
|
||||
}
|
||||
if (ec.value() == ERROR_FILE_NOT_FOUND) {
|
||||
if (detail::is_not_found_error(ec)) {
|
||||
return file_status(file_type::not_found);
|
||||
}
|
||||
return ec ? file_status(file_type::none) : fs;
|
||||
@ -1680,9 +1686,8 @@ GHC_INLINE file_status symlink_status_ex(const path& p, std::error_code& ec, uin
|
||||
file_status f_s = detail::file_status_from_st_mode(fs.st_mode);
|
||||
return f_s;
|
||||
}
|
||||
auto error = errno;
|
||||
ec = std::error_code(error, std::system_category());
|
||||
if (error == ENOENT) {
|
||||
ec = std::error_code(errno, std::system_category());
|
||||
if (detail::is_not_found_error(ec)) {
|
||||
return file_status(file_type::not_found, perms::unknown);
|
||||
}
|
||||
return file_status(file_type::none);
|
||||
@ -1750,9 +1755,8 @@ GHC_INLINE file_status status_ex(const path& p, std::error_code& ec, file_status
|
||||
return fs;
|
||||
}
|
||||
else {
|
||||
auto error = errno;
|
||||
ec = std::error_code(errno, std::system_category());
|
||||
if (error == ENOENT) {
|
||||
if (detail::is_not_found_error(ec)) {
|
||||
return file_status(file_type::not_found, perms::unknown);
|
||||
}
|
||||
return file_status(file_type::none);
|
||||
@ -1793,6 +1797,7 @@ GHC_INLINE u8arguments::u8arguments(int& argc, char**& argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 30.10.8.4.1 constructors and destructor
|
||||
|
||||
@ -2955,10 +2960,10 @@ GHC_INLINE void copy(const path& from, const path& to, copy_options options, std
|
||||
}
|
||||
else if (is_regular_file(fs_from)) {
|
||||
if ((options & copy_options::directories_only) == copy_options::none) {
|
||||
if ((options & copy_options::create_symlinks) == copy_options::create_symlinks) {
|
||||
if ((options & copy_options::create_symlinks) != copy_options::none) {
|
||||
create_symlink(from.is_absolute() ? from : canonical(from, ec), to, ec);
|
||||
}
|
||||
else if ((options & copy_options::create_hard_links) == copy_options::create_hard_links) {
|
||||
else if ((options & copy_options::create_hard_links) != copy_options::none) {
|
||||
create_hard_link(from, to, ec);
|
||||
}
|
||||
else if (is_directory(fs_to)) {
|
||||
@ -2969,7 +2974,12 @@ GHC_INLINE void copy(const path& from, const path& to, copy_options options, std
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_directory(fs_from) && (options == copy_options::none || (options & copy_options::recursive) == copy_options::recursive)) {
|
||||
#ifdef LWG_2682_BEHAVIOUR
|
||||
else if(is_directory(fs_from) && (options & copy_options::create_symlinks) != copy_options::none) {
|
||||
ec = detail::make_error_code(detail::portable_error::is_a_directory);
|
||||
}
|
||||
#endif
|
||||
else if (is_directory(fs_from) && (options == copy_options::none || (options & copy_options::recursive) != copy_options::none)) {
|
||||
if (!exists(fs_to)) {
|
||||
create_directory(to, from, ec);
|
||||
if (ec) {
|
||||
@ -4074,7 +4084,8 @@ GHC_INLINE path weakly_canonical(const path& p, std::error_code& ec) noexcept
|
||||
bool scan = true;
|
||||
for (auto pe : p) {
|
||||
if (scan) {
|
||||
if (exists(result / pe, ec)) {
|
||||
std::error_code tec;
|
||||
if (exists(result / pe, tec)) {
|
||||
result /= pe;
|
||||
}
|
||||
else {
|
||||
|
@ -18,34 +18,7 @@ if(CMAKE_GENERATOR STREQUAL Xcode)
|
||||
target_link_libraries(filesystem_test_cov PUBLIC ghc_filesystem PRIVATE --coverage)
|
||||
endif()
|
||||
ParseAndAddCatchTests(filesystem_test filesystem_test)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
|
||||
if(APPLE)
|
||||
include_directories(/usr/local/opt/llvm/include)
|
||||
link_directories(/usr/local/opt/llvm/lib)
|
||||
endif()
|
||||
add_executable(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
||||
if(APPLE)
|
||||
target_link_libraries(std_filesystem_test -lc++fs)
|
||||
else()
|
||||
target_compile_options(std_filesystem_test PRIVATE "-stdlib=libc++")
|
||||
target_link_libraries(std_filesystem_test -stdlib=libc++ -lc++fs)
|
||||
endif()
|
||||
endif()
|
||||
if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0))
|
||||
add_executable(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)
|
||||
target_link_libraries(std_filesystem_test -lstdc++fs)
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 19.15 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.15))
|
||||
add_executable(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
|
||||
target_compile_options(std_filesystem_test PRIVATE "/Zc:__cplusplus")
|
||||
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
|
||||
|
||||
add_executable(multifile_test multi1.cpp multi2.cpp catch.hpp)
|
||||
target_link_libraries(multifile_test ghc_filesystem)
|
||||
|
@ -87,6 +87,7 @@ using fstream = ghc::filesystem::fstream;
|
||||
#endif
|
||||
#include "catch.hpp"
|
||||
|
||||
#define TEST_LWG_2682_BEHAVIOUR
|
||||
//#define TEST_LWG_2935_BEHAVIOUR
|
||||
#define TEST_LWG_2937_BEHAVIOUR
|
||||
|
||||
@ -1280,6 +1281,9 @@ TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]")
|
||||
generateFile("dir1/file2");
|
||||
fs::create_directory("dir1/dir2");
|
||||
generateFile("dir1/dir2/file3");
|
||||
#ifdef TEST_LWG_2682_BEHAVIOUR
|
||||
REQUIRE_THROWS_AS(fs::copy("dir1", "dir3", fs::copy_options::create_symlinks | fs::copy_options::recursive), fs::filesystem_error);
|
||||
#else
|
||||
REQUIRE_NOTHROW(fs::copy("dir1", "dir3", fs::copy_options::create_symlinks | fs::copy_options::recursive));
|
||||
CHECK(!ec);
|
||||
CHECK(fs::exists("dir3/file1"));
|
||||
@ -1288,6 +1292,7 @@ TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]")
|
||||
CHECK(fs::is_symlink("dir3/file2"));
|
||||
CHECK(fs::exists("dir3/dir2/file3"));
|
||||
CHECK(fs::is_symlink("dir3/dir2/file3"));
|
||||
#endif
|
||||
}
|
||||
{
|
||||
TemporaryDirectory t(TempOpt::change_path);
|
||||
@ -1537,7 +1542,7 @@ TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]"
|
||||
INFO("This test expects LWG #2937 result conformance.");
|
||||
std::error_code ec;
|
||||
bool result = false;
|
||||
CHECK_THROWS_AS(fs::equivalent("foo", "foo3"), fs::filesystem_error);
|
||||
REQUIRE_THROWS_AS(fs::equivalent("foo", "foo3"), fs::filesystem_error);
|
||||
CHECK_NOTHROW(result = fs::equivalent("foo", "foo3", ec));
|
||||
CHECK(!result);
|
||||
CHECK(ec);
|
||||
@ -1555,7 +1560,7 @@ TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]"
|
||||
INFO("This test expects conformance predating LWG #2937 result.");
|
||||
std::error_code ec;
|
||||
bool result = false;
|
||||
CHECK_NOTHROW(result = fs::equivalent("foo", "foo3"));
|
||||
REQUIRE_NOTHROW(result = fs::equivalent("foo", "foo3"));
|
||||
CHECK(!result);
|
||||
CHECK_NOTHROW(result = fs::equivalent("foo", "foo3", ec));
|
||||
CHECK(!result);
|
||||
@ -2288,8 +2293,10 @@ TEST_CASE("30.10.15.39 weakly_canonical", "[filesystem][operations][fs.op.weakly
|
||||
CHECK(fs::weakly_canonical(dir) == dir);
|
||||
CHECK(fs::weakly_canonical(rel) == dir);
|
||||
CHECK(fs::weakly_canonical(dir / "f0") == dir / "f0");
|
||||
CHECK(fs::weakly_canonical(dir / "f0/") == dir / "f0/");
|
||||
CHECK(fs::weakly_canonical(dir / "f1") == dir / "f1");
|
||||
CHECK(fs::weakly_canonical(rel / "f0") == dir / "f0");
|
||||
CHECK(fs::weakly_canonical(rel / "f0/") == dir / "f0/");
|
||||
CHECK(fs::weakly_canonical(rel / "f1") == dir / "f1");
|
||||
CHECK(fs::weakly_canonical(rel / "./f0") == dir / "f0");
|
||||
CHECK(fs::weakly_canonical(rel / "./f1") == dir / "f1");
|
||||
|
Loading…
x
Reference in New Issue
Block a user