* Add -link to dxc.
This commit is contained in:
Xiang Li 2021-03-15 09:09:58 -07:00 коммит произвёл GitHub
Родитель fd07613a95
Коммит de09119850
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 86 добавлений и 171 удалений

Просмотреть файл

@ -141,6 +141,7 @@ public:
bool DebugNameForBinary = false; // OPT_Zsb
bool DebugNameForSource = false; // OPT_Zss
bool DumpBin = false; // OPT_dumpbin
bool Link = false; // OPT_link
bool WarningAsError = false; // OPT__SLASH_WX
bool IEEEStrict = false; // OPT_Gis
bool IgnoreLineDirectives = false; // OPT_ignore_line_directives

Просмотреть файл

@ -405,6 +405,8 @@ def P : Separate<["-", "/"], "P">, Flags<[CoreOption, DriverOption]>, Group<hlsl
def dumpbin : Flag<["-", "/"], "dumpbin">, Flags<[DriverOption]>, Group<hlslutil_Group>,
HelpText<"Load a binary file rather than compiling">;
def link : Flag<["-", "/"], "link">, Flags<[DriverOption]>, Group<hlslutil_Group>,
HelpText<"Link list of libraries provided in <inputs> argument separated by ';'">;
def Qstrip_reflect : Flag<["-", "/"], "Qstrip_reflect">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
HelpText<"Strip reflection data from shader bytecode (must be used with /Fo <file>)">;
def Qstrip_debug : Flag<["-", "/"], "Qstrip_debug">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,

Просмотреть файл

@ -616,6 +616,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
opts.DefaultRowMajor = Args.hasFlag(OPT_Zpr, OPT_INVALID, false);
opts.DefaultColMajor = Args.hasFlag(OPT_Zpc, OPT_INVALID, false);
opts.DumpBin = Args.hasFlag(OPT_dumpbin, OPT_INVALID, false);
opts.Link = Args.hasFlag(OPT_link, OPT_INVALID, false);
opts.NotUseLegacyCBufLoad = Args.hasFlag(OPT_no_legacy_cbuf_layout, OPT_INVALID, false);
opts.NotUseLegacyCBufLoad = Args.hasFlag(OPT_not_use_legacy_cbuf_load_, OPT_INVALID, opts.NotUseLegacyCBufLoad);
opts.PackPrefixStable = Args.hasFlag(OPT_pack_prefix_stable, OPT_INVALID, false);

Просмотреть файл

@ -158,6 +158,7 @@ public:
std::wstring &outputPDBPath, CComPtr<IDxcBlob> &pDebugBlob,
IDxcOperationResult **pCompileResult);
int DumpBinary();
int Link();
void Preprocess();
void GetCompilerVersionInfo(llvm::raw_string_ostream &OS);
};
@ -831,6 +832,61 @@ int DxcContext::Compile() {
return status;
}
int DxcContext::Link() {
CComPtr<IDxcLinker> pLinker;
IFT(CreateInstance(CLSID_DxcLinker, &pLinker));
llvm::StringRef InputFiles = m_Opts.InputFile;
llvm::StringRef InputFilesRef(InputFiles);
llvm::SmallVector<llvm::StringRef, 2> InputFileList;
InputFilesRef.split(InputFileList, ";");
std::vector<std::wstring> wInputFiles;
wInputFiles.reserve(InputFileList.size());
std::vector<LPCWSTR> wpInputFiles;
wpInputFiles.reserve(InputFileList.size());
for (auto &file : InputFileList) {
wInputFiles.emplace_back(StringRefUtf16(file.str()));
wpInputFiles.emplace_back(wInputFiles.back().c_str());
CComPtr<IDxcBlobEncoding> pLib;
ReadFileIntoBlob(m_dxcSupport, wInputFiles.back().c_str(), &pLib);
IFT(pLinker->RegisterLibrary(wInputFiles.back().c_str(), pLib));
}
CComPtr<IDxcOperationResult> pLinkResult;
std::vector<std::wstring> argStrings;
CopyArgsToWStrings(m_Opts.Args, CoreOption, argStrings);
std::vector<LPCWSTR> args;
args.reserve(argStrings.size());
for (const std::wstring &a : argStrings)
args.push_back(a.data());
IFT(pLinker->Link(StringRefUtf16(m_Opts.EntryPoint),
StringRefUtf16(m_Opts.TargetProfile), wpInputFiles.data(),
wpInputFiles.size(), args.data(), args.size(),
&pLinkResult));
HRESULT status;
IFT(pLinkResult->GetStatus(&status));
if (SUCCEEDED(status)) {
CComPtr<IDxcBlob> pContainer;
IFT(pLinkResult->GetResult(&pContainer));
if (pContainer.p != nullptr) {
ActOnBlob(pContainer.p);
}
} else {
CComPtr<IDxcBlobEncoding> pErrors;
IFT(pLinkResult->GetErrorBuffer(&pErrors));
if (pErrors != nullptr) {
printf("Link failed:\n%s",
static_cast<char *>(pErrors->GetBufferPointer()));
}
return 1;
}
return 0;
}
int DxcContext::DumpBinary() {
CComPtr<IDxcBlobEncoding> pSource;
ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.InputFile), &pSource);
@ -1238,6 +1294,10 @@ int dxc::main(int argc, const char **argv_) {
pStage = "Dumping existing binary";
retVal = context.DumpBinary();
}
else if (dxcOpts.Link) {
pStage = "Linking";
retVal = context.Link();
}
else {
pStage = "Compilation";
retVal = context.Compile();

Просмотреть файл

@ -20,6 +20,7 @@ add_clang_executable(dxl
)
target_link_libraries(dxl
dxclib
dxcompiler
)
@ -29,7 +30,9 @@ if (WIN32)
include_directories(AFTER ${DIASDK_INCLUDE_DIRS})
endif (WIN32)
add_dependencies(dxl dxcompiler)
include_directories(${LLVM_SOURCE_DIR}/tools/clang/tools)
add_dependencies(dxl dxclib dxcompiler)
if(UNIX)
set(CLANGXX_LINK_OR_COPY create_symlink)

Просмотреть файл

@ -9,176 +9,24 @@
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/Support/Global.h"
#include "dxc/Support/Unicode.h"
#include "dxc/Support/WinIncludes.h"
#include "dxclib/dxc.h"
#include <vector>
#include "dxc/dxcapi.h"
#include "dxc/Support/dxcapi.use.h"
#include "dxc/Support/HLSLOptions.h"
#include "dxc/DxilContainer/DxilContainer.h"
#ifdef _WIN32
int __cdecl wmain(int argc, const wchar_t **argv_)
{
std::vector<const wchar_t *> args;
for (int i=0;i<argc;i++)
args.emplace_back(argv_[i]);
args.emplace_back(L"-link");
#include "llvm/Support/CommandLine.h"
#include "llvm/Support//MSFileSystem.h"
#include "llvm/Support/FileSystem.h"
#include <dia2.h>
#include <intsafe.h>
using namespace llvm;
using namespace llvm::opt;
using namespace dxc;
using namespace hlsl::options;
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
static cl::opt<std::string>
InputFiles(cl::Positional, cl::desc("<input .lib files seperate with ;>"),
cl::init(""));
static cl::opt<std::string> EntryName("E", cl::desc("Entry function name"),
cl::value_desc("entryfunction"),
cl::init("main"));
static cl::opt<std::string> TargetProfile("T", cl::desc("Target profile"),
cl::value_desc("profile"),
cl::init("ps_6_1"));
static cl::opt<std::string> OutputFilename("Fo",
cl::desc("Override output filename"),
cl::value_desc("filename"));
static cl::opt<bool> ExportShadersOnly("export-shaders-only", cl::desc("Export entry function only"));
class DxlContext {
private:
DxcDllSupport &m_dxcSupport;
template <typename TInterface>
HRESULT CreateInstance(REFCLSID clsid, _Outptr_ TInterface **pResult) {
return m_dxcSupport.CreateInstance(clsid, pResult);
}
public:
DxlContext(DxcDllSupport &dxcSupport) : m_dxcSupport(dxcSupport) {}
int Link();
};
int DxlContext::Link() {
std::string entry = EntryName;
std::string profile = TargetProfile;
CComPtr<IDxcLinker> pLinker;
IFT(CreateInstance(CLSID_DxcLinker, &pLinker));
StringRef InputFilesRef(InputFiles);
SmallVector<StringRef, 2> InputFileList;
InputFilesRef.split(InputFileList, ";");
std::vector<std::wstring> wInputFiles;
wInputFiles.reserve(InputFileList.size());
std::vector<LPCWSTR> wpInputFiles;
wpInputFiles.reserve(InputFileList.size());
for (auto &file : InputFileList) {
wInputFiles.emplace_back(StringRefUtf16(file.str()));
wpInputFiles.emplace_back(wInputFiles.back().c_str());
CComPtr<IDxcBlobEncoding> pLib;
ReadFileIntoBlob(m_dxcSupport, wInputFiles.back().c_str(), &pLib);
IFT(pLinker->RegisterLibrary(wInputFiles.back().c_str(), pLib));
}
CComPtr<IDxcOperationResult> pLinkResult;
std::vector<LPCWSTR> args;
if (ExportShadersOnly) {
args.emplace_back(L"-export-shaders-only");
}
IFT(pLinker->Link(StringRefUtf16(entry), StringRefUtf16(profile),
wpInputFiles.data(), wpInputFiles.size(), args.data(), args.size(),
&pLinkResult));
HRESULT status;
IFT(pLinkResult->GetStatus(&status));
if (SUCCEEDED(status)) {
CComPtr<IDxcBlob> pContainer;
IFT(pLinkResult->GetResult(&pContainer));
if (pContainer.p != nullptr) {
// Infer the output filename if needed.
if (OutputFilename.empty()) {
OutputFilename = EntryName + ".dxbc";
}
WriteBlobToFile(pContainer, StringRefUtf16(OutputFilename), DXC_CP_UTF8); // TODO: Support DefaultTextCodePage
}
} else {
CComPtr<IDxcBlobEncoding> pErrors;
IFT(pLinkResult->GetErrorBuffer(&pErrors));
if (pErrors != nullptr) {
printf("Link failed:\n%s",
static_cast<char *>(pErrors->GetBufferPointer()));
}
}
return status;
return dxc::main(args.size(), args.data());
#else
int main(int argc, const char **argv_) {
std::vector<const wchar_t *> args;
for (int i=0;i<argc;i++)
args.emplace_back(argv_[i]);
args.emplace_back("-link");
return dxc::main(args.size(), args.data());
#endif // _WIN32
}
using namespace hlsl::options;
int __cdecl main(int argc, _In_reads_z_(argc) char **argv) {
const char *pStage = "Operation";
int retVal = 0;
if (llvm::sys::fs::SetupPerThreadFileSystem())
return 1;
llvm::sys::fs::AutoCleanupPerThreadFileSystem auto_cleanup_fs;
if (FAILED(DxcInitThreadMalloc())) return 1;
DxcSetThreadMallocToDefault();
try {
llvm::sys::fs::MSFileSystem *msfPtr;
IFT(CreateMSFileSystemForDisk(&msfPtr));
std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
IFTLLVM(pts.error_code());
pStage = "Argument processing";
// Parse command line options.
cl::ParseCommandLineOptions(argc, argv, "dxil linker\n");
if (InputFiles == "" || Help) {
cl::PrintHelpMessage();
return 2;
}
DxcDllSupport dxcSupport;
// Read options and check errors.
dxc::EnsureEnabled(dxcSupport);
DxlContext context(dxcSupport);
pStage = "Linking";
retVal = context.Link();
} catch (const ::hlsl::Exception &hlslException) {
try {
const char *msg = hlslException.what();
Unicode::acp_char printBuffer[128]; // printBuffer is safe to treat as
// UTF-8 because we use ASCII only errors
// only
if (msg == nullptr || *msg == '\0') {
sprintf_s(printBuffer, _countof(printBuffer),
"Link failed - error code 0x%08x.", hlslException.hr);
msg = printBuffer;
}
printf("%s\n", msg);
} catch (...) {
printf("%s failed - unable to retrieve error message.\n", pStage);
}
return 1;
} catch (std::bad_alloc &) {
printf("%s failed - out of memory.\n", pStage);
return 1;
} catch (...) {
printf("%s failed - unknown error.\n", pStage);
return 1;
}
return retVal;
}