]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
chore: Tweak Clang CUDA code slightly
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 25 May 2025 17:53:25 +0000 (19:53 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 29 May 2025 09:44:59 +0000 (11:44 +0200)
src/ccache/ccache.cpp
src/ccache/util/CMakeLists.txt
src/ccache/util/clang.cpp
src/ccache/util/clang.hpp
test/suites/clang_cu.bash
test/suites/clang_cu_direct.bash
unittest/test_util_clang.cpp

index dce332203aecac02cb8cd7c459a8e7efc62ee4a2..8c0bce3b5ef1b1f2963398cc81209cb8272a1087 100644 (file)
@@ -1335,9 +1335,8 @@ process_cuda_chunk(Context& ctx,
                    const std::string& chunk,
                    size_t index)
 {
-  // 1. Create a temp file for this CUDA chunk
   auto tmp_result = util::TemporaryFile::create(
-    FMT("{}/cuda_tmp_{}.i", ctx.config.temporary_dir(), index),
+    FMT("{}/cuda_tmp_{}", ctx.config.temporary_dir(), index),
     FMT(".{}", ctx.config.cpp_extension()));
   if (!tmp_result) {
     return tl::unexpected(Statistic::internal_error);
@@ -1346,24 +1345,18 @@ process_cuda_chunk(Context& ctx,
   const auto& chunk_path = tmp_result->path;
   tmp_result->fd.close(); // we only need the path, not the open fd
 
-  // 2. Write the chunk contents into the temp file
   if (!util::write_file(chunk_path, chunk)) {
     return tl::unexpected(Statistic::internal_error);
   }
-  // 3. Register the file so it gets cleaned up later
   ctx.register_pending_tmp_file(chunk_path);
-
-  // 4. Add a unique hash delimiter for this chunk
   hash.hash_delimiter(FMT("cu_{}", index));
-
-  // 5. Process the chunk just like a normal preprocessed file
   TRY(process_preprocessed_file(ctx, hash, chunk_path));
 
   return {};
 }
 
 static bool
-get_clang_cu_enable_verbose_mode(Args& args)
+get_clang_cu_enable_verbose_mode(const Args& args)
 {
   for (size_t i = 1; i < args.size(); i++) {
     if (args[i] == "-v") {
@@ -1384,9 +1377,8 @@ get_result_key_from_cpp(Context& ctx, Args& args, Hash& hash)
   util::Bytes cpp_stdout_data;
 
   // When Clang runs in verbose mode, it outputs command details to stdout,
-  // which can corrupt the output of precompiled CUDA files.
-  // Therefore, caching is disabled in this scenario.
-  // (Is there a better approach to handle this?)
+  // which can corrupt the output of precompiled CUDA files. Therefore, caching
+  // is disabled in this scenario. (Is there a better approach to handle this?)
   const bool is_clang_cu = ctx.config.is_compiler_group_clang()
                            && (ctx.args_info.actual_language == "cu"
                                || ctx.args_info.actual_language == "cuda")
@@ -1452,10 +1444,8 @@ get_result_key_from_cpp(Context& ctx, Args& args, Hash& hash)
 
   if (is_clang_cu) {
     util::write_file(preprocessed_path, cpp_stdout_data);
-
     auto chunks =
-      util::split_preprocess_file_in_clang_cuda(preprocessed_path.string());
-
+      util::split_preprocessed_file_from_clang_cuda(preprocessed_path);
     for (size_t i = 0; i < chunks.size(); ++i) {
       TRY(process_cuda_chunk(ctx, hash, chunks[i], i));
     }
index e6d1919527384c353b309fcae000b3ba033638c6..87a0722fe68b8376ab69cf548449a2f8a740378b 100644 (file)
@@ -2,6 +2,7 @@ set(
   sources
   assertions.cpp
   bytes.cpp
+  clang.cpp
   cpu.cpp
   direntry.cpp
   environment.cpp
@@ -24,7 +25,6 @@ set(
   tokenizer.cpp
   umaskscope.cpp
   zstd.cpp
-  clang.cpp
 )
 
 file(GLOB headers *.hpp)
index 4e3a2869598273305a6733207b7d02910ab4a1af..713daeb2be6a64a7ce2ede93ac0d8c78430b373a 100644 (file)
 
 #include "clang.hpp"
 
+#include <ccache/util/filesystem.hpp>
+#include <ccache/util/format.hpp>
 #include <ccache/util/logging.hpp>
 
+#include <cerrno>
 #include <fstream>
 #include <iostream>
-#include <string>
-#include <vector>
+
+namespace fs = util::filesystem;
 
 namespace util {
 
 std::vector<std::string>
-split_preprocess_file_in_clang_cuda(const std::string& mixed_preprocessed_path)
+split_preprocessed_file_from_clang_cuda(const fs::path& path)
 {
-  std::ifstream infile(mixed_preprocessed_path);
-  std::vector<std::string> split_preprocess_file_list;
+  std::ifstream infile(path);
+  std::vector<std::string> chunks;
 
   if (!infile) {
-    LOG("Can't open file {}", mixed_preprocessed_path);
-    return split_preprocess_file_list;
+    LOG("Failed to open {}: {}", path, strerror(errno));
+    return chunks;
   }
 
   std::string delimiter;
   if (!std::getline(infile, delimiter)) {
-    return split_preprocess_file_list;
+    return chunks;
   }
 
-  std::string currentPart = delimiter + "\n";
+  std::string current_part = delimiter + "\n";
   std::string line;
 
   while (std::getline(infile, line)) {
     if (line == delimiter) {
-      split_preprocess_file_list.push_back(currentPart);
-      currentPart = delimiter + "\n";
+      chunks.push_back(current_part);
+      current_part = delimiter + "\n";
     } else {
-      currentPart += line + "\n";
+      current_part += line + "\n";
     }
   }
 
-  if (!currentPart.empty()) {
-    split_preprocess_file_list.push_back(currentPart);
+  if (!current_part.empty()) {
+    chunks.push_back(current_part);
   }
 
-  return split_preprocess_file_list;
+  return chunks;
 }
 
 } // namespace util
index 4c7a262d464d958784fafa3b9993dc9aa89c9ad6..32e4861ad44eb9974ae713b5b6ffdaa00b594ad1 100644 (file)
 
 #pragma once
 
+#include <filesystem>
 #include <string>
 #include <vector>
 
 namespace util {
 
 std::vector<std::string>
-split_preprocess_file_in_clang_cuda(const std::string& mixed_preprocessed_path);
+split_preprocessed_file_from_clang_cuda(const std::filesystem::path& path);
 
 } // namespace util
index a6b35025b148cc7a49526666e4648f717d1923c7..57dbec4e7da180e875f3a286dc2fc89a949161d0 100644 (file)
@@ -1,4 +1,4 @@
-setup_clang() {
+set_up_clang() {
     local CUDA_PATH="--cuda-path=/usr/local/cuda"
     if [  ! -z "$CUDA_HOME" ]; then
         local CUDA_PATH="--cuda-path=$CUDA_HOME"
@@ -23,11 +23,11 @@ clang_cu_PROBE() {
         return
     fi
 
-    setup_clang
+    set_up_clang
 
     touch test.cu
     if ! $REAL_CLANG -c -x cu test.cu  >/dev/null 2>&1; then
-        echo "Clang's CUDA support is not compatible."
+        echo "Clang's CUDA support is not compatible"
     fi
 
 }
@@ -44,7 +44,6 @@ void caller() {
 }
 EOF
 
-
     # Test code using cuda.
     cat <<EOF >test_cuda.cu
 #ifndef NUM
@@ -66,7 +65,7 @@ EOF
 }
 
 clang_cu_tests() {
-    setup_clang
+    set_up_clang
 
     clang_opts_cpp="-c -x c++"
     clang_opts_cuda="-c -x $CLANG_CU_LANG_TYPE"
index 4f98303e780e8cdfdd87c24caa66501f65df9078..31d55d6d28f8298b3ec2d69236e333bae2873019 100644 (file)
@@ -9,7 +9,7 @@ SUITE_clang_cu_direct_SETUP() {
 }
 
 SUITE_clang_cu_direct() {
-    setup_clang
+    set_up_clang
 
     clang_opts_cpp="-c -x c++"
     clang_opts_cuda="-c -x $CLANG_CU_LANG_TYPE"
index 522630df1744aac18af98106e24d924ffa7b0122..afded55f4ac37953833806ab9ffbfbd8160b1722 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "testutil.hpp"
+
 #include <ccache/util/clang.hpp>
+#include <ccache/util/file.hpp>
+#include <ccache/util/filesystem.hpp>
 
 #include <doctest/doctest.h>
 
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <ostream> // https://github.com/doctest/doctest/issues/618
 #include <string>
-#include <vector>
-
-TEST_SUITE_BEGIN("util");
-
-// RAII helper class for test file management
-class TestFileGuard
-{
-private:
-  std::string filename_;
 
-public:
-  explicit TestFileGuard(const std::string& filename) : filename_(filename)
-  {
-  }
-
-  ~TestFileGuard()
-  {
-    try {
-      if (std::filesystem::exists(filename_)) {
-        std::filesystem::remove(filename_);
-      }
-    } catch (...) {
-      // Ignore cleanup errors in destructor
-    }
-  }
+namespace fs = util::filesystem;
 
-  void
-  create_file(const std::string& content)
-  {
-    std::ofstream outfile;
-    outfile.open(filename_);
-    if (outfile.is_open()) {
-      outfile << content;
-      outfile.close();
-    }
-  }
+using TestUtil::TestContext;
 
-  const std::string&
-  filename() const
-  {
-    return filename_;
-  }
-};
+TEST_SUITE_BEGIN("util");
 
-TEST_CASE("util::split_preprocess_file_in_clang_cuda")
+TEST_CASE("util::split_preprocessed_file_from_clang_cuda")
 {
+  TestContext test_context;
+
   SUBCASE("normal")
   {
-    TestFileGuard guard("test_normal.txt");
-    std::string content = R"(# 1 "test_cuda.cu"
+    fs::path filename = "test_normal.txt";
+    util::write_file(filename, R"(# 1 "test_cuda.cu"
 # 1 "<built-in>" 1
 # 1 "<built-in>" 3
 void caller() {
@@ -83,10 +48,9 @@ void caller() {
 # 1 "test_cuda.cu"
 # 1 "<built-in>" 1
 # 1 "<built-in>" 3
-)";
-    guard.create_file(content);
+)");
 
-    auto result = util::split_preprocess_file_in_clang_cuda(guard.filename());
+    auto result = util::split_preprocessed_file_from_clang_cuda(filename);
 
     REQUIRE(result.size() == 2);
     CHECK(result[0] == R"(# 1 "test_cuda.cu"
@@ -104,21 +68,16 @@ void caller() {
 
   SUBCASE("non-existent file")
   {
-    std::string nonexistent_file = "nonexistent_file_12345.txt";
-
-    auto result = util::split_preprocess_file_in_clang_cuda(nonexistent_file);
-
-    CHECK(result.empty());
+    fs::path filename = "nonexistent_file.txt";
+    CHECK(util::split_preprocessed_file_from_clang_cuda(filename).empty());
   }
 
   SUBCASE("empty file")
   {
-    TestFileGuard guard("test_empty.txt");
-    guard.create_file("");
-
-    auto result = util::split_preprocess_file_in_clang_cuda(guard.filename());
+    fs::path filename = "test_empty.txt";
+    util::write_file(filename, "");
 
-    CHECK(result.empty());
+    CHECK(util::split_preprocessed_file_from_clang_cuda(filename).empty());
   }
 }