Problem with Android NDK r8 --- undefined references to static stl

6,465 views
Skip to first unread message

Valeriy Sokolov

unread,
May 12, 2012, 10:00:29 AM5/12/12
to andro...@googlegroups.com
Hello,

I would like to build an application which uses STL with Android NDK r8 tool-chain for armeabi-v7a and keep getting undefined references.

Here is a small example of my problem:

valeriy@ghostwheel ~ $ cat android-stl.cc
#include <string>
#include <iostream>

int main() {
  std::cout << std::string("Hello, Android STL!\n");
  return 0;
}
valeriy@ghostwheel ~ $ /home/valeriy/ANDROID/NDKs/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++  -fPIC --sysroot=/home/valeriy/ANDROID/NDKs/android-ndk-r8/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon  -fPIC -Wall -Wextra -Wcast-align -Wno-unused -Wno-missing-field-initializers -fno-strict-aliasing -Wno-cast-align -mfloat-abi=softfp -mfpu=neon -fexceptions --sysroot=/home/valeriy/ANDROID/NDKs/android-ndk-r8/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon  -fPIC -Wall -Wextra -Wcast-align -Wno-unused -Wno-missing-field-initializers -fno-strict-aliasing -Wno-cast-align -mfloat-abi=softfp -mfpu=neon -O3 -DNDEBUG -fexceptions -Wl,--fix-cortex-a8 -isystem/home/valeriy/ANDROID/NDKs/android-ndk-r8/sources/cxx-stl/gnu-libstdc++/include/  -L"/home/valeriy/ANDROID/NDKs/android-ndk-r8/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a" -isystem /home/valeriy/ANDROID/NDKs/android-ndk-r8/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/include/ -lstdc++ -lsupc++ -lgnustl_static android-stl.cc
/tmp/ccMXmevL.o: In function `global constructors keyed to android_stl.cc':
android-stl.cc:(.text+0x8): undefined reference to `std::ios_base::Init::Init()'
android-stl.cc:(.text+0x24): undefined reference to `std::ios_base::Init::~Init()'
/tmp/ccMXmevL.o: In function `main':
android-stl.cc:(.text+0x3a): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
android-stl.cc:(.text+0x4a): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int)'
android-stl.cc:(.text+0x6a): undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int)'
android-stl.cc:(.text+0x76): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_destroy(std::allocator<char> const&)'
android-stl.cc:(.text+0x80): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
android-stl.cc:(.text+0x86): undefined reference to `__cxa_end_cleanup'
android-stl.cc:(.text+0x94): undefined reference to `std::cout'
android-stl.cc:(.text+0x98): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_empty_rep_storage'
/tmp/ccMXmevL.o:(.ARM.extab+0x0): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status


I think that I added all needed libraries to the command line (in bold).

Please help me to resolve this issue.

David Turner

unread,
May 13, 2012, 2:45:54 AM5/13/12
to andro...@googlegroups.com
1/ Don't add -lstdc++
2/ -lsupc++ should appear _after_ -lgnustl_static



--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/oAWqapmegWsJ.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

Valeriy Sokolov

unread,
May 13, 2012, 6:15:09 AM5/13/12
to android-ndk
I tried your suggestions and they did not work for me:

valeriy@ghostwheel ~ $ cat android-stl.cc
#include <string>
#include <iostream>

int main() {
std::cout << std::string("Hello, Android STL!\n");
return 0;
}
valeriy@ghostwheel ~ $ cat build-android.sh
#!/bin/bash

NDK="/home/valeriy/ANDROID/NDKs/android-ndk-r8/"

$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-
linux-androideabi-g++ \
-fPIC \
--sysroot=$NDK/platforms/android-14/arch-arm \
-DANDROID \
-Wno-psabi \
-fsigned-char \
-mthumb \
-march=armv7-a \
-mfloat-abi=softfp \
-mfpu=neon \
-Wall \
-Wextra \
-Wcast-align \
-Wno-unused \
-Wno-missing-field-initializers \
-fno-strict-aliasing \
-Wno-cast-align \
-fexceptions \
-isystem $NDK/sources/cxx-stl/gnu-libstdc++/include \
-isystem $NDK/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/
include \
-O3 \
-DNDEBUG \
-fexceptions \
-Wl,--no-undefined \
-Wl,--fix-cortex-a8 \
-L"$NDK/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a" \
-lgnustl_static \
-lsupc++ \
android-stl.cc
valeriy@ghostwheel ~ $ bash ./build-android.sh
/tmp/ccGCXY7p.o: In function `global constructors keyed to
android_stl.cc':
android-stl.cc:(.text+0x8): undefined reference to
`std::ios_base::Init::Init()'
android-stl.cc:(.text+0x24): undefined reference to
`std::ios_base::Init::~Init()'
/tmp/ccGCXY7p.o: In function `main':
android-stl.cc:(.text+0x3a): undefined reference to
`std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::basic_string(char const*, std::allocator<char> const&)'
android-stl.cc:(.text+0x4a): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >&
std::__ostream_insert<char, std::char_traits<char>
>(std::basic_ostream<char, std::char_traits<char> >&, char const*,
int)'
android-stl.cc:(.text+0x6a): undefined reference to
`__gnu_cxx::__exchange_and_add(int volatile*, int)'
android-stl.cc:(.text+0x76): undefined reference to
`std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::_Rep::_M_destroy(std::allocator<char> const&)'
android-stl.cc:(.text+0x80): undefined reference to
`std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::~basic_string()'
android-stl.cc:(.text+0x86): undefined reference to
`__cxa_end_cleanup'
android-stl.cc:(.text+0x94): undefined reference to `std::cout'
android-stl.cc:(.text+0x98): undefined reference to
`std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::_Rep::_S_empty_rep_storage'
/tmp/ccGCXY7p.o:(.ARM.extab+0x0): undefined reference to
`__gxx_personality_v0'
collect2: ld returned 1 exit status


On May 13, 10:45 am, David Turner <di...@android.com> wrote:
> 1/ Don't add -lstdc++
> 2/ -lsupc++ should appear _after_ -lgnustl_static
>
> On Sat, May 12, 2012 at 4:00 PM, Valeriy Sokolov
> <sokolov.val...@gmail.com>wrote:
> > *-lstdc++ -lsupc++ -lgnustl_static* android-stl.cc

David Turner

unread,
May 13, 2012, 7:39:46 AM5/13/12
to andro...@googlegroups.com
3/ Put the source file _before_ the libraries it depends on

Valeriy Sokolov

unread,
May 14, 2012, 6:19:01 AM5/14/12
to android-ndk
Thank you, it solved everything! =)

Silly, I had no idea about this feature of the linker before.

On May 13, 3:39 pm, David Turner <di...@android.com> wrote:
> 3/ Put the source file _before_ the libraries it depends on
>
> On Sun, May 13, 2012 at 12:15 PM, Valeriy Sokolov
> <sokolov.val...@gmail.com>wrote:

Tor Lillqvist

unread,
May 14, 2012, 7:31:30 AM5/14/12
to andro...@googlegroups.com
>> 3/ Put the source file _before_ the libraries it depends on

> Silly, I had no idea about this feature of the linker before.

Heh. Unfortunately it is common to see instructions to use command lines like

    gcc -o foo -lbar foo.c

or, equyivalent but perhaps a bit less obviously wrong,

   gcc -o foo `pkg-config --cflags --libs bar` foo.c

on the internets, as in many cases on desktop (GNU/)Linux it works fine to do it like that.

So the ancient rule (since day one of Unix) that libraries should go after object files (or source files) that use them has been largely forgotten. (The GNU linker documentation does say it, but who reads documentation...) This then bites people when they move to (to them) less common  platforms, like MingW, or, apparently, Android.

--tml


David Turner

unread,
May 14, 2012, 7:51:29 AM5/14/12
to andro...@googlegroups.com
Note that in the case of Android, we don't do anything special and just reuse the standard binutils stuff. I have no idea why this acts differently on "desktop" linux.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/5it1F0tanAcJ.

Tor Lillqvist

unread,
May 14, 2012, 8:05:21 AM5/14/12
to andro...@googlegroups.com
Note that in the case of Android, we don't do anything special and just reuse the standard binutils stuff. I have no idea why this acts differently on "desktop" linux.
 
Probably the -Wl,--no-undefined that he used is the key.

--tml


Valeriy Sokolov

unread,
May 15, 2012, 9:51:55 AM5/15/12
to andro...@googlegroups.com
Actually (if i remember correctly...) I tried to remove this option and got same problem. Anyway, I'm glad that I learned about this feature.

Thank you again!

Halsafar

unread,
Aug 1, 2012, 1:56:39 PM8/1/12
to andro...@googlegroups.com
I am having the exact same issue as the OP.

I tried this and it changed the errors to weird multiple definitions of (examples):
unwind-c.c:128: multiple definition of `__gcc_personality_v0'
emutls.c:193: multiple definition of `__emutls_register_common'
To unsubscribe from this group, send email to android-ndk+unsubscribe@googlegroups.com.

Halsafar

unread,
Aug 1, 2012, 1:58:56 PM8/1/12
to andro...@googlegroups.com
Can you please elaborate on what solved your problem.

Exact same issue here.  Same errors.  All my code was working perfect on Android NDK r8.

Valeriy Sokolov

unread,
Aug 1, 2012, 2:56:51 PM8/1/12
to andro...@googlegroups.com
Well, my problem in the simplest case was solved with the command like

$ g++ source.cc some_object.o -lgnustl_static -lsupc++

I.e. the libraries must go after all other object and source files
which use the libraries. Seems the feature of gnu linker is to go
through files with object code from left to right in an argument list
and ignore all the definitions which are not needed for previously
processed object files.

In the whole project we discovered that android-cmake toolchain (
http://code.google.com/p/android-cmake/ ) which we used for our
cmake-based building system has NKD support in recent revisions, so we
just switched to it and it works fine for us.
> --
> You received this message because you are subscribed to the Google Groups
> "android-ndk" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/android-ndk/-/jbqhPcz90sIJ.
>
> To post to this group, send email to andro...@googlegroups.com.
> To unsubscribe from this group, send email to
> android-ndk...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/android-ndk?hl=en.



--
Best regards,
Valeriy Sokolov.
Reply all
Reply to author
Forward
0 new messages