/**
   * Return the type of compiler we need to use. Calculated as follows:
   *
   * <ul>
   *   <li>If we are on a 32-bit system and building a 32-bit target: return "-arch i386" (mac) or
   *       "-m32"
   *   <li>If we are on a 64-bit system and building a 64-bit target: return amd64
   *   <li>If we are on a 32-bit system and building a 64-bit target: return x86_amd64
   * </ul>
   */
  private void appendCompilerArchitecture(Commandline commandline) {
    Arch osArch = Arch.getOsArch();
    Arch outArch = configuration.getOutputArch();

    // warn them if they're trying to do a 64-bit cross-compile
    if ((osArch == Arch.x86) && (outArch == Arch.amd64))
      debug("Building 64-bit target on 32-bit system. Must have multilib installed.");

    // generate the appropriate compile command line argument
    if (outArch == Arch.x86) {
      debug("(system: " + osArch + ") Build target arch: x86");
      if (Platform.getOsPlatform().isLinux()) {
        commandline.createArgument().setValue("-m32");
      } else if (Platform.getOsPlatform().isMac()) {
        commandline.createArgument().setValue("-arch");
        commandline.createArgument().setValue("i386");
      }
    } else {
      debug("(system: " + osArch + ") Build target arch: amd64");
      if (Platform.getOsPlatform().isLinux()) {
        commandline.createArgument().setValue("-m64");
      } else if (Platform.getOsPlatform().isMac()) {
        commandline.createArgument().setValue("-arch");
        commandline.createArgument().setValue("x86_64");
      }
    }
  }
  /** Generates the linker execution command line including library locations, .o files etc... */
  private Commandline generateLinkCommand() {
    // Creating a static library in gcc/clang uses ar instead of ld via gcc.
    // The command line for ar is different, it has been delegated into its own function
    if (configuration.getOutputType() == OutputType.STATIC) return generateStaticLinkCommand();

    // create the command line in which to store the information
    Commandline commandline = new Commandline();
    commandline.setExecutable(executable);

    /////// output file name ///////
    File outputFile = helper.getPlatformSpecificOutputFile();
    commandline.createArgument().setValue("-o");
    commandline.createArgument().setFile(outputFile);

    ////////////////////////////////////
    /////// object files to link ///////
    ////////////////////////////////////
    File objectDirectory = configuration.getObjectDirectory();
    for (File ofile : helper.getFilesThatNeedLinking(objectDirectory)) {
      commandline.createArgument().setFile(ofile);
    }

    /////// output file type ///////
    if (configuration.getOutputType() == OutputType.SHARED) {
      if (Platform.getOsPlatform().isMac()) {
        commandline.createArgument().setValue("-dynamiclib");
        // add the rpath setting if one isn't present
        if (configuration.getLinkerArgs().contains("install_name") == false)
          commandline.createArgument().setLine("-install_name @rpath/" + outputFile.getName());
      } else if (Platform.getOsPlatform().isLinux()) {
        commandline.createArgument().setValue("-shared");
      }
    }

    ////// platform architecture //////
    appendCompilerArchitecture(commandline);

    /////// library search paths ///////
    for (Library library : configuration.getLibraries()) {
      if (library.getPath() != null) {
        for (String path : library.getPath().list())
          commandline.createArgument().setLine("-L" + Commandline.quoteArgument(path));
      }
    }

    /////// libraries to link with ///////
    for (Library library : configuration.getLibraries()) {
      if (library.getLibs().isEmpty() == false) {
        for (String temp : library.getLibs()) commandline.createArgument().setLine("-l" + temp);
      }
    }

    /////// additional args ///////
    String[] commands = Commandline.translateCommandline(configuration.getLinkerArgs());
    commandline.addArguments(commands);

    // return the finished product!
    return commandline;
  }