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" 12*480093f4SDimitry 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"); 25*480093f4SDimitry Andric const bool WriteBin = !Args.getLastArg(options::OPT_emit_merged_ifs); 26*480093f4SDimitry Andric CmdArgs.push_back(WriteBin ? "write-bin" : "write-ifs"); 27a7dea167SDimitry Andric CmdArgs.push_back("-o"); 28*480093f4SDimitry Andric 29*480093f4SDimitry Andric // Normally we want to write to a side-car file ending in ".ifso" so for 30*480093f4SDimitry Andric // example if `clang -emit-interface-stubs -shared -o libhello.so` were 31*480093f4SDimitry Andric // invoked then we would like to get libhello.so and libhello.ifso. If the 32*480093f4SDimitry Andric // stdout stream is given as the output file (ie `-o -`), that is the one 33*480093f4SDimitry Andric // exception where we will just append to the same filestream as the normal 34*480093f4SDimitry Andric // output. 35*480093f4SDimitry Andric SmallString<128> OutputFilename(Output.getFilename()); 36*480093f4SDimitry Andric if (OutputFilename != "-") { 37*480093f4SDimitry Andric if (Args.hasArg(options::OPT_shared)) 38*480093f4SDimitry Andric llvm::sys::path::replace_extension(OutputFilename, 39*480093f4SDimitry Andric (WriteBin ? "ifso" : "ifs")); 40*480093f4SDimitry Andric else 41*480093f4SDimitry Andric OutputFilename += (WriteBin ? ".ifso" : ".ifs"); 42*480093f4SDimitry Andric } 43*480093f4SDimitry Andric 44*480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString(OutputFilename.c_str())); 45*480093f4SDimitry Andric 46*480093f4SDimitry Andric // Here we append the input files. If the input files are object files, then 47*480093f4SDimitry Andric // we look for .ifs files present in the same location as the object files. 48*480093f4SDimitry Andric for (const auto &Input : Inputs) { 49*480093f4SDimitry Andric if (!Input.isFilename()) 50*480093f4SDimitry Andric continue; 51*480093f4SDimitry Andric SmallString<128> InputFilename(Input.getFilename()); 52*480093f4SDimitry Andric if (Input.getType() == types::TY_Object) 53*480093f4SDimitry Andric llvm::sys::path::replace_extension(InputFilename, ".ifs"); 54*480093f4SDimitry Andric CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str())); 55*480093f4SDimitry Andric } 56*480093f4SDimitry Andric 57a7dea167SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger), 58a7dea167SDimitry Andric CmdArgs, Inputs)); 59a7dea167SDimitry Andric } 60a7dea167SDimitry Andric } // namespace ifstool 61a7dea167SDimitry Andric } // namespace tools 62a7dea167SDimitry Andric } // namespace driver 63a7dea167SDimitry Andric } // namespace clang 64