瀏覽代碼

Allow libdxcompiler.so and dxc to find libdxil.so (#5004)

When present in the library search path, linux builds of
libdxcompiler.so and the dxc executable should load libdxil.so and use
it for validation and signing. However, the code to do that was still
searching for dxil.dll even on these platforms.

This change creates appropriate names for the dxcompiler and dxil
libraries for each platform and uses them where appropriate.

In addition, this changes some of the internal interfaces from wide
chars to simple chars as the wide interface wasn't useful here.
Greg Roth 2 年之前
父節點
當前提交
ae51624fca

+ 8 - 13
include/dxc/Support/dxcapi.use.h

@@ -16,6 +16,9 @@
 
 namespace dxc {
 
+  extern const char* kDxCompilerLib;
+  extern const char* kDxilLib;
+
 // Helper class to dynamically load the dxcompiler or a compatible libraries.
 class DxcDllSupport {
 protected:
@@ -23,15 +26,13 @@ protected:
   DxcCreateInstanceProc m_createFn;
   DxcCreateInstance2Proc m_createFn2;
 
-  HRESULT InitializeInternal(LPCWSTR dllName, LPCSTR fnName) {
+  HRESULT InitializeInternal(LPCSTR dllName, LPCSTR fnName) {
     if (m_dll != nullptr) return S_OK;
 
 #ifdef _WIN32
-    m_dll = LoadLibraryW(dllName);
+    m_dll = LoadLibraryA(dllName);
 #else
-    char nameStr[256];
-    std::wcstombs(nameStr, dllName, 256);
-    m_dll = ::dlopen(nameStr, RTLD_LAZY);
+    m_dll = ::dlopen(dllName, RTLD_LAZY);
 #endif
 
     if (m_dll == nullptr) return HRESULT_FROM_WIN32(GetLastError());
@@ -86,16 +87,10 @@ public:
   }
 
   HRESULT Initialize() {
-    #ifdef _WIN32
-    return InitializeInternal(L"dxcompiler.dll", "DxcCreateInstance");
-    #elif __APPLE__
-    return InitializeInternal(L"libdxcompiler.dylib", "DxcCreateInstance");
-    #else
-    return InitializeInternal(L"libdxcompiler.so", "DxcCreateInstance");
-    #endif
+    return InitializeInternal(kDxCompilerLib, "DxcCreateInstance");
   }
 
-  HRESULT InitializeForDll(_In_z_ const wchar_t* dll, _In_z_ const char* entryPoint) {
+  HRESULT InitializeForDll(_In_z_ LPCSTR dll, _In_z_ LPCSTR entryPoint) {
     return InitializeInternal(dll, entryPoint);
   }
 

+ 8 - 0
lib/DxcSupport/CMakeLists.txt

@@ -11,4 +11,12 @@ add_llvm_library(LLVMDxcSupport
   WinFunctions.cpp
   )
 
+#generate header with platform-specific library name
+configure_file(
+${LLVM_MAIN_SRC_DIR}/lib/DxcSupport/SharedLibAffix.inc
+SharedLibAffix.h
+)
+
+include_directories( ${LLVM_INCLUDE_DIR}/DxcSupport) #needed to find the generated header
+
 add_dependencies(LLVMDxcSupport TablegenHLSLOptions)

+ 1 - 2
lib/DxcSupport/HLSLOptions.cpp

@@ -1187,9 +1187,8 @@ int SetupDxcDllSupport(const DxcOpts &opts, dxc::DxcDllSupport &dxcSupport,
                        llvm::raw_ostream &errors) {
   if (!opts.ExternalLib.empty()) {
     DXASSERT(!opts.ExternalFn.empty(), "else ReadDxcOpts should have failed");
-    StringRefWide externalLib(opts.ExternalLib);
     HRESULT hrLoad =
-        dxcSupport.InitializeForDll(externalLib, opts.ExternalFn.data());
+      dxcSupport.InitializeForDll(opts.ExternalLib.data(), opts.ExternalFn.data());
     if (DXC_FAILED(hrLoad)) {
       errors << "Unable to load support for external DLL " << opts.ExternalLib
              << " with function " << opts.ExternalFn << " - error 0x";

+ 24 - 0
lib/DxcSupport/SharedLibAffix.inc

@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// SharedLibAffix.inc                                                        //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Defines shared library prefixes and suffixes for the build platform.      //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#pragma once
+
+#cmakedefine CMAKE_SHARED_LIBRARY_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@"
+#cmakedefine CMAKE_SHARED_LIBRARY_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@"
+
+#ifndef CMAKE_SHARED_LIBRARY_PREFIX
+#define CMAKE_SHARED_LIBRARY_PREFIX
+#endif
+
+#ifndef CMAKE_SHARED_LIBRARY_SUFFIX
+#define CMAKE_SHARED_LIBRARY_SUFFIX
+#endif

+ 4 - 0
lib/DxcSupport/dxcapi.use.cpp

@@ -15,9 +15,13 @@
 #include "dxc/Support/Unicode.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/WinFunctions.h"
+#include "SharedLibAffix.h"
 
 namespace dxc {
 
+const char* kDxCompilerLib = CMAKE_SHARED_LIBRARY_PREFIX "dxcompiler" CMAKE_SHARED_LIBRARY_SUFFIX;
+const char* kDxilLib = CMAKE_SHARED_LIBRARY_PREFIX "dxil" CMAKE_SHARED_LIBRARY_SUFFIX;
+
 #ifdef _WIN32
 static void TrimEOL(_Inout_z_ char *pMsg) {
   char *pEnd = pMsg + strlen(pMsg);

+ 1 - 1
projects/dxilconv/unittests/DxilConvTests.cpp

@@ -166,7 +166,7 @@ private:
 
 bool DxilConvTest::InitSupport() {
   if (!m_dllSupport.IsEnabled()) {
-    VERIFY_SUCCEEDED(m_dllSupport.InitializeForDll(L"dxilconv.dll", "DxcCreateInstance"));
+    VERIFY_SUCCEEDED(m_dllSupport.InitializeForDll("dxilconv.dll", "DxcCreateInstance"));
   }
 
   if (!FindToolInBinDir("%dxbc2dxil", "dxbc2dxil.exe")) {

+ 5 - 5
tools/clang/tools/dxclib/dxc.cpp

@@ -1189,7 +1189,7 @@ void WriteDxCompilerVersionInfo(llvm::raw_ostream &OS,
     CComPtr<IDxcVersionInfo2> VerInfo2;
 #endif // SUPPORT_QUERY_GIT_COMMIT_INFO
 
-    const char *dllName = !ExternalLib ? "dxcompiler.dll" : ExternalLib;
+    const char *dllName = !ExternalLib ? kDxCompilerLib : ExternalLib;
     std::string compilerName(dllName);
     if (ExternalFn)
       compilerName = compilerName + "!" + ExternalFn;
@@ -1244,17 +1244,17 @@ void WriteDXILVersionInfo(llvm::raw_ostream &OS,
       UINT32 validatorMajor, validatorMinor = 0;
       VerInfo->GetVersion(&validatorMajor, &validatorMinor);
       OS << "; "
-         << "dxil.dll"
+         << kDxilLib
          << ": " << validatorMajor << "." << validatorMinor;
 
     }
     // dxil.dll 1.0 did not support IdxcVersionInfo
     else {
       OS << "; "
-         << "dxil.dll: " << 1 << "." << 0;
+         << kDxilLib << ": " << 1 << "." << 0;
     }
     unsigned int version[4];
-    if (GetDLLFileVersionInfo("dxil.dll", version)) {
+    if (GetDLLFileVersionInfo(kDxilLib, version)) {
       OS << "(" << version[0] << "." << version[1] << "." << version[2] << "."
          << version[3] << ")";
     }
@@ -1272,7 +1272,7 @@ void DxcContext::GetCompilerVersionInfo(llvm::raw_string_ostream &OS) {
 
   // Print validator if exists
   DxcDllSupport DxilSupport;
-  DxilSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
+  DxilSupport.InitializeForDll(kDxilLib, "DxcCreateInstance");
   WriteDXILVersionInfo(OS, DxilSupport);
 }
 

+ 1 - 1
tools/clang/tools/dxcompiler/dxcutil.cpp

@@ -176,7 +176,7 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) {
     if (inputs.pDiag) {
       unsigned diagID =
           inputs.pDiag->getCustomDiagID(clang::DiagnosticsEngine::Level::Warning,
-                               "DXIL.dll not found.  Resulting DXIL will not be "
+                               "DXIL signing library (dxil.dll,libdxil.so) not found.  Resulting DXIL will not be "
                                "signed for use in release environments.\r\n");
       inputs.pDiag->Report(diagID);
     }

+ 2 - 9
tools/clang/tools/dxcompiler/dxillib.cpp

@@ -25,11 +25,9 @@ static llvm::sys::Mutex *cs = nullptr;
 // This function is to prevent multiple attempts to load dxil.dll 
 HRESULT DxilLibInitialize() {
   cs = new llvm::sys::Mutex;
-#if LLVM_ON_WIN32
   cs->lock();
-  g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
+  g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance");
   cs->unlock();
-#endif
   return S_OK;
 }
 
@@ -53,19 +51,14 @@ HRESULT DxilLibCleanup(DxilLibCleanUpType type) {
 // If we fail to load dxil.dll, set g_DllLibResult to E_FAIL so that we don't
 // have multiple attempts to load dxil.dll
 bool DxilLibIsEnabled() {
-#if LLVM_ON_WIN32
   cs->lock();
   if (SUCCEEDED(g_DllLibResult)) {
     if (!g_DllSupport.IsEnabled()) {
-      g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
+      g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance");
     }
   }
   cs->unlock();
   return SUCCEEDED(g_DllLibResult);
-#else
-  g_DllLibResult = (HRESULT)-1;
-  return false;
-#endif
 }
 
 

+ 2 - 1
tools/clang/tools/dxopt/dxopt.cpp

@@ -316,7 +316,8 @@ int main(int argc, const char **argv) {
 
     if (externalLib) {
       CW2A externalFnA(externalFn, CP_UTF8);
-      IFT(g_DxcSupport.InitializeForDll(externalLib, externalFnA));
+      CW2A externalLibA(externalFn, CP_UTF8);
+      IFT(g_DxcSupport.InitializeForDll(externalLibA, externalFnA));
     }
     else {
       IFT(g_DxcSupport.Initialize());

+ 1 - 1
tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp

@@ -156,7 +156,7 @@ HRESULT ValidateAndAssembleToContainer(AssembleInputs &inputs) {
     if (inputs.pDiag) {
       unsigned diagID =
           inputs.pDiag->getCustomDiagID(clang::DiagnosticsEngine::Level::Warning,
-                               "DXIL.dll not found.  Resulting DXIL will not be "
+                               "DXIL signing library (dxil.dll,libdxil.so) not found.  Resulting DXIL will not be "
                                "signed for use in release environments.\r\n");
       inputs.pDiag->Report(diagID);
     }

+ 2 - 2
tools/clang/tools/dxrfallbackcompiler/dxillib.cpp

@@ -48,7 +48,7 @@ bool DxilLibIsEnabled() {
   EnterCriticalSection(&cs);
   if (SUCCEEDED(g_DllLibResult)) {
     if (!g_DllSupport.IsEnabled()) {
-      g_DllLibResult = g_DllSupport.InitializeForDll(L"dxil.dll", "DxcCreateInstance");
+      g_DllLibResult = g_DllSupport.InitializeForDll(kDxilLib, "DxcCreateInstance");
     }
   }
   LeaveCriticalSection(&cs);
@@ -65,4 +65,4 @@ HRESULT DxilLibCreateInstance(_In_ REFCLSID rclsid, _In_ REFIID riid, _In_ IUnkn
     LeaveCriticalSection(&cs);
   }
   return hr;
-}
+}

+ 1 - 1
tools/clang/unittests/DxrFallback/test_DxrFallback.cpp

@@ -157,7 +157,7 @@ public:
     , m_path(path)
   {
     dxc::EnsureEnabled(m_dxcSupport);
-    m_dxrFallbackSupport.InitializeForDll(L"DxrFallbackCompiler.dll", "DxcCreateDxrFallbackCompiler");
+    m_dxrFallbackSupport.InitializeForDll("DxrFallbackCompiler.dll", "DxcCreateDxrFallbackCompiler");
   }
 
   void setFiles(const std::vector<std::string>& files)

+ 8 - 0
tools/clang/unittests/HLSLExec/ShaderOpTest.cpp

@@ -37,6 +37,14 @@
 #include <xmllite.h>
 #pragma comment(lib, "xmllite.lib")
 
+
+// Duplicate definition of kDxCompilerLib to that in dxcapi.use.cpp
+// These tests need the header, but don't want to depend on the source
+// Since this is windows only, we only need the windows variant
+namespace dxc {
+const char* kDxCompilerLib = "dxcompiler.dll";
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Useful helper functions.