Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: lib order fixes for picky linkers (e.g. binutils ld) #16182

Closed
wants to merge 15 commits into from

Conversation

vszakats
Copy link
Member

@vszakats vszakats commented Feb 5, 2025

This issue was not addressed with CMake builds so far. curl-for-win
worked thanks to its -Wl,--start-group workaround. It affects
binutils ld linking statically. Shared linking and llvm's lld
doesn't need strict lib order, and are not affected.

The solution is to pass libs in dependency order, with least dependent
(e.g. system) libs last. In case of cyclic dependency, may pass libs
twice.

Fix most issues by moving Windows system libs ws2_32 and bcrypt
last, and move SSH libs first due to their dependence on crypto
backends and zlib compression.

Also:

  • modify an existing Linux curl-for-win job to use gcc.
  • add a specific Windows gcc job to test this. Make it use different
    options than the default to extend build coverage too: libssh,
    zlib-ng, 32-bit.
  • prefer CMake imported targets for OpenSSL and ZLIB.

Examples of issues fixed:

Windows LibreSSL, libpsl vs. ws2_32:

x86_64-w64-mingw32-ld: curl/libressl/lib/libcrypto.a(bss_sock.c.obj):bss_sock.c:(.text$sock_ctrl[sock_ctrl]+0x59): undefined reference to `__imp_shutdown'
x86_64-w64-mingw32-ld: curl/libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_init[CRYPTO_gcm128_init]+0x65): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: curl/libpsl/_x64-win-ucrt/usr/lib/libpsl.a(psl.o):(.text$psl_is_cookie_domain_acceptable+0xef): undefined reference to `__imp_WSAStringToAddressW'

Ref: https://github.com/curl/curl/actions/runs/13157579253/job/36718144881?pr=16182#step:3:5354

Linux libssh2 vs. zlib:

/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_dtor':
(.text.comp_method_zlib_dtor+0x8c): undefined reference to `deflateEnd'
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_comp':
(.text.comp_method_zlib_comp+0x50): undefined reference to `deflate'
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_init':
(.text.comp_method_zlib_init+0x8c): undefined reference to `deflateInit_'

Ref: https://github.com/curl/curl/actions/runs/13157270420/job/36717189086?pr=16182#step:3:5285

Windows libssh vs. ws2_32 and LibreSSL:

/usr/bin/i686-w64-mingw32-ld: curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x92): undefined reference to `WspiapiGetAddrInfo@16'
/usr/bin/i686-w64-mingw32-ld: curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x3d9): undefined reference to `gai_strerrorA'
/usr/bin/i686-w64-mingw32-ld: curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_client_select_hostkeys+0xd2): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_set+0x942): undefined reference to `FIPS_mode'

Ref: https://github.com/curl/curl/actions/runs/13163986294/job/36739557888?pr=16182#step:3:5127
Ref: https://github.com/curl/curl/actions/runs/13163986294/job/36739557888?pr=16182#step:3:5121


  • split-off unrelated OpenSSL/ZLIB target to separate PR.

Another, related, goal is to sync lib order with autotools.

A notable difference is that autotools prepends detected libs, while cmake this was so far done for a couple of libs only.
Order of dependency detection is also not synced between autotools and cmake.

This PR doesn't want to address these, but may be a step towards.

@vszakats vszakats marked this pull request as draft February 5, 2025 12:23
@github-actions github-actions bot added the CI Continuous Integration label Feb 5, 2025
@vszakats vszakats added build cmake and removed CI Continuous Integration labels Feb 5, 2025
@vszakats vszakats changed the title cmake: try to fix lib order for picky linker binutils ld. cmake: try to fix lib order for picky linkers, like binutils ld Feb 5, 2025
@github-actions github-actions bot added the CI Continuous Integration label Feb 5, 2025
@vszakats

This comment was marked as resolved.

@vszakats vszakats changed the title cmake: try to fix lib order for picky linkers, like binutils ld cmake: try to fix lib order for picky linkers, like binutils ld Feb 5, 2025
@vszakats vszakats changed the title cmake: try to fix lib order for picky linkers, like binutils ld cmake: lib order fixes for picky linkers (e.g. binutils ld) Feb 5, 2025
@vszakats vszakats force-pushed the cm-lib-order branch 6 times, most recently from ae8ce20 to 25ebdb3 Compare February 6, 2025 01:53
@vszakats vszakats marked this pull request as ready for review February 6, 2025 02:21
This issue was never addressed in cmake so far. curl-for-win worked
thanks to the `--start-group` workaround used there.

The accurate solution is to either pass what's necessary multiple times,
or arrange the libs in an order that make it work by default, without
duplications.

Only binutils ld is affected. llvm's lld and other linkers are not known
to be so picky.

```
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(bss_sock.c.obj):bss_sock.c:(.text$sock_ctrl[sock_ctrl]+0x59): undefined reference to `__imp_shutdown'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(bss_sock.c.obj):bss_sock.c:(.text$sock_free[sock_free]+0x30): undefined reference to `__imp_shutdown'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_init[CRYPTO_gcm128_init]+0x65): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_init[CRYPTO_gcm128_init]+0x98): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_setiv[CRYPTO_gcm128_setiv]+0x1f1): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_setiv[CRYPTO_gcm128_setiv]+0x228): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_setiv[CRYPTO_gcm128_setiv]+0x24f): undefined reference to `__imp_ntohl'
x86_64-w64-mingw32-ld: libressl/lib/libcrypto.a(gcm128.c.obj):gcm128.c:(.text$CRYPTO_gcm128_encrypt[CRYPTO_gcm128_encrypt]+0x98): more undefined references to `__imp_ntohl' follow
```
```
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: /home/runner/work/curl/curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_dtor':
(.text.comp_method_zlib_dtor+0x8c): undefined reference to `deflateEnd'
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: /home/runner/work/curl/curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_comp':
(.text.comp_method_zlib_comp+0x50): undefined reference to `deflate'
/usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld: /home/runner/work/curl/curl/libssh2/_a64-linux-gnu-libressl/usr/lib/libssh2.a(unity_0_c.c.o): in function `comp_method_zlib_init':
(.text.comp_method_zlib_init+0x8c): undefined reference to `deflateInit_'
```
https://github.com/curl/curl/actions/runs/13157270420/job/36717189086?pr=16182#step:3:5285
```
/usr/bin/x86_64-w64-mingw32-ld: /home/runner/work/curl/curl/libpsl/_x64-win-ucrt/usr/lib/libpsl.a(psl.o):(.text$psl_is_cookie_domain_acceptable+0xef): undefined reference to `__imp_WSAStringToAddressW'
```
https://github.com/curl/curl/actions/runs/13157579253/job/36718144881?pr=16182#step:3:5354
```
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x92): undefined reference to `WspiapiGetAddrInfo@16'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x18a): undefined reference to `WspiapiFreeAddrInfo@4'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x23e): undefined reference to `WspiapiGetAddrInfo@16'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x29d): undefined reference to `WspiapiFreeAddrInfo@4'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x388): undefined reference to `WspiapiFreeAddrInfo@4'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x3d9): undefined reference to `gai_strerrorA'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x4a8): undefined reference to `WspiapiFreeAddrInfo@4'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x568): undefined reference to `WspiapiFreeAddrInfo@4'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x57c): undefined reference to `gai_strerrorA'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(connect.c.obj):(.text$ssh_connect_host_nonblocking+0x5c4): undefined reference to `WspiapiFreeAddrInfo@4'
```
https://github.com/curl/curl/actions/runs/13163986294/job/36739557888?pr=16182#step:3:5127

```
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_client_select_hostkeys+0xd2): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_client_select_hostkeys+0x151): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_set_client_kex+0x90): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_add_to_default_algos+0x24): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_remove_from_default_algos+0x22): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(kex.c.obj):(.text$ssh_remove_from_default_algos+0x59): more undefined references to `FIPS_mode' follow
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_set_algo+0x2f): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_set+0x16a): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_set+0x942): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_get+0xab): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_get+0xd3): undefined reference to `FIPS_mode'
/usr/bin/i686-w64-mingw32-ld: /home/runner/work/curl/curl/libssh/_x86-win-ucrt-libressl/usr/lib/libssh.a(options.c.obj):(.text$ssh_options_get+0xff): more undefined references to `FIPS_mode' follow
```
https://github.com/curl/curl/actions/runs/13163986294/job/36739557888?pr=16182#step:3:5121
@vszakats vszakats closed this in e0443a7 Feb 6, 2025
@vszakats vszakats deleted the cm-lib-order branch February 6, 2025 22:35
vszakats added a commit to curl/curl-for-win that referenced this pull request Feb 6, 2025
…[ci skip]

Please report if any untested build combinations fail due to wrong lib
order.

curl/curl@e0443a7
curl/curl#16182
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build CI Continuous Integration cmake
Development

Successfully merging this pull request may close these issues.

1 participant