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

uuid is missing uuid_clear when building with meson #2895

Open
TimB87 opened this issue Mar 31, 2024 · 18 comments
Open

uuid is missing uuid_clear when building with meson #2895

TimB87 opened this issue Mar 31, 2024 · 18 comments

Comments

@TimB87
Copy link

TimB87 commented Mar 31, 2024

Hi again,

last roadblocker for CRUX seems to be that the static libuuid is not built with uuid_clear(?).

From cryptsetups meson configure statge:

Run-time dependency uuid found: YES 2.40.0
Checking for function "uuid_clear" with dependency uuid: NO

cryptsetup-2.7.1/meson.build:155:0: ERROR: Assert failed: You need the uuid library.

A full log can be found at /home/pkgmk/work/cryptsetup/src/build/meson-logs/meson-log.txt

meson-log.txt contains these informations:

-----------
Run-time dependency uuid found: YES 2.40.0
Running compile:
Working directory:  /home/pkgmk/work/cryptsetup/src/build/meson-private/tmptbm1y51o
Code:
 #include <uuid.h>
#include <limits.h>

        #if defined __stub_uuid_clear || defined __stub___uuid_clear
        fail fail fail this function is not going to work
        #endif

int main(void) {
            void *a = (void*) &uuid_clear;
            long long b = (long long) a;
            return (int) b;
        }
-----------
Command line: `cc -I/usr/include/uuid /home/pkgmk/work/cryptsetup/src/build/meson-private/tmptbm1y51o/testfile.c -o /home/pkgmk/work/cryptsetup/src/build/meson-private/tmptbm1y51o/output.exe -O2 -march=x86-64 -D_FILE_OFFSET_BITS=64 -O0 /usr/lib/libuuid.a` -> 1
stderr:
/usr/bin/ld: /tmp/cc8P86Cp.o: in function `main':
testfile.c:(.text+0x7): undefined reference to `uuid_clear'
collect2: error: ld returned 1 exit status
-----------
Running compile:
Working directory:  /home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu
Code:
 #include <uuid.h>
        int main(void) {

        /* With some toolchains (MSYS2/mingw for example) the compiler
         * provides various builtins which are not really implemented and
         * fall back to the stdlib where they aren't provided and fail at
         * build/link time. In case the user provides a header, including
         * the header didn't lead to the function being defined, and the
         * function we are checking isn't a builtin itself we assume the
         * builtin is not functional and we just error out. */
        #if !0 && !defined(uuid_clear) && !0
            #error "No definition for __builtin_uuid_clear found in the prefix"
        #endif

        #ifdef __has_builtin
            #if !__has_builtin(__builtin_uuid_clear)
                #error "__builtin_uuid_clear not found"
            #endif
        #elif ! defined(uuid_clear)
            __builtin_uuid_clear;
        #endif
        return 0;
        }
-----------
Command line: `cc -I/usr/include/uuid /home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu/testfile.c -o /home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu/output.exe -O2 -march=x86-64 -D_FILE_OFFSET_BITS=64 -O0 /usr/lib/libuuid.a` -> 1
stderr:
/home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu/testfile.c: In function 'main':
/home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu/testfile.c:12:14: error: #error "No definition for __builtin_uuid_clear found in the prefix"
   12 |             #error "No definition for __builtin_uuid_clear found in the prefix"
      |              ^~~~~
/home/pkgmk/work/cryptsetup/src/build/meson-private/tmpi7aubepu/testfile.c:17:18: error: #error "__builtin_uuid_clear not found"
   17 |                 #error "__builtin_uuid_clear not found"
      |                  ^~~~~
-----------
Checking for function "uuid_clear" with dependency uuid: NO

cryptsetup-2.7.1/meson.build:155:0: ERROR: Assert failed: You need the uuid library.

Edit:

Further information: we use -D static-cryptsetup=true with cryptsetup, it builds fine if we set that to false.

Edit 2:

It seems like a similar problem (?) exists with blkid (needed by static udev.a) and building a static lvm binary:

/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/../../../../lib/libudev.a(util.o): in function `get_group_creds':
(.text+0x1eec): warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: (.text+0x1f62): warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/../../../../lib/libudev.a(util.o): in function `get_user_creds':
(.text+0x1e0a): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: (.text+0x1d35): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ../lib/liblvm-internal.a(dev-type.o): in function `fs_block_size_and_type':
dev-type.c:(.text+0x21e6): undefined reference to `blkid_new_probe_from_filename'
/usr/bin/ld: dev-type.c:(.text+0x21ff): undefined reference to `blkid_probe_enable_superblocks'
/usr/bin/ld: dev-type.c:(.text+0x220c): undefined reference to `blkid_probe_set_superblocks_flags'
/usr/bin/ld: dev-type.c:(.text+0x2214): undefined reference to `blkid_do_safeprobe'
/usr/bin/ld: dev-type.c:(.text+0x2241): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x229d): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x231a): undefined reference to `blkid_free_probe'
/usr/bin/ld: ../lib/liblvm-internal.a(dev-type.o): in function `fs_get_blkid':
dev-type.c:(.text+0x24b6): undefined reference to `blkid_new_probe_from_filename'
/usr/bin/ld: dev-type.c:(.text+0x24cf): undefined reference to `blkid_probe_enable_superblocks'
/usr/bin/ld: dev-type.c:(.text+0x24dc): undefined reference to `blkid_probe_set_superblocks_flags'
/usr/bin/ld: dev-type.c:(.text+0x24e4): undefined reference to `blkid_do_safeprobe'
/usr/bin/ld: dev-type.c:(.text+0x2514): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x254f): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2574): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x259e): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x25b1): undefined reference to `blkid_free_probe'
/usr/bin/ld: dev-type.c:(.text+0x2632): undefined reference to `blkid_free_probe'
/usr/bin/ld: dev-type.c:(.text+0x2687): undefined reference to `blkid_free_probe'
/usr/bin/ld: dev-type.c:(.text+0x273b): undefined reference to `blkid_free_probe'
/usr/bin/ld: ../lib/liblvm-internal.a(dev-type.o): in function `wipe_known_signatures':
dev-type.c:(.text+0x2925): undefined reference to `blkid_new_probe_from_filename'
/usr/bin/ld: dev-type.c:(.text+0x293e): undefined reference to `blkid_probe_enable_partitions'
/usr/bin/ld: dev-type.c:(.text+0x294b): undefined reference to `blkid_probe_set_partitions_flags'
/usr/bin/ld: dev-type.c:(.text+0x2958): undefined reference to `blkid_probe_enable_superblocks'
/usr/bin/ld: dev-type.c:(.text+0x2965): undefined reference to `blkid_probe_set_superblocks_flags'
/usr/bin/ld: dev-type.c:(.text+0x2974): undefined reference to `blkid_do_probe'
/usr/bin/ld: dev-type.c:(.text+0x29d7): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2a51): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2aa6): undefined reference to `blkid_do_probe'
/usr/bin/ld: dev-type.c:(.text+0x2b13): undefined reference to `blkid_free_probe'
/usr/bin/ld: dev-type.c:(.text+0x2b30): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2b4e): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2ba5): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2c50): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2c66): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2d22): undefined reference to `blkid_probe_step_back'
/usr/bin/ld: dev-type.c:(.text+0x2e55): undefined reference to `blkid_probe_lookup_value'
/usr/bin/ld: dev-type.c:(.text+0x2f8a): undefined reference to `blkid_probe_lookup_value'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:142: lvm.static] Error 1
@jwillikers
Copy link
Contributor

Can you see if the symbol actually exists in libuuid.a? You should see uuid_clear in src_clear.c.o in the output from the following command.

nm --print-armap build/libuuid/libuuid.a

It looks like that error message in the Meson build is looking for a builtin. It might be a problem with the check in cryptsetup.

@TimB87
Copy link
Author

TimB87 commented Apr 2, 2024

Interesting!

Your comment made me compare the output of different builds:

And then tried cryptsetup with meson w/o lto, and it starts missing a static popt library :)

cryptsetup-2.7.1/meson.build:228:10: ERROR: C static library 'popt' not found

edit: actually, strike the thing with static popt. Both lvm2 and cryptsetup will build successfully if we omit LTO for util-linux.

@jwillikers
Copy link
Contributor

Oh yeah, that's LTO.

@t-8ch
Copy link
Member

t-8ch commented Apr 2, 2024

different builds

Autotools and meson w/ lto are the same link

@TimB87
Copy link
Author

TimB87 commented Apr 2, 2024

Autotools and meson w/ lto are the same link

This had to happen 😀 Sorry! Let me try again:

@t-8ch
Copy link
Member

t-8ch commented Apr 2, 2024

Can you provide a full reproducer?

@TimB87
Copy link
Author

TimB87 commented Apr 2, 2024

Sure! :)

	meson setup $name-$version build \
		--prefix=/usr \
		--bindir=/usr/bin \
		--sbindir=/sbin \
		--libdir=/lib \
		--buildtype=plain \
		--wrap-mode=nodownload \
		-D b_lto=true \
		-D b_pie=true \
		-D nls=disabled \
		-D pamlibdir=/lib/security \
		-D cryptsetup=disabled \
		-D build-chfn-chsh=disabled \
		-D build-login=disabled \
		-D build-su=disabled \
		-D build-sulogin=disabled \
		-D build-nologin=disabled \
		-D build-runuser=disabled \
		-D build-vipw=disabled \
		-D build-raw=disabled \
		-D build-newgrp=disabled \
		-D build-bfs=disabled \
		-D build-minix=disabled

	meson compile -C build

This triggers the problem for us.

@t-8ch
Copy link
Member

t-8ch commented Apr 2, 2024

This works correctly for me with gcc 13.2.1 and ld 2.42.0

@jwillikers
Copy link
Contributor

Is lld in use perhaps?

@t-8ch
Copy link
Member

t-8ch commented Apr 2, 2024

I'm struggling to see how LTO can legally optimize something out of a static library.

@TimB87
Copy link
Author

TimB87 commented Apr 2, 2024

lld is unavailable to the container building the package so I can safely say no to that.

We are currently still on gcc 12.3.0 with ld 2.39. I can test it with the current versions, I am sure none of us tried that yet :-)

@jwillikers
Copy link
Contributor

jwillikers commented Apr 2, 2024

I don't think that LTO is optimizing out the symbol, rather, maybe it's doing things that might break Meson's detection of the symbol? For those libraries built with the LTO option, can you try passing the LTO plugin to nm? There's one on my Fedora system at /usr/libexec/gcc/x86_64-redhat-linux/13/liblto_plugin.so.

nm --plugin /usr/libexec/gcc/x86_64-redhat-linux/13/liblto_plugin.so  --print-armap build/libuuid/libuuid.a

@TimB87
Copy link
Author

TimB87 commented Apr 2, 2024

Tried a newer toolchain (gcc 13.2.0, ld 2.42) and still encounter the same problem with cryptsetup. Again, disabling lto fixes building cryptsetup and lvm2.

nm indeed seems to just have missed the plugin: https://sprunge.us/HErcei

@karelzak
Copy link
Collaborator

karelzak commented Apr 3, 2024

I'm able to reproduce it:

meson build:

$ readelf -a build/libuuid/libuuid.a | grep clear
File: build/libuuid/libuuid.a(src_clear.c.o)
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS clear.c
     8: 0000000000000000    37 FUNC    GLOBAL DEFAULT    1 uuid_clear

meson build -D b_lto=true:

$ readelf -a build/libuuid/libuuid.a | grep clear
File: build/libuuid/libuuid.a(src_clear.c.o)
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS clear.c
     6: 0000000000000000     0 NOTYPE  WEAK   HIDDEN     4 clear.c.ed831df9

versions:

  • meson 1.3.2
  • gcc (GCC) 13.2.1 20240316 (Red Hat 13.2.1-7)
  • GNU ld version 2.40-14.fc39

@karelzak
Copy link
Collaborator

karelzak commented Apr 3, 2024

Upgrade to gcc (GCC) 14.0.1 and ld version 2.42.50.20240318 does not change anything.

@jwillikers
Copy link
Contributor

jwillikers commented Apr 3, 2024

What happens if you add -ffat-lto-objects? I think this is likely a limitation of using LTO with static libraries, as described in mesonbuild/meson#10300.

@jwillikers
Copy link
Contributor

jwillikers commented Apr 3, 2024

I'm not sure why, but I can't seem to reproduce this on Fedora 39, with Meson 1.3.2, although my readelf output for LTO indicates the same result.

$ readelf -a build/libuuid/libuuid.a | grep clear
File: build/libuuid/libuuid.a(src_clear.c.o)
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS clear.c
     6: 0000000000000000     0 NOTYPE  WEAK   HIDDEN     4 clear.c.8238b85b

Here's the steps to reproduce, assuming dependencies are already installed:

git clone https://github.com/util-linux/util-linux.git
cd util-linux
git checkout v2.40
meson setup -D b_lto=true -D pamlibdir=/lib/security build
meson compile -C build
sudo meson install -C build

cd ..
git clone https://gitlab.com/cryptsetup/cryptsetup.git
cd cryptsetup
git checkout v2.7.1
meson setup -D static-cryptsetup=true build

The check for uuid_clear in cryptsetup passes for me:

Run-time dependency uuid found: YES 2.40.0
Checking for function "uuid_clear" with dependency uuid: YES 

@TimB87
Copy link
Author

TimB87 commented Apr 3, 2024

@jwillikers it seems like defining fat-lto is the missing bit here! Can confirm util-linux builds fine with -ffat-lto-objects defined and cryptsetup (and lvm2) will build as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants