protonscr

lsteamclient compilation errors

protonclosed
ValveSoftware/Proton#7867 · opened 2024-07-02 by h0tc0d3 · updated 2024-07-08 · 8 comments · github
Hh0tc0d3 2024-07-02 github

I'm trying to build the latest version of lsteamclient, but I'm getting errors. I was able to remove -Wimplicit-function-declaration errors in C files by lowering the C standard to 89. For some reason, include in CPP files does not work correctly. lsteamclinet from proton_8.0 compiles successfully. Probably newer versions of compilers are more strict about errors.

winegcc --version
gcc (GCC) 14.1.1 20240620 (Red Hat 14.1.1-6)
export CFLAGS="-O2 -std=gnu89"
export CXXFLAGS="-O2 -std=gnu++17"
winemaker --wine32 --dll \
    --nosource-fix \
    --nolower-include \
    --nodlls \
    --nomsvcrt \
    -I${SOURCE_DIR:?}/wine/include \
    -I${SOURCE_DIR:?}/wine/include/wine \
    -I/usr/include \
    -DWINE_NO_LONG_TYPES \
    -DSTEAM_API_EXPORTS \
    -Dprivate=public \
    -Dprotected=public \
    .

sed -re 's#_LDFLAGS=#_LDFLAGS= -static-libgcc -static-libstdc++#' -i Makefile
make -e CC="winegcc -m32" CXX="wineg++ -m32" -j$(nproc)
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingServerListResponse_099u::RefreshComplete(uint32_t)':
unix_steam_networking_manual.cpp:624:5: error: 'TRACE' was not declared in this scope
  624 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamMatchmakingServerListResponse_099u* create_LinuxISteamMatchmakingServerListResponse_099u(void*)':
unix_steam_networking_manual.cpp:637:5: error: 'TRACE' was not declared in this scope
  637 |     TRACE("-> %p.\n", ret);
      |     ^~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingServerListResponse_106::RefreshComplete(void*, uint32_t)':
unix_steam_networking_manual.cpp:662:5: error: 'TRACE' was not declared in this scope
  662 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp: In function 'uint32_t (__attribute__((sysv_abi)) * manual_convert_Set_SteamAPI_CCheckCallbackRegisteredInProcess_func(w_SteamAPI_CheckCallbackRegistered_t))(int32_t)':
unixlib.cpp:195:5: error: 'FIXME' was not declared in this scope
  195 |     FIXME("not implemented!\n");
      |     ^~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamMatchmakingServerListResponse_106* create_LinuxISteamMatchmakingServerListResponse_106(void*)':
unix_steam_networking_manual.cpp:675:5: error: 'TRACE' was not declared in this scope
  675 |     TRACE("-> %p.\n", ret);
      |     ^~~~~
unixlib.cpp: In function 'uint32_t (__attribute__((sysv_abi)) * manual_convert_Set_SteamAPI_CCheckCallbackRegisteredInProcess_func_156(w_SteamAPI_CheckCallbackRegistered_t_156))(int32_t)':
unixlib.cpp:206:5: error: 'FIXME' was not declared in this scope
  206 |     FIXME("not implemented!\n");
      |     ^~~~~
unixlib_generated.cpp:9:18: error: 'unixlib_entry_t' does not name a type; did you mean 'unixlib_handle_t'?
    9 | extern "C" const unixlib_entry_t __wine_unix_call_funcs[] =
      |                  ^~~~~~~~~~~~~~~
      |                  unixlib_handle_t
unixlib.cpp: In function 'void (__attribute__((sysv_abi)) * manual_convert_Set_SteamAPI_CPostAPIResultInProcess_func(w_SteamAPI_PostAPIResultInProcess_t))(uint64_t, void*, uint32_t, int)':
unixlib.cpp:216:5: error: 'FIXME' was not declared in this scope
  216 |     FIXME("not implemented!\n");
      |     ^~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingPingResponse::ServerResponded(gameserveritem_t_105*)':
unix_steam_networking_manual.cpp:689:5: error: 'TRACE' was not declared in this scope
  689 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp: In function 'void (__attribute__((sysv_abi)) * manual_convert_Remove_SteamAPI_CPostAPIResultInProcess_func(w_SteamAPI_PostAPIResultInProcess_t))(uint64_t, void*, uint32_t, int)':
unixlib.cpp:222:5: error: 'FIXME' was not declared in this scope
  222 |     FIXME("not implemented!\n");
      |     ^~~~~
unixlib.cpp: In function 'void (__attribute__((sysv_abi)) * manual_convert_DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess__a(w_void_SteamAPI_PostAPIResultInProcess_t))()':
unixlib.cpp:232:5: error: 'FIXME' was not declared in this scope
  232 |     FIXME("not implemented!\n");
      |     ^~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingPingResponse::ServerFailedToRespond()':
unix_steam_networking_manual.cpp:696:5: error: 'TRACE' was not declared in this scope
  696 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp: In function 'void (__attribute__((sysv_abi)) * manual_convert_DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess__a(w_void_SteamAPI_PostAPIResultInProcess_t))()':
unixlib.cpp:238:5: error: 'FIXME' was not declared in this scope
  238 |     FIXME("not implemented!\n");
      |     ^~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamMatchmakingPingResponse* create_LinuxISteamMatchmakingPingResponse(void*)':
unix_steam_networking_manual.cpp:708:5: error: 'TRACE' was not declared in this scope
  708 |     TRACE("-> %p.\n", ret);
      |     ^~~~~
unixlib.cpp: In function 'NTSTATUS steamclient_init(void*)':
unixlib.cpp:383:9: error: 'ERR' was not declared in this scope
  383 |         ERR( "unable to load native steamclient library\n" );
      |         ^~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:394:5: note: in expansion of macro 'LOAD_FUNC'
  394 |     LOAD_FUNC( CreateInterface );
      |     ^~~~~~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingPlayersResponse::PlayersFailedToRespond()':
unix_steam_networking_manual.cpp:728:5: error: 'TRACE' was not declared in this scope
  728 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:395:5: note: in expansion of macro 'LOAD_FUNC'
  395 |     LOAD_FUNC( Steam_BGetCallback );
      |     ^~~~~~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:396:5: note: in expansion of macro 'LOAD_FUNC'
  396 |     LOAD_FUNC( Steam_GetAPICallResult );
      |     ^~~~~~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingPlayersResponse::PlayersRefreshComplete()':
unix_steam_networking_manual.cpp:735:5: error: 'TRACE' was not declared in this scope
  735 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:397:5: note: in expansion of macro 'LOAD_FUNC'
  397 |     LOAD_FUNC( Steam_FreeLastCallback );
      |     ^~~~~~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamMatchmakingPlayersResponse* create_LinuxISteamMatchmakingPlayersResponse(void*)':
unix_steam_networking_manual.cpp:747:5: error: 'TRACE' was not declared in this scope
  747 |     TRACE("-> %p.\n", ret);
      |     ^~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:398:5: note: in expansion of macro 'LOAD_FUNC'
  398 |     LOAD_FUNC( Steam_ReleaseThreadLocalMemory );
      |     ^~~~~~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:399:5: note: in expansion of macro 'LOAD_FUNC'
  399 |     LOAD_FUNC( Steam_IsKnownInterface );
      |     ^~~~~~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingRulesResponse::RulesFailedToRespond()':
unix_steam_networking_manual.cpp:767:5: error: 'TRACE' was not declared in this scope
  767 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp:390:9: error: 'ERR' was not declared in this scope
  390 |         ERR( "unable to load " #x "\n" );                      \
      |         ^~~
unixlib.cpp:400:5: note: in expansion of macro 'LOAD_FUNC'
  400 |     LOAD_FUNC( Steam_NotifyMissingInterface );
      |     ^~~~~~~~~
unix_steam_networking_manual.cpp: In member function 'virtual void SteamMatchmakingRulesResponse::RulesRefreshComplete()':
unix_steam_networking_manual.cpp:774:5: error: 'TRACE' was not declared in this scope
  774 |     TRACE("Deleting this %p, w_iface %p.\n", this, this->w_iface);
      |     ^~~~~
unixlib.cpp:402:49: error: 'debugstr_a' was not declared in this scope
  402 |     TRACE( "Loaded host steamclient from %s\n", debugstr_a(path) );
      |                                                 ^~~~~~~~~~
unixlib.cpp:402:5: error: 'TRACE' was not declared in this scope
  402 |     TRACE( "Loaded host steamclient from %s\n", debugstr_a(path) );
      |     ^~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamMatchmakingRulesResponse* create_LinuxISteamMatchmakingRulesResponse(void*)':
unix_steam_networking_manual.cpp:786:5: error: 'TRACE' was not declared in this scope
  786 |     TRACE("-> %p.\n", ret);
      |     ^~~~~
unixlib.cpp: In function 'void collapse_path(WCHAR*, UINT)':
unixlib.cpp:457:36: error: 'wcslen' was not declared in this scope
  457 |                 memmove( p, next, (wcslen(next) + 1) * sizeof(WCHAR) );
      |                                    ^~~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamNetworkingConnectionCustomSignaling* create_LinuxISteamNetworkingConnectionCustomSignaling(void*)':
unix_steam_networking_manual.cpp:792:5: error: 'FIXME' was not declared in this scope
  792 |     FIXME( "not implemented!\n" );
      |     ^~~~~
unixlib_generated.cpp:20949:41: error: 'ARRAY_SIZE' was not declared in this scope; did you mean 'ARRAYSIZE'?
20949 | const unsigned int callback_data_size = ARRAY_SIZE(callback_data);
      |                                         ^~~~~~~~~~
      |                                         ARRAYSIZE
unixlib.cpp:494:68: error: 'wcslen' was not declared in this scope
  494 |             if (p > path + mark && p[-1] == '.') memmove( p-1, p, (wcslen(p) + 1) * sizeof(WCHAR) );
      |                                                                    ^~~~~~
unix_steam_networking_manual.cpp: In function 'u_ISteamNetworkingCustomSignalingRecvContext* create_LinuxISteamNetworkingCustomSignalingRecvContext(void*)':
unix_steam_networking_manual.cpp:798:5: error: 'FIXME' was not declared in this scope
  798 |     FIXME( "not implemented!\n" );
      |     ^~~~~
Hh0tc0d3 2024-07-02 github

There is also probably an error in this commit:
https://github.com/ValveSoftware/Proton/commit/5d374bdc2cf3b38f9be60b30ee8fc98ea4c4e381
The compiler throws an error because u""

steamclient_main.c: In function 'load_steamclient':
steamclient_main.c:347:22: error: 'u' undeclared (first use in this function)
  347 |     if (!get_env_win(u"SteamAppId", steam_app_id, sizeof(steam_app_id)))
      |                      ^
steamclient_main.c:347:22: note: each undeclared identifier is reported only once for each function it appears in
steamclient_main.c:347:23: error: expected ')' before string constant
  347 |     if (!get_env_win(u"SteamAppId", steam_app_id, sizeof(steam_app_id)))
      |                     ~ ^~~~~~~~~~~~
      |                       )
steamclient_main.c:347:10: error: too few arguments to function 'get_env_win'
  347 |     if (!get_env_win(u"SteamAppId", steam_app_id, sizeof(steam_app_id)))
      |          ^~~~~~~~~~~
steamclient_main.c:329:13: note: declared here
  329 | static BOOL get_env_win(const WCHAR *name, char *value, unsigned int size)
      |             ^~~~~~~~~~~
steamclient_main.c:352:23: error: expected ')' before string constant
  352 |     if (!get_env_win(u"IgnoreChildProcesses", ignore_child_processes, sizeof(ignore_child_processes)))
      |                     ~ ^~~~~~~~~~~~~~~~~~~~~~
      |                       )
steamclient_main.c:352:10: error: too few arguments to function 'get_env_win'
  352 |     if (!get_env_win(u"IgnoreChildProcesses", ignore_child_processes, sizeof(ignore_child_processes)))
      |          ^~~~~~~~~~~
steamclient_main.c:329:13: note: declared here
  329 | static BOOL get_env_win(const WCHAR *name, char *value, unsigned int size)
u"SteamAppId"
u"IgnoreChildProcesses"

There probably should be:

L"SteamAppId"
L"IgnoreChildProcesses"

The L symbol in front of a string literal simply means that each character in the string will be stored as a wchar_t.

https://stackoverflow.com/questions/1810343/is-a-wide-character-string-literal-starting-with-l-like-lhello-world-guarantee

Hh0tc0d3 2024-07-02 github

Compilation error: Include_winsock_h_before_stdlib_h_or_use_the_MSVCRT_library

In file included from wine/include/winsock2.h:160,
                 from steamclient_main.c:13:
wine/include/winsock2.h:561:19: error: redefinition of 'struct timeval'
  561 | typedef struct WS(timeval)
      |                   ^~~~~~~
wine/include/ws2def.h:27:18: note: in definition of macro 'WS'
   27 | #define WS(x)    x
      |                  ^
In file included from /usr/include/sys/select.h:37,
                 from /usr/include/sys/types.h:179,
                 from /usr/include/stdlib.h:514,
                 from steamclient_main.c:2:
/usr/include/bits/types/struct_timeval.h:8:8: note: originally defined here
    8 | struct timeval
      |        ^~~~~~~
winegcc -c -O2 -std=gnu89  -Iwine/include -Iwine/include/wine -I/usr/include -I. -DWINE_NO_LONG_TYPES -DSTEAM_API_EXPORTS -Dprivate=public -Dprotected=public  -o winISteamScreenshots.o winISteamScreenshots.c
winegcc -c -O2 -std=gnu89  -Iwine/include -Iwine/include/wine -I/usr/include -I. -DWINE_NO_LONG_TYPES -DSTEAM_API_EXPORTS -Dprivate=public -Dprotected=public  -o winISteamUGC.o winISteamUGC.c
wine/include/winsock2.h:51:22: error: unknown type name 'Include_winsock_h_before_stdlib_h_or_use_the_MSVCRT_library'
   51 | #  define fd_set     Include_winsock_h_before_stdlib_h_or_use_the_MSVCRT_library
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wine/include/ws2def.h:27:18: note: in definition of macro 'WS'
   27 | #define WS(x)    x
      |                  ^
wine/include/winsock2.h:1078:56: note: in expansion of macro 'fd_set'
 1078 | WINSOCK_API_LINKAGE int WINAPI __WSAFDIsSet(SOCKET, WS(fd_set) *);
SSaancreed 2024-07-02 github
error: 'TRACE' was not declared in this scope
error: 'FIXME' was not declared in this scope
error: 'ERR' was not declared in this scope

As expected, you are building a Wine (side-)module so __WINESRC__ is required to be defined and this is how the lack of it usually manifests. You probably forgot to add -D__WINESRC__ somewhere.

error: 'u' undeclared (first use in this function)

That's just a UTF-16 string literal. Don't cripple your compiler with custom/old -std=… and it should work as long as it knows what C11 is.

error: redefinition of 'struct timeval'
…
In file included from /usr/include/sys/select.h:37,
                 from /usr/include/sys/types.h:179,
                 from /usr/include/stdlib.h:514,
                 from steamclient_main.c:2:

Hmm, looks like steamclient_main.c is not a part of the unixlib and therefore it should probably be compiled with winegcc -b x86_64-w64-mingw32 (or winegcc -b i686-w64-mingw32 for 32-bit). I think this means that either your Makefile (generator?) is broken because it isn't using the correct cross-compiler or your Mingw is broken because it's including system/unixside headers from /usr/include while it should be looking at something closer to /usr/{x86_64,i686}-w64-mingw32/include (like it does on Arch).

…_or_use_the_MSVCRT_library

This is probably the way to go if commit message from https://github.com/ValveSoftware/Proton/commit/838d14d66ee1e5ae535f49b7634f2ea937e77938 is to be trusted :sweat_smile:

But why is MSVCRT not the default I have no idea, even though it should for PE builds since 2022. Try explicit -mno-cygwin?

Hh0tc0d3 2024-07-02 github

@Saancreed Thx. Yes you are right, I looked at the header files and they require __WINESRC__ to be set. Also need to remove --nomsvcrt.

winemaker --wine32 --dll \
    --nosource-fix \
    --nolower-include \
    --nodlls \
    --nobackup \
    -D__WINESRC__ \
    -I${SOURCE_DIR:?}/wine/include \
    -I${SOURCE_DIR:?}/wine/include/wine \
    -I/usr/include \
    -DWINE_NO_LONG_TYPES \
    -DSTEAM_API_EXPORTS \
    -Dprivate=public \
    -Dprotected=public \
    -lws2_32 \
    .

sed -re 's@_LDFLAGS=@_LDFLAGS= -static-libgcc -static-libstdc++@' -i Makefile
make -s -e CC="winegcc -m32" CXX="wineg++ -m32" -j$(nproc)

Now I'm facing another problem:

/usr/bin/ld: /home/user/wine/bin/../lib/wine/i386-unix/libwinecrt0.a(unix_lib.o): warning: relocation in read-only section `.text'
/usr/bin/ld: unixlib.o: in function `steamclient_dos_to_unix_path':
unixlib.cpp:(.text+0x1827): undefined reference to `ntdll_umbstowcs'
/usr/bin/ld: unixlib.o: in function `steamclient_dos_to_unix_path_array':
unixlib.cpp:(.text+0x1afd): undefined reference to `ntdll_umbstowcs'
/usr/bin/ld: unixlib.o: in function `steamclient_unix_path_to_dos_path':
unixlib.cpp:(.text+0x1fb4): undefined reference to `ntdll_wcstoumbs'
/usr/bin/ld: warning: creating DT_TEXTREL in a shared object
collect2: error: ld returned 1 exit status
winegcc: /usr/bin/g++ failed
make: *** [Makefile:363: lsteamclient.dll.so] Error 2

I also tried to compile the dll inside wine and registered the module in configure.ac, the module compiles successfully, but after start game raise exception Access violation in
https://github.com/ValveSoftware/Proton/commit/a287ebaaf970c5ca34639264d1dbc5156fbb2f5f

SSaancreed 2024-07-02 github

ntdll_umbstowcs
ntdll_wcstoumbs

They are implemented in Unix-side ntdll.so, try -l:ntdll.so. It's a bit hack-ish, yeah, but I'm not sure how to convince winegcc to link to ntdll.so otherwise.

warning: relocation in read-only section '.text'

Curious, maybe due to lack of -fPIC?

Access violation in

Unfortunately that's not very helpful. Either it's caused by some other build issue or it's gdb time.

Hh0tc0d3 2024-07-03 github

They are implemented in Unix-side ntdll.so, try -l:ntdll.so. It's a bit hack-ish, yeah, but I'm not sure how to convince winegcc to link to ntdll.so otherwise.

Did not help. I also tried -lntdll and -intdll.

SSaancreed 2024-07-03 github

Welp, my sample works for me when I do that. Check if it's searching correct directories for that library, e.g. when I compile with -Wl,--verbose -Wl,-l:ntdll.so the linker prints something like

…
/usr/bin/ld: mode elf_x86_64
attempt to open /usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/../../../../lib/crti.o
attempt to open /usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/crtbeginS.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/crtbeginS.o
attempt to open /usr/bin/../lib/wine/x86_64-unix/ntdll.so succeeded
/usr/bin/../lib/wine/x86_64-unix/ntdll.so
…

Which exports wanted symbols:

$ nm -D /usr/lib/wine/x86_64-unix/ntdll.so | grep ntdll_
0000000000013430 T ntdll_get_build_dir
0000000000013440 T ntdll_get_data_dir
000000000005e600 T ntdll_set_exception_jmp_buf
00000000000118e0 T ntdll_umbstowcs
0000000000011d90 T ntdll_wcsicmp
0000000000011e20 T ntdll_wcsnicmp
0000000000011b80 T ntdll_wcstoumbs

But if -Wl,--verbose doesn't help you to find the cause then I have no idea how else you could debug this, sorry. You'd probably have to check exactly how the full Proton build handles lsteamclient and capture relevant arguments from there.

Hh0tc0d3 2024-07-08 github

The old compilation method does not work, so I had to patch wine's makedep.
https://github.com/ValveSoftware/wine/commits/f80ddae9e217f2bad68455891371fa0f524451e7/tools/makedep.c

Proton versions

DLLs