some dependency inversion: make sure gcc does not depend on retro68_tools

This commit is contained in:
Wolfgang Thaller 2021-11-24 23:26:24 +01:00
parent 90b7a3332d
commit 273f7eacba
2 changed files with 139 additions and 140 deletions

View File

@ -41,13 +41,12 @@ using std::string;
using std::vector; using std::vector;
using std::ofstream; using std::ofstream;
string argvZero; string realLdPath;
void RealLD(vector<string> args) void RealLD(vector<string> args)
{ {
vector<const char*> argv; vector<const char*> argv;
string realLD = argvZero + ".real"; argv.push_back(realLdPath.c_str());
argv.push_back(realLD.c_str());
for(string& s : args) for(string& s : args)
argv.push_back(s.c_str()); argv.push_back(s.c_str());
argv.push_back(NULL); argv.push_back(NULL);
@ -90,134 +89,132 @@ int main(int argc, char *argv[])
{ {
vector<string> args; vector<string> args;
std::copy(argv + 1, argv+argc, std::back_inserter(args)); std::copy(argv + 1, argv+argc, std::back_inserter(args));
argvZero = argv[0]; realLdPath = string(argv[0]) + ".real";
if(boost::algorithm::ends_with(argv[0], "ld")) if (char *path = getenv("RETRO68_REAL_LD"))
realLdPath = path;
string outputFile = "a.out";
string entryPoint = "_start";
bool elf2mac = false;
bool flatoutput = false;
bool segments = true;
bool stripMacsbug = false;
bool saveLdScript = false;
SegmentMap segmentMap;
vector<string> args2;
for(auto p = args.begin(), e = args.end(); p != e; ++p)
{ {
string outputFile = "a.out"; if(*p == "--elf2mac-real-ld")
string entryPoint = "_start";
bool elf2mac = false;
bool flatoutput = false;
bool segments = true;
bool stripMacsbug = false;
bool saveLdScript = false;
SegmentMap segmentMap;
vector<string> args2;
for(auto p = args.begin(), e = args.end(); p != e; ++p)
{ {
if(*p == "-o") ++p;
{ if(p == e)
++p; errx(EXIT_FAILURE, "--elf2mac-real-ld missing argument");
if(p == e) realLdPath = *p;
errx(EXIT_FAILURE, "-o missing argument");
outputFile = *p;
}
else if(boost::algorithm::starts_with(*p, "-o"))
{
outputFile = (*p).substr(2);
}
else if(*p == "-elf2mac" || *p == "--elf2mac")
{
elf2mac = true;
}
else if(*p == "-e")
{
++p;
if(p == e)
errx(EXIT_FAILURE, "-e missing argument");
entryPoint = *p;
}
else if(boost::algorithm::starts_with(*p, "-e"))
{
entryPoint = (*p).substr(2);
}
else if(*p == "--mac-flat")
{
elf2mac = true;
flatoutput = true;
segments = false;
}
else if(*p == "--mac-single")
{
elf2mac = true;
flatoutput = false;
segments = false;
}
else if(*p == "--mac-segments")
{
elf2mac = true;
if(flatoutput)
errx(EXIT_FAILURE, "--mac-segments can't be used with --mac-flat");
++p;
if(p == e)
errx(EXIT_FAILURE, "--mac-segments missing argument");
segmentMap = SegmentMap(*p);
}
else if(*p == "--mac-strip-macsbug")
{
stripMacsbug = true;
}
else if(*p == "--mac-keep-ldscript")
{
saveLdScript = true;
}
else
{
args2.push_back(*p);
}
} }
else if(*p == "-o")
if(elf2mac)
{ {
char tmpfile[] = "/tmp/ldscriptXXXXXX"; ++p;
int fd = mkstemp(tmpfile); if(p == e)
if(fd < 0) errx(EXIT_FAILURE, "-o missing argument");
errx(EXIT_FAILURE, "can't create temp file"); outputFile = *p;
}
{ else if(boost::algorithm::starts_with(*p, "-o"))
ofstream out(tmpfile); {
if(segments) outputFile = (*p).substr(2);
{ }
segmentMap.CreateLdScript(out, entryPoint, stripMacsbug); else if(*p == "-elf2mac" || *p == "--elf2mac")
} {
else elf2mac = true;
{ }
CreateFlatLdScript(out, entryPoint, stripMacsbug); else if(*p == "-e")
} {
} ++p;
if(p == e)
args2.push_back("-o"); errx(EXIT_FAILURE, "-e missing argument");
args2.push_back(outputFile + ".gdb"); entryPoint = *p;
args2.push_back("-T"); }
args2.push_back(tmpfile); else if(boost::algorithm::starts_with(*p, "-e"))
RealLD(args2); {
if(saveLdScript) entryPoint = (*p).substr(2);
std::cerr << "Ld Script at: " << tmpfile << std::endl; }
else else if(*p == "--mac-flat")
unlink(tmpfile); {
Object theObject(outputFile + ".gdb"); elf2mac = true;
flatoutput = true;
segments = false;
}
else if(*p == "--mac-single")
{
elf2mac = true;
flatoutput = false;
segments = false;
}
else if(*p == "--mac-segments")
{
elf2mac = true;
if(flatoutput) if(flatoutput)
theObject.FlatCode(outputFile); errx(EXIT_FAILURE, "--mac-segments can't be used with --mac-flat");
else if(segments) ++p;
theObject.MultiSegmentApp(outputFile, segmentMap); if(p == e)
else errx(EXIT_FAILURE, "--mac-segments missing argument");
theObject.SingleSegmentApp(outputFile); segmentMap = SegmentMap(*p);
}
else if(*p == "--mac-strip-macsbug")
{
stripMacsbug = true;
}
else if(*p == "--mac-keep-ldscript")
{
saveLdScript = true;
} }
else else
{ {
RealLD(args); args2.push_back(*p);
} }
return 0; }
if(elf2mac)
{
char tmpfile[] = "/tmp/ldscriptXXXXXX";
int fd = mkstemp(tmpfile);
if(fd < 0)
errx(EXIT_FAILURE, "can't create temp file");
{
ofstream out(tmpfile);
if(segments)
{
segmentMap.CreateLdScript(out, entryPoint, stripMacsbug);
}
else
{
CreateFlatLdScript(out, entryPoint, stripMacsbug);
}
}
args2.push_back("-o");
args2.push_back(outputFile + ".gdb");
args2.push_back("-T");
args2.push_back(tmpfile);
RealLD(args2);
if(saveLdScript)
std::cerr << "Ld Script at: " << tmpfile << std::endl;
else
unlink(tmpfile);
Object theObject(outputFile + ".gdb");
if(flatoutput)
theObject.FlatCode(outputFile);
else if(segments)
theObject.MultiSegmentApp(outputFile, segmentMap);
else
theObject.SingleSegmentApp(outputFile);
} }
else else
{ {
if(argc != 2) RealLD(args);
errx(EXIT_FAILURE, "usage : %s file-name ", argv[0]);
Object theObject(argv[1]);
SegmentMap segmentMap;
theObject.MultiSegmentApp("out.bin", segmentMap);
} }
return 0; return 0;
} }

View File

@ -154,32 +154,29 @@
[ "--target=${stdenv.targetPlatform.config}" "--disable-doc" ] [ "--target=${stdenv.targetPlatform.config}" "--disable-doc" ]
++ stdenv.targetPlatform.retro68BinutilsConfig or [ ]; ++ stdenv.targetPlatform.retro68BinutilsConfig or [ ];
enableParallelBuilding = true; enableParallelBuilding = true;
postInstall = let
ld = "$out/bin/${stdenv.targetPlatform.config}-ld";
ld_real = "$out/bin/${stdenv.targetPlatform.config}-ld.real";
in ''
mv ${ld} ${ld_real}
echo "#!${stdenv.shell}" > ${ld}
echo "exec \$'' + ''{RETRO68_LD_WRAPPER_${stdenv.targetPlatform.cmakeSystemName}-${ld_real}} \"\$@\"" >> ${ld}
chmod +x ${ld}
rm $out/${stdenv.targetPlatform.config}/bin/ld
ln -s ${ld} $out/${stdenv.targetPlatform.config}/bin/ld
'';
}; };
# retro68_binutils_with_tools -- binutils with ld wrapped by retro68_tools.Elf2Mac
retro68_binutils_with_tools = with pkgs;
if stdenv.targetPlatform.system == "m68k-macos" then
symlinkJoin {
name = "retro68_binutils_with_tools";
paths = [ retro68_binutils buildPackages.retro68_tools ];
# Move the real linker aside and install symlinks to Elf2Mac
postBuild = ''
mv $out/bin/m68k-apple-macos-ld $out/bin/m68k-apple-macos-ld.real
mv $out/m68k-apple-macos/bin/ld $out/m68k-apple-macos/bin/ld.real
ln -s $out/bin/Elf2Mac $out/bin/m68k-apple-macos-ld
ln -s $out/bin/Elf2Mac $out/m68k-apple-macos/bin/ld
'';
}
else
retro68_binutils;
# retro68_gcc -- gcc, without any wrappers # retro68_gcc -- gcc, without any wrappers
retro68_gcc = with pkgs; retro68_gcc = with pkgs;
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "retro68_gcc"; name = "retro68_gcc";
src = filterSrc (self + /gcc); src = filterSrc (self + /gcc);
buildInputs = [ retro68_binutils_with_tools gmp mpfr libmpc ]; buildInputs = [ retro68_binutils gmp mpfr libmpc ];
configureFlags = [ configureFlags = [
"--target=${stdenv.targetPlatform.config}" "--target=${stdenv.targetPlatform.config}"
"--enable-languages=c,c++" "--enable-languages=c,c++"
@ -192,7 +189,7 @@
# nix does in-source builds by default, and something breaks # nix does in-source builds by default, and something breaks
buildCommand = '' buildCommand = ''
mkdir -p $out/${stdenv.targetPlatform.config}/bin mkdir -p $out/${stdenv.targetPlatform.config}/bin
ln -s ${retro68_binutils_with_tools}/${stdenv.targetPlatform.config}/bin/* $out/${stdenv.targetPlatform.config}/bin/ ln -s ${retro68_binutils}/${stdenv.targetPlatform.config}/bin/* $out/${stdenv.targetPlatform.config}/bin/
export target_configargs="--disable-nls --enable-libstdcxx-dual-abi=no --disable-libstdcxx-verbose" export target_configargs="--disable-nls --enable-libstdcxx-dual-abi=no --disable-libstdcxx-verbose"
$src/configure ${builtins.toString configureFlags} --prefix=$out $src/configure ${builtins.toString configureFlags} --prefix=$out
@ -206,7 +203,7 @@
# binutils -- binutils with the wrappers provided by nixpkgs # binutils -- binutils with the wrappers provided by nixpkgs
binutils = if pkgs.stdenv.targetPlatform ? retro68 then binutils = if pkgs.stdenv.targetPlatform ? retro68 then
pkgs.wrapBintoolsWith { pkgs.wrapBintoolsWith {
bintools = pkgs.retro68_binutils_with_tools; bintools = pkgs.retro68_binutils;
} }
else else
prev.binutils; prev.binutils;
@ -251,7 +248,12 @@
}; };
hook = pkgs.writeTextFile { hook = pkgs.writeTextFile {
name = "retro68_setup_hook"; name = "retro68_setup_hook";
text = "export CMAKE_TOOLCHAIN_FILE=${toolchain}"; text = ''
export CMAKE_TOOLCHAIN_FILE=${toolchain}
'' + (pkgs.lib.optionalString (systemName == "Retro68") ''
export RETRO68_LD_WRAPPER_Retro68="${pkgs.buildPackages.retro68_tools}/bin/Elf2Mac"
export RETRO68_REAL_LD="${pkgs.buildPackages.retro68_binutils}/bin/m68k-apple-macos-ld.real"
'');
}; };
in pkgs.makeSetupHook { } hook; in pkgs.makeSetupHook { } hook;