RFC: Investigate the winegcc/wineg++ support in CMake (via CMakeParseImplicit[Include/Link]Info or Compiler/Wine-GNU etc.)?

Hello, everyone, it would be great to add the winegcc/wineg++ support into CMake, as they are wrappers over system gcc, and they add the new include/link paths into compiler flags, but it’s not easy to extract them w/o CMake support.
I found these ways to try to parse for a new includes/link paths and implicit libraries:
Include dirs:

$ echo | LANG=C winegcc -xc -E -v -
/usr/lib64/ccache/gcc -m64 -fshort-wchar -DWINE_UNICODE_NATIVE -D_REENTRANT -fPIC -DWIN64 -D_WIN64 -D__WIN64 -D__WIN64__ -DWIN32 -D_WIN32 -D__WIN32 -D__WIN32__ -D__WINNT -D__WINNT__ -D__stdcall=__attribute__((ms_abi)) -D__cdecl=__stdcall -D__fastcall=__stdcall -D_stdcall=__stdcall -D_cdecl=__cdecl -D_fastcall=__fastcall -D__declspec(x)=__declspec_##x -D__declspec_align(x)=__attribute__((aligned(x))) -D__declspec_allocate(x)=__attribute__((section(x))) -D__declspec_deprecated=__attribute__((deprecated)) -D__declspec_dllimport=__attribute__((dllimport)) -D__declspec_dllexport=__attribute__((dllexport)) -D__declspec_naked=__attribute__((naked)) -D__declspec_noinline=__attribute__((noinline)) -D__declspec_noreturn=__attribute__((noreturn)) -D__declspec_nothrow=__attribute__((nothrow)) -D__declspec_novtable=__attribute__(()) -D__declspec_selectany=__attribute__((weak)) -D__declspec_thread=__thread -D__int8=char -D__int16=short -D__int32=int -D__int64=long -D__WINE__ -E -v -xc - -isystem/usr/bin/../include/wine/windows -idirafter/usr/bin/../include -isystem/usr/include/wine/windows -idirafter/usr/include -isystem/usr/local/include/wine/windows -idirafter/usr/local/include
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-12.2.1-20220819/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none --without-cuda-driver --enable-offload-defaulted --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.1 20220819 (Red Hat 12.2.1-2) (GCC) 
COLLECT_GCC_OPTIONS='-m64' '-fshort-wchar' '-D' 'WINE_UNICODE_NATIVE' '-D' '_REENTRANT' '-fPIC' '-D' 'WIN64' '-D' '_WIN64' '-D' '__WIN64' '-D' '__WIN64__' '-D' 'WIN32' '-D' '_WIN32' '-D' '__WIN32' '-D' '__WIN32__' '-D' '__WINNT' '-D' '__WINNT__' '-D' '__stdcall=__attribute__((ms_abi))' '-D' '__cdecl=__stdcall' '-D' '__fastcall=__stdcall' '-D' '_stdcall=__stdcall' '-D' '_cdecl=__cdecl' '-D' '_fastcall=__fastcall' '-D' '__declspec(x)=__declspec_##x' '-D' '__declspec_align(x)=__attribute__((aligned(x)))' '-D' '__declspec_allocate(x)=__attribute__((section(x)))' '-D' '__declspec_deprecated=__attribute__((deprecated))' '-D' '__declspec_dllimport=__attribute__((dllimport))' '-D' '__declspec_dllexport=__attribute__((dllexport))' '-D' '__declspec_naked=__attribute__((naked))' '-D' '__declspec_noinline=__attribute__((noinline))' '-D' '__declspec_noreturn=__attribute__((noreturn))' '-D' '__declspec_nothrow=__attribute__((nothrow))' '-D' '__declspec_novtable=__attribute__(())' '-D' '__declspec_selectany=__attribute__((weak))' '-D' '__declspec_thread=__thread' '-D' '__int8=char' '-D' '__int16=short' '-D' '__int32=int' '-D' '__int64=long' '-D' '__WINE__' '-E' '-v' '-isystem' '/usr/bin/../include/wine/windows' '-idirafter' '/usr/bin/../include' '-isystem' '/usr/include/wine/windows' '-idirafter' '/usr/include' '-isystem' '/usr/local/include/wine/windows' '-idirafter' '/usr/local/include' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-redhat-linux/12/cc1 -E -quiet -v -D WINE_UNICODE_NATIVE -D _REENTRANT -D WIN64 -D _WIN64 -D __WIN64 -D __WIN64__ -D WIN32 -D _WIN32 -D __WIN32 -D __WIN32__ -D __WINNT -D __WINNT__ -D __stdcall=__attribute__((ms_abi)) -D __cdecl=__stdcall -D __fastcall=__stdcall -D _stdcall=__stdcall -D _cdecl=__cdecl -D _fastcall=__fastcall -D __declspec(x)=__declspec_##x -D __declspec_align(x)=__attribute__((aligned(x))) -D __declspec_allocate(x)=__attribute__((section(x))) -D __declspec_deprecated=__attribute__((deprecated)) -D __declspec_dllimport=__attribute__((dllimport)) -D __declspec_dllexport=__attribute__((dllexport)) -D __declspec_naked=__attribute__((naked)) -D __declspec_noinline=__attribute__((noinline)) -D __declspec_noreturn=__attribute__((noreturn)) -D __declspec_nothrow=__attribute__((nothrow)) -D __declspec_novtable=__attribute__(()) -D __declspec_selectany=__attribute__((weak)) -D __declspec_thread=__thread -D __int8=char -D __int16=short -D __int32=int -D __int64=long -D __WINE__ -isystem /usr/bin/../include/wine/windows -idirafter /usr/bin/../include -isystem /usr/include/wine/windows -idirafter /usr/include -isystem /usr/local/include/wine/windows -idirafter /usr/local/include - -m64 -mtune=generic -march=x86-64 -fshort-wchar -fPIC -dumpbase -
ignoring duplicate directory "/usr/include/wine/windows"
ignoring nonexistent directory "/usr/local/include/wine/windows"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/12/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include"
ignoring duplicate directory "/usr/bin/../include"
ignoring duplicate directory "/usr/include"
ignoring duplicate directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../include/wine/windows
 /usr/lib/gcc/x86_64-redhat-linux/12/include
 /usr/local/include
 /usr/include
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "<stdin>"
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/12/:/usr/libexec/gcc/x86_64-redhat-linux/12/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/12/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/12/:/usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/12/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-m64' '-fshort-wchar' '-D' 'WINE_UNICODE_NATIVE' '-D' '_REENTRANT' '-fPIC' '-D' 'WIN64' '-D' '_WIN64' '-D' '__WIN64' '-D' '__WIN64__' '-D' 'WIN32' '-D' '_WIN32' '-D' '__WIN32' '-D' '__WIN32__' '-D' '__WINNT' '-D' '__WINNT__' '-D' '__stdcall=__attribute__((ms_abi))' '-D' '__cdecl=__stdcall' '-D' '__fastcall=__stdcall' '-D' '_stdcall=__stdcall' '-D' '_cdecl=__cdecl' '-D' '_fastcall=__fastcall' '-D' '__declspec(x)=__declspec_##x' '-D' '__declspec_align(x)=__attribute__((aligned(x)))' '-D' '__declspec_allocate(x)=__attribute__((section(x)))' '-D' '__declspec_deprecated=__attribute__((deprecated))' '-D' '__declspec_dllimport=__attribute__((dllimport))' '-D' '__declspec_dllexport=__attribute__((dllexport))' '-D' '__declspec_naked=__attribute__((naked))' '-D' '__declspec_noinline=__attribute__((noinline))' '-D' '__declspec_noreturn=__attribute__((noreturn))' '-D' '__declspec_nothrow=__attribute__((nothrow))' '-D' '__declspec_novtable=__attribute__(())' '-D' '__declspec_selectany=__attribute__((weak))' '-D' '__declspec_thread=__thread' '-D' '__int8=char' '-D' '__int16=short' '-D' '__int32=int' '-D' '__int64=long' '-D' '__WINE__' '-E' '-v' '-isystem' '/usr/bin/../include/wine/windows' '-idirafter' '/usr/bin/../include' '-isystem' '/usr/include/wine/windows' '-idirafter' '/usr/include' '-isystem' '/usr/local/include/wine/windows' '-idirafter' '/usr/local/include' '-mtune=generic' '-march=x86-64'

Link dirs/implicit dirs and link options:

$ LANG=C winegcc -lopengl32 -Xlinker -v
ollect2 version 12.2.1 20220819 (Red Hat 12.2.1-2)
/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/12/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/12/lto-wrapper -plugin-opt=-fresolution=/tmp/cccwrKwe.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o a.out.so /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/12/crtbeginS.o -L/usr/bin/../lib64/wine/x86_64-unix -L/usr/bin/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/12 -L/usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/12/../../.. -v -Bsymbolic -z max-page-size=0x1000 -z defs a.out-633be3b5.spec.o /usr/bin/../lib64/wine/x86_64-unix/libopengl32.a /usr/bin/../lib64/wine/x86_64-unix/libadvapi32.a /usr/bin/../lib64/wine/x86_64-unix/libuser32.a /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /usr/bin/../lib64/wine/x86_64-unix/libkernel32.a -lm -lc -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-redhat-linux/12/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crtn.o
GNU ld version 2.37-36.fc36
/usr/bin/ld: /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a(exe_main.o): in function `main':
(.text.startup+0x99): undefined reference to `WinMain'
collect2: error: ld returned 1 exit status
winegcc: /usr/lib64/ccache/gcc failed

And the most interesting one:

echo | LANG=C winegcc -xc -v -fsyntax-only -
/usr/bin/winebuild -v -fno-asynchronous-unwind-tables "--cc-cmd=/usr/lib64/ccache/gcc -m64" --ld-cmd=/usr/bin/ld -fPIC --exe -o a.out-633bea96.spec.o -F a.out --subsystem console -L/usr/bin/../lib64/wine/x86_64-unix -L/usr/bin/../lib64 -- /usr/bin/../lib64/wine/x86_64-unix/libadvapi32.a /usr/bin/../lib64/wine/x86_64-unix/libuser32.a /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /usr/bin/../lib64/wine/x86_64-unix/libkernel32.a /usr/bin/../lib64/wine/x86_64-unix/libntdll.a
/usr/lib64/ccache/gcc -m64 -xassembler -c -o a.out-633bea96.spec-c677d52e.o a.out-633bea96.spec-633bea97.s
/usr/bin/ld -r -o a.out-633bea96.spec-29b3bfc5.o a.out-633bea96.spec-c677d52e.o /usr/bin/../lib64/wine/x86_64-unix/libadvapi32.a /usr/bin/../lib64/wine/x86_64-unix/libuser32.a /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /usr/bin/../lib64/wine/x86_64-unix/libkernel32.a /usr/bin/../lib64/wine/x86_64-unix/libntdll.a
/usr/bin/nm -u a.out-633bea96.spec-29b3bfc5.o
/usr/lib64/ccache/gcc -m64 -xassembler -c -o a.out-633bea96.spec.o a.out-633bea96.spec-8cefaa5c.s
Creating file try_link-c677d52c.c
/usr/lib64/ccache/gcc -m64 -o try_link-29b3bfc2.out -Wl,-z,max-page-size=0x1000 try_link-c677d52c.c
Creating file try_link-f02b94ee.c
/usr/bin/ld: /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a(exe_main.o): in function `main':
(.text.startup+0x99): undefined reference to `WinMain'
collect2: error: ld returned 1 exit status
winegcc: /usr/lib64/ccache/gcc failed
/usr/lib64/ccache/gcc -m64 -shared -Wl,-Bsymbolic -o try_link-53677f84.out -Wl,-z,defs try_link-f02b94ee.c
/usr/lib64/ccache/gcc -m64 -shared -Wl,-Bsymbolic -Wl,-z,max-page-size=0x1000 -Wl,-z,defs -o a.out.so -L/usr/bin/../lib64/wine/x86_64-unix -L/usr/bin/../lib64 a.out-633bea96.spec.o /usr/bin/../lib64/wine/x86_64-unix/libadvapi32.a /usr/bin/../lib64/wine/x86_64-unix/libuser32.a /usr/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /usr/bin/../lib64/wine/x86_64-unix/libkernel32.a -lm -lc

The last one also reveals the winebuild tool.

The question is: how is better integrate the winegcc/wineg++ into CMake? (the “easiest” is the toolchain, but it has to include the copy-paste from CMakeParse***Info files)…

Sorry for my bad text/motivation and a bunch of output text. Thanks in advance

Is there a reason this can’t act like a cross-compiler (just like mingw toolchains provided by distros)?

Yes, it might, but it is kind of “dual” compiler, which uses library names from Windows (e.g. for proper find_package(OpenGL) you must forcebly set (WIN32 1)) but actually compiles binaries as Linux ELFs (and helper sh launcher script).

Oh, that is weird. That probably needs some new logic indeed. Please file an issue about this toolchain.

1 Like

Issue for this was created here: https://gitlab.kitware.com/cmake/cmake/-/issues/24842

1 Like