I have a .cpp file which has usage of NULL at several places. When I try to compile this cpp file for Android/x86 platform using clang++ on Windows machine + standalone tool chain, I am running into "expected expression" error at the places where NULL is used. I find the definition of NULL in stddef.h of clang headers provided by Android NDK as below.
#if defined(__need_NULL)
#undef NULL
#ifdef __cplusplus
# if !defined(__MINGW32__) && !defined(_MSC_VER)
# define NULL __null
# else
# define NULL 0
# endif
#else
# define NULL ((void*)0)
#endif
As far as I know, __null is specific to GNU compiler. In my case both _MSC_VER and __MINGW32__ are undefined because I am compiling for Android platform using clang++ and standalone tool chain. So it is hitting into define NULL __null. Since clang++ has no clue of what __null is, it is resulting into "expected expression" error.
My question is, why is clang using macros(like __null) provided by GNU compiler? Or am I missing something here?
Could somebody please help me understand. Thanks
Why is clang defining NULL as __null?
__null is superior to 0, because former is only a null pointer constant, while the latter is also an integer constant. This difference is significant in case of overload resolution and type deduction:
void foo(int);
void foo(void*);
foo(0); // calls foo(int)
foo(__null); // call is ambiguous, program is ill-formed
foo(NULL); // could have either behaviour
// call to foo(int) would be undesirable
foo(nullptr); // calls foo(void*)
The reason is same or similar as why nullptr was introduced to the language in C++11.
Another reason to do so is that clang strives to be closely compatible with GCC.
Since clang++ has no clue of what __null is
clang++ appears to know what __null is.
Related
I'm trying to compile libfuse with NDK, my environment:
Win10(64bit) + NDK(r14b,64bit) + libfuse(3.1.0)
Error occurs in fuse_common.h, it checks size of off_t:
$ ndk-build
[armeabi-v7a] Compile thumb : fuse <= buffer.c
In file included from jni/../../libfuse/lib/buffer.c:15:
In file included from jni/../../libfuse/lib/fuse_i.h:9:
In file included from jni/../../libfuse/include\fuse.h:19:
jni/../../libfuse/include/fuse_common.h:745:13: error: bit-field
'_fuse_off_t_must_be_64bit' has negative width (-1)
{ unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
^
1 error generated.
make: *** [obj/local/armeabi-v7a/objs/fuse/__/__/libfuse/lib/buffer.o] Error 1
here's the check in fuse_common.h:
struct _fuse_off_t_must_be_64bit_dummy_struct \
{ unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
I searched on google, there's _FILE_OFFSET_BITS=64 definition, which can be used to change the size of off_t, I have this defined my 'Android.mk' file:
LOCAL_CFLAGS := \
....
-D_FILE_OFFSET_BITS=64 \
....
And even add this line at the beginning of fuse_common.h
#define _FILE_OFFSET_BITS 64
Still not working, how to fix it?
Update to NDK r15c. _FILE_OFFSET_BITS=64 works from there on out.
Note that most off64_t system calls weren't available until android-21. If your minSdkVersion is set below that and you use _FILE_OFFSET_BITS=64, many functions will not be available.
NOTE Provided solution is much like workaround, see #Dan's answer for reliable and official way to get 64-bit off_t.
On Android off_t is always 32-bit length, and there is no preprocessor macro that controls its size. (Though it is true only for NDK development since modern bionic allow to configure off_t size at compile time). And because of this you cannot compile your library directly.
But I guess there is some way to workaround it. Android NDK offers non-POSIX extended type - off64_t, and also it provides a complementary set of library functions that accept it instead of off_t. They are distinguished by 64 suffix, i.e. lseek64(), mmap64(). So to make things work you may try to add global configuration header to your project:
/* let off_t to be a 64-bit length */
typedef off64_t off_t;
/* use appropriate versions of system functions */
/* list here only functions that have off_t parameters and are used by your library */
#define mmap mmap64
#define lseek lseek64
And of course keep in mind that compiled code now is linked against *64() functions instead of regular ones and any public interfaces expect off64_t instead of off_t.
Im trying to build an Ubuntu Touch tree, based on an Aosp tree I already correctly built.
It fails with this error
CAPEWrapper.cpp:16: error: undefined reference to '__xlog_buf_printf'
this is the header that file includes
#include "CAPEWrapper.h"
which on cascade includes
#include <cutils/xlog.h>
which in turn defines
#if defined(__cplusplus)
extern "C" {
#endif
int __xlog_buf_printf(int bufid, const struct xlog_record *rec, ...);
#if defined(__cplusplus)
}
#endif
I suspect that my g++ doesn't set __cplusplus macro. Could it be a realistic scenario with this kind of error? If this could be the problem, should I need to specify a standard implementation with "stdc=something" to solve it?
Any other idea is welcome.
Make sure that your project is linking libcutils, and that it's linking it in the correct order (i.e. that -lcutils appears in the linker command line after any module that depends on it).
In the end, I found that the modules was listed inside a macro called LOCAL_WHOLE_STATIC_LIBRARIES, that in Android environment passes its content to the --whole-archive flag of GCC linker.
I'm compiling C++ code written primarily for Mac OS, using the Android NDK and I get the following error:
- Type 'errno_t' could not be resolved
In Xcode this type is defined on OSX 10.0/usr/include/sys/_types/_errno_t.h as this:
#ifndef _ERRNO_T
#define _ERRNO_T
typedef int errno_t;
#endif /* _ERRNO_T */
Any suggestions on how to convert this to the NDK, or add compiler flags to make this compile, or where to even get the source code to define this type in my source code itself?
Thanks.
See this answer for information on errno_t.
errno_t is not a part of the C standard, and bionic doesn't support it.
The fix is simply to change all the errno_ts to be ints.
A question from https://stackoverflow.com/a/11467040/1442443
my final target is to dump user space stack.
I try to build a cpp file as below to a executable on android platform. Therefore, by calling tryToGetStack(), I can get call stack of my executable in run time.
#include <utils/CallStack.h>
namespace android
{
extern "C" void tryToGetStack()
{
CallStack stack;
stack.update();
stack.dump("");
}
}
and add lib setting to to Android.mak since CallStack.tpp is in libutils
LOCAL_SHARED_LIBRARIES += libutils
but I always get error with message:
error: undefined reference to 'android::CallStack::CallStack()'
error: undefined reference to 'android::CallStack::update(int, int)'
...
It seems the executable resolve the symbols at link time rather than load the .so file in runtime?
Do I missing something or there is some limit in Android build system?
I know it is a simple question, but I really need help...
update1
I try to add the code to another executable. The result is same... Does anyone knows the rule of android build system?
update2
There are some key words in my console "target StaticExecutable: ...", I think is is the answer.
http://en.wikipedia.org/wiki/Static_executable
my final target is to dump user space stack.
after google so many information from internet, I found there are 4 ways:
ptraceļ¼ http://en.wikipedia.org/wiki/Ptrace
It is really hard to use ptrace, and we need to stop the thread before using ptrace to attach
_unwind_backtrace: the way used by CallStack (CallStack class in CallStack.cpp)
example: http://git.stlinux.com/?p=stm/uclibc.git;a=blob;f=libubacktrace/sysdeps/sh/backtrace.c;h=18b91b1bb3fa26344a521927c631553a410fcf56;hb=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3
It is work with a drawback: if you use it as the thread is processing signal, it would dump signal stack rather than dump thread stack
The same problen: How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
backtrace: http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
a GNU extension function, not be implemented in Bionic libc used by Android
reference: https://stackoverflow.com/a/8295238/1442443
reference: http://lists.puredata.info/pipermail/pd-list/2012-02/094258.html
a patch to dump user space thread stack: http://www.gossamer-threads.com/lists/linux/kernel/1525096
but only be implemented in X86 architecture... orz
I try to port it to android, no it only shows the first frame of stack since arm does not use frame pointer.
So... 2 is the answer.
However, I wonder if someone can resolve the problem : How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
update:
if you can use cross compiler to use glic to compile your code, maybe you can use 3. backtrace !
http://communities.mentor.com/community/cs/archives/arm-gnu/msg02514.html
update2
a good article
http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html
Since this is such an important question here is my answer that worked for me. My code is in C so it has to call a C++ function that can access android::CallStack.
stackdump.cpp:
#include < utils/CallStack.h >
extern "C" void dumpCallStack( char *label)
{
android::CallStack cs;
cs.update();
cs.dump(label);
}
my main code (foo.c):
void dumpCallStack(char *label);
...
dumpCallStack(\__FUNCTION__);
I have had the same problem once. And it is hard to interpret.
The syntax is of course correct and reasonable!
I have tried many methods but it did not work.
Finally, I got an idea that, the lib reference "LOCAL_SHARED_LIBRARIES += libutils" should be put into a makefile generating a dynamic library rather than into a makefile generating a static library. This is the final reason.
Reference:
http://yongbingchen.github.io/blog/2013/05/09/dump-stack-in-android-native-c-code/
I also received this error, but I added:
LOCAL_STATIC_LIBRARIES += libutils
before line of LOCAL_MODULE := xxx in vm/Android.m of three targets and added
LOCAL_SHARED_LIBRARIES += libcorkscrew
in vm/Android.mk
and libdex/Android.mk, and same for the dexlist/Android.mk, dexdump/Android.mk
After all these done, it works for me.
I am trying to build a C++ code using NDK in android. I have a method which has a parameter vector < vector <float> > coordinates
Everything builds fine until I write this line inside my method
vector<float> firstPoint = coordinates.at(0);
I start getting this error
D:/eclipseworkspace/myLibProject/obj/local/armeabi/libmyLibProject.a(FileName.o): In function `std::priv::_Vector_base<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > >::_M_throw_out_of_range() const':
D:/androidndk/sources/cxx-stl/stlport/stlport/stl/_vector.c:45: undefined reference to `std::__stl_throw_out_of_range(char const*)'
collect2: ld returned 1 exit status
make: *** [/cygdrive/d/eclipseworkspace/myLibProject/obj/local/armeabi/libOutputName.so] Error 1
I have no clue why this is happening and Google is not helping either.
Thanks.
I think you are using two different implementation of the standard library in the same project.
It looks like you are compiling your files with (the headers of) an stlport implementation of the standard library in D:/android..., and you link against your local library.
You have to configure the linker in your ide (or Makefile) to use also the lib file of the same implementation (somewhere in D:/android... I guess).
This is a linking error. You need to add APP_STL := stlport_static to your Apllication.mk file. Also make sure that you use -fno-exceptions flag, since STLport is not compatible with C++ exceptions and RTTI.
You can get more info in APPLICATION-MK.HTML which is availavle in the docs folder of the NDK. CPLUSPLUS-SUPPORT.HTML is also worth to read.
this looks like a linker error. You probably forgot to add STL library reference to your build. Or it can't be found
Did you do this ?
#include <stdexcept>
#include <vector>
using namespace std;
When I changed
vector<float> firstPoint = coordinates.at(0);
to
vector<float> firstPoint = coordinates[0];
it started compiling..... :s y?