On 3/26/14, Stephen Kelly <steve...@gmail.com> wrote: > Eric Wing wrote: >> I have been using my fork of the Android-CMake (originally from >> OpenCV) that you want to obsolete. My fork contains a lot of fixes to >> deal with more recent NDK updates and more complicated requirements >> that I have. >> https://bitbucket.org/ewing/android-cmake > > It's great to have someone here who is both familiar with cmake and with > Android! > >> >> It is completely reliant on the Android "standalone toolchain" >> technique which I vastly dislike, > > Sorry, I don't know what you're referring to. What is a standalone > toolchain? This: > > https://www.assembla.com/code/android-gb-for-sharp-is01/git/nodes/debug/ndk/docs/STANDALONE-TOOLCHAIN.html > > ? > > It looks like the primary usefulness of that is to avoid the caller having > to specify the -sysroot. Do I misunderstand? With CMAKE_SYSROOT in CMake > 3.0, and with the platform file I proposed, I don't see what makes that > "standalone toolchain" stuff useful. > > Can you explain? >
Yes, I think that one. In the docs/ directory of the Android NDK you download, you can find the file: STANDALONE-TOOLCHAIN.html As I understand it, it basically copies selected things out of the Android NDK into another directory with a layout more consistent with typical distributions so you can more easily use 3rd party tools like CMake. Since Android overloads things like the architectures, the compiler, and the standard libraries, each permutation you care about must be copied out into a separate standalone toolchain instance. This is one of the things that is annoying about it; depending on Android NDK version, you may have 4 different compilers, each with 4 different C++ standard libraries (all of which are not necessarily compatible with each other). That means 4x4=16 permutations. If you want to distinguish between dynamic and static linking, then you may need to multiply by 2. Additionally, each architecture is a permutation, so you need to multiply another 2 or 3. Then if you can about specific ARM features not available on all chips (e.g. NEON), you add a bunch more for that. (The current Android-CMake toolchain seems to have some settings for those which I've mostly ignored so far.) Oh yeah, I think each API version needs its own standalone toolchain. It also looks like the latest Android NDK (r9d) made some additions/changes. https://developer.android.com/tools/sdk/ndk/index.html I think it is theoretically possible to invoke the Android build process without using the standalone toolchain, but the file/directory layout doesn't necessarily follow normal conventions. I think the original Android-CMake toolchain did support this, but somewhere around the 64-bit toolchain release, things broke pretty badly and I never got it to work. Android is free to re-arrange things and rename things and they seem to be emboldened to do so in the non-standalone toolchain. Additionally, because things are overloaded, you need to be very careful about not invoking the wrong options on the toolchain. I am mostly in middleware, so I need to build libraries that other people use. This means I am extremely sensitive to ABI issues and things like dynamic linking of C++ standard libraries or specific architecture optimizations that are not portable are huge no-no's and I need to trust what the toolchain is doing. There was also an alternative Android/CMake toolchain somebody wrote which I think didn't use the standalone toolchain and I tried to work with, but I started hitting a lot of the above problems which is what led me back to the more complicated OpenCV one. >> So while I'm not opposed to a brand new Android toolchain file, I want >> to assert that it needs to be correct and it does need to handle a >> variety of cases. So learn as much as you can from the existing ones. > > My aim is to put the things which should be in a Android.cmake platform file > > shipped with CMake into such a file. Some things belong in such a file, I > think, and others belong in a toolchain file maintained externally. > >> In my fork, I spent a lot of time re-reverse-engineering the >> standard/default Android flags passed to the compiler. OpenCV took too >> many liberties with changing what Android passes normally which >> resulted in unexpected/broken behavior for some of my other projects. >> I think a very conservative, deferential approach should be taken. > > If you can provide details, I think that would be useful. I wrote some comments in the changelog history in the comments of the file. My Mercurial history also has some stuff. There are too many details for me to remember. However, my general conclusion was try to match watch Android does by default (i.e. same flags). Another example is, I would defer to using the official "stable" compiler unless overridden. I think it is still gcc 4.6, not 4.8. I presume there is a reasoning behind the one they pick as the default/stable. >> I >> would also like it to understand multiple architectures which would >> also go a long way to simplifying the end-user experience, though I'm >> worried this might take deeper CMake changes. > > I expect so, but knowing what the needs are helps inform what those changes > > might look like. > > http://public.kitware.com/Bug/view.php?id=14539 > I'm not sure either. I recall an old thread about this, and it sounded like CMake doesn't currently have the infrastructure to handle this. Mac/iOS avoid the problem because Apple overloaded the compiler so it could build Universal binaries with some additional flags which can avoid problems like needing to invoke the compiler/linker multiple times and having different files with different names or subdirectories. One other issue I would like to see fixed is that it is impossible to change some of the settings like architecture after the first generation. I find that this makes the CMake GUI interface completely useless to me and I always have to load up all my parameters up front on the command line. >> >>> set(ANDROID_SDK_ROOT "/home/stephen/android/android-sdk-linux/") >>> set(ANDROID_NDK_ROOT "/home/stephen/android/android-ndk-r9/") >> >> It should also handle the semi-blessed/official Android environmental >> variables like ANDROID_SDK_ROOT and ANDROID_NDK_ROOT so you don't have >> to explicitly set them in CMake scripts. > > It does. Did you look at the Android.cmake I posted? I only skimmed it. I missed the $ENV{ANDROID_SDK_ROOT} you had. I'm glad you included that. Looks like there are some new ones we should support like NDK_TOOLCHAIN_VERSION. >>> set(ANDROID_NDK_PLATFORM "android-18") >> >> It should automatically detect and use the latest Android target API >> if it is not explicitly specified. > > My Android.cmake also reads that from the environment. If there's a way to > detect it automatically, that might be a good idea. Can you say how? My idea is just to scan the directories in the NDK itself and take the highest number found. In platforms/, there are the following directories: android-13/ android-14/ android-15/ android-16/ android-17/ android-18/ android-19/ android-3/ android-4/ android-5/ android-8/ android-9/ 19 is the max in my NDK, so that should be the one that is picked by default. > Can you tell me for certain whether you looked at the Android.cmake file I > linked to already? Knowing whether you did would help our discussion I > think. > I'm looking at it now. I think you understand the non-standalone toolchain better than me, so you might be able to lead that part of the discussion. Though, one other consideration is maintainability. Android keeps changing version numbers and moving/breaking things. I don't have a good answer, but you can see in the OpenCV toolchain, there is a lot of version fixes which are pretty unwieldily. One simple idea is to not try to write a single toolchain that handles all the differences, but just copy the file and make changes as needed for each NDK version. Thanks, Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers