Opened 12 years ago

Closed 12 years ago

#3271 closed task (fixed)

Udev/Systemd 197

Reported by: Armin Owned by: bdubbs@…
Priority: normal Milestone: 7.3
Component: Book Version: SVN
Severity: normal Keywords:
Cc:

Description

Change History (11)

comment:1 by bdubbs@…, 12 years ago

Owner: changed from lfs-book@… to bdubbs@…
Status: newassigned

I can get a clean build by adding time-util.c to the COMMON_SRCS Makefile variable.

There is an issue when building with glibc older than 2.17. There needs to be a line in cfg.h:

#define secure_getenv secure_getenv

But it's not needed for current lfs-svn which does use 2.17. Do we need to address this? If so, I'm not sure how to best test for it. We could look for /lib/libc-*.so or run '/lib/libc.so.6 | head -n1' and then parse for the version.

Another approach would be to put the define into cfg.h commented out and add a note to the book to uncomment it if using it with a glibc prior to 2.17.

comment:2 by Armin, 12 years ago

How about this?

#ifndef secure_getenv
#define secure_getenv __secure_getenv
#endif

comment:3 by bdubbs@…, 12 years ago

I don't think that will work. We don't know if secure_getenv is defined unless we check the glibc version.

in reply to:  2 comment:4 by Matthew Burgess, 12 years ago

Replying to Krejzi:

How about this?

#ifndef secure_getenv
#define secure_getenv __secure_getenv
#endif

That's kind of handled by systemd's 'src/shared/missing.h':

#ifndef HAVE_SECURE_GETENV
#  ifdef HAVE___SECURE_GETENV
#    define secure_getenv __secure_getenv
#  else
#    error neither secure_getenv nor __secure_getenv are available
#  endif
#endif

So, what we need in our udev-lfs-197/cfg.h is a similar #ifdef selection, I think. Something like:

# ifdef (something particular to glibc-2.17) # define HAVE_SECURE_GETENV # else # define HAVE_SECURE_GETENV # endif

/usr/include/gnu/libc-version.h defines gnu_get_libc_version() but you'd obviously have to compile a C program first to be able to get that info.

The only way I can see getting around this automatically is to start reinventing/reimplementing a portion of Udev's configure machinery, to try compiling a small program that calls secure_getenv() first, and if that fails, calls 'secure_getenv' and sets the relevant preprocessor macro.

I wouldn't want to start putting 'if you're using version x of package y, then do a), otherwise do b)' type instructions in the book. We quite reasonably assume that folks use the same version of the book during their entire build, be that a released or a dated dev version. Similarly, folks reasonably expect us to have tested the versions of the software that appear in a particular release against each other. As such, I can't see a requirement leaping out for being able to mix and match packages from different versions of the book. Maybe that's just me not wanting to see such a requirement though :-)

comment:5 by bdubbs@…, 12 years ago

The only thing needed in udev-lfs-196-4/cfg.h for glibc-2.17 is

#define HAVE_SECURE_GETENV 1

If it's not defined though and glibc is older (in my case 2.16), I get a bunch of warnings:

src/libudev/libudev.c:203:9: warning: implicit declaration of function 'secure_getenv' [-Wimplicit-function-declaration]
src/libudev/libudev.c:203:13: warning: assignment makes pointer from integer without a cast [enabled by default]

...
build/udev-local.a(libudev.o): In function `udev_new':
libudev.c:(.text.udev_new+0x1e3): undefined reference to `secure_getenv'
collect2: error: ld returned 1 exit status
make: *** [build/udevd] Error 1

If I add only

#define secure_getenv secure_getenv

to cfg.h, I get a clean build.

Perhaps a note in the systemd section "systemd-197 is not recommended for systems with glibc older than 2.17" would be appropriate.

comment:6 by Armin, 12 years ago

I've tried building systemd-197 on Glibc 2.17.0 system, but it failed with following:

LINK build/udevd
build/udevd.o: In function `main':
udevd.c:(.text.startup.main+0x9c6): undefined reference to `now'
udevd.c:(.text.startup.main+0xda3): undefined reference to `now'
udevd.c:(.text.startup.main+0x142d): undefined reference to `now'
udevd.c:(.text.startup.main+0x14a8): undefined reference to `now'
udevd.c:(.text.startup.main+0x1b12): undefined reference to `now'
build/udevd.o:udevd.c:(.text.startup.main+0x20e3): more undefined references to `now' follow
build/udev-rules.o: In function `udev_rules_check_timestamp':
udev-rules.c:(.text.udev_rules_check_timestamp+0x44): undefined reference to `timespec_load'
udev-rules.c:(.text.udev_rules_check_timestamp+0x86): undefined reference to `timespec_load'
build/udev-event.o: In function `udev_event_new':
udev-event.c:(.text.udev_event_new+0x5a): undefined reference to `now'
build/udev-event.o: In function `udev_event_spawn':
udev-event.c:(.text.udev_event_spawn+0x425): undefined reference to `now'
udev-event.c:(.text.udev_event_spawn+0x5e9): undefined reference to `now'
build/udev-event.o: In function `udev_event_execute_rules':
udev-event.c:(.text.udev_event_execute_rules+0x516): undefined reference to `now'
build/udev-local.a(log.o): In function `log_dispatch':
log.c:(.text.log_dispatch+0x2e9): undefined reference to `now'
build/udev-local.a(libudev-hwdb.o): In function `udev_hwdb_validate':
libudev-hwdb.c:(.text.udev_hwdb_validate+0x3d): undefined reference to `timespec_load'
libudev-hwdb.c:(.text.udev_hwdb_validate+0x4a): undefined reference to `timespec_load'
collect2: error: ld returned 1 exit status
make: *** [build/udevd] Error 1

I was using 196-4 tarball. However, I added time-util.c to COMMON_SRCS or whatever and build was fixed.

As for secure_getenv, I think that it should be handled by default on non glibc 2.17 because, as Matt pointed out, missing.h has #ifndef guards for that function.

comment:7 by Armin, 12 years ago

Also, you can always check for function like this (It's probably incorrect)

printf '#include <stdlib.h>\nint main(void){__secure_getenv();}' | gcc -xc - -o /dev/null && CFLAGS+=-DHAVE___SECURE_GETENV
printf '#include <stdlib.h>\nint main(void){secure_getenv();}' | gcc -xc - -o /dev/null && CFLAGS+=-DHAVE_SECURE_GETENV

Just find a right way to do it in Makefile.

Also, on my system, I've noticed this

checking for __secure_getenv... no
checking for secure_getenv... yes

comment:8 by bdubbs@…, 12 years ago

The 'checking for...' messages are from configure, right? We want to avoid that.

What we have now in cfg.h is:

#define HAVE_SECURE_GETENV 1

but that needs to be removed for glibc-2.17 and we need

#define HAVE_SECURE_GETENV 1

Notice the underscores. For glibc earlier than 2.17, we need the 1st define. I suppose if we have:

#define HAVE_SECURE_GETENV 1 #define HAVE_SECURE_GETENV 1

as the default, then the only change needed for earlier glibc version is to uncomment the 2nd define and comment the 1st one or a sed to change HAVE_SECURE to HAVE_SECURE.

I still don't think we want to address this directly in LFS. I'm not sure about BLFS.

comment:9 by bdubbs@…, 12 years ago

Make that:

#define HAVE_SECURE_GETENV 1
 //#define HAVE___SECURE_GETENV 1

comment:10 by bdubbs@…, 12 years ago

This is a hack, but it seems to work for me. In Makefile.lfs:

SECURE = $(shell if nm /lib/libc.so.6 | grep -q " secure_getenv"; \
         then echo yes; fi)

ifeq "$(SECURE)" "yes"
  SECURE_GETENV = SECURE_GETENV
else
  SECURE_GETENV = __SECURE_GETENV
endif

...

cfg.h: udev-lfs-$(VERSION)/cfg.h
   sed  -e 's/LFS-VERSION/$(SYSTEMD_VERSION)/' \
        -e 's/SECURE_GETENV/$(SECURE_GETENV)/' \
        udev-lfs-$(VERSION)/cfg.h > ./cfg.h

Of course udev-lfs-$VERSION/cfg.h has:

#define HAVE_SECURE_GETENV 1

so the define is either unchanged or HAVE___SECURE_GETENV

comment:11 by bdubbs@…, 12 years ago

Resolution: fixed
Status: assignedclosed

Fixed at revision 10093 and 10094.

Note: See TracTickets for help on using tickets.