1a7dea167SDimitry Andric //===--- InterfaceStubs.cpp - Base InterfaceStubs Implementations C++ ---===// 2a7dea167SDimitry Andric // 3a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a7dea167SDimitry Andric // 7a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 8a7dea167SDimitry Andric 9a7dea167SDimitry Andric #include "InterfaceStubs.h" 10a7dea167SDimitry Andric #include "CommonArgs.h" 11a7dea167SDimitry Andric #include "clang/Driver/Compilation.h" 12480093f4SDimitry Andric #include "llvm/Support/Path.h" 13a7dea167SDimitry Andric 14a7dea167SDimitry Andric namespace clang { 15a7dea167SDimitry Andric namespace driver { 16a7dea167SDimitry Andric namespace tools { 17a7dea167SDimitry Andric namespace ifstool { 18a7dea167SDimitry Andric void Merger::ConstructJob(Compilation &C, const JobAction &JA, 19a7dea167SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 20a7dea167SDimitry Andric const llvm::opt::ArgList &Args, 21a7dea167SDimitry Andric const char *LinkingOutput) const { 22a7dea167SDimitry Andric std::string Merger = getToolChain().GetProgramPath(getShortName()); 23a7dea167SDimitry Andric llvm::opt::ArgStringList CmdArgs; 24a7dea167SDimitry Andric CmdArgs.push_back("-action"); 25480093f4SDimitry Andric const bool WriteBin = !Args.getLastArg(options::OPT_emit_merged_ifs); 26480093f4SDimitry Andric CmdArgs.push_back(WriteBin ? "write-bin" : "write-ifs"); 27a7dea167SDimitry Andric CmdArgs.push_back("-o"); 28480093f4SDimitry Andric 29480093f4SDimitry Andric // Normally we want to write to a side-car file ending in ".ifso" so for 30480093f4SDimitry Andric // example if `clang -emit-interface-stubs -shared -o libhello.so` were 31480093f4SDimitry Andric // invoked then we would like to get libhello.so and libhello.ifso. If the 32480093f4SDimitry Andric // stdout stream is given as the output file (ie `-o -`), that is the one 33480093f4SDimitry Andric // exception where we will just append to the same filestream as the normal 34480093f4SDimitry Andric // output. 35480093f4SDimitry Andric SmallString<128> OutputFilename(Output.getFilename()); 36480093f4SDimitry Andric if (OutputFilename != "-") { 37480093f4SDimitry Andric if (Args.hasArg(options::OPT_shared)) 38480093f4SDimitry Andric llvm::sys::path::replace_extension(OutputFilename, 39480093f4SDimitry Andric (WriteBin ? "ifso" : "ifs")); 40480093f4SDimitry Andric else 41480093f4SDimitry Andric OutputFilename += (WriteBin ? ".ifso" : ".ifs"); 42480093f4SDimitry Andric } 43480093f4SDimitry Andric 44480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString(OutputFilename.c_str())); 45480093f4SDimitry Andric 46480093f4SDimitry Andric // Here we append the input files. If the input files are object files, then 47480093f4SDimitry Andric // we look for .ifs files present in the same location as the object files. 48480093f4SDimitry Andric for (const auto &Input : Inputs) { 49480093f4SDimitry Andric if (!Input.isFilename()) 50480093f4SDimitry Andric continue; 51480093f4SDimitry Andric SmallString<128> InputFilename(Input.getFilename()); 52480093f4SDimitry Andric if (Input.getType() == types::TY_Object) 53480093f4SDimitry Andric llvm::sys::path::replace_extension(InputFilename, ".ifs"); 54480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str())); 55480093f4SDimitry Andric } 56480093f4SDimitry Andric 575ffd83dbSDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), 585ffd83dbSDimitry Andric Args.MakeArgString(Merger), CmdArgs, 59*e8d8bef9SDimitry Andric Inputs, Output)); 60a7dea167SDimitry Andric } 61a7dea167SDimitry Andric } // namespace ifstool 62a7dea167SDimitry Andric } // namespace tools 63a7dea167SDimitry Andric } // namespace driver 64a7dea167SDimitry Andric } // namespace clang 65