// 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
