I'm using Gradle and CMake to compile an Android NDK project from the command line. Previously, I was using Ant and ndk-build but I'm trying to migrate the project completely to Gradle and CMake.
In my build.gradle I have the following lines to invoke CMake:
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
Now how can I force CMake to print all compiler calls to the console before it makes them? Specifically, I want to see just how CMake runs the compiler and linker.
I've already tried the following, all to no avail:
1) In my CMakeLists.txt I have put the following line:
set(CMAKE_VERBOSE_MAKEFILE on)
Didn't have any effect.
2) I have started the build like this:
./gradlew build --info
Gradle printed some stuff, but no compiler calls.
3) And like this:
./gradlew build --debug
Gradle printed lots of stuff, but no compiler calls.
So none of those three attempts did what I wanted which makes me wonder how can I see how CMake runs clang on my individual source files?
Disclaimer: the following description applies to the version of Android Gradle Plugin (AGP) that was the latest at the time I updated this Answer (aug '21). If you are curious, have a look at the history of edits.
As #artyomd has noticed, for AGP 4.2.0 and higher, you can set android.native.buildOutput gradle property to verbose to force cmake logging.
In Android Studio, gradle creates directory .cxx under the module root, for each module that has NDK integration, via CMake or ndk-build.
For CMake, the gradle plugin is quite verbose. For each build variant it creates separate subdirectory, e.g. .cxx/cmake/debug/x86 or .cxx/cmake/release/armeabi-v7a, etc.
Each directory contains some useful files: cmake_build_command.txt describes the actual parameters passed to CMake; android_gradle_build.json shows what parameters the gradle plugin derived for your binaries; from build.ninja you can deduce the how these parameters were applied for each compilation or linkage step.
For ndk-build, the android_gradle_build.json file is also quite useful. ndkBuild_build_command.txt lists all parameters passed to ndk-build command, and ndkBuild_build_output.txt is the unabridged output of that command. You can easily add V=1 to the arguments, e.g.
externalNativeBuild {
ndkBuild {
cppFlags "-std=c++11"
arguments "APP_STL=c++_static", "APP_OPTIM=release", "NDK_DEBUG=0", "V=1"
abiFilters "armeabi-v7a"
}
}
For CMake, the relevant argument is "-DCMAKE_VERBOSE_MAKEFILE=ON" (see explanation
and alternatives):
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
arguments "-DCMAKE_VERBOSE_MAKEFILE=ON"
abiFilters "armeabi-v7a"
}
}
But, as #user7860670 has observed, the recent versions of AGP ignore this flag.
Without CMAKE_VERBOSE_MAKEFILE, the Gradle Console displays:
:app:externalNativeBuildDebug
Build native-lib armeabi-v7a
[1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
[2/2] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so
With "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON", I used to get tons of output:
:app:externalNativeBuildDebug
Build native-lib armeabi-v7a
[1/2] /Users/alex/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=armv5te-none-linux-androideabi --gcc-toolchain=/Users/alex/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 --sysroot=/Users/alex/Library/Android/sdk/ndk-bundle/platforms/android-14/arch-arm -Dnative_lib_EXPORTS -isystem /Users/alex/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include -isystem /Users/alex/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -isystem /Users/alex/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include/backward -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info -fPIC -MD -MT CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -MF CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o.d -o CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -c /Users/alex/test/egl/app/src/main/cpp/native-lib.cpp
[2/2] : && /Users/alex/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=armv5te-none-linux-androideabi --gcc-toolchain=/Users/alex/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 --sysroot=/Users/alex/Library/Android/sdk/ndk-bundle/platforms/android-14/arch-arm -fPIC -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -llog -lEGL -lGLESv2 -lm "/Users/alex/Library/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a" "-latomic" && :
Not anymore. As far as I know, this information is filtered by Gradle Plugin and is completely lost. I can recover it only manually: run the command
/Users/alex/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake --build app/.cxx/cmake/debug/armeabi-v7a
You can use the Terminal window (Alt-F12) of Android Studio. This will invoke ninja with -v flag when -DCMAKE_VERBOSE_MAKEFILE=ON was used to sync C++ with Gradle.
Note that the expected file .cxx/cmake/debug/armeabi-v7a/cmake_build_output.txt does not contain interesting information (unless you have problems with CMake configuration per se).
P.S. with this 3.6.0 Gradle Plugin, if you have a compilation error, then the whole command line for compiler is shown in Build Output window, no matter whether you set CMAKE_VERBOSE_MAKEFILE or not. Actually, twice: once, in black on white (I don't use the dark theme), second time, in brown on white, after
FAILURE: Build failed with an exception.
* What went wrong:
As an ugly workaround I've replaced ninja with my own executable that passes all the commands to the real ninja executable appending "-v"
Try to update your gradle version.
Related
I noticed that in the default release configuration, qmake (qmake 3.1, qt 5.9.5 - whatever is installed on my Ubuntu build box) passes -Wl,O1 to g++ when linking. So the linking command line looks like
g++ -Wl,-O1 -flto -O2 -o program program.o lib1.a lib2.a ...
where -flto -O2 are the options that I'm passing via QMAKE_LFLAGS_RELEASE to enable LTO.
Now the question: why qmake has this -Wl,-O1 option and is it going to interfere with LTO?
QMake passes -Wl,O1, because it is meant to be a good default.
It will not harm LTO, because your -O2 option comes later and overrides the -Wl,O1.
From g++'s man page:
If you use multiple -O options, with or without level numbers, the
last such option is the one that is effective.
You can remove the -Wl,-O1 from your Makefile by specifying
QMAKE_LFLAGS_RELEASE -= -Wl,-O1
Im using poky version of yocto, and adding zbar library in my yocto build. I found a readymade recipe at http://cgit.openembedded.org/meta-openembedded/tree/meta-oe/recipes-support/zbar/zbar_0.10.bb and modified it a bit to get working with poky. I got it working fine with imagemagick, and the compiled zbarimg works on the target board.
The modified recipe is available here: http://paste.ubuntu.com/25725000/
When I proceed configuring python support (--with-python) to the build, some dependency issues crept up, which Im unable to resolve.
It appears as if the compiler doesn't find the appropriate headers, since the include paths don't contain appropriate folder.
The full compiler command is:
arm-poky-linux-gnueabi-libtool: compile: arm-poky-linux-gnueabi-gcc -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7 --sysroot=/home/jlumme/imx_build/build-x11-pico-imx6ul/tmp/sysroots/pico-imx6ul-emmc -DHAVE_CONFIG_H -I. -I/home/jlumme/imx_build/build-x11-pico-imx6ul/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/zbar/0.10-r0/zbar-0.10 -I./include -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -I/usr/include/python2.7 -I/usr/include/python2.7 -I/home/jlumme/imx_build/build-x11-pico-imx6ul/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/zbar/0.10-r0/zbar-0.10/include -Wall -Wno-parentheses -O2 -pipe -g -feliminate-unused-debug-types -c /home/jlumme/imx_build/build-x11-pico-imx6ul/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/zbar/0.10-r0/zbar-0.10/python/symbol.c -fPIC -DPIC -o python/.libs/python_zbar_la-symbol.o
You can see that sysroot variable is set, and it appears like the right location, and there is /usr/include/python2.7 there, though its pointing right at the host system include path.
There is a warning from compiler: cc1: warning: include location "/usr/include/python2.7" is unsafe for cross-compilation [-Wpoison-system-directories] which I don't know why it happens, but it seems like the python2.7 folder is appropriately looked at, just not under the sysroot (my host system doesn't have /usr/lib/python2.7)
If I go to the sysroot include (/home/jlumme/imx_build/build-x11-pico-imx6ul/tmp/sysroots/pico-imx6ul-emmc/usr/include/) folder, I can see that it has a subfolder python2.7. If under this usr/include folder I add a symlink Python.h -> python2.7/Python.h, the compiler will complain about the next header file which is not found.
So to me it seems, all I should do is add the appropriate 'sysroot' + usr/include/python2.7 as include search folder it would compile happily - but Im not sure how..
The full compilation log is available here: http://paste.ubuntu.com/25725014/
This is a bug in the zbar configure script.
Try inheriting pythonnative so the configure script can run a compatible Python to know where to look.
Running the build script from ELLCC results in this error
gcc -DHAVE_CONFIG_H -I. -I../../../src/binutils/binutils -I. -I../../../src/binutils/binutils -I../bfd -I../../../src/binutils/binutils/../bfd -I../../../src/binutils/binutils/../include -I./../intl -DLOCALEDIR="\"/Library/Caches/Homebrew/ellcc--svn-HEAD/lib/share/locale\"" -Dbin_dummy_emulation=bin_vanilla_emulation -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -Wno-unused-value -Wno-shadow -MT nm.o -MD -MP -MF .deps/nm.Tpo -c -o nm.o ../../../src/binutils/binutils/nm.c
../../../src/binutils/binutils/nm.c:1690:28: error: 'sbrk' is deprecated
[-Werror,-Wdeprecated-declarations]
char *lim = (char *) sbrk (0);
^
/usr/include/unistd.h:582:7: note: 'sbrk' declared here
void *sbrk(int);
^
The following compilers have been used with the same result:
gcc 4.8
llvm-gcc 2.8
llvm 3.3
I had the same issue compiling binutils-2.24 on Mac OSX Mavericks 13.2.0 with clang. Thanks to Richard Pennington's suggestion, I was able to get binutils to compile by specifying a few other -Wno-error arguments to gcc by setting CFLAGS before running configure. Namely, these are the commands I ran to build and install binutils:
CFLAGS="-Wno-error=deprecated-declarations -Wno-error=unused-variable -Wno-error=unused-function" ./configure --prefix=/usr/local/toolchain-arm-linux-elf --target=arm-linux-elf
make
make install
EDIT: I just noticed that the binutils configure script accepts an --disable-werror argument, which disables gcc turning warnings into errors, and removes the need for the settings CFLAGS. With this argument, building could be done as follows:
./configure --prefix=/usr/local/toolchain-arm-linux-elf --target=arm-linux-elf --disable-werror
make
make install
This error is occurring because sbrk() is deprecated on OSX, -Werror is enabled for the binutils build, and the compiler (in this case "gcc" is an alias for clang) rightly complains about the use of sbrk(). I'll be looking into eliminating this error this weekend when I won't have to be at my day job. ;-)
I looked into it a bit more. This happened because the latest version of OS X (Mavericks) uses clang as its compiler and /usr/include/unistd.h has a deprecated declaration of sbrk().
The solution was to add a -Wno-error=deprecated-declarations option to the CFLAGS for binutils. I also had to make a few other changes to complete the Max OS build. You can find the latest stuff in the ELLCC subversion tree.
I'm using GCC 4.7.2 and LD 2.23 but when I add -flto to my compile options my compile time increases by over 20%! The manual seems to indicate that -fuse-linker-plugin is needed for the optimization to work. It also says that it's enabled by default with -flto but when I add it explicitly I see the following error in the link command:
g++: error: -fuse-linker-plugin is not supported in this configuration
According to manual, it should be supported by LD 2.21 or greater. Any idea why I'm getting this error? For reference here are examples of my full compile commands:
g++ -Wall -pipe -O3 -flto -fno-strict-aliasing -mtune=generic --no-exceptions -fPIC -c some.cc
g++ -o exec -Xlinker some1.o some2.o -static some1.a some2.a -Wl,--wrap,open -flto -fuse-linker-plugin
Running 'ld --help | grep plugin' shows "-plugin" option so I don't understand why GCC is complaining:
-plugin PLUGIN Load named plugin
-plugin-opt ARG Send arg to last-loaded plugin
Link time optimizations aren't supposed to reduce compilation time, but optimize runtime of your program.
#options, just add "-flto -fuse-linker-plugin" to your CFLAGS(or CXXFLAGS for c++) and LDFLAGS and it should work just fine.
#gold: ld --version is probably gonna return gnu LD, to switch to gold, make ld symlink which ld point to which ld.gold
e.g. ln -s /usr/bin/ld.gold /usr/bin/ld
I am using GCC for ARM (Red Suite 4 NXP). I am compiling static library files (.a) that are used for a final application. I need to configure the project so any developer can produce the exact same static library output. (This is mainly so a new developer can verify they have their setup correct.) I have two copies of my project (two checkouts from SVN). When I build with each, I notice some absolute path information in the static library .a output files. This means that SVN detects as a change. I'm using the ar -D (deterministic) option already. Are there any other options to remove path information? I tried gcc -s but this didn't work (it appears this is only for final executable, not libraries)
I don't know where/why the absolute paths are in the .a, but I can provide more information if someone can point me in the right direction.
I've looked at the strip utility man pages (haven't tried it yet), would this remove this path information?
Also, I am using Red Suite to manage the project, so I'm trying to do things the Red Suite way (and to let it do its thing). However, if there is a gcc or ar option I need to adjust, I do know how to do that. I just don't know what option to change.
Here is the build console output. This causes the absolute path of my project to be included into the resulting .a. That is what I am trying to fix.
**** Build of configuration Release for project lib_touch ****
make -j all
Building file: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/Touch.c
Building file: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchCalibration.c
Building file: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchPoint.c
Building file: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchEventQueue.c
Invoking: MCU C Compiler
Invoking: MCU C Compiler
arm-none-eabi-gcc -D__REDLIB__ -DNDEBUG -D__CODE_RED -D__USE_CMSIS=CMSISv2p00_LPC177x_8x -I"C:\Users\my_user_name\Documents\My Project Verification build\src\build\RedSuite4NXP\CMSISv2p00_LPC177x_8x\inc" -I../../../../board -I../../../../board/lpc1788 -I../../../../communication -I../../../../events -I../../../../geometry -I../../../../graphics -I../../../../hmilogic/include -I../../../../sound -I../../../../util -O3 -Wall -Werror -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -std=gnu99 -mcpu=cortex-m3 -mthumb -MMD -MP -MF"touch/Touch.d" -MT"touch/Touch.d" -o"touch/Touch.o" "C:/Users/my_user_name/Documents/My Project Verification build/src/touch/Touch.c"
arm-none-eabi-gcc -D__REDLIB__ -DNDEBUG -D__CODE_RED -D__USE_CMSIS=CMSISv2p00_LPC177x_8x -I"C:\Users\my_user_name\Documents\My Project Verification build\src\build\RedSuite4NXP\CMSISv2p00_LPC177x_8x\inc" -I../../../../board -I../../../../board/lpc1788 -I../../../../communication -I../../../../events -I../../../../geometry -I../../../../graphics -I../../../../hmilogic/include -I../../../../sound -I../../../../util -O3 -Wall -Werror -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -std=gnu99 -mcpu=cortex-m3 -mthumb -MMD -MP -MF"touch/TouchCalibration.d" -MT"touch/TouchCalibration.d" -o"touch/TouchCalibration.o" "C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchCalibration.c"
Invoking: MCU C Compiler
Invoking: MCU C Compiler
arm-none-eabi-gcc -D__REDLIB__ -DNDEBUG -D__CODE_RED -D__USE_CMSIS=CMSISv2p00_LPC177x_8x -I"C:\Users\my_user_name\Documents\My Project Verification build\src\build\RedSuite4NXP\CMSISv2p00_LPC177x_8x\inc" -I../../../../board -I../../../../board/lpc1788 -I../../../../communication -I../../../../events -I../../../../geometry -I../../../../graphics -I../../../../hmilogic/include -I../../../../sound -I../../../../util -O3 -Wall -Werror -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -std=gnu99 -mcpu=cortex-m3 -mthumb -MMD -MP -MF"touch/TouchEventQueue.d" -MT"touch/TouchEventQueue.d" -o"touch/TouchEventQueue.o" "C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchEventQueue.c"
Finished building: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/Touch.c
arm-none-eabi-gcc -D__REDLIB__ -DNDEBUG -D__CODE_RED -D__USE_CMSIS=CMSISv2p00_LPC177x_8x -I"C:\Users\my_user_name\Documents\My Project Verification build\src\build\RedSuite4NXP\CMSISv2p00_LPC177x_8x\inc" -I../../../../board -I../../../../board/lpc1788 -I../../../../communication -I../../../../events -I../../../../geometry -I../../../../graphics -I../../../../hmilogic/include -I../../../../sound -I../../../../util -O3 -Wall -Werror -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -std=gnu99 -mcpu=cortex-m3 -mthumb -MMD -MP -MF"touch/TouchPoint.d" -MT"touch/TouchPoint.d" -o"touch/TouchPoint.o" "C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchPoint.c"
Finished building: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchEventQueue.c
Finished building: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchCalibration.c
Finished building: C:/Users/my_user_name/Documents/My Project Verification build/src/touch/TouchPoint.c
Building target: lib_touch.a
Invoking: MCU Archiver
arm-none-eabi-ar -rD "lib_touch.a" ./touch/Touch.o ./touch/TouchCalibration.o ./touch/TouchEventQueue.o ./touch/TouchPoint.o
c:\code_red\RedSuiteNXP_4.3.0_1033\redsuite\tools\bin\arm-none-eabi-ar.exe: creating lib_touch.a
Finished building target: lib_touch.a
make --no-print-directory post-build
Performing post-build steps
arm-none-eabi-size "lib_touch.a" ; cp "lib_touch.a" "../../../../lib/lib_touch.a"; # arm-none-eabi-objdump -h -S "lib_touch.a" >"lib_touch.lss"
text data bss dec hex filename
1864 0 156 2020 7e4 Touch.o (ex lib_touch.a)
576 0 0 576 240 TouchCalibration.o (ex lib_touch.a)
320 0 0 320 140 TouchEventQueue.o (ex lib_touch.a)
96 0 0 96 60 TouchPoint.o (ex lib_touch.a)
UPDATE: MORE INFORMATION
I have done some more digging, and it appears the full file path is in front of a string constant. The path data within the .a file shows
C:/Users/my_user_name/Documents/My Project Verification build/src/touch/Touch.c.TouchIdleTimer
I have a string literal "TouchIdleTimer" within the file Touch.c. Is this the cause? How would I remove the path portion, or is it possible? TIA
Update
Via this answer to GCC: static linking only some libraries
Note: If you use full path of a .so file, it will again be linked in dynamically.
Enhanced Static Library Support in Code Red IDE v4: Creating static library projects
Searching around I'm seeing suggestions for -fPIC or -fpic. It was recommended in this comment thread in response to a question similar to yours.
3.2 Shared libraries and static libraries provides a nice breakdown of compiling shared and static libraries.
You stated static not shared libraries but just in case: How to Write Shared Libraries