contrib: provide wine compatible fxc compiler
authorPierre Lamot <pierre@videolabs.io>
Tue, 15 Jan 2019 09:09:32 +0000 (10:09 +0100)
committerThomas Guillem <thomas@gllm.fr>
Wed, 10 Apr 2019 09:12:47 +0000 (11:12 +0200)
fxc compiler is required to compile ANGLE version of Qt.

Signed-off-by: Thomas Guillem <thomas@gllm.fr>
contrib/src/fxc2/0001-make-Vn-argument-as-optional-and-provide-default-var.patch [new file with mode: 0644]
contrib/src/fxc2/0002-accept-windows-style-flags-and-splitted-argument-val.patch [new file with mode: 0644]
contrib/src/fxc2/0003-Use-meson-as-a-build-system.patch [new file with mode: 0644]
contrib/src/fxc2/0004-Revert-Fix-narrowing-conversion-from-int-to-BYTE.patch [new file with mode: 0644]
contrib/src/fxc2/rules.mak [new file with mode: 0644]

diff --git a/contrib/src/fxc2/0001-make-Vn-argument-as-optional-and-provide-default-var.patch b/contrib/src/fxc2/0001-make-Vn-argument-as-optional-and-provide-default-var.patch
new file mode 100644 (file)
index 0000000..7e7b042
--- /dev/null
@@ -0,0 +1,81 @@
+From cfa41961473446e8f4b9df869bbd1aab65e9b9b0 Mon Sep 17 00:00:00 2001
+From: Pierre Lamot <pierre.lamot@yahoo.fr>
+Date: Mon, 14 Jan 2019 09:52:49 +0100
+Subject: [PATCH 1/4] make /Vn argument as optional and provide default
+ variable name
+
+---
+ fxc2.cpp | 40 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 37 insertions(+), 3 deletions(-)
+
+diff --git a/fxc2.cpp b/fxc2.cpp
+index 990e669..066608c 100755
+--- a/fxc2.cpp
++++ b/fxc2.cpp
+@@ -18,6 +18,29 @@ typedef HRESULT(__stdcall *pCompileFromFileg)(LPCWSTR,
+                                             ID3DBlob**,
+                                             ID3DBlob**);
++struct ProfilePrefix {
++  const char* name;
++  const char* prefix;
++};
++
++static const ProfilePrefix g_profilePrefixTable[] = {
++  { "ps_2_0", "g_ps20"},
++  { "ps_2_a", "g_ps21"},
++  { "ps_2_b", "g_ps21"},
++  { "ps_2_sw", "g_ps2ff"},
++  { "ps_3_0", "g_ps30"},
++  { "ps_3_sw", "g_ps3ff"},
++
++  { "vs_1_1", "g_vs11"},
++  { "vs_2_0", "g_vs20"},
++  { "vs_2_a", "g_vs21"},
++  { "vs_2_sw", "g_vs2ff"},
++  { "vs_3_0", "g_vs30"},
++  { "vs_3_sw", "g_vs3ff"},
++
++  { NULL, NULL}
++};
++
+ void print_usage_arg() {
+   // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509709(v=vs.85).aspx
+   printf("You have specified an argument that is not handled by fxc2\n");
+@@ -167,11 +190,22 @@ int main(int argc, char* argv[])
+     print_usage_missing("entryPoint");
+   if(defines == NULL)
+     print_usage_missing("defines");
+-  if(variableName == NULL)
+-    print_usage_missing("variableName");
+   if(outputFile == NULL)
+     print_usage_missing("outputFile");
++  //Default output variable name
++  if (variableName == NULL) {
++      const char* prefix = "g";
++      for (int i = 0; g_profilePrefixTable[i].name != NULL; i++) {
++          if (strcmp(g_profilePrefixTable[i].name, model) == 0) {
++              prefix = g_profilePrefixTable[i].prefix;
++              break;
++          }
++      }
++      variableName = (char*)malloc(strlen(prefix) + strlen(entryPoint) + 2);
++      sprintf(variableName, "%s_%s", prefix, entryPoint);
++  }
++
+   // ====================================================================================
+   // Shader Compilation
+@@ -280,7 +314,7 @@ int main(int argc, char* argv[])
+     FILE* f;
+     errno_t err = fopen_s(&f, outputFile, "w");
+-    fprintf(f, "const signed char %s[] =\n{\n", entryPoint);
++    fprintf(f, "const signed char %s[] =\n{\n", variableName);
+     for (i = 0; i < len; i++) {
+      fprintf(f, "%4i", outString[i]);
+      if (i != len - 1)
+-- 
+2.19.1
+
diff --git a/contrib/src/fxc2/0002-accept-windows-style-flags-and-splitted-argument-val.patch b/contrib/src/fxc2/0002-accept-windows-style-flags-and-splitted-argument-val.patch
new file mode 100644 (file)
index 0000000..3ce618f
--- /dev/null
@@ -0,0 +1,261 @@
+From 7c502bc09182958fa7268bfa792a338891c3df7b Mon Sep 17 00:00:00 2001
+From: Pierre Lamot <pierre.lamot@yahoo.fr>
+Date: Mon, 14 Jan 2019 15:09:36 +0100
+Subject: [PATCH 2/4] accept windows style flags and splitted argument value
+
+  - accept windows style flags: /opt or -opt
+  - accept split arguments : -FhFilename.h or -Fh Filename
+---
+ fxc2.cpp | 194 +++++++++++++++++++++++++++----------------------------
+ 1 file changed, 95 insertions(+), 99 deletions(-)
+
+diff --git a/fxc2.cpp b/fxc2.cpp
+index 066608c..01a8d07 100755
+--- a/fxc2.cpp
++++ b/fxc2.cpp
+@@ -2,7 +2,7 @@
+ #include <d3dcommon.h>
+ #include <direct.h>
+ #include <stdio.h>
+-#include <getopt.h>
++#include <assert.h>
+ #include <string>
+ #include <wchar.h>
+@@ -59,7 +58,41 @@ void print_usage_toomany() {
+   exit(1);
+ }
+-int main(int argc, char* argv[])
++bool parseOpt( const char* option, int argc, const char** argv, int* index, char** argumentOption )
++{
++    assert(option != NULL);
++    if (!index || *index >= argc) {
++      return false;
++    }
++    const char* argument = argv[*index];
++    if (argument[0] == '-' || argument[0] == '/')
++      argument++;
++    else
++      return false;
++
++    size_t optionSize = strlen(option);
++    if (strncmp(argument, option, optionSize) != 0) {
++      return false;
++    }
++
++    if (argumentOption) {
++      argument += optionSize;
++      if (*argument == '\0') {
++        *index += 1;
++        if (*index >= argc) {
++          printf("Error: missing required argument for option %s\n", option);
++          return false;
++        }
++        *argumentOption = strdup(argv[*index]);
++      } else {
++        *argumentOption = strdup(argument);
++      }
++    }
++    *index += 1;
++    return true;
++}
++
++int main(int argc, const char* argv[])
+ {
+   // ====================================================================================
+   // Process Command Line Arguments
+@@ -71,114 +104,77 @@ int main(int argc, char* argv[])
+   char* entryPoint = NULL;
+   char* variableName = NULL;
+   char* outputFile = NULL;
++  char* defineOption = NULL;
+   int numDefines = 1;
+   D3D_SHADER_MACRO* defines = new D3D_SHADER_MACRO[numDefines];
+   defines[numDefines-1].Name = NULL;
+   defines[numDefines-1].Definition = NULL;
+-  int i, c;
+-  static struct option longOptions[] =
+-  {
+-    /* These options set a flag. */
+-    {"nologo", no_argument,       &verbose, 0},
+-    {0, 0, 0, 0}
+-  };
+-
++  int index = 1;
+   while (1) {
+     D3D_SHADER_MACRO* newDefines;
+-    int optionIndex = 0;
+-    c = getopt_long_only (argc, argv, "T:E:D:V:F:",
+-                     longOptions, &optionIndex);
+-
+     /* Detect the end of the options. */
+-    if (c == -1)
++    if (index >= argc)
+       break;
+-    switch (c)
+-    {
+-      case 0:
+-        //printf ("option -nologo (quiet)\n");
+-        //Technically, this is any flag we define in longOptions
+-        break;
+-      case 'T':
+-        model = strdup(optarg);
+-        if(verbose) {
+-          printf ("option -T (Shader Model/Profile) with arg %s\n", optarg);
+-        }
+-        break;
+-      case 'E':
+-        entryPoint = strdup(optarg);
+-        if(verbose) {
+-          printf ("option -E (Entry Point) with arg %s\n", optarg);
+-        }
+-        break;
+-      case 'D':
+-        numDefines++;
+-        //Copy the old array into the new array, but put the new definition at the beginning
+-        newDefines = new D3D_SHADER_MACRO[numDefines];
+-        for(i=1; i<numDefines; i++)
+-          newDefines[i] = defines[i-1];
+-        delete[] defines;
+-        defines = newDefines;
+-        defines[0].Name = strdup(optarg);
+-        defines[0].Definition = "1";
++    if (parseOpt("nologo", argc, argv, &index, NULL)) {
++      continue;
++    } else if (parseOpt("T", argc, argv, &index, &model)) {
++      if(verbose) {
++        printf ("option -T (Shader Model/Profile) with arg '%s'\n", model);
++      }
++        continue;
++    } else if (parseOpt("E", argc, argv, &index, &entryPoint)) {
++      if(verbose) {
++        printf ("option -E (Entry Point) with arg '%s'\n", entryPoint);
++      }
++      continue;
++    } else if (parseOpt("D", argc, argv, &index, &defineOption)) {
++      numDefines++;
++      //Copy the old array into the new array, but put the new definition at the beginning
++      newDefines = new D3D_SHADER_MACRO[numDefines];
++      for(int i=1; i<numDefines; i++)
++        newDefines[i] = defines[i-1];
++      delete[] defines;
++      defines = newDefines;
++      defines[0].Name = defineOption;
++      defines[0].Definition = "1";
++      if(verbose) {
++        printf ("option -D with arg %s\n", defineOption);
++      }
++      continue;
++    } else if (parseOpt("Vn", argc, argv, &index, &variableName)) {
++      if(verbose) {
++        printf ("option -Vn (Variable Name) with arg '%s'\n", variableName);
++      }
++      continue;
++    } else if (parseOpt("Vi", argc, argv, &index, NULL)) {
++      if(verbose) {
++        printf("option -Vi (Output include process details) acknowledged but ignored.\n");
++      }
++      continue;
++    } else if (parseOpt("Fh", argc, argv, &index, &outputFile)) {
++      if(verbose) {
++        printf ("option -Fh (Output File) with arg %s\n", outputFile);
++      }
++      continue;
++    } else if (parseOpt("?", argc, argv, &index, NULL)) {
++      print_usage_arg();
++      continue;
++    } else {
++      if (!inputFile)
++      {
++        inputFile = new wchar_t[strlen(argv[index])+1];
++        mbstowcs(inputFile, argv[index], strlen(argv[index])+1);
+         if(verbose) {
+-          printf ("option -D with arg %s\n", optarg);
+-        }
+-        break;
+-
+-      case 'V':
+-        switch(optarg[0])
+-        {
+-          case 'n':
+-            variableName = strdup(&optarg[1]);
+-            if(verbose) {
+-              printf ("option -Vn (Variable Name) with arg %s\n", &optarg[1]);
+-            }
+-            break;
+-          case 'i':
+-            if(verbose) {
+-              printf("option -Vi (Output include process details) acknowledged but ignored.\n");
+-            }
+-            break;
+-          default:
+-            print_usage_arg();
+-            break;
++          wprintf(L"input file: %ls\n", inputFile);
+         }
+-        break;
+-      case 'F':
+-        switch(optarg[0])
+-        {
+-          case 'h':
+-            outputFile = strdup(&optarg[1]);
+-            if(verbose) {
+-              printf ("option -Fh (Output File) with arg %s\n", &optarg[1]);
+-            }
+-            break;
+-          default:
+-            print_usage_arg();
+-            break;
+-        }
+-        break;
+-
+-      case '?':
+-      default:
+-        print_usage_arg();
+-        break;
+-    }
+-  }
+-
+-  if (optind < argc) {
+-    inputFile = new wchar_t[strlen(argv[optind])+1];
+-    mbstowcs(inputFile, argv[optind], strlen(argv[optind])+1);
+-    if(verbose) {
+-      wprintf(L"input file: %ls\n", inputFile);
+-    }
+-
+-    optind++;
+-    if(optind < argc) {
+-      print_usage_toomany();
++        index += 1;
++      } else {
++        print_usage_toomany();
++        return 1;
++      }
+     }
+   }
+@@ -243,7 +239,7 @@ int main(int argc, char* argv[])
+     wprintf(L"\t %ls,\n", inputFile);
+     
+     printf("\t");
+-    for(i=0; i<numDefines-1; i++)
++    for(int i=0; i<numDefines-1; i++)
+       printf(" %s=%s", defines[i].Name, defines[i].Definition);
+     printf(",\n");
+@@ -315,7 +311,7 @@ int main(int argc, char* argv[])
+     errno_t err = fopen_s(&f, outputFile, "w");
+     fprintf(f, "const signed char %s[] =\n{\n", variableName);
+-    for (i = 0; i < len; i++) {
++    for (int i = 0; i < len; i++) {
+      fprintf(f, "%4i", outString[i]);
+      if (i != len - 1)
+        fprintf(f, ",");
+-- 
+2.19.1
+
diff --git a/contrib/src/fxc2/0003-Use-meson-as-a-build-system.patch b/contrib/src/fxc2/0003-Use-meson-as-a-build-system.patch
new file mode 100644 (file)
index 0000000..272bf46
--- /dev/null
@@ -0,0 +1,47 @@
+From 6289103998e7eb564e05f0866f4e5e9ba8afca45 Mon Sep 17 00:00:00 2001
+From: Pierre Lamot <pierre.lamot@yahoo.fr>
+Date: Mon, 14 Jan 2019 09:49:38 +0100
+Subject: [PATCH 3/4] Use meson as a build system
+
+---
+ meson.build | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+ create mode 100644 meson.build
+
+diff --git a/meson.build b/meson.build
+new file mode 100644
+index 0000000..a3a8601
+--- /dev/null
++++ b/meson.build
+@@ -0,0 +1,28 @@
++project('fxc2', 'cpp')
++
++if host_machine.system() != 'windows' or not host_machine.cpu_family().startswith('x86')
++  error('only compilation for windows i686/x86_64 is supported')
++endif
++
++executable(
++  'fxc2',
++  'fxc2.cpp',
++  override_options : [
++    'b_lundef=false',
++    'b_asneeded=false'
++  ],
++  link_args: ['-static'],
++  install: true
++)
++
++d3dcompiler_dll = []
++if host_machine.cpu_family() == 'x86'
++  d3dcompiler_dll += 'dll/d3dcompiler_47_32.dll'
++else
++  d3dcompiler_dll += 'dll/d3dcompiler_47.dll'
++endif
++
++install_data(d3dcompiler_dll,
++  rename: ['d3dcompiler_47.dll'],
++  install_dir : 'bin'
++)
+-- 
+2.19.1
+
diff --git a/contrib/src/fxc2/0004-Revert-Fix-narrowing-conversion-from-int-to-BYTE.patch b/contrib/src/fxc2/0004-Revert-Fix-narrowing-conversion-from-int-to-BYTE.patch
new file mode 100644 (file)
index 0000000..d334201
--- /dev/null
@@ -0,0 +1,56 @@
+From 24359310304ceee121489fd785fb31484cf36c0d Mon Sep 17 00:00:00 2001
+From: Pierre Lamot <pierre.lamot@yahoo.fr>
+Date: Mon, 14 Jan 2019 15:37:02 +0100
+Subject: [PATCH 4/4] Revert "Fix: narrowing conversion from 'int' to 'BYTE'"
+
+This reverts commit 82527b81104e5e21390d3ddcd328700c67ce73d4.
+---
+ fxc2.cpp | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fxc2.cpp b/fxc2.cpp
+index 01a8d07..ac17328 100755
+--- a/fxc2.cpp
++++ b/fxc2.cpp
+@@ -216,7 +216,7 @@ int main(int argc, const char* argv[])
+   memset(dllPath + bytes, '\0', MAX_PATH - bytes);
+   //Copy the dll location over top fxc2.exe
+   strcpy(strrchr(dllPath, '\\') + 1, "d3dcompiler_47.dll");
+-  
++
+   HMODULE h = LoadLibrary(dllPath);
+   if(h == NULL) {
+     printf("Error: could not load d3dcompiler_47.dll from %s\n", dllPath);
+@@ -235,9 +235,9 @@ int main(int argc, const char* argv[])
+   if(verbose) {
+     printf("Calling D3DCompileFromFile(\n");
+-    
++
+     wprintf(L"\t %ls,\n", inputFile);
+-    
++
+     printf("\t");
+     for(int i=0; i<numDefines-1; i++)
+       printf(" %s=%s", defines[i].Name, defines[i].Definition);
+@@ -310,7 +310,7 @@ int main(int argc, const char* argv[])
+     FILE* f;
+     errno_t err = fopen_s(&f, outputFile, "w");
+-    fprintf(f, "const signed char %s[] =\n{\n", variableName);
++    fprintf(f, "const BYTE %s[] =\n{\n", variableName);
+     for (int i = 0; i < len; i++) {
+      fprintf(f, "%4i", outString[i]);
+      if (i != len - 1)
+@@ -319,7 +319,7 @@ int main(int argc, const char* argv[])
+        fprintf(f, "\n");
+     }
+-    fprintf(f, "\n};\n");
++    fprintf(f, "\n};");
+     fclose(f);
+     if(verbose) {
+-- 
+2.19.1
+
diff --git a/contrib/src/fxc2/rules.mak b/contrib/src/fxc2/rules.mak
new file mode 100644 (file)
index 0000000..49ca73f
--- /dev/null
@@ -0,0 +1,30 @@
+FXC2_HASH := 63ad74b7faa7033f2c1be9cc1cd0225241a1a9a5
+FXC2_VERSION := git-$(FXC2_HASH)
+FXC2_GITURL := https://github.com/mozilla/fxc2.git
+
+ifeq ($(call need_pkg,"fxc2"),)
+PKGS_FOUND += fxc2
+endif
+
+$(TARBALLS)/fxc2-$(FXC2_VERSION).tar.xz:
+       $(call download_git,$(FXC2_GITURL),,$(FXC2_HASH))
+
+.sum-fxc2: fxc2-$(FXC2_VERSION).tar.xz
+       $(call check_githash,$(FXC2_HASH))
+       touch $@
+
+fxc2: fxc2-$(FXC2_VERSION).tar.xz .sum-fxc2
+       rm -rf $@-$(FXC2_VERSION) $@
+       mkdir -p $@-$(FXC2_VERSION)
+       tar xvf "$<" --strip-components=1 -C $@-$(FXC2_VERSION)
+       $(APPLY) $(SRC)/fxc2/0001-make-Vn-argument-as-optional-and-provide-default-var.patch
+       $(APPLY) $(SRC)/fxc2/0002-accept-windows-style-flags-and-splitted-argument-val.patch
+       $(APPLY) $(SRC)/fxc2/0003-Use-meson-as-a-build-system.patch
+       $(APPLY) $(SRC)/fxc2/0004-Revert-Fix-narrowing-conversion-from-int-to-BYTE.patch
+       $(MOVE)
+
+.fxc2: fxc2 crossfile.meson
+       cd $< && rm -rf ./build
+       cd $< && $(HOSTVARS_MESON) $(MESON) build
+       cd $< && cd build && ninja install
+       touch $@