I am trying to link 9base against uClibc. Linkage fails thus:
make[3]: Entering directory
`/home/strake/buildroot-2011.11/output/build/9base-6/awk'
make[3]: warning: jobserver unavailable: using -j1. Add `+' to parent
make rule.
LD awk
../lib9/lib9.a(fltfmt.o): In function `xdtoa':
fltfmt.c:(.text+0x39a): undefined reference to `frexp'
../lib9/lib9.a(strtod.o): In function `fmtstrtod':
strtod.c:(.text+0x994): undefined reference to `ldexp'
collect2: ld returned 1 exit status
make[3]: *** [awk] Error 1
make[3]: Leaving directory
`/home/strake/buildroot-2011.11/output/build/9base-6/awk'
make[2]: *** [all] Error 2
make[2]: Leaving directory
`/home/strake/buildroot-2011.11/output/build/9base-6/awk'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/strake/buildroot-2011.11/output/build/9base-6'
make: *** [/home/strake/buildroot-2011.11/output/build/9base-6/.stamp_built]
Error 2
It fails thus also when built without buidroot, but works when linked
against GNU libc.
uClibc configuration here: http://hpaste.org/64419
$ nm uClibc-0.9.32/lib/libm.a | human-grep frexp
s_frexp.os:
0000000000000000 r .LC0
0000000000000000 T __GI_frexp
0000000000000000 T frexp
$ nm uClibc-0.9.32/lib/libm.a | human-grep ldexp
s_ldexp.os:
U _GLOBAL_OFFSET_TABLE_
U __GI___finite
0000000000000000 T __GI_ldexp
U __GI_scalbn
U __errno_location
0000000000000000 T ldexp
I looked at lib9/libc.h, and found
extern double frexp(double, int*);
/* extern double ldexp(double, int); <math.h> */
Not sure why one is commented out, and not the other.
I searched the d...@suckless.org archives and found no such trouble.
I haven't a clue why this failed. How can I link this?
Thanks.
Cheers,
strake
Cheers,
Anthony
diff -r 12764b326f2b yacc.mk
--- a/yacc.mk Sun Feb 12 23:13:17 2012 +0100
+++ b/yacc.mk Sun Feb 26 17:26:11 2012 -0800
@@ -35,4 +35,4 @@
${TARG}: ${OFILES}
@echo LD ${TARG}
- @${CC} ${LDFLAGS} -o ${TARG} ${OFILES} -lm -L../lib9 -l9
+ @${CC} ${LDFLAGS} -o ${TARG} ${OFILES} -L../lib9 -l9 -lm
Problem solved. Many thanks.
Unfortunately, now linkage fails later. Solution might be quite plain;
I shall try to further diagnose when I have the time.
Failure mode:
make[2]: Entering directory
`/home/strake/buildroot-2011.11/output/build/9base-6/du'
CC du.c
LD du
../lib9/lib9.a(dirread.o): In function `mygetdents':
dirread.c:(.text+0x3a): undefined reference to `getdirentries64'
collect2: ld returned 1 exit status
make[2]: *** [du] Error 1
make[2]: Leaving directory
`/home/strake/buildroot-2011.11/output/build/9base-6/du'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/strake/buildroot-2011.11/output/build/9base-6'
make: *** [/home/strake/buildroot-2011.11/output/build/9base-6/.stamp_built]
Error 2
Thanks again.
Cheers,
strake
>
> Unfortunately, now linkage fails later. Solution might be quite plain;
> I shall try to further diagnose when I have the time.
>
I didn't drink my coffee yet, so my head isn't straight yet. I tried
to build 9base/plan9port/9vx with uClibc year or two ago (without
success). Those errors looks familiar, but my memory isn't fresh.
AFAIK uClibc doesn't provide getdirentries(), which is used by
lib9/dirread.c. As for error with getdirentries64, just look
at /usr/include/dirent.h:
# define getdirentries getdirentries64
I think I fixed that by providing own version of getdirentries(), but
hit later other issues.
Still it would be nice to fix this once and for all, because plan9port
and 9vx has same issues (I don't think that this got fixed).
I hope that the coffee is.
> AFAIK uClibc doesn't provide getdirentries(), which is used by lib9/dirread.c.
Ah, true.
$ nm uClibc-0.9.32/lib/* | grep getdir
getdirname.os:
$
> As for error with getdirentries64, just look at /usr/include/dirent.h:
>
> # define getdirentries getdirentries64
>
> I think I fixed that by providing own version of getdirentries(), but
> hit later other issues.
>
> Still it would be nice to fix this once and for all, because plan9port
> and 9vx has same issues (I don't think that this got fixed).
I agree. A quick search yielded this: http://9fans.net/archive/2006/06/463
Not sure where the patch is, though.
Cheers,
strake
It won't solve your problem, though.
--
- yiyus || JGL .
Thanks, applied.
As for the getdirentries() function, I would suggest adding ifdef's
for the BSDs if needed (see the old Matthias Teege thread on 9fans).
Cheers,
Anselm
Also join has some issues, I removed its entry from Makefile just to
check if ls/du commands works.
--- lib9/dirread.c.orig 2012-02-28 23:09:24.000000000 +0100
+++ lib9/dirread.c 2012-02-28 23:22:48.000000000 +0100
@@ -4,9 +4,25 @@
#include <sys/stat.h>
#include <dirent.h>
+#if defined(__UCLIBC__)
+# include <sys/syscall.h>
+# if defined(__USE_LARGEFILE64)
+# define getdents SYS_getdents64
+# else
+# define getdents SYS_getdents
+# endif
+#endif
+
extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**,
char*);
#if defined(__linux__)
+# if defined(__UCLIBC__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ return syscall(getdents, fd, (void*)buf, n);
+}
+# else
static int
mygetdents(int fd, struct dirent *buf, int n)
{
@@ -18,6 +34,7 @@ mygetdents(int fd, struct dirent *buf, i
nn = getdirentries(fd, (void*)buf, n, &off);
return nn;
}
+# endif
#elif defined(__APPLE__) || defined(__FreeBSD__)
static int
mygetdents(int fd, struct dirent *buf, int n)
...and Linux, on which my trouble was had, which I forgot to tell.
> Cheers,
> Anselm
>
>
Cheers,
strake
> +
> extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**,
> char*);
As for join command, problem was related to conflicting declarations -
system time.h (which was included in longer chain by stdio.h) vs 9base
libc.h. I fixed that by moving stdio.h inclusion in join.c to the top
of the file and undefining some things like this:
#include <stdio.h>
#undef gmtime
#undef localtime
#undef asctime
#undef ctime
Maybe it would be better to fix that in libc.h and move inclusion of
libc.h after stdio.h in join.c? Something like this in libc.h:
#ifndef NOPLAN9DEFINES
# ifdef gmtime
# undef gmtime
# endif
#define gmtime p9gmtime
>
> > The link order in yacc.mk is wrong.
> > Try building with this patch.
>
Same goes for rc/Makefile and sam/Makefile (move -lm flag to the end).
Also uClibc doesn't provide futimes, so we need to use futimesat() in
lib9/dirfwstat.c (patch is attached).
After that (and earlier fixes) everything builds nicely, whole 9base
linked against uClibc is ~5.5MB.
Thanks, applied.
Cheers,
Anselm
>
> Thanks, applied.
>
Great, so only issues left are conflicting declarations in join case
and missing getdirentries.
In first case, the problem is that time.h is included in longer chain:
stdio.h -> bits/uClibc_stdio.h -> bits/uClibc_mutex.h -> pthread.h ->
time.h.
You can find fix_conflicting_declarations.patch in attachments.
I avoided using ifdef soup and opted for simplest solution.
I moved "#include libc.h" behind "#include stdio.h" in join.c and added
some "undefs" to libc.h.
As for getdirentries I cleaned up my previous patch, check
uclibc_dirread.patch in attachments. Still it isn't my call if this
patch should be applied or not. I provided some "#warning" for this
case, informing that direct syscall is used.
I would like to hear from Matthew Farkas-Dyck, if with those patches he
can compile working 9base in his setup.
I cannot:
$ make
...
>>> 9base 6 Extracting
gzip -d -c /home/strake/buildroot-2011.11/dl/9base-6.tar.gz | tar
--strip-components=1 -C
/home/strake/buildroot-2011.11/output/build/9base-6 -xf -
>>> 9base 6 Patching package//9base
Applying 9base-6-dirfwstat.patch using plaintext:
patching file lib9/dirfwstat.c
Applying 9base-6-dirread.getdents.patch using plaintext:
patching file lib9/dirread.c
patch: **** malformed patch at line 27: @@ -18,6 +34,7 @@
Patch failed! Please fix 9base-6-dirread.getdents.patch!
make: *** [/home/strake/buildroot-2011.11/output/build/9base-6/.stamp_patched]
Error 1
$
This is Paul Onyschuk's patch. I tried to hack it a bit to make it
work, alas, in vain, so far. Find latest patches, as I have them,
attached. I had the same trouble with the original patch.
I have two tests to write and a lab report to give in tomorrow, but
after that I shall try again.
Cheers,
strake
>
> Patch failed! Please fix 9base-6-dirread.getdents.patch!
>
> I have two tests to write and a lab report to give in tomorrow, but
> after that I shall try again.
>
It is no surprise that patching failed. I used tip version from
repository to generate diffs. Try this:
$ hg clone http://hg.suckless.org/9base
$ cd 9base
$ patch -p0 < uclibc_dirread.patch
$ patch -p1 < fix_conflicting_declarations.patch
$ make
Tried it; same trouble. Anyhow, it's moot, since I just applied it
with the human patch algorithm and made a new patch (find attached).
With Paul Onyschuk's join patch, I can now build glitchlessly!
Many thanks to Paul Onyschuk and Anthony Martin for all their work.
Thanks to everyone else who took the time to read this, too (^_^)
Cheers,
strake
Thanks applied.
Anselm