From 8aa1dfd9d0fd0de5cc02e67bf8c8627da3422b17 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Tue, 27 Aug 2024 03:45:07 -0400 Subject: [PATCH] And the basic idea works... --- Makefile | 2 +- bake.cc | 49 +++++++++++++++++++++++++++++++---------------- test-bake/lib.cc | 10 ++++++++++ test-bake/lib.h | 2 ++ test-bake/main.cc | 4 +++- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index f2a3a1c..c1ecce5 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CPPFLAGS+= -I . -CXXFLAGS+= -std=c++2c +CXXFLAGS+= -std=c++2c -O0 -g LDFLAGS+= -L ./Alepha/ -Wl,-rpath=/home/adam/proj/bake/Alepha LDLIBS+= -lalepha CXX=g++-14 diff --git a/bake.cc b/bake.cc index 80f6ae3..454b474 100644 --- a/bake.cc +++ b/bake.cc @@ -33,6 +33,13 @@ namespace abort(); } + std::string + getExtension( const auto &entry ) + { + if( entry.path().extension().string().empty() ) return ""; + return entry.path().extension().string().substr( 1 ); + } + auto collectFiles( const std::filesystem::path where, const std::set< std::string > extensions ) { @@ -43,8 +50,8 @@ namespace if( C::debug ) std::cerr << "Examining file: `" << entry << "`" << std::endl; if( not entry.is_regular_file() ) continue; if( C::debug ) std::cerr << "Was regular file..." << std::endl; - if( C::debug ) std::cerr << "Examining extension: `" << entry.path().extension() << "`" << std::endl; - if( not extensions.contains( entry.path().extension().string().substr( 1 ) ) ) continue; + if( C::debug ) std::cerr << "Examining extension: `" << getExtension( entry ) << "`" << std::endl; + if( not extensions.contains( getExtension( entry ) ) ) continue; if( C::debug ) std::cerr << "Adding collected file: `" << entry << "`" << std::endl; rv.push_back( entry.path() ); } @@ -88,15 +95,9 @@ namespace struct LinkEntry { - std::int64_t addr; + std::string addr; std::string type; std::string symbol; - - friend std::istream & - operator >> ( std::istream &is, LinkEntry &entry ) - { - return is >> entry.addr >> entry.type >> entry.symbol; - } }; namespace C @@ -108,18 +109,18 @@ namespace std::vector< std::string > findSymbols( const std::filesystem::path object, const std::string opt ) { + const std::string nmCmd= "nm --just-symbols " + opt + " " + object.string(); + std::cerr << nmCmd << std::endl; Alepha::AutoRAII inF { - [&]{ return popen( ( "nm " + opt + " " + object.string() ).c_str(), "r" ); }, + [&]{ return popen( nmCmd.c_str(), "r" ); }, pclose }; std::ifstream in{ "/dev/null" }; const int handle= in.native_handle(); ::dup2( fileno( inF ), handle ); - std::vector< std::string > rv; - std::transform( std::istream_iterator< LinkEntry >{ in }, std::istream_iterator< LinkEntry >{}, - back_inserter( rv ), []( const auto &element ) { return element.symbol; } ); + std::vector< std::string > rv{ std::istream_iterator< std::string >{ in }, std::istream_iterator< std::string >{} }; return rv; } @@ -178,17 +179,31 @@ namespace components.insert( program ); auto unresolved= findUndefs( program ) | std::ranges::to< std::set >(); + std::cerr << "In linking `" << program.stem().stem() << "` we have the following unresolved symbols: " << std::endl; + for( const auto sym: unresolved ) + { + std::cerr << " - `" << sym << "`" << std::endl; + } while( not unresolved.empty() ) { auto sym= *unresolved.begin(); + if( sym.starts_with( "_ZNS" ) or sym.starts_with( "_ZSt" ) or sym == "_GLOBAL_OFFSET_TABLE_" ) + { + unresolved.erase( sym ); + continue; + } if( not providers.contains( sym ) ) { throw std::runtime_error{ "Unable to find a provider for symbol `" + sym + "` when linking `" + program.stem().string() }; } + const auto provider= providers.lower_bound( sym )->second; + + std::cerr << "Using `" << provider << "` to satisfy `" << sym << "`" << std::endl; + const auto provided= findDefs( provider ); const auto needed= findUndefs( provider ); @@ -258,14 +273,15 @@ namespace std::filesystem::create_directories( ".bake"/source.parent_path() ); const auto targetBase= ".bake"/source; + const auto cmdline= compiler() + " " + source.string() + " " + preprocOptions() + " -E -o " + targetBase.string()+".E.new"; + std::cerr << cmdline << std::endl; + ::system( cmdline.c_str() ); + if( not std::filesystem::exists( targetBase.string()+".E" ) ) { rv.push_back( source ); continue; } - const auto cmdline= compiler() + " " + preprocOptions() + " -E -o " + targetBase.string()+".E.new"; - std::cerr << cmdline << std::endl; - ::system( cmdline.c_str() ); if( diff( targetBase.string()+".E", targetBase.string()+".E.new" ) ) rv.push_back( source ); } @@ -284,6 +300,7 @@ namespace const auto cmdline=compiler() + " " + compileOptions() + " -c -o " + targetBase.string()+".o " + source.string(); std::cerr << cmdline << std::endl; system( cmdline.c_str() ); + std::filesystem::rename( targetBase.string()+".E.new", targetBase.string()+".E" ); } } diff --git a/test-bake/lib.cc b/test-bake/lib.cc index d2fa05a..7d734ef 100644 --- a/test-bake/lib.cc +++ b/test-bake/lib.cc @@ -1,7 +1,17 @@ #include "lib.h" +namespace lib +{ + void func2(); +} + int lib::func() { return 42; } + +void +lib::func2() +{ +} diff --git a/test-bake/lib.h b/test-bake/lib.h index 4b92678..6271c73 100644 --- a/test-bake/lib.h +++ b/test-bake/lib.h @@ -1,4 +1,6 @@ namespace lib { int func(); + + void func2(); } diff --git a/test-bake/main.cc b/test-bake/main.cc index 3aaea0b..0436917 100644 --- a/test-bake/main.cc +++ b/test-bake/main.cc @@ -1,9 +1,11 @@ +#include + #include "lib.h" int main() { - lib::func(); + std::cout << lib::func() << std::endl; return 0; }