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

NDK: Unified Headers issue #445

Closed
nurupo opened this Issue Jul 6, 2017 · 12 comments

Comments

Projects
None yet
5 participants
@nurupo

nurupo commented Jul 6, 2017

Description

Android NDK's unified headers cause compile errors in OpenSSL and TokTok C-Toxcore libraries. This doesn't happen with the deprecated headers.

OpenSSL:

./libcrypto.so: error: undefined reference to 'stderr'
./libcrypto.so: error: undefined reference to 'stdin'
./libcrypto.so: error: undefined reference to 'signal'
./libcrypto.so: error: undefined reference to 'tcsetattr'
./libcrypto.so: error: undefined reference to 'tcgetattr'

TokTok C-Toxcore:

../testing/DHT_test.c:208: error: undefined reference to 'stdin'
../toxcore/DHT.c:2404: error: undefined reference to 'rand'
../toxcore/DHT.c:1626: error: undefined reference to 'rand'
../toxcore/DHT.c:1629: error: undefined reference to 'rand'
../toxcore/DHT.c:1938: error: undefined reference to 'rand'
../toxcore/network.c:548: error: undefined reference to 'srand'

Environment Details

Not all of these will be relevant to every bug, but please provide as much
information as you can.

  • NDK Version: 15.1.4119039
  • Build system: standalone toolchain
  • Host OS: Debian Jessie amd64
  • Compiler: Clang? (whatever make_standalone_toolchain.py produces)
  • ABI: arm
  • STL: Not specified
  • NDK API level: No idea
  • Device API level: 14
@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Jul 6, 2017

As far as Toxcore goes:

  1. rand() is defined in C's stdlib.h.
  2. You can see that network.h has an unconditional #include <stdlib.h>.
  3. You can see that DHT.c, the one that we get error: undefined reference to 'rand' in, has an unconditional #include "network.h".
  4. Thus DHT.c should have rand defined, as it includes network.h which includes stdlib.h.

The only way this error is possible is if rand is no defined in Unified Header's stdlib.h.

nurupo commented Jul 6, 2017

As far as Toxcore goes:

  1. rand() is defined in C's stdlib.h.
  2. You can see that network.h has an unconditional #include <stdlib.h>.
  3. You can see that DHT.c, the one that we get error: undefined reference to 'rand' in, has an unconditional #include "network.h".
  4. Thus DHT.c should have rand defined, as it includes network.h which includes stdlib.h.

The only way this error is possible is if rand is no defined in Unified Header's stdlib.h.

@enh

This comment has been minimized.

Show comment
Hide comment
@enh

enh Jul 6, 2017

Contributor

how did you configure your standalone toolchain? looks like you've told the compiler to aim for a recent API level (where these symbols are available) but the linker to aim for an older one (where they were inline references to other symbols).

Contributor

enh commented Jul 6, 2017

how did you configure your standalone toolchain? looks like you've told the compiler to aim for a recent API level (where these symbols are available) but the linker to aim for an older one (where they were inline references to other symbols).

@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Jul 6, 2017

I build it using multiple toolchains, each targeting different architectures. It fails for all toolchains I try, while it succeeds with --deprecated-headers flag when creating a toolchain and with older NDK versions.

I create a toolchain like this

export ANDROID_NDK_HOME=/opt/android-ndk
"$ANDROID_NDK_HOME/build/tools/make_standalone_toolchain.py" --arch $ARCH --api $API --install-dir "$TOOLCHAIN_DIR" --force

$API and $ARCH are 14 for arm, 21 for arm64, 21 for x86_64 and 14 for x86. Then I build using the corresponding toolchain, which are

arm-linux-androideabi
aarch64-linux-android
x86_64-linux-android
i686-linux-android

nurupo commented Jul 6, 2017

I build it using multiple toolchains, each targeting different architectures. It fails for all toolchains I try, while it succeeds with --deprecated-headers flag when creating a toolchain and with older NDK versions.

I create a toolchain like this

export ANDROID_NDK_HOME=/opt/android-ndk
"$ANDROID_NDK_HOME/build/tools/make_standalone_toolchain.py" --arch $ARCH --api $API --install-dir "$TOOLCHAIN_DIR" --force

$API and $ARCH are 14 for arm, 21 for arm64, 21 for x86_64 and 14 for x86. Then I build using the corresponding toolchain, which are

arm-linux-androideabi
aarch64-linux-android
x86_64-linux-android
i686-linux-android
@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Jul 6, 2017

Here is a build log, if it's of any help.

nurupo commented Jul 6, 2017

Here is a build log, if it's of any help.

@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Jul 6, 2017

Ok, specifying CFLAGS=-D__ANDROID_API__=$API fixed this for me

Didn't notice this before

Standalone toolchains using GCC are not supported out of the box. To use GCC, pass -D__ANDROID_API__=$API when compiling. Note: this is not something we will be fixing.

Using clang instead of gcc also works, e.g. for autotools-based projects CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --host=arm-linux-androideabi ... works without disabling unified headers and without specifying __ANDROID_API__. I guess we are supposed to use clang anyway, given how gcc is deprecated since r12 or something like that.

nurupo commented Jul 6, 2017

Ok, specifying CFLAGS=-D__ANDROID_API__=$API fixed this for me

Didn't notice this before

Standalone toolchains using GCC are not supported out of the box. To use GCC, pass -D__ANDROID_API__=$API when compiling. Note: this is not something we will be fixing.

Using clang instead of gcc also works, e.g. for autotools-based projects CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --host=arm-linux-androideabi ... works without disabling unified headers and without specifying __ANDROID_API__. I guess we are supposed to use clang anyway, given how gcc is deprecated since r12 or something like that.

@DanAlbert

This comment has been minimized.

Show comment
Hide comment
@DanAlbert

DanAlbert Jul 11, 2017

Member

CC=arm-linux-androideabi-clang

FYI, CC=clang should work too. The triple prefix is unnecessary for Clang with standalone toolchains.

Member

DanAlbert commented Jul 11, 2017

CC=arm-linux-androideabi-clang

FYI, CC=clang should work too. The triple prefix is unnecessary for Clang with standalone toolchains.

@dkhanchopoulo

This comment has been minimized.

Show comment
Hide comment
@dkhanchopoulo

dkhanchopoulo Sep 2, 2017

guys, please clarify how did you make it work with clang because
when I made a tool-chain with script https://github.com/supertuxkart/stk-code/blob/master/android/make.sh
it still has the issue for clang: clang50: error: unknown argument: '-mandroid'

dkhanchopoulo commented Sep 2, 2017

guys, please clarify how did you make it work with clang because
when I made a tool-chain with script https://github.com/supertuxkart/stk-code/blob/master/android/make.sh
it still has the issue for clang: clang50: error: unknown argument: '-mandroid'

@drFabio

This comment has been minimized.

Show comment
Hide comment
@drFabio

drFabio Sep 28, 2017

@nurupo Can you exemplify how you built it with ndk 15b?

drFabio commented Sep 28, 2017

@nurupo Can you exemplify how you built it with ndk 15b?

@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Sep 28, 2017

If I remember it right, using clang toolchain just worked for me. gcc on the other hand had issues and you had to specify CFLAGS=-D__ANDROID_API__= for it to work. You shouldn't be using gcc on Android anyway though, since its support on Android is being deprecated in favor of clang.

nurupo commented Sep 28, 2017

If I remember it right, using clang toolchain just worked for me. gcc on the other hand had issues and you had to specify CFLAGS=-D__ANDROID_API__= for it to work. You shouldn't be using gcc on Android anyway though, since its support on Android is being deprecated in favor of clang.

@drFabio

This comment has been minimized.

Show comment
Hide comment
@drFabio

drFabio Sep 28, 2017

THe CFLAGS was needed but I could got it only with a standalone toolchain not the installed NDK by android studio, will try from the scratch later and try with clang

drFabio commented Sep 28, 2017

THe CFLAGS was needed but I could got it only with a standalone toolchain not the installed NDK by android studio, will try from the scratch later and try with clang

@nurupo

This comment has been minimized.

Show comment
Hide comment
@nurupo

nurupo Sep 28, 2017

Standalone toolchains is what I'm using.

nurupo commented Sep 28, 2017

Standalone toolchains is what I'm using.

@drFabio

This comment has been minimized.

Show comment
Hide comment
@drFabio

drFabio Sep 28, 2017

That's probably why I was confused and the things were not working I was following the wiki with NDK root being the installed NDK.

Glad to know I'm not diverging the path.

Thanks a lot for your response @nurupo

drFabio commented Sep 28, 2017

That's probably why I was confused and the things were not working I was following the wiki with NDK root being the installed NDK.

Glad to know I'm not diverging the path.

Thanks a lot for your response @nurupo

neolit123 added a commit to neolit123/subsurface that referenced this issue Apr 29, 2018

android: build with clang instead of GCC
Attempt to fix "undefined reference to 'stdout' by
building with clang instead of GCC.

ref:
android-ndk/ndk#445 (comment)

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment