Skip to content

Support for Windows (MinGW/MSYS) #35

@maleadt

Description

@maleadt

I naively started working on a build of ocl-icd for MSYS2 in msys2/MINGW-packages#22623, but encountered several issues that seemed to indicate the code currently isn't really compatible with Windows environments. I don't have the time to fix these myself, but figured it would be useful to open an issue tracking what (some of) the remaining problems are:

  • libtool: error: can't build x86_64-w64-mingw32 shared library unless -no-undefined is specified, for which Cygwin has a patch: https://cygwin.com/cgit/cygwin-packages/ocl-icd/tree/ocl-icd-2.3.2-1.src.patch
  • When building with 64-bit clang (MINGW_ARCH=clang64), linking fails with lld: error: unknown argument: --version-script (also see https://lists.llvm.org/pipermail/llvm-dev/2018-June/124385.html). Detecting Windows and disabling USE_MAP helps, but it would probably be better to get this to work properly:
    diff --git a/configure.ac b/configure.ac
    index 2ef2e7a..0a9f588 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -17,6 +17,10 @@ case $host_os in
       *darwin*) macos="yes" ;;
       *) macos="no" ;;
     esac
    +case $host_os in
    +  *msys*|*cygwin*|*mingw*|*windows*) windows="yes" ;;
    +  *) windows="no" ;;
    +esac
     AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.9 tar-pax check-news color-tests parallel-tests])
     AMX_SILENT_RULES([AM_DEFAULT_VERBOSITY=1])
     # AM_PROG_AR must be called before LT_INIT...
    @@ -196,7 +200,7 @@ AS_IF([test x"$OCL_ICD_LAYERDIR" = x"/etc/OpenCL/layers"], [
     ])
    
     # always use versionned symbols (check required for MacOSX)
    -if test "x$macos" == xyes ; then
    +if test "x$macos" == xyes || test "x$windows" = xyes ; then
     AM_CONDITIONAL([USE_MAP], [false])
     else
     AM_CONDITIONAL([USE_MAP], [true])
  • long is used to cast and format function pointers, but on 64-bit Windows that means casting to a smaller integer.
    Possible patch:
    diff --git a/ocl_icd_debug.h b/ocl_icd_debug.h
    index 87aee14..a8ce622 100644
    --- a/ocl_icd_debug.h
    +++ b/ocl_icd_debug.h
    @@ -65,7 +65,7 @@ extern int debug_ocl_icd_mask;
        } while(0)
     #  define RETURN(val) do { \
            __typeof__(val) ret=(val); \
    -       debug(D_TRACE, "return: %ld/0x%lx", (long)ret, (long)ret);      \
    +       debug(D_TRACE, "return: %td/0x%tx", (intptr_t)ret, (intptr_t)ret);      \
            return ret; \
        } while(0)
     #  define RETURN_STR(val) do { \
    @@ -94,7 +94,7 @@ static inline void debug_init(void) {
     }
    
     #  define dump_field(pid, f, name) \
    -    debug(D_ALWAYS, "%40s=%p [%p/%p]", #name, pid->dispatch->name, f(#name), ((long)(pid->dispatch->clGetExtensionFunctionAddressForPlatform)>10)?pid->dispatch->clGetExtensionFunctionAddressForPlatform(pid, #name):NULL)
    +    debug(D_ALWAYS, "%40s=%p [%p/%p]", #name, pid->dispatch->name, f(#name), ((intptr_t)(pid->dispatch->clGetExtensionFunctionAddressForPlatform)>10)?pid->dispatch->clGetExtensionFunctionAddressForPlatform(pid, #name):NULL)
    
     #else
     #  define debug(...) (void)0
  • Lots of warnings: visibility attribute not supported in this configuration; ignored
  • Probably related: When building with 32-bit gcc (MINGW_ARCH=mingw32), lots of errors a la:
    ocl_icd_loader.c:1098:14: error: 'clGetExtensionFunctionAddress_hid' aliased to undefined symbol 'clGetExtensionFunctionAddress'
     1098 | hidden_alias(clGetExtensionFunctionAddress);
          |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ocl_icd_loader.c:1008:16: note: in definition of macro 'hidden_alias'
     1008 |   typeof(name) name##_hid __attribute__ ((alias (#name), visibility("hidden")))
          |                ^~~~
    
    Making hidden_alias bail out when defined(_WIN32) "fixes" this. Similar changes need to be made in the Ruby generator as well:
    ocl_icd_loader_gen.c:3683:14: error: 'clGetDeviceIDs_hid' aliased to undefined symbol 'clGetDeviceIDs'
     3683 | hidden_alias(clGetDeviceIDs);
          |              ^~~~~~~~~~~~~~
    
  • Missing CL_API_CALL annotations in the generated code, leading to errors a la:
    ocl_icd_loader_gen.c:4613:3: error: initialization of 'cl_int (__attribute__((stdcall)) *)(struct _cl_command_queue *, void *, cl_uint,  struct _cl_event * const*, struct _cl_event **)' {aka 'int (__attribute__((stdcall)) *)(struct _cl_command_queue *, void *, unsigned int,  struct _cl_event * const*, struct _cl_event **)'} from incompatible pointer type 'cl_int (*)(struct _cl_command_queue *, void *, cl_uint,  struct _cl_event * const*, struct _cl_event **)' {aka 'int (*)(struct _cl_command_queue *, void *, unsigned int,  struct _cl_event * const*, struct _cl_event **)'} [-Wincompatible-pointer-types]
     4613 |   clEnqueueSVMUnmap_disp,
          |   ^~~~~~~~~~~~~~~~~~~~~~
    ocl_icd_loader_gen.c:4613:3: note: (near initialization for 'master_dispatch.clEnqueueSVMUnmap')
    
    The mismatch here is the stdcall attribute. Naively adding CL_API_CALL to the generated signatures (which picks up stdcall from the vendored Khronos headers) fixes the issue listed above, but introduces new mismatches.

As I'm not familiar with how the loader works, the stdcall mismatches is where I gave up. It would be great if somebody familiar with the codebase could patch these up and revive my MSYS2 PR, the groundwork has been laid already.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions