20 Apr 2014

cmake and the Android NDK

TL;DR: how to build Android NDK applications with cmake instead of the custom NDK build system, this is useful for projects which already use cmake to create multiplatform/cross-compiling build files.

Update: Thanks to thp for pointing out a rather serious bug: packaging the standard shared libraries into the APK should NOT be necessary since these are pre-installed on the device. I noticed that I didn’t set a library search path to the toolchain lib dir in the linker step (-L…) which might explain the crash I had earlier, but unfortunately I can’t reproduce this crash anymore with the old behaviour (no library search path and no shared system libraries in the APK). I’ll keep an eye on that and update the blog post with my findings.


I’ve spent the last 2.5 days adding Android support to Oryol’s build system. This wasn’t exactly on my to-do list until I sorta “impulse-bought” a Nexus7 tablet last Thursday. It basically went like this “hey that looks quite neat for a non-iPad tablet => wow, scrolling feels smooth, very non-Android-like => holy shit it runs my Oryol WebGL samples at 60fps => hmm 179 Euros seems quite reasonable…” - I must say I’m impressed how far the Android “user experience” has come since I last dabbled with it. The UI finally feels completely smooth, and I didn’t have any of those Windows8-Metro-style WTF-moments yet.

Ok, so the logical next step would be to add support for Android to the Oryol build system (if you don’t know what Oryol is: it’s a new experimental C++11 multi-plat engine I started a couple months ago: https://github.com/floooh/oryol).

The Oryol build system is cmake-based, with a python script on top which simplifies managing the dozens of possible build-configs. A build-config is one specific combination of target-platform (osx, ios, win32, win64, …), build-tools (make, ninja, Visual Studio, Xcode, …) and compile-mode (Release, Debug) stored under a descriptive name (e.g. osx-xcode-debug, win32-vstudio-release, emscripten-make-debug, …).

The front-end python script called ‘oryol’ is used to juggle all the build-configs, invoke cmake with the right options, and perform command line builds.

One can for instance simply call:

> ./oryol update osx-xcode-debug

…to generate an Xcode project.

Or to perform a command line build with xcodebuild instead:

> ./oryol build osx-xcode-debug

Or to build Oryol for emscripten with make in Release mode (provided the emscripten SDK has been installed):

> ./oryol build emscripten-make-release

This also works on Windows (32- or 64-bit):

> oryol build win64-vstudio-debug
> oryol build win32-vstudio-debug

…or on Linux:

> ./oryol build linux-make-debug

Now, what I want to do with my shiny new Nexus7 is of course this:

> ./oryol build android-make-debug

This turned out to be harder then usual. But lets start at the beginning:

A cross-compiling scenario is normally well defined in the GCC/cmake world:

A toolchain wraps the target-platform’s compiler tools, system headers and libs under a standardized directory structure:

The compiler tools usually reside in a bin subdirectory, and are called gcc and g++, or in the LLVM world: clang and clang++, sometimes the tools also have a prefix: pnacl-clang and pnacl-clang++), or they have completely different names (like emcc in the emscripten SDK).

Headers and libs are often located in a usr directory (usr/include and usr/lib).

The toolchain headers contain at least the the C-Runtime headers, like stdlib.h, stdio.h and usually the C++ headers (vector, iostream, …) and often also the OpenGL headers and other platform-specific header files.

Finally the lib directory contains precompiled system libraries for the target platform (for instance libc.a, libc++.a, etc…).

With such a standard gcc-style toolchain, cross-compilation is very simple. Just make sure that the toolchain-compiler tools are called instead of the host platform’s tools, and that the toolchain headers and libs are used.

cmake standardizes this process with its so-called toolchain-files. A toolchain-file defines what compilers tools, headers and libraries should be used instead of the ‘default’ ones, and usually also overrides compile and linker flags.

The typical strategy when adding a new target platform to a cmake build system looks like this:

  • setup the target platform’s SDK
  • create a new toolchain file (obviously)
  • tell cmake where to find the compiler tools, header and libs
  • add the right compile and linker flags

Once the toolchain file has been created, call cmake with the toolchain file:

> cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=[path-to-toolchain-file] [path-to-project]

Then run make in verbose mode to check whether the right compiler is called, and with the right options:

> make VERBOSE=1

This approach works well for platforms like emscripten or Google Native Client. Some platforms require a bit of additional cmake-magic, a Portable Native Client executable for instance must be “finalized” after it has been linked. Additional build steps like these can be added easily in cmake with the add_custom_command macro.

Integrating Android as a new target platform isn’t so easy though:

  • the Android SDK itself only allows to create pure Java applications, for C/C++ apps, the separate Android NDK (Native Development Kit) is required
  • the NDK doesn’t produce complete Android applications, it needs the Android Java SDK for this
  • native Android code isn’t a typical executable, but lives in a shared library which is called from Java through JNI
  • the Android SDK and NDK both have their own build systems which hide a lot of complexity
  • …this complexity comes from the combination of different host platforms (OSX, Linux, Windows), target API levels (android-3 to android-19, roughly corresponding to Android versions), compiler versions (gcc4.6, gcc4.9, clang3.3, clang3.4), and finally CPU architectures and instruction sets (ARM, MIPS, X86, with several variations for ARM (armv5, armv7, with or without NEON, etc…)
  • C++ support is still bolted on, the C++ headers and libs are not in their standard locations
  • the NDK doesn’t follow the standard GCC toolchain directory structure at all

The custom build system coming with the NDK does a good job to hide all this complexity, for instance it can automatically build for all CPU architectures, but it stops after the native shared library has been compiled: it cannot create a complete Android APK. For this, the Android Java SDK tools must be called from the command line.

So back to how to make this work in cmake:

The plan looks simple enough:

  1. compile our C/C++ code into a shared library instead of an executable
  2. somehow get this into a Java APK package file…
  3. …deploy APK to Android device and run it

Step 1 starts rather innocent, create a toolchain file, look up the paths to the compiler tools, headers and libs in the NDK, then lookup the compiler and linker command line args by watching a verbose build. Then put all this stuff into the right cmake variables. At least this is how it usually works. Of course for Android it’s all a bit more complicated:

  • first we need to decide on a target CPU architecture and what compiler to use. I settled for ARM and gcc4.8, which leads us to […]/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt
  • in there is a directory darwin-x86_64 so we need separate paths by host platform here
  • finally in there is a bin directory with the compiler tools, so GCC would be for instance at [..]/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc
  • there’s also an include, lib and share directory but the stuff in there definitely doesn’t look like system headers and libs… bummer.
  • the system headers and libs are under the platforms directory instead: [..]/android-ndk-r9d/platforms/android-19/arch-arm/usr/include, and [..]/android-ndk-r9d/platforms/android-19/arch-arm/usr/lib
  • so far so good… put this stuff into the toolchain file and it seems to compile fine – until the first C++ header must be included - WTF?
  • on closer inspection, the system include directory doesn’t contain any C++ headers, and there’s different C++ lib implementations to choose from under [..]/android-ndk-r9d/sources/cxx-stl

This was the point where was seriously thinking about calling it a day until I stumbled across the make-standalone-toolchain.sh in build/tools. This is a helper script which will build a standard GCC-style toolchain for one specific Android API-level and target CPU:

sh make-standalone-toolchain.sh –-platform=android-19 
  –-ndk-dir=/Users/[user]/android-ndk-r9d
  –-install-dir=/Users/[user]/android-toolchain 
  –-toolchain=arm-linux-androideabi-4.8
  --system=darwin-x86_64

This will extract the right tools, headers and libs, and also integrate C++ headers (by default gnustl, but can be selected with the –stl option). When the script is done, a new directory ‘android-toolchain’ has been created which follows the GCC toolchain standard, and is much easier to integrate with cmake:

The important directories are:
- [..]/android-toolchain/bin, this is where the compiler tools are located, these are still prefixed though (e.g. arm-linux-androideabi-gcc
- [..]/android-toolchain/sysroot/usr/include CRT headers, plus EGL, GLES2, etc…, but NOT the C++ headers
- [..]/android-toolchain/include the C++ headers are here, under ‘c++’
- [..]/android-toolchain/sysroot/usr/lib .a and .so system libs, libstc++.a/.so is also here, no idea why

After setting these paths in the toolchain file, and telling cmake to create shared-libs instead of exes when building for the Android platform I got the compiler and linker steps. Instead of a CoreHello executable, I got a libCoreHello.so. So far so good.

Next step was to figure out how to get this .so into a APK which can be uploaded to an Android device.

The NDK doesn’t help with this, so this is where we need the Java SDK tools, which uses yet another build system: ant. From looking at the SDK samples I figured out that it is usually enough to call ant debug or ant release within a sample directory to build an .apk file into a bin subdirectory. ant requires a build.xml file which defines the build tasks to perform. Furthermore, Android apps have an embedded AndroidManifest.xml file which describes how to run the application, and what privileges it requires. None of these exist in the NDK samples directories though…

After some more exploration it became clear: The SDK has a helper script called android which is used (among many other things) to setup a project directory structure with all required files for ant to create a working APK:

> android create project
    --path MyApp
    --target android-19
    --name MyApp
    --package com.oryol.MyApp
    --activity MyActivity

This will setup a directory ‘MyApp’ with a complete Android Java skeleton app. Run ‘ant debug’ in there and it will create a ‘MyApp-debug.apk’ in the ‘bin’ subdirectory which can be deployed to the Android device with ‘adb install MyApp-debug.apk’, which when executed displays a ‘Hello World, MyActivity’ string.

Easy enough, but there are 2 problems, first: how to get our native shared library packaged and called?, and second: the Java SDK project directory hierarchy doesn’t really fit well into the source tree of a C/C++ project. There should be a directory per sample app with a couple of C++ files and a CMakeLists.txt file and nothing more.

The first problem is simple to solve: the project directory hierarchy contains a libs directory, all .so files in there will be copied into the APK by ant (to verify this: a .apk is actually a zip file, simply changed the file extension to zip and peek into the file). One important point: the lib directory contains one sub-directory-level for the CPU architecture, so once we start to support multiple CPU instruction sets we need to put them into subdirectories like this:

FlohOfWoe:libs floh$ ls
armeabi     armeabi-v7a mips        x86

Since my cmake build-system currently only supports building for armeabi-v7a I’ve put my .so file in the armeabi-v7a subdirectory.

Now I thought that I had everything in place, I got an APK file with my native code .so lib in it, I used the NativeActivity and the android_native_app_glue.h approach, and logged out a “Hello World” to the system log (which can be inspected with adb logcat from the host system).

And still the App didn’t start, instead this showed up in the log:

D/AndroidRuntime(  482): Shutting down VM
W/dalvikvm(  482): threadid=1: thread exiting with uncaught exception (group=0x41597ba8)
E/AndroidRuntime(  482): FATAL EXCEPTION: main
E/AndroidRuntime(  482): Process: com.oryol.CoreHello, PID: 482
E/AndroidRuntime(  482): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.oryol.CoreHello/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/com.oryol.CoreHello-1/libCoreHello.so
E/AndroidRuntime(  482):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)

This was the second time where I banged my head against the wall for a while until I started to look into how linker dependencies are resolved for the shared library. I was pretty sure that I gave all the required libs on the linker command line (-lc -llog -landroid, etc), the error was that I assumed that these are linked statically. Instead default linking against system libraries is dynamic. The ndk-depends helps in finding the dependencies:

localhost:armeabi-v7a floh$ ~/android-ndk-r9d/ndk-depends libCoreHello.so 
libCoreHello.so
libm.so
liblog.so
libdl.so
libc.so
libandroid.so
libGLESv2.so
libEGL.so

This is basically the list of .so files which must be contained in the APK. After I copied these to the SDK project's lib directory, together with my libCoreHello.so. Update: These shared libs are not supposed to be packaged into the APK! Instead the standard system shared libraries which already exist on the device should be linked at startup.

I finally saw the sweet, sweet ‘Hello World!’ showing up in the adb log!

But I skipped one important part: so far I fixed everything manually, but of course I want automated Android batch builds, and without having those ugly Android skeleton project files in the git repository.

To solve this I did a bit of cmake-fu:

Instead of having the Android SDK project files committed into version control, I’m treating these as temporary build files.

When cmake runs for an Android build target, it does the following additional steps:

For each application target, a temporary Android SDK project is created in the build directory (basically the ‘android create project’ call described above):

# call the android SDK tool to create a new project
execute_process(COMMAND ${ANDROID_SDK_TOOL} create project
                --path ${CMAKE_CURRENT_BINARY_DIR}/android
                --target ${ANDROID_PLATFORM}
                --name ${target}
                --package com.oryol.${target}
                --activity DummyActivity
                WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

The output directory for the shared library linker step is redirected to the ‘libs’ subdirectory of this skeleton project:

# set the output directory for the .so files to point to the android project's 'lib/[cpuarch] directory
set(ANDROID_SO_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/android/libs/${ANDROID_NDK_CPU})
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${ANDROID_SO_OUTDIR})
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${ANDROID_SO_OUTDIR})
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${ANDROID_SO_OUTDIR})

The required system shared libraries are also copied there: (DON’T DO THIS, normally the system’s standard shared libraries should be used)

# copy shared libraries over from the Android toolchain directory
# FIXME: this should be automated as post-build-step by invoking the ndk-depends command
# to find out the .so's, and copy them over
file(COPY ${ANDROID_SYSROOT_LIB}/libm.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/liblog.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/libdl.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/libc.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/libandroid.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/libGLESv2.so DESTINATION ${ANDROID_SO_OUTDIR})
file(COPY ${ANDROID_SYSROOT_LIB}/libEGL.so DESTINATION ${ANDROID_SO_OUTDIR})

The default AndroidManifest.xml file is overwritten with a customized one:

# override AndroidManifest.xml 
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/android/AndroidManifest.xml
    "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
    "  package=\"com.oryol.${target}\"\n"
    "  android:versionCode=\"1\"\n"
    "  android:versionName=\"1.0\">\n"
    "  <uses-sdk android:minSdkVersion=\"11\" android:targetSdkVersion=\"19\"/>\n"
    "  <uses-feature android:glEsVersion=\"0x00020000\"></uses-feature>"
    "  <application android:label=\"${target}\" android:hasCode=\"false\">\n"
    "    <activity android:name=\"android.app.NativeActivity\"\n"
    "      android:label=\"${target}\"\n"
    "      android:configChanges=\"orientation|keyboardHidden\">\n"
    "      <meta-data android:name=\"android.app.lib_name\" android:value=\"${target}\"/>\n"
    "      <intent-filter>\n"
    "        <action android:name=\"android.intent.action.MAIN\"/>\n"
    "        <category android:name=\"android.intent.category.LAUNCHER\"/>\n"
    "      </intent-filter>\n"
    "    </activity>\n"
    "  </application>\n"
    "</manifest>\n")

And finally, a custom build-step to invoke the ant-build tool on the temporary skeleton project to create the final APK:

if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
    set(ANT_BUILD_TYPE "debug")
else()
    set(ANT_BUILD_TYPE "release")
endif()
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${ANDROID_ANT} ${ANT_BUILD_TYPE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/android)

With all this in place, I can now do a:

> ./oryol make CoreHello android-make-debug

To compile and package a simple Hello World Android app!

What’s currently missing is a simple wrapper to deploy and run an app on the device:

> ./oryol deploy CoreHello
> ./oryol run CoreHello

These would be simple wrappers around the adb tool, later this should of course also work for iOS apps.

Right now the Android build system only works on OSX and only for the ARM V7A instruction set, and there’s no proper Android port of the actual code yet, just a single log message in the CoreHello sample.

Phew, that’s it! All this stuff is also available on github (https://github.com/floooh/oryol/tree/master/cmake).

Written with StackEdit.

102 comments:

thp said...

I'm pretty sure you don't have to (read: shouldn't) copy the files libm.so, liblog.so, libdl.so, libc.so, libandroid.so, libGLESv2.so and libEGL.so into your .apk file - they are available in /system/lib/ on every Android device (well, every recent one since 2.x or something). In any case, could it be that your linker path is set in a wrong way?

Andre Weissflog said...

Thanks for the hint, this step doesn't indeed feel right. It's also strange that I never got any unresolved symbols warnings in the linker step, which I'm usually getting when first trying to link for a new platform. I'll try to get this fixed and update the the blog post.

Andre Weissflog said...

Ok, I indeed forgot the -L to the toolchain's lib directory in the linker step, and I don't need to include the .so's in the APK. What's worrying is that I cannot reproduce my earlier crash. With or without the search path, the app now runs without the packaged shared libs and I have no idea why it crashed the first time :/ I'll update the blog post and keep an eye on this. Thanks again :)

Geetha Devi said...

Very informative ..i suggest this blog to my friends..Thank you for sharing
Android Training in velachery | Android Training in chennai | Android Training in chennai with placement

Saranya N said...

Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more ... good luck.
Android Training in chennai | Best Android Training in chennai|Android Training in chennai with placement | Android Training in velachery

johnsy sai said...

Existing without the answers to the difficulties you’ve sorted out through this guide is a critical case, as well as the kind which could have badly affected my entire career if I had not discovered your website.
Digital Marketing online training

full stack developer training in pune

full stack developer training in annanagar

full stack developer training in tambaram

full stack developer training in velachery

Mouni yoga said...

I would really like to read some personal experiences like the way, you've explained through the above article. I'm glad for your achievements and would probably like to see much more in the near future. Thanks for share.
python training institute in chennai
python training in chennai
python training in chennai

pooja saravanan said...

It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.Most of ideas can be nice content.The people to give them a good shake to get your point and across the command

Blueprism training in Chennai

Blueprism training in Bangalore

Blueprism training in Pune

Ezhil K S said...

It would have been the happiest moment for you,I mean if we have been waiting for something to happen and when it happens we forgot all hardwork and wait for getting that happened.

Data Science training in rajaji nagar
Data Science training in chennai
Data Science training in electronic city
Data Science training in USA
Data science training in pune
Data science training in kalyan nagar

Afiah B said...

Hello I am so delighted I found your blog, I really found you by mistake, while I was looking on Yahoo for something else, anyways I am here now and would just like to say thanks for a tremendous post. Please do keep up the great work.
java training in chennai | java training in bangalore

java online training | java training in pune

genga g said...

The knowledge of technology you have been sharing thorough this post is very much helpful to develop new idea. here by i also want to share this.

angularjs Training in chennai
angularjs Training in chennai

angularjs-Training in tambaram

angularjs-Training in sholinganallur

angularjs-Training in velachery

kim john said...

Useful content, I have bookmarked this page for my future reference.
Python Training in Chennai
Python course in Chennai
Robotics Process Automation Training in Chennai
Angularjs Training in Chennai
AWS course in Chennai
DevOps Certification Chennai

Sri Nithya said...

Very Good information. Keep sharing more like this.
Blue Prism Training in Chennai
Blue Prism Training Institute in Chennai
Blue Prism Training near me
Blue Prism course in Chennai
Blue Prism Training in Velachery
Blue Prism Training in Tambaram

infotechbrn1@gmail.com said...


Nice Blog, When i was read this blog i learnt new things & its truly have well stuff related to developing technology, Thank you for sharing this blog.
iPhone app training course in bangalore
iPhone job oriented course in bangalore
Best iphone training institute bangalore
iOS course fee in bangalore

kate technologies said...

Thank you for your post. This is excellent information. It is amazing and wonderful to visit your site.
mobile app development in kphb
best mobile development in hyderabad
best mobile development in gachibowli
best mobile development in ameerpet
best mobile development in kphb

Ananya Krishnan said...

Good job in presenting the correct content with the clear explanation. The content looks real with valid information. Good Work

DevOps is currently a popular model currently organizations all over the world moving towards to it. Your post gave a clear idea about knowing the DevOps model and its importance.

Good to learn about DevOps at this time.


devops training in chennai | devops training in chennai with placement | devops training in chennai omr | devops training in velachery | devops training in chennai tambaram | devops institutes in chennai | devops certification in chennai | trending technologies list 2018

i4 consulting said...

Such a nice information you shared in this article, I really like it. Wordpress Development in Dubai

mercyroy said...

Thanks for your interesting ideas.the information's in this blog is very much useful
for me to improve my knowledge.
german Training near me
German Training in chennai
german language coaching classes in bangalore
german learning courses in bangalore

pavithra dass said...

Great post and informative blog.it was awesome to read, thanks for sharing this great content to my vision.
Good discussion.
Android Development Course in Chennai
Android app Development Course in Chennai
Android Course in Chennai
Aws Certification in Chennai
Amazon Web Services Training in Chennai
AWS Training centers in Chennai

Gunika Dawar said...

Hey there, great stuff this MeshLab! I just found out about it, it seems pretty nice.
check out https://ayevainstitute.com/

Anand said...

Thanks for Sharing such a Useful Information!!!

Java Training in Chennai
Python Training in Chennai
IOT Training in Chennai
Selenium Training in Chennai
Data Science Training in Chennai
FSD Training in Chennai
MEAN Stack Training in Chennai

Anbarasan14 said...

Nice post. Thanks for sharing such a worthy information.

English Coaching Center in Chennai
English Coaching in Chennai
Spoken English Center in Chennai
Best Spoken English Coaching Center near me
Spoken English Training in Chennai
Best Spoken English in Chennai
English Language Classes in Chennai

sultana mohammed said...

Thanks for sharing this valuable information to our vision. You have posted a worthy blog keep sharing.
hadoop training in bangalore
hadoop training in bangalore
Java Coaching Institutes in Bangalore
Advanced Java Training Institute in Bangalore
Best Institute For Java Course in Bangalore

Mirnalini Sathya said...

you have done a meritorious work by posting this content.

selenium Classes in chennai
selenium certification in chennai
Selenium Training in Chennai
web designing training in chennai
Big Data Hadoop Training in Chennai
Hadoop Certification
Hadoop Training in adyar

Riya Raj said...

Really great blog… Thanks for your useful information.
Best Spoken English Institute in Coimbatore
Spoken English Course in Coimbatore
Best Spoken English Coaching Center in Coimbatore
Coimbatore Spoken English Center
English Speaking Course in Coimbatore

Nadeem Malik said...

hello sir,
thanks for giving that type of information.
digital marketing company in delhi

Mobile app development company in Gurgaon said...

Mobile app development company in toronto

Ananya Krishnan said...

Good job in presenting the correct content with the clear explanation. The content looks real with valid information. Good Work

DevOps is currently a popular model currently organizations all over the world moving towards to it. Your post gave a clear idea about knowing the DevOps model and its importance.

Good to learn about DevOps at this time.


devops training in chennai | devops training in chennai with placement | devops training in chennai omr | devops training in velachery | devops training in chennai tambaram | devops institutes in chennai | devops certification in chennai | trending technologies list 2018

Robotic Process Automation Tutorial said...

Thank you so much for your information,its very useful and helful to me.Keep updating and sharing. Thank you.
RPA training in chennai | UiPath training in chennai


Rithi Rawat said...

Thankyou for providing the information, I am looking forward for more number of updates from you thank you



Very nice post here thanks for it .I always like and such a super contents of these post.Excellent and very cool idea and great content of different kinds of the valuable information's.
machine learning training in chennai
machine learning certification in chennai
top institutes for machine learning in chennai
Android training in chennai
PMP training in chennai

Akash Thakur said...

Thanks for giving great kind of information. So useful and practical for me. Thanks for your excellent blog, nice work keep it up thanks for sharing the knowledge.
interior designer company in noida

Pooja Rao said...

ppc for tech support
web designing company in Gurgaon
ppc company in gurgaon

Pooja Rao said...

Namkeen Pouch Manufacturers
Rice Packaging Bags Manufacturers
Pouch Manufacturers

Vikash Kumar said...

nice work keep it up thanks for sharing the knowledge.Thanks for sharing this type of information, it is so useful.
block adhesive manufacturer in delhi

Amase LED Lighting said...

Home Decor Wall Lights in delhi
Thanks for giving great kind of information. So useful and practical for me. Thanks for your excellent blog, nice work keep it up thanks for sharing the knowledge.

lather said...

Goyal packers and movers in Panchkula is highly known for their professional and genuine packing and moving services. We are top leading and certified relocation services providers in Chandigarh deals all over India. To get more information, call us.

Packers and movers in Chandigarh
Packers and movers in Panchkula
Packers and movers in Mohali
Packers and movers in Zirakpur
Packers and movers in Patiala
Packers and movers in Ambala
Packers and movers in Ambala cantt
Packers and movers in Pathankot
Packers and movers in Jalandhar
Packers and movers in Ludhiana

REKHA PUNIA said...

If you live in Delhi and looking for a good and reliable vashikaran specialist in Delhi to solve all your life problems, then you are at right place. 
love marriage specialist in delhi

vashikaran specialist in delhi

love vashikaran specialist molvi ji

get love back by vashikaran

black magic specialist in Delhi

husband wife problem solution
love marriage specialist in delhi
love vashikaran specialist
intercast love marriage problem solution
vashikaran specialist baba ji
online love problem solution baba ji

kirti batra said...

Thinking of growing as best packers and movers. Just click on click track india, and you are ready for the skyrocket sales.


Packers and movers in Chandigarh

Packers and movers in Mohali

Packers and movers in Noida

Packers and movers in Gurgaon

Packers and movers in Delhi NCR

Packers and movers in Bangalore

Nadeem Malik said...

hello sir,
thanks for giving that type of information. Really enjoyed this blog post. Really looking forward to reading more. Much obliged.
digital marketing company in delhi

Apps Lure said...

Alot of blogs I see these days don't really provide anything that I'm interested in, but I'm most definitely interested in this one. Just thought that I would post and let you know. Nice! thank you so much! Thank you for sharing.
Website Development Company in Delhi
Website Designing Company in Delhi
Mobile App Development Company
Mobile App Development Company in India

Aayushi Sharma said...

Thanks for providing such a great Information, you can see
Peptide Synthesis

TeknikoGlobal said...

Thanks, you guys that is a great explanation. keep up the good work in your granite blog.
Mobile app Development Company in Noida

Unknown said...

pouch manufacturers
wall putty bag manufacturers

Unknown said...

iso certification in noida
iso certification in delhi
Halal Certification in Delhi
haccp certification in delhi

IELTS Coaching in Dwarka said...

I feel happy about and learning more about this topic. keep sharing your information regularly for my future reference. This content creates a new hope and inspiration with in me. Thanks for sharing article like this. the information which you have provided is better then other blog.
Best IELTS training centre in Dwarka

dhanam said...

Were a gaggle of volunteers as well as starting off a brand new gumption within a community. Your blog furnished us precious details to be effective on. You've got completed any amazing work!
Microsoft Azure online training
Selenium online training
Java online training
Java Script online training
Share Point online training

Ram Niwas said...

Good Post..Thanks for sharing such a wonderful Blog..

Website Designing Company in Delhi
Website Development Company in Delhi

Ram Niwas said...
This comment has been removed by the author.
sasitamil said...

This is ansuperior writing service point that doesn't always sink in within the context of the classroom. In the first superior writing service paragraph you either hook the reader's interest or lose it. Of course your teacher, who's getting paid to teach you how to write an good essay, 
devops online training

aws online training

data science with python online training

data science online training

rpa online training

IELTS Coaching in Dwarka said...

I feel happy about and learning more about this topic. keep sharing your information regularly for my future reference. This content creates new hope and inspiration within me. Thanks for sharing an article like this. the information which you have provided is better than another blog.
IELTS Coaching in Dwarka sector 7

Chiến SEOCAM said...

Chúc mừng bạn đã có một bài viết hay và thú vị. Cảm ơn bạn rất nhiều!




Bồn ngâm massage chân

Bồn ngâm chân

Có nên dùng bồn ngâm chân

Cách sử dụng bồn ngâm chân

Ramya Krishnan said...

This is the exact information I am been searching for, Thanks for sharing the required infos with the clear update and required points. To appreciate this I like to share some useful information regarding Microsoft Azure which is latest and newest,

Regards,
Ramya

Azure Training in Chennai
Azure Training Center in Chennai
Best Azure Training in Chennai
Azure Devops Training in Chenna
Azure Training Institute in Chennai
Azure Training in Chennai OMR
Azure Training in Chennai Velachery
Azure Online Training
Azure Training in Chennai Credo Systemz
DevOps Training in Chennai Credo Systemz
Best Cloud Computing Service Providers

creative web solution said...

Are you looking for a maid for your home to care your baby,patient care taker, cook service or a japa maid for your pregnent wife we are allso providing maid to take care of your old

parents.we are the best and cheapest service provider in delhi for more info visit our site and get all info.

maid service provider in South Delhi
maid service provider in Dwarka
maid service provider in Gurgaon
maid service provider in Paschim Vihar

cook service provider in Paschim Vihar
cook service provider in Dwarka
cook service provider in south Delhi

baby care service provider in Delhi NCR
baby care service provider in Gurgaon
baby care service provider in Dwarka
baby service provider in south Delhi

servant service provider in Delhi NCR
servant service provider in Paschim Vihar
servant Service provider in South Delhi

japa maid service in Paschim Vihar
japa maid service in Delhi NCR
japa maid service in Dwarka
japa maid service in south Delhi

patient care service in Paschim Vihar
patient care service in Delhi NCR
patient care service in Dwarka
Patient care service in south Delhi

Diya shree said...
This comment has been removed by the author.
Diya shree said...

Good job and thanks for sharing such a good blog You’re doing a great job. Keep it up !!

PMP Certification Fees in Chennai | Best PMP Training in Chennai |
pmp certification cost in chennai | PMP Certification Training Institutes in Velachery |
pmp certification courses and books | PMP Certification requirements in Chennai

Joe said...

Good Job. You have an in-depth knowledge. The way of sharing is very unique.
Informatica Training in Chennai
Informatica Training Center Chennai
Best Informatica Training Institute In Chennai
Best Informatica Training center In Chennai
Informatica institutes in Chennai
Informatica courses in Chennai
Informatica Training
Informatica Training in Tambaram
Informatica Training in Adyar

Chiến SEOCAM said...

ความสนุกและความสุขจะมาหาคุณ ลาก่อน


Phối chó bull pháp

Phối giống chó Corgi

Phối chó Pug

Phối giống cho Pug

Designer said...

Có lẽ cần phải trải qua tuổi thanh xuân mới có thể hiểu được( cách dạy con học toán lớp 1 cho trẻ ) tuổi xuân là khoảng thời gian ta( dạy trẻ học toán tư duy ) sống ích kỷ biết chừng nào. Có lúc nghĩ, sở dĩ tình yêu cần phải đi một vòng tròn lớn như vậy, phải trả một cái giá quá đắt như thế,( phương pháp dạy toán cho trẻ mầm non ) là bởi vì nó đến không đúng thời điểm. Khi có được( Toán mầm non ) tình yêu, chúng ta thiếu đi trí tuệ. Đợi đến khi( Bé học đếm số ) có đủ trí tuệ, chúng ta đã không còn sức lực để yêu một tình yêu thuần khiết nữa.

Sarah Alfred said...

If anyone is in search of android developer then sky potential best android mobile app development agency which I can recommend because it is tested and I really like the quality of their work.

creative web solution said...

such a nice post thanks for sharing this with us really so impressible and attractive post
are you searching for a caterers service provider in Delhi or near you then contact us and get all info and also get best offers and off on pre booking

caterers services sector 29 gurgaon
caterers services in west Delhi
event organizers rajouri garden
wedding planners in Punjabi bagh
party organizers in west Delhi
party organizers Dlf -phase-1
wedding planners Dlf phase-1
wedding planners Dlf phase-2
event organizers  Dlf phase-3
caterers services Dlf phase-4
caterers services Dlf phase-5

creative web solution said...

Alleyaaircool is the one of the best home appliances repair canter in all over Delhi we deals in repairing window ac, Split ac , fridge , microwave, washing machine, water cooler, RO and more other home appliances in cheap rates

Window AC Repair in vaishali
Split AC Repair in indirapuram
Fridge Repair in kaushambi
Microwave Repair in patparganj
Washing Machine Repair in vasundhara
Water Cooler Repair in indirapuram
RO Service AMC in vasundhara
Any Cooling System in vaishali
Window AC Repair in indirapuram

creative web solution said...

Are you looking for a maid for your home to care your baby,patient care taker, cook service or a japa maid for your pregnent wife we are allso providing maid to take care of your old parents.we are the best and cheapest service provider in delhi for more info visit our site and get all info.

maid service provider in South Delhi
maid service provider in Dwarka
maid service provider in Gurgaon
maid service provider in Paschim Vihar
cook service provider in Paschim Vihar
cook service provider in Dwarka
cook service provider in south Delhi
baby care service provider in Delhi NCR
baby care service provider in Gurgaon
baby care service provider in Dwarka
baby service provider in south Delhi
servant service provider in Delhi NCR
servant service provider in Paschim Vihar
servant Service provider in South Delhi
japa maid service in Paschim Vihar
japa maid service in Delhi NCR
japa maid service in Dwarka
japa maid service in south Delhi
patient care service in Paschim Vihar
patient care service in Delhi NCR
patient care service in Dwarka
Patient care service in south Delhi

creative web solution said...

In This Summers get the best designer umbrellas for you or for your family members we allso deals in wedding umbrellas and in advertising umbrellas For more info visit links given bellow
UMBRELLA WHOLESALERS IN DELHI
FANCY UMBRELLA DEALERS
CORPORATE UMBRELLA MANUFACTURER
BEST CUSTOMIZED UMBRELLA
FOLDING UMBRELLA DISTRIBUTORS
DESIGNER UMBRELLA
GOLF UMBRELLA DEALERS/MANUFACTURERS
TOP MENS UMBRELLA
LADIES UMBRELLA DEALERS
WEDDING UMBRELLA DEALERS
BEST QUALITY UMBRELLA
BIG UMBRELLA
Top Umbrella Manufacturers in India
Umbrella Manufacturers in Mumbai
Umbrella Manufacturers in Delhi
Garden Umbrella Dealers
Garden Umbrella Manufacturers
PROMOTIONAL UMBRELLA DEALERS IN DELHI/MUMBAI
PROMOTIONAL UMBRELLA MANUFACTURERS IN DELHI / MUMBAI
ADVERTISING UMBRELLA MANUFACTURERS

creative web solution said...

Totalsolution is the one of the best home appliances repair canter in all over Delhi we deals in repairing window ac, Split ac , fridge , microwave, washing machine, water cooler, RO and more other home appliances in cheap rates

LCD, LED Repair in Janakpuri
LCD, LED Repair in Dwarka
LCD, LED Repair in Vikaspuri
LCD, LED Repair in Uttam Nagar
LCD, LED Repair in Paschim Vihar
LCD, LED Repair in Rohini
LCD, LED Repair in Punjabi Bagh
LCD, LED Repair in Delhi. & Delhi NCR
LCD, LED Repair in Delhi. & Delhi NCR
Washing Machine repair on your doorstep
Microwave repair on your doorstep

creative web solution said...

We are the one of the top blue art pottery manufacturers in jaipur get contact us and get all informations in detail visit our site
blue pottery jaipur
blue pottery shop in jaipur
blue pottery manufacturers in jaipur
blue pottery market in jaipur
blue pottery work shop in jaipur
blue pottery
top blue pottery in jaipur
blue pottery wholesale in jaipur

creative web solution said...

Rihan electronics is one of the best repairing service provider all over india we are giving our service in many different different cities like Noida,Gazibad,Delhi,Delhi NCR

AC Repair in NOIDA
Refrigerator Repair Gaziabad
Refrigerator repair in NOIDA
washing machine repair in Delhi
LED Light Repair in Delhi NCR
plasma TV repair in Gaziyabad
LCD TV Repair in Delhi NCR
LED TV Repair in Delhi

creative web solution said...

we are one of the top rated movers and packers service provider in all over india.we taqke all our own risks and mentanance. for more info visit our site and get all details and allso get amazing offers

Packers and Movers in Haryana
Packers and Movers Haryana
Best Packers and Movers Gurugram
Packers and Movers in Gurugram
packers and movers in east delhi
packers and movers in south delhi
packer mover in delhi
cheapest packers and movers in faridabad
best Packers and Movers Faridabad

creative web solution said...

Are you searching for a home maid or old care attandents or baby care aaya in india contact us and get the best and experianced personns in all over india for more information visit our site

best patient care service in India
Male  attendant service provider in India
Top critical care specialist in India
Best physiotherapist providers in India
Home care service provider in India
Experienced Baby care aaya provider in India
best old care aaya for home in India
Best medical equipment suppliers in India

cynthiawilliams said...

I am very happy to visit your blog. This is definitely helpful to me, eagerly waiting for more updates.
Machine Learning course in Chennai
Machine Learning Training in Chennai
Data Science Course in Chennai
Data Science Certification in Chennai
R Training in Chennai
R Programming Training in Chennai
Machine Learning Training in Velachery
Data Science Course in Anna Nagar

Mobile app development company in Mumbai said...

We are leading mobile app development company in Mumbai, Navi Mumbai, India. We provide a wide range of Android & iOS app development services at a cost-effective price. Thanks you for very nice its sharing.
Mobile app development company in Navi mumbai

Shanthi Cabs said...

The article is very interesting and very understood to be read, may be useful for the people. I wanted to thank you for this great read!! I definitely enjoyed every little bit of it. I have to bookmarked to check out new stuff on your post. Thanks for sharing the information keep updating, looking forward for more posts..
Kindly visit us @
Madurai Travels
Best Travels in Madurai
Cabs in Madurai
Tours and Travels in Madurai

Unknown said...

SEO Company India

Phụ kiện tủ bếp Qman said...

HVO Vietnam Education Services Joint Stock Company was established in 2017 with the desire to bring a learning environment to maximize the creativity and logic of children through the subjects of the program. Home thinking math (Toán tư duy tại nhà ), Army summer camp (trại hè quân đội), Homeschool

Rigid Box said...

Excellent Blog. I really want to admire the quality of this post. I like the way of your presentation of ideas, views and valuable content. No doubt you are doing great work. I’ll be waiting for your next post. Thanks .Keep it up!
Kindly visit us @
Luxury Packaging Box
Wallet Box
Perfume Box Manufacturer
Candle Packaging Boxes
Luxury Leather Box
Luxury Clothes Box
Luxury Cosmetics Box
Shoe Box Manufacturer
Luxury Watch Box

Pardeep Mengi said...

Usually I never comment on blogs but your article is so convincing that I never stop myself to say something about it. You’re doing a great job Man,Keep it up.
overseas education consultants in delhi

gokul said...

Thank you for this informative blog
data science interview questions pdf
data science interview questions online
data science job interview questions and answers
data science interview questions and answers pdf online
frequently asked datascience interview questions
top 50 interview questions for data science
data science interview questions for freshers
data science interview questions
data science interview questions for beginners
data science interview questions and answers pdf

Christoper stalin said...

Great blog!!!!! Nice content.
web design and programming courses
php training institute with placement
magento training institute in chennai

Benish said...

thank you for sharing your information..
AngularJS interview questions and answers/angularjs interview questions/angularjs 6 interview questions and answers/mindtree angular 2 interview questions/jquery angularjs interview questions/angular interview questions/angularjs 6 interview questions

Dale Morris said...

Microsoft Edge Customer Service Number
Mozilla firefox Customer Support Number
Outlook Customer Support Phone Number
Sbcglobal Support Phone Number
Yahoo Mail Contact Number Canada

Benish said...

Thank you for sharing useful information...
Best Python Training in Chennai/Python Training Institutes in Chennai/Python/Python Certification in Chennai/Best IT Courses in Chennai/python course duration and fee/python classroom training/python training in chennai chennai, tamil nadu/python training institute in chennai chennai, India/

Durai Raj said...

I feel satisfied to read your blog, you have been delivering a useful & unique information to our vision.keep blogging.
Regards,
Data Science Course in Chennai
Data Science Certification in Chennai
Data Science Training Institute in Chennai
R Training in Chennai
RPA Training in Chennai
DevOps certification in Chennai
Data Science course in Velachery
Data Science course in Tambaram
Data Science Training in Porur

Pardeep Mengi said...

Usually I never comment on blogs but your article is so convincing that I never stop myself to say something about it. You’re doing a great job Man,Keep it up.
New Zealand education Consultants in Delhi

Kayal m said...

The article is so informative. This is more useful for me. Keep doing great work and a good job.

Tableau Training in Chennai
Tableau Course in Chennai
Advanced Excel Training in Chennai
Corporate Training in Chennai
Pega Training in Chennai
Linux Training in Chennai
Power BI Training in Chennai
Job Openings in Chennai
Tableau Training in Tambaram
Tableau Training in Adyar

gokul said...

Thank you for this informative blog
Top 5 Data science training in chennai
Data science training in chennai
Data science training in velachery
Data science training in OMR
Best Data science training in chennai
Data science training course content
Data science certification in chennai
Data science courses in chennai
Data science training institute in chennai
Data science online course
Data science with python training in chennai
Data science with R training in chennai

Robbie Royce said...

Good information and, keep sharing like this.

Crm Software Development Company in Chennai

Benish said...

Nice post...Thank you for sharing..
Best Python Training in Chennai/Python Training Institutes in Chennai/Python/Python Certification in Chennai/Best IT Courses in Chennai/python course duration and fee/python classroom training/python training in chennai chennai, tamil nadu/python training institute in chennai chennai, India/

swathima said...

Nice Presentation and its hopefull words..
if you want a cheap web hosting in web
cheap web hosting company chennai
erp software development company in chennai
Professional webdesigning company in chennai
best seo company in chennai

Savanah Eden said...

thanks for ur valuable information,keep going touch with us

Scaffolding dealers in chennai

shanthumA said...

Nice post, you provided a valuable information, keep going.

Prestashop ecommerce development company chennai
Prestashop ecommerce development company in chennai
Prestashop ecommerce development company
Prestashop ecommerce development company in india

Benish said...

Nice blog...Thanks for sharing..
Python training in Chennai/Python training in OMR/Python training in Velachery/Python certification training in Chennai/Python training fees in Chennai/Python training with placement in Chennai/Python training in Chennai with Placement/Python course in Chennai/Python Certification course in Chennai/Python online training in Chennai/Python training in Chennai Quora/Best Python Training in Chennai/Best Python training in OMR/Best Python training in Velachery/Best Python course in Chennai/<a

Jasikajessy said...

Nice information keep sharing like this.

scaffolding dealers in chennai
Aluminium scaffolding dealers in chennai
Aluminium scaffolding hire

Health said...

Thanks For Sharing Such a Amazing Post.
a2z life style

taishadarelene said...

Wow, Great information and this is very useful for us.

professional bridal makeup artist in chennai
best bridal makeup artist in chennai

Unknown said...


Nice information Keep going
vito food oil dealers in chennai
freezer with plastic body dealers in chennai

gautham said...

Nice and updated information you have provided. this will be helpful to learn through azure online training hyderabad on azure technology

Unknown said...


Great information and this is very useful for us.

post free classified ads in india

Techy said...

Nice Post
For Data Science training in Bangalore, Visit:
Data Science training in Bangalore

Unknown said...

लिंग 2-3 इंच लम्बा, 1 इंच मोटा करें यौन शक्ति को बढ़ायें, वीर्य को ताकतवर बनायें तथा, शीघ्रपतन की समस्या को जड़ से समाप्त करें। ODER NOW :- http://www.ubracare.com/hot/

Techy said...

Nice post
For AWS training in Bangalore, Visit:
AWS training in Bangalore

Techy said...

Visit for Artificial intelligence in Bangalore-->
Artificial Intelligence training in Bangalore

balamurugan said...

Thanks for updating this information. Good job.
German Classes in Chennai
German Language Classes in Chennai
French Classes in Chennai
pearson vue test center in chennai
Informatica Training in Chennai
Data Analytics Courses in Chennai
spanish language in chennai
content writing training in chennai
content writing course in chennai
spanish language course in chennai
German Classes in T Nagar
German Classes in Anna Nagar

DumpsPass4sure said...

Comprehensiveness and conciseness are the two specialties of Checkpoint briandumps which attracted me the most. It was because of these qualities that I aced my IT certification by the first attempt. Pass4sure Checkpoint dumps material does not have any other match and is the best.