// Copyright 2020 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "compiler/plugins/target/LLVMCPU/LinkerTool.h"
#include "iree/compiler/Utils/ToolUtils.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"

#define DEBUG_TYPE "llvm-linker"

namespace mlir::iree_compiler::IREE::HAL {

// Unix linker (ld-like); for ELF files.
class UnixLinkerTool : public LinkerTool {
public:
  using LinkerTool::LinkerTool;

  std::string getSystemToolPath() const override {
    // First check for setting the linker explicitly.
    auto toolPath = LinkerTool::getSystemToolPath();
    if (!toolPath.empty()) {
      return toolPath;
    }

    // No explicit linker specified, search the environment for common tools.
    // We want LLD:
    // * On Apple, we want the system linker, which is named `ld`
    if (targetIsApple()) {
      // On macOS, the standard system linker is `ld`, and it's
      // unconditionally what we want to use.
      toolPath = findToolInEnvironment({"ld"});
    } else {
      // On Linux, the only linker basename that's standard is `ld` but it could
      // be any of ld.bfd, ld.gold, ld.lld, which are inequivalent in the way
      // explained in the comment below on the -shared flag. We specifically
      // want ld.lld here, however we still search for `ld` as a fallback name,
      // in case the linker would be ld.lld but would be installed only under
      // the name `ld`.
      //
      // Having `ld` as a fallback name also makes sense (at least
      // theoretically) on "generic Unix": `ld` is the standard name of the
      // system linker, and `-static -shared` should in theory be supported by
      // the system linker (as suggested by both the FreeBSD and GNU man pages
      // for ld).
      //
      // On the other hand, on Linux where the possible fallbacks are ld.bfd or
      // ld.gold, we are specifically not interested in falling back on any
      // of these, at least given current behavior.
      toolPath = findToolInEnvironment({"ld.lld", "ld"});
    }
    if (!toolPath.empty()) {
      return toolPath;
    }

    llvm::errs() << "No Unix linker tool found in environment.\n";
    return "";
  }

  std::optional<Artifacts>
  linkDynamicLibrary(StringRef libraryName,
                     ArrayRef<Artifact> objectFiles) override {
    Artifacts artifacts;

    // Create the shared object name; if we only have a single input object we
    // can just reuse that.
    if (objectFiles.size() == 1) {
      artifacts.libraryFile =
          Artifact::createVariant(objectFiles.front().path, "so");
    } else {
      artifacts.libraryFile = Artifact::createTemporary(libraryName, "so");
    }
    artifacts.libraryFile.close();

    SmallVector<std::string, 8> flags = {
        getSystemToolPath(),
        "-o " + artifacts.libraryFile.path,
    };

    if (targetIsApple()) {
      // Statically link all dependencies so we don't have any runtime deps.
      // We cannot have any imports in the module we produce.
      flags.push_back("-static");

      // Produce a Mach-O dylib file.
      flags.push_back("-dylib");
      flags.push_back("-flat_namespace");
      flags.push_back(
          "-L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib "
          "-lSystem");
    } else {
      // Avoids including any libc/startup files that initialize the CRT as
      // we don't use any of that. Our shared libraries must be freestanding.
      flags.push_back("-nostdlib"); // -nodefaultlibs + -nostartfiles

      // Statically link all dependencies so we don't have any runtime deps.
      // We cannot have any imports in the module we produce.
      flags.push_back("-static");

      // Generate a dynamic library (ELF type: ET_DYN), otherwise dlopen()
      // won't succeed on it. This is not incompatible with -static. The GNU
      // man page for ld, `man ld`, says the following:
      //
      //   -static
      //       Do not link against shared libraries. [...] This option can be
      //       used with -shared. Doing so means that a shared library is
      //       being created but that all of the library's external references
      //       must be resolved by pulling in entries from static libraries.
      //
      // While that much is said in the GNU ld man page, the reality is that
      // out of ld.bfd, ld.gold and ld.lld, only ld.lld actually implements
      // that. Meanwhile, ld.bfd interprets -static -shared as just -static,
      // and ld.gold rejects -static -shared outright as "incompatible".
      flags.push_back("-shared");
    }

    // Strip debug information (only, no relocations) when not requested.
    if (!targetOptions.target.debugSymbols) {
      flags.push_back("--strip-debug");
    }

    // Link all input objects. Note that we are not linking whole-archive as
    // we want to allow dropping of unused codegen outputs.
    for (auto &objectFile : objectFiles) {
      flags.push_back(objectFile.path);
    }

    auto commandLine = llvm::join(flags, " ");
    if (failed(runLinkCommand(commandLine))) {
      return std::nullopt;
    }
    return artifacts;
  }

private:
  bool targetIsApple() const {
    return targetTriple.isOSDarwin() || targetTriple.isiOS();
  }
};

std::unique_ptr<LinkerTool>
createUnixLinkerTool(const llvm::Triple &targetTriple,
                     LLVMTargetOptions &targetOptions) {
  return std::make_unique<UnixLinkerTool>(targetTriple, targetOptions);
}

} // namespace mlir::iree_compiler::IREE::HAL
