And the basic idea works...
This commit is contained in:
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
|||||||
CPPFLAGS+= -I .
|
CPPFLAGS+= -I .
|
||||||
CXXFLAGS+= -std=c++2c
|
CXXFLAGS+= -std=c++2c -O0 -g
|
||||||
LDFLAGS+= -L ./Alepha/ -Wl,-rpath=/home/adam/proj/bake/Alepha
|
LDFLAGS+= -L ./Alepha/ -Wl,-rpath=/home/adam/proj/bake/Alepha
|
||||||
LDLIBS+= -lalepha
|
LDLIBS+= -lalepha
|
||||||
CXX=g++-14
|
CXX=g++-14
|
||||||
|
49
bake.cc
49
bake.cc
@ -33,6 +33,13 @@ namespace
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
getExtension( const auto &entry )
|
||||||
|
{
|
||||||
|
if( entry.path().extension().string().empty() ) return "";
|
||||||
|
return entry.path().extension().string().substr( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
auto
|
auto
|
||||||
collectFiles( const std::filesystem::path where, const std::set< std::string > extensions )
|
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( C::debug ) std::cerr << "Examining file: `" << entry << "`" << std::endl;
|
||||||
if( not entry.is_regular_file() ) continue;
|
if( not entry.is_regular_file() ) continue;
|
||||||
if( C::debug ) std::cerr << "Was regular file..." << std::endl;
|
if( C::debug ) std::cerr << "Was regular file..." << std::endl;
|
||||||
if( C::debug ) std::cerr << "Examining extension: `" << entry.path().extension() << "`" << std::endl;
|
if( C::debug ) std::cerr << "Examining extension: `" << getExtension( entry ) << "`" << std::endl;
|
||||||
if( not extensions.contains( entry.path().extension().string().substr( 1 ) ) ) continue;
|
if( not extensions.contains( getExtension( entry ) ) ) continue;
|
||||||
if( C::debug ) std::cerr << "Adding collected file: `" << entry << "`" << std::endl;
|
if( C::debug ) std::cerr << "Adding collected file: `" << entry << "`" << std::endl;
|
||||||
rv.push_back( entry.path() );
|
rv.push_back( entry.path() );
|
||||||
}
|
}
|
||||||
@ -88,15 +95,9 @@ namespace
|
|||||||
|
|
||||||
struct LinkEntry
|
struct LinkEntry
|
||||||
{
|
{
|
||||||
std::int64_t addr;
|
std::string addr;
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
|
|
||||||
friend std::istream &
|
|
||||||
operator >> ( std::istream &is, LinkEntry &entry )
|
|
||||||
{
|
|
||||||
return is >> entry.addr >> entry.type >> entry.symbol;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace C
|
namespace C
|
||||||
@ -108,18 +109,18 @@ namespace
|
|||||||
std::vector< std::string >
|
std::vector< std::string >
|
||||||
findSymbols( const std::filesystem::path object, const std::string opt )
|
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
|
Alepha::AutoRAII inF
|
||||||
{
|
{
|
||||||
[&]{ return popen( ( "nm " + opt + " " + object.string() ).c_str(), "r" ); },
|
[&]{ return popen( nmCmd.c_str(), "r" ); },
|
||||||
pclose
|
pclose
|
||||||
};
|
};
|
||||||
std::ifstream in{ "/dev/null" };
|
std::ifstream in{ "/dev/null" };
|
||||||
const int handle= in.native_handle();
|
const int handle= in.native_handle();
|
||||||
::dup2( fileno( inF ), handle );
|
::dup2( fileno( inF ), handle );
|
||||||
|
|
||||||
std::vector< std::string > rv;
|
std::vector< std::string > rv{ std::istream_iterator< std::string >{ in }, std::istream_iterator< std::string >{} };
|
||||||
std::transform( std::istream_iterator< LinkEntry >{ in }, std::istream_iterator< LinkEntry >{},
|
|
||||||
back_inserter( rv ), []( const auto &element ) { return element.symbol; } );
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -178,17 +179,31 @@ namespace
|
|||||||
components.insert( program );
|
components.insert( program );
|
||||||
|
|
||||||
auto unresolved= findUndefs( program ) | std::ranges::to< std::set >();
|
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() )
|
while( not unresolved.empty() )
|
||||||
{
|
{
|
||||||
auto sym= *unresolved.begin();
|
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 ) )
|
if( not providers.contains( sym ) )
|
||||||
{
|
{
|
||||||
throw std::runtime_error{ "Unable to find a provider for symbol `" + sym + "` when linking `"
|
throw std::runtime_error{ "Unable to find a provider for symbol `" + sym + "` when linking `"
|
||||||
+ program.stem().string() };
|
+ program.stem().string() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const auto provider= providers.lower_bound( sym )->second;
|
const auto provider= providers.lower_bound( sym )->second;
|
||||||
|
|
||||||
|
std::cerr << "Using `" << provider << "` to satisfy `" << sym << "`" << std::endl;
|
||||||
|
|
||||||
const auto provided= findDefs( provider );
|
const auto provided= findDefs( provider );
|
||||||
const auto needed= findUndefs( provider );
|
const auto needed= findUndefs( provider );
|
||||||
|
|
||||||
@ -258,14 +273,15 @@ namespace
|
|||||||
std::filesystem::create_directories( ".bake"/source.parent_path() );
|
std::filesystem::create_directories( ".bake"/source.parent_path() );
|
||||||
const auto targetBase= ".bake"/source;
|
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" ) )
|
if( not std::filesystem::exists( targetBase.string()+".E" ) )
|
||||||
{
|
{
|
||||||
rv.push_back( source );
|
rv.push_back( source );
|
||||||
continue;
|
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 );
|
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();
|
const auto cmdline=compiler() + " " + compileOptions() + " -c -o " + targetBase.string()+".o " + source.string();
|
||||||
std::cerr << cmdline << std::endl;
|
std::cerr << cmdline << std::endl;
|
||||||
system( cmdline.c_str() );
|
system( cmdline.c_str() );
|
||||||
|
std::filesystem::rename( targetBase.string()+".E.new", targetBase.string()+".E" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
|
namespace lib
|
||||||
|
{
|
||||||
|
void func2();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lib::func()
|
lib::func()
|
||||||
{
|
{
|
||||||
return 42;
|
return 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lib::func2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace lib
|
namespace lib
|
||||||
{
|
{
|
||||||
int func();
|
int func();
|
||||||
|
|
||||||
|
void func2();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
lib::func();
|
std::cout << lib::func() << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user