From 421996707e28caec9ce3702e3f9b451bf5d4c969 Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Thu, 12 Sep 2024 09:26:51 -0700 Subject: [PATCH] Legacy support: customized filesystem --- .../test/rtc/include/rtc/compile_kernel.hpp | 4 +- codegen/test/rtc/include/rtc/tmp_dir.hpp | 4 +- codegen/test/rtc/src/compile_kernel.cpp | 8 +- codegen/test/rtc/src/tmp_dir.cpp | 6 +- include/ck/filesystem.hpp | 179 ++++++++++++++++++ 5 files changed, 190 insertions(+), 11 deletions(-) create mode 100644 include/ck/filesystem.hpp diff --git a/codegen/test/rtc/include/rtc/compile_kernel.hpp b/codegen/test/rtc/include/rtc/compile_kernel.hpp index 5a4a4b0dd6..01bc379371 100644 --- a/codegen/test/rtc/include/rtc/compile_kernel.hpp +++ b/codegen/test/rtc/include/rtc/compile_kernel.hpp @@ -2,14 +2,14 @@ #define GUARD_HOST_TEST_RTC_INCLUDE_RTC_COMPILE_KERNEL #include -#include +#include #include namespace rtc { struct src_file { - std::filesystem::path path; + fs::path path; std::string_view content; }; diff --git a/codegen/test/rtc/include/rtc/tmp_dir.hpp b/codegen/test/rtc/include/rtc/tmp_dir.hpp index f0fd1f72bb..905845c684 100644 --- a/codegen/test/rtc/include/rtc/tmp_dir.hpp +++ b/codegen/test/rtc/include/rtc/tmp_dir.hpp @@ -2,13 +2,13 @@ #define GUARD_HOST_TEST_RTC_INCLUDE_RTC_TMP_DIR #include -#include +#include namespace rtc { struct tmp_dir { - std::filesystem::path path; + fs::path path; tmp_dir(const std::string& prefix = ""); void execute(const std::string& cmd) const; diff --git a/codegen/test/rtc/src/compile_kernel.cpp b/codegen/test/rtc/src/compile_kernel.cpp index d84ebf4de9..62b4b984ac 100644 --- a/codegen/test/rtc/src/compile_kernel.cpp +++ b/codegen/test/rtc/src/compile_kernel.cpp @@ -70,9 +70,9 @@ kernel compile_kernel(const std::vector& srcs, compile_options options for(const auto& src : srcs) { - std::filesystem::path full_path = td.path / src.path; - std::filesystem::path parent_path = full_path.parent_path(); - std::filesystem::create_directories(parent_path); + fs::path full_path = td.path / src.path; + fs::path parent_path = full_path.parent_path(); + fs::create_directories(parent_path); write_string(full_path.string(), src.content); if(src.path.extension().string() == ".cpp") { @@ -86,7 +86,7 @@ kernel compile_kernel(const std::vector& srcs, compile_options options td.execute(compiler() + options.flags); auto out_path = td.path / out; - if(not std::filesystem::exists(out_path)) + if(not fs::exists(out_path)) throw std::runtime_error("Output file missing: " + out); auto obj = read_buffer(out_path.string()); diff --git a/codegen/test/rtc/src/tmp_dir.cpp b/codegen/test/rtc/src/tmp_dir.cpp index 1cc8f75b29..4e89bc3539 100644 --- a/codegen/test/rtc/src/tmp_dir.cpp +++ b/codegen/test/rtc/src/tmp_dir.cpp @@ -31,10 +31,10 @@ std::string unique_string(const std::string& prefix) } tmp_dir::tmp_dir(const std::string& prefix) - : path(std::filesystem::temp_directory_path() / + : path(fs::temp_directory_path() / unique_string(prefix.empty() ? "ck-rtc" : "ck-rtc-" + prefix)) { - std::filesystem::create_directories(this->path); + fs::create_directories(this->path); } void tmp_dir::execute(const std::string& cmd) const @@ -43,6 +43,6 @@ void tmp_dir::execute(const std::string& cmd) const std::system(s.c_str()); } -tmp_dir::~tmp_dir() { std::filesystem::remove_all(this->path); } +tmp_dir::~tmp_dir() { fs::remove_all(this->path); } } // namespace rtc diff --git a/include/ck/filesystem.hpp b/include/ck/filesystem.hpp new file mode 100644 index 0000000000..97b447659c --- /dev/null +++ b/include/ck/filesystem.hpp @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2018-2024, Advanced Micro Devices, Inc. All rights reserved. + +#ifndef GUARD_CK_FILESYSTEM_HPP_ +#define GUARD_CK_FILESYSTEM_HPP_ + +#include +#include + +// clang-format off +#if defined(CPPCHECK) + #define CK_HAS_FILESYSTEM 1 + #define CK_HAS_FILESYSTEM_TS 1 +#elif defined(_WIN32) + #if _MSC_VER >= 1920 + #define CK_HAS_FILESYSTEM 1 + #define CK_HAS_FILESYSTEM_TS 0 + #elif _MSC_VER >= 1900 + #define CK_HAS_FILESYSTEM 0 + #define CK_HAS_FILESYSTEM_TS 1 + #else + #define CK_HAS_FILESYSTEM 0 + #define CK_HAS_FILESYSTEM_TS 0 + #endif +#elif defined(__has_include) + #if __has_include() && __cplusplus >= 201703L + #define CK_HAS_FILESYSTEM 1 + #else + #define CK_HAS_FILESYSTEM 0 + #endif + #if __has_include() && __cplusplus >= 201103L + #define CK_HAS_FILESYSTEM_TS 1 + #else + #define CK_HAS_FILESYSTEM_TS 0 + #endif +#else + #define CK_HAS_FILESYSTEM 0 + #define CK_HAS_FILESYSTEM_TS 0 +#endif +// clang-format on + +#if CK_WORKAROUND_USE_BOOST_FILESYSTEM +#undef CK_HAS_FILESYSTEM +#undef CK_HAS_FILESYSTEM_TS +#define CK_HAS_FILESYSTEM 0 +#define CK_HAS_FILESYSTEM_TS 0 +#endif + +#if CK_HAS_FILESYSTEM +#include +#elif CK_HAS_FILESYSTEM_TS +#include +#elif CK_WORKAROUND_USE_BOOST_FILESYSTEM +/// Explicit inclusion of is a workaround for the Boost 1.83 issue. +/// +/// Boost doc is saying: +/// When writing template classes, you might not want to include the main hash.hpp header as it's +/// quite an expensive include that brings in a lot of other headers, so instead you can include +/// the header which forward declares boost::hash, +/// boost::hash_combine, boost::hash_range, and boost::hash_unordered_range. You'll need to +/// include the main header before instantiating boost::hash. +/// +/// \ref https://www.boost.org/doc/libs/1_83_0/libs/container_hash/doc/html/hash.html#combine +/// +/// It seems like boost::filesystem uses boost::hash_range but misses to include hash.hpp, so we +/// have to include it explicitly. Otherwise an error like this happens at runtime (!): +/// +/// \code +/// ...symbol lookup error: .../libCK.so.1: undefined symbol: +/// _ZN5boost10hash_rangeIN9__gnu_cxx17__normal_iteratorIPKcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEEEmT_SC_ +/// \endcode +#include +#define BOOST_FILESYSTEM_NO_DEPRECATED 1 +#include +#else +#error "No filesystem include available" +#endif + +namespace CK { + +#if CK_HAS_FILESYSTEM +namespace fs = ::std::filesystem; +#elif CK_HAS_FILESYSTEM_TS +namespace fs = ::std::experimental::filesystem; +#elif CK_WORKAROUND_USE_BOOST_FILESYSTEM +namespace fs = ::boost::filesystem; +#endif + +} // namespace CK + +inline std::string operator+(const std::string_view s, const CK::fs::path& path) +{ +#if CK_WORKAROUND_USE_BOOST_FILESYSTEM + return std::string(path.native()).insert(0, s); +#else + return path.string().insert(0, s); +#endif +} + +inline std::string operator+(const CK::fs::path& path, const std::string_view s) +{ +#if CK_WORKAROUND_USE_BOOST_FILESYSTEM + return std::string(path.native()).append(s); +#else + return path.string().append(s); +#endif +} + +// Hack to minimize changes for boost fs. +#if CK_WORKAROUND_USE_BOOST_FILESYSTEM +#define FS_ENUM_PERMS_ALL fs::perms::all_all +#else +#define FS_ENUM_PERMS_ALL fs::perms::all +#endif + +#if CK_HAS_FILESYSTEM_TS +#ifdef __linux__ +#include +namespace CK { +inline fs::path weakly_canonical(const fs::path& path) +{ + std::string result(PATH_MAX, '\0'); + std::string p{path.is_relative() ? (fs::current_path() / path).string() : path.string()}; + char* retval = realpath(p.c_str(), &result[0]); + return (retval == nullptr) ? path : fs::path{result}; +} +} // namespace CK +#else +#error "Not implmeneted!" +#endif +#else +namespace CK { +inline fs::path weakly_canonical(const fs::path& path) { return fs::weakly_canonical(path); } +} // namespace CK +#endif + +namespace CK { + +#ifdef _WIN32 +constexpr std::string_view executable_postfix{".exe"}; +constexpr std::string_view library_prefix{""}; +constexpr std::string_view dynamic_library_postfix{".dll"}; +constexpr std::string_view static_library_postfix{".lib"}; +constexpr std::string_view object_file_postfix{".obj"}; +#else +constexpr std::string_view executable_postfix{""}; +constexpr std::string_view library_prefix{"lib"}; +constexpr std::string_view dynamic_library_postfix{".so"}; +constexpr std::string_view static_library_postfix{".a"}; +constexpr std::string_view object_file_postfix{".o"}; +#endif + +inline fs::path make_executable_name(const fs::path& path) +{ + return path.parent_path() / (path.filename() + executable_postfix); +} + +inline fs::path make_dynamic_library_name(const fs::path& path) +{ + return path.parent_path() / (library_prefix + path.filename() + dynamic_library_postfix); +} + +inline fs::path make_object_file_name(const fs::path& path) +{ + return path.parent_path() / (path.filename() + object_file_postfix); +} + +inline fs::path make_static_library_name(const fs::path& path) +{ + return path.parent_path() / (library_prefix + path.filename() + static_library_postfix); +} + +struct FsPathHash +{ + std::size_t operator()(const fs::path& path) const { return fs::hash_value(path); } +}; +} // namespace CK + +#endif // GUARD_CK_FILESYSTEM_HPP_