[Toybox] toys/android/log.c with android NDK?

Rob Landley rob at landley.net
Mon Mar 12 11:06:34 PDT 2018


On 03/10/2018 11:06 PM, enh wrote:
>> $ sudo build/tools/make_standalone_toolchain.py --arch x86_64 --api 26 \
>>   --stl=libc++ --install-dir=/opt/android/x86-64
>> $ CROSS_COMPILE=/opt/android/x86-64/bin/llvm- CFLAGS=--static make defconfig
>> It has no llvm-cc... ok then:
>> $ sudo ln -s clang /opt/android/x86-64/bin/llvm-cc
>> $ CROSS_COMPILE=/opt/android/x86-64/bin/llvm- CFLAGS=--static make defconfig
>> $ CROSS_COMPILE=/opt/android/x86-64/bin/llvm- CFLAGS=--static make
>> many warnings ignored...
>> generated/obj/log.o:log.c:function log_main: error: undefined reference to
>> '__android_log_write'
>> $ CROSS_COMPILE=... make menuconfig # switch off log in android menu.
> 
> (or add -llog.)

Hmmm, should already be there in scripts/make.sh...

  # We trust --as-needed to remove each library if we don't use any symbols
  # out of it, this loop is because the compiler has no way to ignore a library
  # that doesn't exist, so we have to detect and skip nonexistent libraries
  # for it.

  > generated/optlibs.dat
  for i in util crypt m resolv selinux smack attr rt crypto z log
  do

Ah, here's the problem:

$ /opt/android/x86-64/bin/llvm-cc -llog hello.c
$ ./a.out
bash: ./a.out: No such file or directory
$ /opt/android/x86-64/bin/llvm-cc -llog hello.c --static
/opt/android/x86-64/bin/../lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld:
cannot find -llog
clang60: error: linker command failed with exit code 1 (use -v to see invocation)

The library only exists for dynamic, not static. And I can't run a dynamic
bionic binary on an ubuntu host.

Of course...

$ /opt/android/x86-64/bin/llvm-cc --static hello.c
$ ./a.out
Illegal instruction (core dumped)

Still an issue with api 28.

>> $ CROSS_COMPILE=... make
>> more warnings, more warnings...
>> scripts/make.sh: line 28: /opt/android/x86-64/bin/llvm-strip: No such file or
>> directory
>> strip failed, using unstripped

You know that one's trivial enough I might just add a "strip" to toybox. (It's
basically objcopy with some excludes.)

(The hiccup is that the japanese developers implementing the sh4 toolchain had a
translated copy of the ELF spec and the codepage switch turned "_" into "." so
they dutifully used . as the symbol prefix, and if you use the wrong strip there
it mangles your executables. So one strip working on all targets requires
checking to see what if any prefix is currently in use, and that's why I use the
prefixed strip.)

>> And that file is doing #include <iconv.h> so I don't see _why_ it's not getting
>> them?
> 
> because <iconv.h> isn't there until API 28, but a side-effect of the
> single sysroot for all API levels is that the *file* is there, but the
> contents are #ifdef'ed out since you asked for API level 26.

Cut and paste from the example in the web page. :)

I redid it with api 28, and switching off android/log I got the rest of it to
build. But the result still immediately segfaults, as does hello world.

(I tried building with the included gcc toolchain too: same thing.)

> we'll be able to provide better errors (along the lines of "iconv_open
> is only available in API level 28 and later") when we remove GCC later
> this year and only have to support clang, but r17 still includes GCC
> so it's just #ifdef'ed out.

The ability to build an x86-64 hello world binary statically linked against
bionic which runs on an ubuntu host would be nice. Is there a design reason
that's not supported?

Rob



More information about the Toybox mailing list