I have some open source library files in my project (e.g: http://nothings.org/stb_vorbis/stb_vorbis.c). -Wall option is enabled in my Android.mk file. During compilation several warnings are generated in stb_vorbis.c.
warning: unused variable <var>
warning: statement with no effect
warning: <var> defined but not used
warning: <var> may be used uninitialized in this function
For some reason I do not want to modify stb_vorbis.c but still want the -Wall option to be available for my own source files. Is there any way to disable -Wall option for specific files/folder ?
Is there any way to disable -Wall option for specific files/folder ?
I do not believe there is any gcc option that could be used to achieve this. You need to change your Makefile that you used to compile the problematic source files.
You could do something like
CFLAGS:=$(filter-out -Wall, $(CFLAGS))
in the Makefile for stb_vorbis, if your make supports filter-out function.
Also you could write a specific rule for that stb_vorbis.c:
STB_VOBIS_CFLAGS:=$(filter-out -Wall, $(CFLAGS))
stb_vorbis.o: stb_vorbis.c ...
$(CC) $(STB_VOBIS_CFLAGS) -o $# -c $<
Although there's no way to turn off -Wall with one option, you can turn off specific warnings in GCC, using the -Wno-* for warning *. So, for example, to suppress the unused variable warning you can add -Wno-unused-variable. See http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html for more information on different warning options.
So for example you could use target-specific variables, like:
stb_vorbis.c: CFLAGS += -Wno-unused-variable
Using target-specific variables you can append the -w option to inhibit all warning messages for stb_vorbis.c file:
stb_vorbis.o: CFLAGS += -w
or for an entire directory:
third_party/%.o: CFLAGS += -w
A general rule of thumb is that if you have two or more mutually exclusive options, gcc will generally take later options over earlier ones.
using -isystem was the working solution for me.
For example, instead of -IC:\\boost_1_52_0, say -isystem C:\\boost_1_52_0.
Described in detail in the following thread:
How do you disable the unused variable warnings coming out of gcc in 3rd party code I do not wish to edit?
Thank you #lee-duhem for your kind and useful suggestions.
Related
so I'm trying to figure out how to build ICU for android. Initially I tryed to make it with standalone tool-chain, and after some battles I was able to do that at least for x86_64 arch (didn't try with others). However I don't want to have fully custom build system so I decide to figure out how to make it with prebuild toolchains. And I found that it's behave very different - which is very strange. So this was my command when I actually try to configure ICU with standalone tool-chain:
icu/source/configure --disable-shared --enable-static --disable-dyload
--disable-extras --disable-tests --disable-samples --prefix=/icu/build --host=x86_64-linux-android --with-cross-build=/toplay/icu/icu_linux CC=/custom_toolchain/bin/clang
CXX=/custom_toolchain/bin/clang++
LD=/custom_toolchain/bin/x86_64-linux-android-ld
AR=/custom_toolchain/bin/x86_64-linux-android-ar
CFLAGS="-fPIC -DANDROID -fdata-sections -ffunction-sections"
CXXFLAGS="-fPIC -DANDROID -frtti -fno-exceptions -fdata-sections
-ffunction-sections"
So, having all the same command, but only changing compilers and tools from prebuild toolchain which will look like:
icu/source/configure --disable-shared --enable-static --disable-dyload
--disable-extras --disable-tests --disable-samples --prefix=/icu/build --host=x86_64-linux-android --with-cross-build=/toplay/icu/icu_linux CC=/ndk-bundle/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/clang
CXX=/ndk-bundle/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/clang++
LD=/ndk-bundle/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-ld
AR=/ndk-bundle/toolchains/x86_64-4.9/prebuilt/linux-x86_64//bin/x86_64-linux-android-ar
CFLAGS="-fPIC -DANDROID -fdata-sections -ffunction-sections"
CXXFLAGS="-fPIC -DANDROID -frtti -fno-exceptions -fdata-sections
-ffunction-sections"
I get very different configure step results. Which I placed there: (TLDR: main diff: in prebuild tool-chain case system can't understand that it's cross-compile mode, it's find nl_langinfo, strtod_l which isn't available in android) And if standalone tool-chain initially could build ICU, in prebuild case build process eventually broke.
So my question: what is the difference between compilers and tools in prebuild and standalone case and what flags/settings I need to add to make it work in prebuild case?
This is the expected behavior. I've answered this on our bugtracker.
Our Clang defaults to targeting x86 Linux, not any flavor of Android. Setting up your target flags is one of the many things standalone toolchains do.
I'm not really sure what problem you're trying to solve. Whatever you get working with autoconf is going to essentially be a cobbled together standalone toolchain. Standalone toolchains exist entirely for dealing with this kind of scenario.
To answer your specific question here:
what is the difference between compilers and tools in prebuild and standalone case and what flags/settings I need to add to make it work in prebuild case?
Standalone toolchains are the prebuilt toolchains with a different directory layout (so the compilers can infer the locations of binutils, the sysroot, and the STL) and a few default flags (like -target for Clang). If you were to get this working, you'd have just reinvented this wheel (possibly by using -gcc-toolchain and a bunch of --sysroot, -isystem, -L stuff rather than changing the directory structure.
In case "why doesn't this work out of the box?" is a follow up question, remember that in Android you have many architectures, even more target versions of the OS, and a handful of STLs to choose from. Neither Clang nor GCC can currently be set up in a way that it can deal with all of Android's variations (long term I do expect to change that, but that's quite a ways down the road).
I am trying to build the C++ POCO library for an Android target in a fresh Ubuntu that I just installed for that.
I have installed the Android NDK in /home/user/dev/Android/android-ndk-r9-x86 and added the path to the NDK in the environement variables using :
export ANDROID_NDK_ROOT=/home/user/dev/Android/android-ndk-r9-x86
To build the libraries I first move to the root directory of the POCO library, and configure it using :
./configure --omit=NetSSL_OpenSSL,Crypto,Data/ODBC,Data/MySQL --static --config=Android
So that it compiles static .a libraries, doesn't compile the modules I don't want and compiles for an Android target.
But than calling make causes the following error :
user#user-VirtualBox:~/dev/Lib/POCO/poco-1.6.1$ make
make -C /home/user/dev/Lib/POCO/poco-1.6.1/Foundation
make[1]: Entering directory `/home/user/dev/Lib/POCO/poco-1.6.1/Foundation'
** Compiling src/ArchiveStrategy.cpp (debug, static)
arm-linux-androideabi-g++ -Iinclude -I/home/user/dev/Lib/POCO/poco-1.6.1/CppUnit/include -I/home/user/dev/Lib/POCO/poco-1.6.1/CppUnit/WinTestRunner/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Foundation/include -I/home/user/dev/Lib/POCO/poco-1.6.1/XML/include -I/home/user/dev/Lib/POCO/poco-1.6.1/JSON/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Util/include -I/home/user/dev/Lib/POCO/poco-1.6.1/Net/include -mthumb -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions -DPOCO_BUILD_HOST=user-VirtualBox -DPOCO_ANDROID -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_WSTRING -DPOCO_NO_SHAREDMEMORY -g -D_DEBUG -c src/ArchiveStrategy.cpp -o /home/user/dev/Lib/POCO/poco-1.6.1/Foundation/obj/Android/armeabi/debug_static/ArchiveStrategy.o
sh: 1: arm-linux-androideabi-g++: not found
make[1]: *** [/home/user/dev/Lib/POCO/poco-1.6.1/Foundation/obj/Android/armeabi/debug_static/ArchiveStrategy.o] Error 127
make[1]: Leaving directory `/home/user/dev/Lib/POCO/poco-1.6.1/Foundation'
make: *** [Foundation-libexec] Error 2
Make seems unable to find the compiler used for Android, and I have no idea why ? What am I missing ? Did i forget something when "installing" the NDK ?
Thank you.
The error you're getting is caused by a missing toolchain invocation - rather, the arm-linux-androideabi-g++ command/executable/binary was nowhere to be found.
Luckily, we can get around that by installing the Standalone toolchain - that one actually has the exact thing you're missing, a general purpose arm-linux-androideabi cross-compiler instead of some other, a bit more obscure, vendor/platform-specific crosscompiler/toolchain, such as armv7a-marvell-linux-android which is what marvell uses, or arm-linux-android which is what Clang uses. For more info on Clang, look here. I could be wrong though and that Clang actually produces a arm-linux-androideabi toolchain out of the box, but I'm unsure. I know you can use it easily, I'm just unsure if it can be used "straight out of the box" which is what you're looking for. The "rest of the work" is just a few path exports - but still. We're aiming for the laziest solution here.
The standalone toolchain should be quite sufficient for your task, so try using it as much as possible over any other cross-compilation solutions.
However, if you're feeling adventurous - you're free to make your own cross-compiler (or the whole toolchain!) using the crosstool-ng tool. However, try to stick with the Linaro libc branch; personal experience showed me that one somehow works the best and causes the least amount of problems/time wasted.
Also, make sure you download the right one for your architecture (arch) and OS, 32bit vs 64bit matters here as well. After a lengthy discussion, we realized it was a "32bit vs 64bit" problem.
Here's a link to read more about it.
I found that using ndk-build to build an libxxx.so doesn't need -fPIC in LOCAL_CFLAGS. Does that mean that position-independent code isn't necessary for android or that -fPIC is concealed as a default option which you don't need to add again or something else like that? What's the truth?
I am having trouble to get up and running with Google test. I have read the suggested steps from Google, I also looked a previous post, and read some other examples, but it doesn't clear much things up.
To keep things simple, I am trying the suggested example from Google test that is available from the directory in the Android ndk - sample1:
// main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "gtest/gtest.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
testing::InitGoogleTest(&argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/factorial/main.qml"));
viewer.showExpanded();
return RUN_ALL_TESTS();
}
// sample1_unittest.cpp
#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
// Tests factorial of 0.
TEST(FactorialTest, Zero) {
EXPECT_EQ(1, Factorial(0));
}
The files sample1.h, sample1.cpp are also in the project, which contain the factorial function. Google test was equally informed to the project file - factorial.pro:
INCLUDEPATH +=
/opt/android-studio/ndk/sources/third_party/googletest/googletest/include
When I press [Build > Build Project "factorial"] it gets the following error:
main.cpp:8: error: undefined reference to 'testing::InitGoogleTest(int*, char**)'
sample1_unittest.cpp:17: error: undefined reference to 'testing::Test::Test()'
I am working with Ubuntu, QtCreator, Android and C++. Indeed I have spent already 3 days mocking around, but getting not much anywhere so far. Thus, I am posting here in hope some guru may give any hint on this. Any help will be mostly appreciated.
It seems you haven't built Google Test from what you describe. You need to compile the project into a library and then link against it. If you have CMake installed, then you have two options:
Use CMake's GUI (it's fairly intuitive) to generate the build system files, and then use those as usual (e.g. if you generate a Visual Studio solution, open the .sln file and build the project).
Use the command line to do the same thing; essentially you just create a new directory and do cmake <path-to-google-test> inside of it. The rest is the same.
You could also build the library by yourself. The distribution contains a folder named fused-src which should contain at least two files: gtest_main.cpp and gtest-all.cpp. Compile those files and you're done. You need to generate two libraries here: gtest out of gtest-all.cpp and gtest_main out of gtest_main.cpp.
Another alternative would be to get already built libraries. I've never searched for them, but they might be out there.
Try something like this:
$ g++ -I $GTEST_HOME/include -L $GTEST_HOME/lib -lgtest -lgtest_main -lpthread test.cpp
For more details:
How to setup googleTest as a shared library on Linux
If it still doesn't work, may find interesting to consider to use Makefile:
# A sample Makefile for building Google Test and using it in user
# tests. Please tweak it to suit your environment and project. You
# may want to move it to your project's root directory.
#
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make clean - removes all files generated by make.
# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.
# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ..
# Where to find user code.
USER_DIR = ../samples
# Flags passed to the preprocessor.
# Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread
# All tests produced by this Makefile. Remember to add new tests you
# created to the list.
TESTS = sample1_unittest
# All Google Test headers. Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
# House-keeping build targets.
all : $(TESTS)
clean :
rm -f $(TESTS) gtest.a gtest_main.a *.o
# Builds gtest.a and gtest_main.a.
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $# $^
gtest_main.a : gtest-all.o gtest_main.o
$(AR) $(ARFLAGS) $# $^
# Builds a sample test. A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.
sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
$(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $#
If you have to use Makefile to get gtest working, you probably may need to adjust the given template for your case, as you intend to build it to use with Android.
We noticed that some dead functions are not removed from the generated shared object file (.so) that is built as release (via "ndk-build" without any parameter).
To prove that we introduced a dummy function that is definitely not called anywhere (and is also not exported since the default visibility is already set to "hidden" for the whole .so). Somehow the symbol of the dummy function still exists and we can see it by using "nm" against the generated .so.
We are using NDK r8d on Linux 11.10.
Is there any specific compiler/linker flags that we need to apply to Android.mk in order to get the dead code removed?
Thank you!
Removing dead functions can greatly reduce the binary size too. For this, change C and C++ compilation flags and the linker flags in Android.mk.
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections
LOCAL_CFLAGS += -ffunction-sections -fdata-sections
LOCAL_LDFLAGS += -Wl,--gc-sections
Also, the visibility features in GCC can be of help.
http://gcc.gnu.org/wiki/Visibility