Am using a Customized Android Compiler. That compiles cpp code and generates the .so file. From Command Prompt it is working fine but when I try to Build using Cmake then Cmake always picks wither Clang or GNU Compiler for Android compilation even after setting the compiler name in toolchain file.
My Analysis and Findings are as below.
I am working towards creating a toolchain file for an ANDROID compiler
I understand that the flow in CMAKE, when CMAKE_SYSTEM_NAME is specified in Android is different when compared to specifying CMAKE_SYSTEM_NAME as IOS or LINUX
Please validate my current understanding when a toolchain file or command-line option sets CMAKE_SYSTEM_NAME to "Android"
CMakeDetermineSystem.cmake loads this file: Android-Determine.cmake
Next is the platform-specific initialization step: CMakeSystemSpecificInitialize.cmake which loads Android-Initialize.cmake to select the sysroot.
A "determine" step also runs for each language when it is first enabled in a new build tree:
Android-Determine-C.cmake
Android-Determine-CXX.cmake
The language files go here:
Determine-Compiler.cmake
Determine-Compiler-NDK.cmake
The latter file is where we parse a bunch of information from the NDK.
The results persist in CMakeFiles/$v/CMake${lang}Compiler.cmake for future runs.
Next is the language-specific initialization step. For Example – in case {lang} is C : CMakeCInformation.cmake
That loads one of these:
Android-GNU-C.cmake
Android-Clang-C.cmake
which loads one of these:
Android-GNU.cmake
Android-Clang.cmake
Determine-Compiler-NDK.cmake is where cmake looks for versions of clang or gcc or llvm toolchains and sets the appropriate compiler.
Our Requirement and Problem statement
When I tried manually setting a c and cxx compiler from a toolchain file, cmake would not allow me to point to my custom compilers. Ideally, I would want my toolchain file to tell cmake the libraries to include/link and the compilers to use. But once System has been determined as android, cmake goes through the above sequence of events and expects toolchains to be specified for either clang, gcc or llvm compilers.
I believe I would probably need to make changes in the following files to accommodate cmake to use custom compilers.
Determine-Compiler-NDK.cmake - We would need to add support for an "NewCompiler Toolchain" which would contain android libraries and compilers.
New Android-{NewCompiler}-C.cmake, Android-{ NewCompiler }-CXX.cmake, Android-{ NewCompiler }.cmake and another appropriate toolchain file to set target architecture and compiler flags.
Any comments on the process or how to go about this would be appreciated.
Toolchain files can set the path to compilers on the host, but
target-platform-wide information like the set of libraries and
include directories to use typically belongs in platform information
modules (e.g. Platform/Android-... and the like).
Since your compiler doesn't come with the NDK, perhaps you could look
at using the standalone toolchain mode.
We've got a Visual Studio Android solution with (among others) a static library project that contains functionality implemented in assembly. Like:
my.S -> libMine.a -> libMyApp.so
Some hoops (below) have already been jumped through, to get it to compile. Then, the linking of the main app shared library project fails (on both architectures that we care about - x64 and arm64), with undefined references to the functions that are implemented in [the] assembly [file].
It appears that Visual Studio (or its Cross Platform Mobile Dev / Android plug-in) doesn't handle assembly file project items quite correctly - treated as C/C++ Compiler files, it'll error out on the first dot character (i.e. in .text); and the Microsoft Macro Assembler is "not supported on this platform". So I looked into setting up a custom build step, with the following command:
$(ClangToolExe) %(FullPath) --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o
This will preprocess, compile and link - but with the wrong linker: instead of the one for the particular Android toolchain, it'll go for the one in my MinGW install, which doesn't recognise the emulation mode - anyway, that's not the location of my NDK toolchain.
We can skip the linking of the object for now (add -c to the above command). Much to our dismay, the resulting object file still doesn't get added to the static library, as confirmed by {Rest of the toolchain path}ar t libMine.a. And indeed, the library will have undefined symbols for our functions, as shown by {Rest of the toolchain path}objdump -t libMine.a.
Let's add the object file to the resulting library quite manually, as a post build step. Command:
$(ToolChainPrebuiltPath){Rest of the toolchain path}ar.exe ru $(TargetPath) $(IntDir)my.o
objdump -t libMine.a will now show that we've got the symbols. There is however also the *UND*efined pair.
Fast forward:
Adding my.o with ar rub otherObjectThatReferencesMyFunctions.o libMine.a, to have the good symbols show up before the undefined ones doesn't make a difference.
Linking my compiled assembly file with a second custom build step, $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(IntDir)%(FileName).o -o $(IntDir)%(FileName).o doesn't make a meaningful difference.
Running the linker again on the static library, as a second post-build step $(ToolChainPrebuiltPath){Rest of the toolchain path}ld.exe $(TargetPath) doesn't make a meaningful difference.
The last two steps result in a warning about a missing symbol _start (entry point?). I'm guessing this is in reference to linking an executable, which we don't want.
What am I doing wrong? How can I resolve those undefined references?
What seems to have worked was to:
1, Make sure that the extension of the assembly file is .S, i.e. capital S. This is one of the few instances I've found, where the case of a filename matters on Windows.
2, Configure the project so that the assembly file is built with clang.exe {full/path/to/assembly.S, i.e. %(FullPath)} -c --target=$(ClangTarget) -g -o $(IntDir)%(FileName).o. In the case of VS Android, we need to specify the build output separately, which is the $(IntDir)%(FileName).o part all over again.
3, Run ar as a post build command: {correct toolchain}/ar.exe rus $(TargetPath) {output from assembly compilation}, for each assembly file.
One thing this solution is lacking is detecting [a lack of] changes, meaning that the assembly file will be rebuilt on each compilation, and everything that depends on it.
I am building Opencv 3.1.0 and Opencv_Extra_module for Android from source using the following procedures using CMake and mingw
start cmake-gui and select the opencv source code folder and the folder where binaries will be built (the 2 upper forms of the interface)
Press the Add Entry button and set Name=ANDROID_NDK select path and add the ndk directory to value
press the configure button. I choose the Specify toolchain for cross-compiling. Press Next and specify the toolchain file and i set to C:/Users/The/Documents/opencv-master/platforms/android/android.toolchain.cmake. Press finish it builds fine but there are two many reptitive warning
i) CMake Deprecation Warning at C:/CMake/share/cmake 3.7/ Modules/CMakeForce Compiler.cmake:69 (message):The CMAKE_FORCE_C_COMPILER macro is deprecated. Instead just set CMAKE_C_COMPILER and allow CMake to identify the compiler.
ii) CMake Deprecation Warning at C:/CMake/share/cmake-3.7/Modules/ CMakeForce Compiler.cmake:83 (message):The CMAKE_FORCE_CXX_COMPILER macro is deprecated. Instead just set CMAKE_CXX_COMPILER and allow CMake to identify the compiler.
To compile the Opencv Extra module set the OPENCV_EXTRA_MODULES_PATH=C:\Users\The\Downloads\opencv_contrib-master\modules
press the configure button for the second time but here is the error occuring Error in configuration process,projects files may be invalid error occured on this stage.
Please help me guys I have been searching for two days on how to build opencv and its extra module for android i asked this question no one answered it?
NOTE: it apparently is a recurrent question on StackOverflow, but - for what I have seen - either people never find a way or their solution does not work for me
The problem:
I am using Eclipse Juno ADT. Everything was working fine until I tried to update the NDK. I replaced my ndk folder (that was the ndk-r8d) by the new version (i.e. ndk-r8e) and, in my Paths and Symbols configuration, I changed the includes to go from g++ 4.6 to 4.7.
It seemed to break my index: I could compile my code, but Eclipse was giving semantic errors, exactly like in [1] and [2]. The errors mainly come from symbol used by OpenCV4Android, such as distance, pt, queryIdx and trainIdx.
When I tried to backup to my old configuration, the index was still broken! I cannot find a way to change this.
What I have tried
Clean up the project
Rebuild, refresh, and all the other options in the "Index" submenu (when "right-clicking" on the project)
Disable / enable the indexer in the preferences
Verify that symbols such as trainIdx only appear in my OpenCV4Android include in the Paths and Symbols section.
Change the order of my includes in the Paths and Symbols section. I basically tried to put the OpenCV include in the beginning and in the end.
Some observations
What is not working
I assume that it is the CDT index because of the following:
In command line, I can build my project using ndk-build clean and ndk-build.
When I start Eclipse, I have no error until I open a C++ file (from the jni folder).
I can always build the project, but as long as I have opened a C++ file, I can't run the application anymore because of a lot of Field '<name>' could not be resolved.
If I don't open the C++ files, Eclipse doesn't report any error and can build and deploy the Android application successfully.
Interesting fact
The following code reports errors on line, queryIdx, pt:
cv::line(mRgb, keypointsA[matches[i].queryIdx].pt, keypointsB[matches[i].trainIdx].pt, cv::Scalar(255, 0, 0, 255), 1, 8, 0);
If I write it as follows, it works:
cv::DMatch tmpMatch = matches[i];
cv::KeyPoint queryKp = keypointsA[tmpMatch.queryIdx];
cv::KeyPoint trainKp = keypointsB[tmpMatch.trainIdx];
cv::line(mRgb, queryKp.pt, trainKp.pt, cv::Scalar(255, 0, 0, 255), 1, 8, 0);
It is not that all of the OpenCV functions are unresolved: only pt, queryIdx and trainIdx are.
Any comment will be really appreciated.
In your selected project preferences within the Eclipse environment, go to C/C++ General -> Code Analysis -> Launching. Make sure that both check boxes are unchecked. Close and reopen the project or restart eclipse and rebuild the project.
Since indexing for Android native code on Eclipse is incomplete, I managed to enable indexing in my NDK projects the following unintuitive way, it should work whether you use ndk-build or plain make or even cmake. I'm using Kepler but it should work on older versions too.
Get your toolchain right
Right click on project -> Properties -> C/C++ Build -> Tool Chain Editor -> Uncheck Display compatible toolchains only.
In the same window, set Current toolchain to Linux GCC.
In the same window, set Current builder to Android Builder if you're using ndk-build, set it to Gnu Make Builder otherwise (this step may be wrong, sorry in advance if it is).
Right click on project -> Properties -> C/C++ Build -> Build Variables -> Make sure Build command reads the correct command for your project; if it's not, uncheck Use default build command and correct it (it may be ndk-build or make -j5 that you want). If you build the native code in a separate terminal, you can skip this step.
Make a standalone toolchain, it's probably the cleanest way to get STL sources in one place
Go to the NDK root directory.
Run the following (tweak the settings according to your liking). Add sudo if you don't have write permissions to the --install-dir because the script fails silently.
./build/tools/make-standalone-toolchain.sh \
--platform=android-14 \
--install-dir=/opt/android-toolchain \
--toolchain=arm-linux-androideabi-4.8
This is assuming that you use GNU-STL. If you use another C/C++ library, you will need to tweak the above command, and probably also the include paths in the next command.
Add the necessary include paths to your project
Right click on project -> Properties -> C/C++ General -> Paths and Symbols -> Go to the Includes tab -> Select GNU C++ from Languages -> Click Add and add the following paths (assuming you installed the standalone toolchain to /opt/android-toolchain):
/opt/android-toolchain/include/
/opt/android-toolchain/include/c++/4.8/
/opt/android-toolchain/include/c++/4.8/arm-linux-androideabi/
/opt/android-toolchain/lib/gcc/arm-linux-androideabi/4.8/include/
/opt/android-toolchain/include/c++/4.8/backward/
/opt/android-toolchain/lib/gcc/arm-linux-androideabi/4.8/include-fixed/
/opt/android-toolchain/sysroot/usr/include/
Here, you can add every include path you want. In fact, I have my OpenCV built for Android and installed in the standalone toolchain, so I have the following include there:
/opt/android-toolchain/sysroot/usr/share/opencv/sdk/native/jni/include/
Now, the indexing should work. You should also be able to run ndk-build (or make if that's your build method) and then deploy your project to your device inside Eclipse.
Why?
Android native development on Eclipse is incomplete since the indexing doesn't work out of the box. This is due to having to support multiple architectures (ARMv7, Intel etc.), multiple STL options, multiple Android versions etc. This is why you have the bare make based ndk-build and the whole NDK structure, and this is also why NDK development is very unclean and few large volume native Android projects exist.
A big Android project is OpenCV where they had to develop a 1500 odd line CMake script to get it to compile for Android properly. At some point, they tried to export that script as a CMake based build system for Android but it couldn't keep up with the changes in the NDK system and was abandoned. This support should have been inside NDK itself.
The default NDK build system should have been standalone toolchain only, with all different architectures/C++ libraries having their own toolchains at the cost of storage space but with the advantage of cleanness, intuitiveness and good practice. Then you can incorporate any standard cross-compilation system that is also used elsewhere, is tested and is well-known, e.g CMake. You can, and in my opinion you should, do that with the NDK's make-standalone-toolchain command as shown above. But in the end, this is only my opinion. If you feel comfortable enough with ndk-build then go ahead.
It's actually quite hard to say what is the problem. Here are some advices:
Try to import and build hello-jni (it is located in jni's samples folder). If it runs without problems than problem is with linking OpenCV to your project.
It seems that you forgot to update android-ndk location in project properties -> c/c++ build -> environment. Here's link to problem Issue with build Android NDK project.
Build from console your project (ndk-build -B), delete all errors in Eclipse manually (in Problems view select all errors and just click delete) and try to run project now. Sometimes this "hack" helps me to run project.
Close Eclipse and delete folder path-to-your-workspace/.metadata/.plugins/org.eclipse.cdt.core (backup it first).
Go to Preferences > C/C++ > Language Mapping > ADD (Source C File and select GNU C) Do the same for C++
I had the same issue. I had all the proper include paths setup but after opening the .c/.cpp or .h file and it would start marking everything as "Unresolved."
This worked for me...
Go to:
PREFERENCES -> C/C++ -> INDEXER
Check Index Source And Header Files Open in Editor.
I had the same issue, like many people.
I followed the steps in Ayberk Özgür post, which make good sense. Although I also had to make sure to put includes under all three languages: GNU C, GNU C++, and Assembly. Probably because I'm not using a stand alone tool chain.
I at first had my includes only under GNU C and GNU C++ languages. Which left me still with the unresolved includes error. Not until I assigned my includes under the Assembler language as well did my errors go away.
I do not know why eclipse is only searching through the Assembler includes in my project. I also do not know how this part of the solution will work for bigger more complicated projects.
Hope this helps.
I had the similar situation with Eclipse CDT working with the OpenCV library. I got several error messages while the program compiled correctly. I changed the indexer setting in "window->preferences->Indexer" "build configuration for indexer" box to "Use Active Configuration" which solved my issue.
I just spent about 3h banging my head against this Eclipse NDK indexing issue!..
What made it work: make sure that you have only ONE cpu architecture specified in Your Application.mk file.
Otherwise the .metadata/.plugins/com.android.ide.eclipse.ndk/*.pathInfo file will not be generated by the NDK build. This file contains built-in values from Project -> Properties -> C/C++ General -> Paths and Symbols -> Includes (just making .pathInfo file does not fix the problem)
This is really frustrating
- I can build my native code from command line, but when I build from eclipse(Sequoyah plug-in enabled) its simply through simple compilation errors like headers not found...
EVen when i build the library from command line everytime I try to run from eclipse it rebuuilds and there goes errors again
- I'm frustrated as I ran out of option to locate the issue
Can some one shed some light on this.
The error you are seeing is Unresolved inclusion with error markers at each header that Eclipse's editor cannot find. This is confounding when you see it, because it is expected that after installing Sequoyah and the ADT, pointing the Sequoyah configuration to your NDK, that you'd have everything you need to start coding.
Two things to observe. The process of building in the ADT "Android Perspective" will work until you click on one of your C/C++ files in your jni directory. Once you open one of these, you'll see the error marker and the project will be tagged as containing errors.
Second observation, when you convert the project to C/C++ perspective or to Sequoyah's Android Native perspective (apparently there's two ways to skin this cat), you will have the ability to configure the project settings around NDK toolchain, include paths, and builder settings. This is where you can set the ndk-build to automatically fire off on each change. And funny thing too is that the ndk-build will work fine until you click on one of your C/C++ sources.
So solution, click [here] http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.cdt.doc.user/tasks/cdt_t_proj_paths.htm and you'll get instructions for configuring the CDT's include paths. You want to set your include paths for C/C++ (either, or both) so that you get to the platform folder includes.
Example, I've got my project hello-jni-to-the-world project set to android-9. So configure the include path: android-ndk-r6b/platforms/android-9/arch-arm/usr/include . Now the magic won't show up until you click apply/save and you'll be prompted to rebuild the indexes.
There are two to three other threads on Stackoverflow asking the same question, and I'll have to find them and add them to the comments. Basically, there were no definitive answers and there's a lot of the usual answering a question with a question: which version of NDK do you have, can you post your code, did you install java, is your computer on ?