From 273f7eacba0fb3f2a71805b5c204e8267ae46d8e Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Wed, 24 Nov 2021 23:26:24 +0100 Subject: [PATCH] some dependency inversion: make sure gcc does not depend on retro68_tools --- Elf2Mac/Elf2Mac.cc | 233 ++++++++++++++++++++++----------------------- flake.nix | 46 ++++----- 2 files changed, 139 insertions(+), 140 deletions(-) diff --git a/Elf2Mac/Elf2Mac.cc b/Elf2Mac/Elf2Mac.cc index 48436b5b03..4a4589b2ed 100644 --- a/Elf2Mac/Elf2Mac.cc +++ b/Elf2Mac/Elf2Mac.cc @@ -41,13 +41,12 @@ using std::string; using std::vector; using std::ofstream; -string argvZero; +string realLdPath; void RealLD(vector args) { vector 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 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 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 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; } diff --git a/flake.nix b/flake.nix index 671670aad1..e4946fdbc3 100644 --- a/flake.nix +++ b/flake.nix @@ -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;