Header-only C++ library (GLM) doesn't compile with Android-NDK - c++

I want to use the GLM (glm.g-truc.net) header-only C++ library in an Android NDK project, but I get compile errors. In the Android.mk, I've added the header search path
LOCAL_CFLAGS += -I/Users/Johannes/Development/glm_include/
and I've also tried to compile using STLport and GNU-STL by setting the following in Application.mk like described in the CPLUSPLUS-SUPPORT document:
APP_STL := stlport_static
or
APP_STL := gnustl_static
respectively. Nothing helps; Those are the errors I get when including <glm/glm.h> and using an glm::ivec2. ndk-build outputs:
Compile++ arm : wbar <= QCARBase.cpp
In file included from /Users/Johannes/Development/glm_include/glm/glm.hpp:66,
from /Users/Johannes/proj/WirtschaftsblattAR/app/android/wbar/jni/QCARBase.cpp:45:
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:240: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:240: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:240: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:251: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:251: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:251: error: expected ')' before 'sizeof'
In file included from /Users/Johannes/Development/glm_include/glm/./core/func_common.hpp:335,
from /Users/Johannes/Development/glm_include/glm/glm.hpp:66,
from /Users/Johannes/proj/WirtschaftsblattAR/app/android/wbar/jni/QCARBase.cpp:45:
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1202: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1202: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1202: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1217: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1217: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1217: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1228: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1228: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1228: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1240: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1240: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1240: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1253: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1253: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1253: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1268: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1268: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1268: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1279: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1279: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1279: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1291: error: expected unqualified-id before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1291: error: expected ')' before 'sizeof'
/Users/Johannes/Development/glm_include/glm/./core/func_common.inl:1291: error: expected ')' before 'sizeof'
make: *** [/Users/Johannes/proj/WirtschaftsblattAR/app/android/wbar/obj/local/armeabi/objs/wbar/QCARBase.o] Error 1
I'm using the Crystax NDK r6 (www.crystax.net)

After a bit of header hopping, I figured out how to fix this with the GNU libstdc++ runtime.
Try defining _GLIBCXX_USE_C99_MATH to 1 before including <glm.hpp>, like this:
#define _GLIBCXX_USE_C99_MATH 1
#include <glm/glm.hpp>
<glm.hpp> includes <cmath>, which in turn includes <math.h>. The _GLIBCXX_USE_C99_MATH macro forces <cmath> to #undef some macros from <math.h> which would otherwise hide some glm functions like isnan(), isinf(), etc.

Somehow I've managed to compile it. Specifying the following options in the Application.mk did the trick:
APP_OPTIM := release
APP_STL := stlport_static
LOCAL_ARM_MODE := thumb
APP_ABI := armeabi armeabi-v7a
And, I think with the STLport, you can't use RTTI or Exceptions, so don't enable -frtti or -fexceptions in the Android.mk

Try building a small sample test app like this:
#include <glm/glm.h>
int main(int argc, char* argv[])
{
return 0;
}
Does that work?
If it does, then I'm going to bet that in your app, you have your glm.h include after some #define that has a symbol collision with a symbol that is used in glm. Your #define is probably making use of the sizeof keyword and that is being substituted in the glm lines that have errors.
A possible solution would be to move the glm.h include above any other #includes and/or #defines, if you make it the first thing in the file you may bypass the problem.
A better solution would be to try to avoid #defines and use inline functions whenever possible.
I hope this helps.

I'm running into the same issue when I try to compile glm against gnustl_static, but I don't have any issues when I try to compile with stlport_static. My only suggestion would be to try declaring an stlport dependency using LOCAL_STATIC_LIBRARIES in your shared library module.
Also, have you tried using stlport_shared? stlport has both shared and static libraries, whereas gnustl only has a static version (but supports exceptions/RTTI).

Related

errors when trying to build boost filesystem in cygwin: error: expected unqualified-id before '&&' token

I have cygwin 2.6 with gcc 5.4 installed. I installed boost.build and it seems to be working. However when I try to build the filesystem module, it fails with the error:
work#PC /lib/boost_1_62_0/libs/filesystem/example/test
$ ./build.sh
Compiling example programs...
tut4.cpp:40:18: error: expected unqualified-id before '&&' token
tut4.cpp:40:18: error: expected ';' before '&&' token
tut4.cpp:40:23: error: expected ';' before ':' token
tut4.cpp:40:23: error: expected primary-expression before ':' token
tut4.cpp:40:23: error: expected ')' before ':' token
tut4.cpp:40:23: error: expected primary-expression before ':' token
tut4.cpp:45:18: error: expected unqualified-id before '&&' token
tut4.cpp:45:18: error: expected ';' before '&&' token
tut4.cpp:45:23: error: expected ';' before ':' token
tut4.cpp:45:23: error: expected primary-expression before ':' token
tut4.cpp:45:23: error: expected ')' before ':' token
tut4.cpp:45:23: error: expected primary-expression before ':' token
tut4.cpp:40:21: error: label 'x' used but not defined
../../../../boost/system/error_code.hpp: At global scope:
../../../../boost/system/error_code.hpp:221:36: warning: 'boost::system::posix_category' defined but not
used [-Wunused-variable]
static const error_category & posix_category = generic_category();
../../../../boost/system/error_code.hpp:222:36: warning: 'boost::system::errno_ecat' defined but not use
d [-Wunused-variable]
static const error_category & errno_ecat = generic_category();
../../../../boost/system/error_code.hpp:223:36: warning: 'boost::system::native_ecat' defined but not us
ed [-Wunused-variable]
static const error_category & native_ecat = system_category();
path_info.cpp:41:13: error: 'element' does not name a type
path_info.cpp:44:3: error: expected ';' before 'cout'
path_info.cpp:49:62: error: expected ')' before ';' token
../../../../boost/system/error_code.hpp: At global scope:
../../../../boost/system/error_code.hpp:221:36: warning: 'boost::system::posix_category' defined but not
used [-Wunused-variable]
static const error_category & posix_category = generic_category();
../../../../boost/system/error_code.hpp:222:36: warning: 'boost::system::errno_ecat' defined but not use
d [-Wunused-variable]
static const error_category & errno_ecat = generic_category();
../../../../boost/system/error_code.hpp:223:36: warning: 'boost::system::native_ecat' defined but not us
ed [-Wunused-variable]
static const error_category & native_ecat = system_category();
What should I do to fix this?
I install b2 in /usr/local/ and set boost-build.jam inside /usr/local/share/boost-build to have those value:
# Copyright 2001, 2002 Dave Abrahams
# Copyright 2002 Rene Rivera
# Copyright 2003 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
boost-build src/kernel ;
using gcc : 5.4 : g++-5.4 : <cxxflags>=c++11 ; // Could it be that this settings is wrong or not applying during compilation?
I'm trying to follow instruction from official boost docs, which say I should go this way:
$ cd boost-root/libs/filesystem/example/test
$ ./setup.sh
Copying example programs...
$ ./build.sh
Compiling example programs...
$ ./tut1
Usage: tut1 path
Your problem caused by the fact, that you trying to build your code without C++11 support, as was already mentioned in comments.
I'm not a boost expert, so actually couldn't say why settings from your jam file didn't apply and what is a correct order of resolving such settings in boost env, since I prefer write commands myself. However it will be really nice, if some one will be able to explain your mistake with *.jam files.
But for fixing your problem just use something like:
b2 toolset=gcc cxxflags="-std=c++11" $* > build.log instead of ./build.sh and your project will compiled as expected.

after compiling gcc 5.4.0 what header folders to export

I have compiled gcc 5.4.0 (make, make install into non root folder) and have exported it to anther machine of the same base distro. however when I try to compile a hello world on the 2nd machine I get an error for stdio.h and that cascades to cstdio etc.
for gcc I used configure --prefix=/home/mybin --bindir=/home/mybin/bin --libdir=/home/mybin/lib etc for all available folders as per --help.
On the gcc compile machine it seems the source folder /home/tmp/gcc-5.4.0/libstdc++-v3/include was installed into the --includedir=/home/mybin/include folder with all the sub directories.
Searching for stdio.h on the 5.4.0 compiling machine I get several folders that contain a version of stdio.h.
/home/tmp/gcc-5.4.0/libstdc++-v3/include/tr1/stdio.h
/home/tmp/gcc-5.4.0/libstdc++-v3/include/c_compatibility/stdio.h
/home/tmp/gcc-5.4.0/fixincludes/tests/base/rtldef/stdio.h
/home/tmp/gcc-5.4.0/fixincludes/tests/base/stdio.h
/home/tmp/gcc-5.4.0/libssp/ssp/stdio.h
/home/tmp/gcc-5.4.0/gcc/testsuite/gcc.dg/cpp/usr/include/stdio.h
and the search of the --prefix=/home/mybin/ returns
/home/mybin/lib/gcc/x86_64-unknown-linux-gnu/5.4.0/include/ssp/stdio.h
/home/mybin/include/c++/5.4.0/tr1/stdio.h
/home/mybin/include/c_compatibility/stdio.h
So I copied the ``--prefix=/home/mybin/` folder to the new machine and tried to use
gcc -Wall -I/home/mybin/include/c_compatibility /home/myuser/test.c -o /home/myuser/hello
this gives
In file included from /home/myuser/test.c:3:0:
/home/mybin/include/c_compatibility/stdio.h:29:18: fatal error: cstdio: No such file or directory
BUT I do have
/home/mybin/include/c++/5.4.0/tr1/cstdio
/home/mybin/include/c++/5.4.0/cstdio
/home/mybin/include/c_std/cstdio
/home/mybin/include/c/cstdio
so updated to
gcc -Wall -I/home/mybin/include/c_compatibility -I/home/mybin/include/c_std /home/myuser/test.c -o /home/myuser/hello
In file included from /home/mybin/include/bits/c++config.h:482:0,
from /home/mybin/include/c_std/cstdio:44,
from /home/mybin/include/c_compatibility/stdio.h:29,
from /home/myuser/test.c:3:
/home/mybin/include/bits/os_defines.h:39:22: fatal error: features.h: No such file or directory
compilation terminated.
BUT I do have /home/mybin/include/c++/5.4.0/parallel/features.h
gcc -Wall -I/home/mybin/include/c_compatibility -I/home/mybin/include/c_std /home/myuser/test.c -o /home/myuser/hello
In file included from /home/mybin/include/bits/c++config.h:482:0,
from /home/mybin/include/c_std/cstdio:44,
from /home/mybin/include/c_compatibility/stdio.h:29,
from /home/myuser/test.c:3:
/home/mybin/include/bits/os_defines.h:39:22: fatal error: features.h: No such file or directory
compilation terminated.
gcc -Wall -I/home/mybin/include/c_compatibility -I/home/mybin/include/c_std -I/home/mybin/include/c++/5.4.0/parallel /home/myuser/test.c -o /home/myuser/hello
In file included from /home/mybin/include/bits/c++config.h:482:0,
from /home/mybin/include/c_std/cstdio:44,
from /home/mybin/include/c_compatibility/stdio.h:29,
from /home/myuser/_test.c:3:
/home/mybin/include/bits/os_defines.h:44:19: error: missing binary operator before token "("
#if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE)
^
In file included from /home/mybin/include/c_compatibility/stdio.h:29:0,
from /home/myuser/_test.c:3:
/home/mybin/include/c_std/cstdio:96:1: error: unknown type name 'namespace'
namespace std
^
/home/mybin/include/c_std/cstdio:97:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
{
^
/home/mybin/include/c_std/cstdio:155:1: error: unknown type name 'namespace'
namespace __gnu_cxx
^
/home/mybin/include/c_std/cstdio:156:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
{
^
/home/mybin/include/c_std/cstdio:181:1: error: unknown type name 'namespace'
namespace std
^
/home/mybin/include/c_std/cstdio:182:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
{
^
/home/myuser/_test.c:7:1: warning: return type defaults to 'int' [-Wimplicit-int]
main()
^
/home/myuser/test.c: In function 'main':
/home/myuser/test.c:9:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
printf("Heh now");
^
/home/myuser/_test.c:9:5: warning: incompatible implicit declaration of built-in function 'printf'
/home/myuser/_test.c:9:5: note: include '<stdio.h>' or provide a declaration of 'printf'
I have tried exporting LD config flags as well
How do I know what folder to export and to other machines made from the same base image so I can compile with this version. Why are the includes not being found or getting confused?
I am using centos7

Boost Asio GCC Link Error

I've just installed a clean vm with xubuntu 12.10 and I'm trying to port over some C++ code which works perfectly on Windows. First off, I've installed Virtualbox guest additions and GCC and I can compile code.
I've downloaded the boost library from the internet (boost_1_52) and I've dropped in the asio library from the asio website (boost_asio_1_4_8) and I've installed the multi-threading, shared link version using these instructions:
./bootstrap.sh --prefix=/usr &&
./b2 stage threading=multi link=shared
as root:
I know for a fact that boost works because I've been able to compile the test application here (linking with lboost_regex) and it works perfectly:
#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
std::string line;
boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );
while (std::cin)
{
std::getline(std::cin, line);
boost::smatch matches;
if (boost::regex_match(line, matches, pat))
std::cout << matches[2] << std::endl;
}
}
So I'm trying to build one of the ASIO examples, which I've built before with no problems on Windows. The files are here:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html
See:
boost_asio/example/serialization/client.cpp
boost_asio/example/serialization/connection.hpp
boost_asio/example/serialization/server.cpp
boost_asio/example/serialization/stock.hpp
I throw my compiler this:
gcc client.cpp -I /usr/include/boost -lboost_system -lboost_thread -lboost_serialization
Which gives me this error:
connection.hpp:75:35: error: template argument 1 is invalid
connection.hpp:75:35: error: template argument 2 is invalid
connection.hpp:75:44: error: invalid type in declaration before ‘;’ token
connection.hpp:76:13: error: request for member ‘push_back’ in ‘buffers’, which is of non-class type ‘int’
connection.hpp:76:23: error: ‘asio’ is not a class or namespace
connection.hpp:77:13: error: request for member ‘push_back’ in ‘buffers’, which is of non-class type ‘int’
connection.hpp:77:23: error: ‘asio’ is not a class or namespace
connection.hpp:78:5: error: ‘asio’ is not a class or namespace
connection.hpp:78:23: error: ‘socket_’ was not declared in this scope
connection.hpp: In member function ‘void s11n_example::connection::async_read(T&, Handler)’:
connection.hpp:87:15: error: ‘asio’ does not name a type
connection.hpp:87:31: error: expected unqualified-id before ‘&’ token
connection.hpp:87:31: error: expected ‘)’ before ‘&’ token
connection.hpp:87:31: error: expected initializer before ‘&’ token
connection.hpp:90:5: error: ‘asio’ has not been declared
connection.hpp:90:22: error: ‘socket_’ was not declared in this scope
connection.hpp:90:31: error: ‘asio’ has not been declared
connection.hpp:91:21: error: ‘f’ was not declared in this scope
connection.hpp:92:17: error: ‘asio’ has not been declared
client.cpp: At global scope:
client.cpp:26:10: error: ‘asio’ has not been declared
client.cpp:26:26: error: expected ‘)’ before ‘&’ token
client.cpp:43:29: error: ‘asio’ does not name a type
client.cpp:43:45: error: expected unqualified-id before ‘&’ token
client.cpp:43:45: error: expected ‘)’ before ‘&’ token
client.cpp:43:35: error: expected ‘;’ at end of member declaration
client.cpp:43:47: error: ISO C++ forbids declaration of ‘e’ with no type [-fpermissive]
client.cpp:43:47: error: expected ‘;’ at end of member declaration
client.cpp:43:48: error: expected unqualified-id before ‘)’ token
client.cpp:125:1: error: expected ‘}’ at end of input
client.cpp:125:1: error: expected unqualified-id at end of input
client.cpp:125:1: error: expected ‘}’ at end of input
I'm really confused, its as if I've not built boost or I'm missing another link. I've also tried linking with Winsock, with no results. Please help!
Cheers
You are using gcc and g++ interchangeably. The line which doesn't work uses gcc, but the line which works uses g++. Using g++ instead of gcc may effect which default include path is used. Your initial error was not linking. It was compiling. Also, if you use the boost version, asio namespace is not asio. It's boost::asio.
Looks like boost/asio.hpp didn't get included correctly.
I don't remember exactly what the prefix option does, but I think your problem may be somewhere in there. The boost directory may not be in /usr/include/boost, but instead possibly /usr/boost.
That's one possibility. The second is that, instead of passing /usr/include/boost, you need to pass /usr/include, i.e.
gcc client.cpp -I /usr/include -lboost_system -lboost_thread -lboost_serialization
If you look at the example files, e.g. the connection.cpp example, it includes boost/asio.hpp. The boost/ part refers to a folder that should be looked for by the compiler in the include path(s) you specify using -I. So if you specified /usr/include/boost, the compiler is going to look for /usr/include/boost/boost/asio.hpp (notice the 2 occurrences of boost).
I think I've fixed the problem now. Using bjam and the auto-installer doesn't seem to accomplish much (it won't resolve to those paths for some reason).
Anyway, I downloaded the ASIO source code (non-boost this time) and put that in a directory on my desktop. In a similar fashion to how I do it on windows in Visual Studio, I managed to get it to link:
g++ client.cpp -I/home/devbox/desktop/asio-1.5.3/include - L/home/devbox/Desktop/boost_1_53_0/stage/lib -lboost_system -lboost_thread -lboost_serialization -o test
Cheers all

Compile error: g++-v4/tr1_impl/type_traits(226): error: expected an identifier

The error is generated when a Makefile attempts to compile a .cu (CUDA) file.
We were able to compile this by itself with an .hpp made specifically for it. When we try to get it to compile under an existing header with it's own a .cpp (in other words .hpp, .cpp plus a .cu), we keep getting this strange compilation error.
For the sake of readability, all the follow messages where prefixed with this directory:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.4/include/g++-v4/tr1_impl/
Messages:
type_traits(226): error: expected an identifier
type_traits(227): error: expected a ")"
type_traits(227): error: a template argument list is not allowed in a declaration of a primary template
type_traits(229): error: expected an identifier
type_traits(230): error: expected a ")"
type_traits(230): error: a template argument list is not allowed in a declaration of a primary template
type_traits(232): error: expected an identifier
type_traits(233): error: expected a ")"
type_traits(233): error: expected a ">"
type_traits(235): error: expected an identifier
type_traits(236): error: expected a ")"
type_traits(236): error: expected a ">"
type_traits(238): error: expected an identifier
type_traits(239): error: expected a ")"
type_traits(239): error: expected a ">"
type_traits(241): error: expected an identifier
type_traits(242): error: expected a ")"
type_traits(242): error: expected a ">"
type_traits(244): error: expected an identifier
type_traits(245): error: expected a ")"
type_traits(245): error: expected a ">"
type_traits(247): error: expected an identifier
type_traits(248): error: expected a ")"
type_traits(248): error: expected a ">"
Is it possible to have a single .hpp with a .cu and a .cpp behind it?
Yes it is possible, and in fact very common, but if the .hpp includes files that nvcc can't build, then you can't include it from the .cu.
You could use #ifndef __CUDACC__ around those files so they don't get included when compiling the .cu with nvcc.

C++ Compilation error against GNU's Multi-precision library

I get the following error when compiling this third-party library (called azove 2.0) which relies on the GNU Multi-precision library:
> make
g++ -Wall -O3 -DFIX_NUMBER_OF_SIGMDDNODE_SONS -DUSE_TIMER -I. -c conBDD.cpp -o conBDD.o
In file included from conBDDnode.hpp:27,
from conBDD.hpp:25,
from conBDD.cpp:22:
/usr/include/gmpxx.h: In destructor ‘__gmp_alloc_cstring::~__gmp_alloc_cstring()’:
/usr/include/gmpxx.h:2096: error: ‘strlen’ was not declared in this scope
conBDD.cpp: In member function ‘void conBDD::build()’:
conBDD.cpp:61: error: ‘numeric_limits’ was not declared in this scope
conBDD.cpp:61: error: expected primary-expression before ‘int’
conBDD.cpp:61: error: expected `;' before ‘int’
conBDD.cpp:68: error: expected primary-expression before ‘int’
conBDD.cpp:68: error: expected `;' before ‘int’
make: *** [conBDD.o] Error 1
I have tried adding either and both of the following lines
#include <cstdlib>
using std::strlen;
to conBDD.cpp, but the error persists.
I can't tell if this is an error comes from GNU's Multi-precision library or from Azove. Any pointers would be greatly appreciated.
I would start by apportioning blame. Create an empty cpp file, say test.cpp, in your project and include only the offending gmpxx.h file. If you can compile test cpp, GMP is off the hook. Then try including only the offending azove header. If you can compile the azove header in an otherwise empty file, azove is off the hook and something you are including/defining is interfering with them. Once you have narrowed down the source of the problem you should find it easier to fix.