simplify cppipe code

This commit is contained in:
vrd
2025-06-06 18:00:38 +03:00
parent 4619776fa5
commit 6da2d6bc0f
+28 -28
View File
@@ -4,6 +4,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string_view> #include <string_view>
#include <optional>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
@@ -45,9 +46,9 @@ fs::path get_cache_dir_path(const fs::path& src_file);
// map file in memory with write persmissions // map file in memory with write persmissions
MappedFile mapfile_for_writing(const fs::path& file); MappedFile mapfile_for_writing(const fs::path& file);
// preprocess the src file and compare the result to the previous version, return weather it's changed // preprocess the src file, compare and overwrite the result to the previous version
// remove cached bin if true // return the path of the preprocessed file if it's different
bool preprocess_and_compare(); optional<fs::path> preprocess_and_compare();
// only recompile if changes are present // only recompile if changes are present
void compile_src_file(); void compile_src_file();
@@ -114,10 +115,13 @@ int parse_args_until_src(int argc, char* argv[])
if( arg == "--help" ) if( arg == "--help" )
{ {
print_usage(); print_usage();
cout << "Compile and run C/C++ source FILE.\n" cout << "Compile and run C/C++ source FILE\n"
"Pass the ARGUMENTS to the compiled binary.\n" "Pass the ARGUMENTS to the compiled binary\n"
"The binaries are cached and recompiled only if the source or it's headers have changed.\n" "The binaries are cached and recompiled only if the source or it's headers have changed\n\n"
"-g debug the binary, asserts are also enabled\n"; "Options:\n"
"-g debug the binary, asserts are also enabled\n\n"
"Environment variables:\n"
"CPPIPEPATH - ':'-separated list of directories to prepend to the FILE search path\n";
exit(0); exit(0);
} }
else if( arg == "-g" ) else if( arg == "-g" )
@@ -154,7 +158,7 @@ fs::path find_path_to_src(string_view src_file)
{ {
const string_view cppipepath = cppipepath_var; const string_view cppipepath = cppipepath_var;
for(size_t begin = 0, end = cppipepath.find(':'); for(size_t begin = 0, end = cppipepath.find(':');
; end != string::npos;
begin = end+1, end = cppipepath.find(':', begin) ) begin = end+1, end = cppipepath.find(':', begin) )
{ {
const fs::path path_entry = cppipepath.substr(begin, end - begin); const fs::path path_entry = cppipepath.substr(begin, end - begin);
@@ -163,9 +167,6 @@ fs::path find_path_to_src(string_view src_file)
{ {
return p; return p;
} }
if(end == string::npos)
break;
} }
} }
@@ -190,8 +191,7 @@ fs::path get_cache_dir_path(const fs::path& src_file)
} }
else else
{ {
cache_dir = HOME; cache_dir = HOME / ".cache/cppipe";
cache_dir /= ".cache/cppipe";
} }
cache_dir += fs::canonical( src_file ).parent_path(); cache_dir += fs::canonical( src_file ).parent_path();
fs::create_directories(cache_dir); fs::create_directories(cache_dir);
@@ -210,7 +210,7 @@ MappedFile mapfile_for_writing(const fs::path& file)
return res; return res;
} }
bool preprocess_and_compare() optional<fs::path> preprocess_and_compare()
{ {
Cmd preprocess( Cmd preprocess(
src_type == SrcType::C ? CC : CXX, src_type == SrcType::C ? CC : CXX,
@@ -220,27 +220,29 @@ bool preprocess_and_compare()
#endif #endif
); );
// Add preprocessor flags
if(src_type == SrcType::C) if(src_type == SrcType::C)
{ {
for(const char* flag: { CFLAGS }) preprocess.append_args({ CFLAGS });
preprocess += flag;
} }
else else
{ {
for(const char* flag: { CXXFLAGS }) preprocess.append_args({ CXXFLAGS });
preprocess += flag;
preprocess += "-xc++"; // treat the file as a cpp preprocess += "-xc++"; // treat the file as a cpp
} }
// File to be preprocessed
preprocess += src_file.c_str(); preprocess += src_file.c_str();
if(!debug) if(!debug)
preprocess += "-DNDEBUG"; preprocess += "-DNDEBUG";
// Preprocessed file from the previous run
fs::path old_pp_path = cache_dir / (debug ? DEBUG_PREFIX : "") += src_file.stem() fs::path old_pp_path = cache_dir / (debug ? DEBUG_PREFIX : "") += src_file.stem()
+= (src_type == SrcType::C ? ".i" : ".ii"); += (src_type == SrcType::C ? ".i" : ".ii");
// Result of preprocessing as string
string new_pp = $(preprocess); string new_pp = $(preprocess);
if( fs::exists(old_pp_path) ) // todo: clean up if else blocks if( fs::exists(old_pp_path) ) // todo: clean up if else blocks
@@ -250,45 +252,43 @@ bool preprocess_and_compare()
MappedFile old_pp = mapfile_for_writing(old_pp_path); MappedFile old_pp = mapfile_for_writing(old_pp_path);
if( !memcmp(old_pp.data, &new_pp[0], old_pp.len) ) // unchanged if( !memcmp(old_pp.data, &new_pp[0], old_pp.len) ) // unchanged
{ {
return false; return nullopt;
} }
else else
{ {
memcpy(old_pp.data, &new_pp[0], old_pp.len); memcpy(old_pp.data, &new_pp[0], old_pp.len);
munmap(old_pp.data, old_pp.len); munmap(old_pp.data, old_pp.len);
return true; return old_pp_path;
} }
// todo // todo
// munmap(data, len); // munmap(data, len);
} }
else else
{ {
fs::remove(bin); // rm old bin
ofstream pp_file(old_pp_path); ofstream pp_file(old_pp_path);
pp_file << new_pp; pp_file << new_pp;
return true; return old_pp_path;
} }
} }
else else
{ {
fs::remove(bin); // rm old bin
ofstream pp_file(old_pp_path); ofstream pp_file(old_pp_path);
pp_file << new_pp; pp_file << new_pp;
return true; return old_pp_path;
} }
} }
void compile_src_file() void compile_src_file()
{ {
optional<fs::path> new_preprocessed = preprocess_and_compare();
// Only compile if the source is newer then the bin // Only compile if the source is newer then the bin
if(preprocess_and_compare() || !fs::exists(bin)) if(new_preprocessed || !fs::exists(bin))
{ {
string preprocessed_file = cache_dir / (debug ? DEBUG_PREFIX : "") += src_file.stem()
+= (src_type == SrcType::C ? ".i" : ".ii"); // todo: duplicates with old_pp_path (std::optional?)
Cmd compile( Cmd compile(
src_type == SrcType::C ? CC : CXX, src_type == SrcType::C ? CC : CXX,
preprocessed_file.c_str(), new_preprocessed->c_str(),
"-o", bin.c_str() "-o", bin.c_str()
); );