libimobiledevice / libimobiledevice-glue

A library with common code used by libraries and tools around the libimobiledevice project
GNU Lesser General Public License v2.1
95 stars 76 forks source link

No reference implementation for getifaddrs available for this platform #16

Open voltagex opened 2 years ago

voltagex commented 2 years ago

I'm building against an ancient uclibc (not my choice) and I can't build libimobiledevice-glue

make  all-recursive
make[1]: Entering directory '/src/libimobiledevice-glue'
Making all in src
make[2]: Entering directory '/src/libimobiledevice-glue/src'
  CC     socket.lo
socket.c:698:2: error: #error No reference implementation for getifaddrs available for this platform.

All I'm after in the end is USB tethering, is it possible to #ifdef out all the wifi based stuff as well?

Otherwise, I note that you've got a portable-ish getifaddrs for Windows in socket.c, could this be made to work for uclibc as well?

voltagex commented 2 years ago

Strangely, while stubbing it, I see /src/am-toolchains/brcm-arm-sdk/hndtools-arm-linux-2.6.36-uclibc-4.5.3/bin/../arm-brcm-linux-uclibcgnueabi/sysroot/usr/include/ifaddrs.h:59:12: note: previous declaration of 'getifaddrs' was here, so maybe the #ifdefs are just incorrect?

nikias commented 2 years ago

Hi, something in configure doesn't seem to work out. A simple workaround would be to set the environment variable ac_cv_func_getifaddrs=yes before running configure. But I'd prefer to fix this to detect it properly. Can you apply this patch and re-run ./autogen.sh?


diff --git a/configure.ac b/configure.ac
index bfc443e..799a2ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,7 +44,11 @@ AC_TYPE_UINT32_T
 AC_TYPE_UINT8_T

 # Checks for library functions.
-AC_CHECK_FUNCS([asprintf strcasecmp strdup strerror strndup stpcpy vasprintf getifaddrs])
+AC_CHECK_FUNCS([asprintf strcasecmp strdup strerror strndup stpcpy vasprintf])
+
+# Check for additional functions
+AC_CHECK_HEADERS(ifaddrs.h)
+AC_CHECK_FUNCS(getifaddrs)

 # Check for operating system
 AC_MSG_CHECKING([for platform-specific build settings])```
nikias commented 2 years ago

Hmm... guess that doesn't really make a difference...

voltagex commented 2 years ago

Hmm... guess that doesn't really make a difference...

I don't have direct access to this device at the moment but my workaround was this

https://git.sr.ht/~voltagex/rt68u-itethering/tree/main/item/getifaddrs-stub.patch

nikias commented 2 years ago

I see... Next time you do, could you check config.log, search for getifaddrs and paste the lines around it? That would be really helpful. What the check basically does is something like:

#ifdef __cplusplus
extern "C"
#endif
char getifaddrs();

int
main ()
{
  return getifaddrs();

  return 0;
}

And then it tries to link that trying to see if that symbol exists. Something like /your/cool/compiler/gcc -o conftest conftest.c

Thanks for trying to figure this out.

voltagex commented 2 years ago

config.log, search for getifaddrs

With or without your patch?

nikias commented 2 years ago

Without. The patch is not really changing anything :)

voltagex commented 2 years ago

Apologies for the delay in getting back to you, @nikias. I have re-run the commands and attached logs here.

config.log.txt make.txt

nikias commented 2 years ago

No problem at all. So it looks like it expects the symbol to be in some library after all:

configure:8736: checking for getifaddrs
configure:8736: arm-brcm-linux-uclibcgnueabi-gcc -std=gnu99 -o conftest -I/opt/brcm-arm/include -L/opt/brcm-arm/lib  -lplist-2.0 -lpthread -lrt conftest.c -lplist-2.0 -lpthread -lrt >&5
/tmp/ccOprCHS.o: In function `main':
conftest.c:(.text+0x8): undefined reference to `getifaddrs'

Any idea what library that could be? Maybe /opt/brcm-arm/lib holds it. Try this command (notice the + at the end!)

find /opt/brcm-arm/lib -name "*.so" -exec sh -c 'for i; do VAL=`nm $i |grep "T _getifaddrs"`; if test -n "$VAL"; then echo $i; echo $VAL; fi; done' sh {} +
voltagex commented 2 years ago

Yeah, this is in Broadcom's proprietary (?) toolchain (?), in libshared.so - but when I looked again I actually did find it in AsusWRT Merlin

nm: /opt/brcm-arm/lib/ld-uClibc-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libc.so: no symbols
nm: /opt/brcm-arm/lib/libcrypt-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libdl-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libgcc_s.so: file format not recognized
nm: /opt/brcm-arm/lib/libm-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libnsl-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libresolv-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/librt-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libthread_db-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libuClibc-0.9.32.1.so: no symbols
nm: /opt/brcm-arm/lib/libutil-0.9.32.1.so: no symbols

https://github.com/RMerl/asuswrt-merlin.ng/blob/8a77382a6ea8c86e102fbd0d8b2cb0f58c7b81c6/release/src/router/shared/ifaddrs.c

I ended up writing a shim to make the thing build, and then it looks like the symbol/.so is available on the device itself - unpacking the trx file (using 7zip) from wget https://sourceforge.net/projects/asuswrt-merlin/files/RT-AC68U/Release/RT-AC68U_386.4_0.zip, I can see the symbols.

strings ./usr/lib/libshared.so | grep ifaddrs
getifaddrs
freeifaddrs
getifaddrs failed: %s
getifaddrs netmask error: %x

Sorry, this is probably really offtopic for your project - it's not a libimobiledevice issue, however, setting the autoconf variable then leads to

/opt/brcm-arm/lib/libimobiledevice-glue-1.0.so: undefined reference to `freeifaddrs'
/opt/brcm-arm/lib/libimobiledevice-glue-1.0.so: undefined reference to `getifaddrs'

as soon as something tries to link with libimobiledevice-glue.

nikias commented 2 years ago

I agree this is really specific, but nonetheless it should be possible to get this to link somehow. So would it work if you link with -lshared ?

voltagex commented 2 years ago

-lshared fails unless I use the shim from my repo. If I get some time I'll try to get in contact with the Merlin devs and see if they can make a change so that the libshared library is available

nikias commented 2 years ago

OK, thanks. Your patch only adds the ifaddr.h include, is that defining the functions?

voltagex commented 2 years ago

Yes, only the functions, and just barely.

JonasVautherin commented 4 months ago

I have the exact same issue when cross-compiling for Android (using dockcross). @voltagex's patch fixes the build, but I understand it is not ideal:

diff --git a/src/socket.c b/src/socket.c
index ad6135f..61da815 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -695,7 +695,8 @@ static int getifaddrs(struct ifaddrs** ifap)
    return 0;
 }
 #else
-#error No reference implementation for getifaddrs available for this platform.
+#warning No reference implementation for getifaddrs available for this platform.
+#include "ifaddrs.h"
 #endif
 #endif

For me, config.log says:

configure:13345: checking for getifaddrs
configure:13345: /usr/aarch64-linux-android/bin/clang -o conftest -g -O2   conftest.c  >&5
ld: error: undefined symbol: getifaddrs
>>> referenced by conftest.c:60
>>>               /tmp/conftest-deaa86.o:(main)
clang140: error: linker command failed with exit code 1 (use -v to see invocation)

Though I have ifaddrs.h in /usr/include and in /usr/aarch64-linux-android/sysroot/usr/include :thinking:.

@nikias: any suggestion what else I should check?