| // Copyright 2021 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 <algorithm> | |
| #include <cstring> | |
| #include <fstream> | |
| #include <iomanip> | |
| #include <iostream> | |
| #include "llvm/Support/FileSystem.h" | |
| #include "llvm/Support/Path.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| namespace mlir::iree_compiler::IREE::HAL { | |
| static void generatePrefix(llvm::raw_ostream &os, | |
| const std::string &library_name, | |
| const std::string &query_function_name) { | |
| // Intro Comment: | |
| os << "// === [" << library_name << "] static library ===\n" | |
| << "//\n" | |
| << "// To use:\n" | |
| << "// - Include this header and generated object into your program \n" | |
| << "// - At runtime: retrieve library name from host binary \n" | |
| << "// - Query library from " << query_function_name << "()<< \n" | |
| << "// - Feed library into static_library_loader \n" | |
| << "//\n" | |
| << "// === Automatically generated file. DO NOT EDIT! === \n\n"; | |
| // IfDef Open: | |
| llvm::StringRef ref(library_name); | |
| os << "#ifndef IREE_GENERATED_STATIC_EXECUTABLE_LIBRARY_" << ref.upper() | |
| << "_\n" | |
| << "#define IREE_GENERATED_STATIC_EXECUTABLE_LIBRARY_" << ref.upper() | |
| << "_\n"; | |
| // Executable Library Include: | |
| os << "\n#include \"iree/hal/local/executable_library.h\"\n"; | |
| // ExternC Open: | |
| os << "\n#if __cplusplus\n" | |
| << "extern \"C\" {\n" | |
| << "#endif // __cplusplus\n\n"; | |
| } | |
| static void generateQueryFunction(llvm::raw_ostream &os, | |
| const std::string &library_name, | |
| const std::string &query_function_name) { | |
| os << "const iree_hal_executable_library_header_t**\n" | |
| << query_function_name << "(\n" | |
| << "iree_hal_executable_library_version_t max_version, const " | |
| "iree_hal_executable_environment_v0_t* environment);\n"; | |
| } | |
| static void generateSuffix(llvm::raw_ostream &os, | |
| const std::string &library_name, | |
| const std::string &query_function_name) { | |
| // ExternC Close: | |
| os << "\n#if __cplusplus\n" | |
| << "}\n" | |
| << "#endif // __cplusplus\n\n"; | |
| // IfDef Close: | |
| llvm::StringRef ref(library_name); | |
| os << "#endif // IREE_GENERATED_STATIC_EXECUTABLE_LIBRARY_" << ref.upper() | |
| << "_\n"; | |
| } | |
| static bool | |
| generateExecutableLibraryHeader(const std::string &library_name, | |
| const std::string &query_function_name, | |
| const std::string &header_file_path) { | |
| std::error_code ec; | |
| llvm::raw_fd_ostream os(header_file_path, ec); | |
| generatePrefix(os, library_name, query_function_name); | |
| generateQueryFunction(os, library_name, query_function_name); | |
| generateSuffix(os, library_name, query_function_name); | |
| os.close(); | |
| return !os.has_error(); | |
| } | |
| bool outputStaticLibrary(const std::string &library_name, | |
| const std::string &query_function_name, | |
| const std::string &library_output_path, | |
| const std::string &temp_object_path) { | |
| llvm::SmallString<32> object_file_path(library_output_path); | |
| llvm::sys::path::replace_extension(object_file_path, ".o"); | |
| llvm::SmallString<32> header_file_path(library_output_path); | |
| llvm::sys::path::replace_extension(header_file_path, ".h"); | |
| // Copy the object file. | |
| llvm::SmallString<32> copy_from_path(temp_object_path); | |
| if (llvm::sys::fs::copy_file(copy_from_path, object_file_path)) { | |
| return false; | |
| } | |
| // Generate the header file. | |
| return generateExecutableLibraryHeader(library_name, query_function_name, | |
| header_file_path.c_str()); | |
| } | |
| } // namespace mlir::iree_compiler::IREE::HAL |