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::ofstream;
string argvZero;
string realLdPath;
void RealLD(vector<string> args)
{
vector<const char*> argv;
string realLD = argvZero + ".real";
argv.push_back(realLD.c_str());
argv.push_back(realLdPath.c_str());
for(string& s : args)
argv.push_back(s.c_str());
argv.push_back(NULL);
@ -90,134 +89,132 @@ int main(int argc, char *argv[])
{
vector<string> 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";
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 == "--elf2mac-real-ld")
{
if(*p == "-o")
{
++p;
if(p == e)
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);
}
++p;
if(p == e)
errx(EXIT_FAILURE, "--elf2mac-real-ld missing argument");
realLdPath = *p;
}
if(elf2mac)
else if(*p == "-o")
{
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");
++p;
if(p == e)
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)
theObject.FlatCode(outputFile);
else if(segments)
theObject.MultiSegmentApp(outputFile, segmentMap);
else
theObject.SingleSegmentApp(outputFile);
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
{
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
{
if(argc != 2)
errx(EXIT_FAILURE, "usage : %s file-name ", argv[0]);
Object theObject(argv[1]);
SegmentMap segmentMap;
theObject.MultiSegmentApp("out.bin", segmentMap);
RealLD(args);
}
return 0;
}

View File

@ -154,32 +154,29 @@
[ "--target=${stdenv.targetPlatform.config}" "--disable-doc" ]
++ stdenv.targetPlatform.retro68BinutilsConfig or [ ];
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 = with pkgs;
stdenv.mkDerivation rec {
name = "retro68_gcc";
src = filterSrc (self + /gcc);
buildInputs = [ retro68_binutils_with_tools gmp mpfr libmpc ];
buildInputs = [ retro68_binutils gmp mpfr libmpc ];
configureFlags = [
"--target=${stdenv.targetPlatform.config}"
"--enable-languages=c,c++"
@ -192,7 +189,7 @@
# nix does in-source builds by default, and something breaks
buildCommand = ''
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"
$src/configure ${builtins.toString configureFlags} --prefix=$out
@ -206,7 +203,7 @@
# binutils -- binutils with the wrappers provided by nixpkgs
binutils = if pkgs.stdenv.targetPlatform ? retro68 then
pkgs.wrapBintoolsWith {
bintools = pkgs.retro68_binutils_with_tools;
bintools = pkgs.retro68_binutils;
}
else
prev.binutils;
@ -251,7 +248,12 @@
};
hook = pkgs.writeTextFile {
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;