CMake + Gradle for Android

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Robert Dailey-2
Another reason to reduce the number of binary directories is that
there are different ways of managing third party libraries. One in
particular that we use is to clone a repository into the binary
directory and build all third party libs in real time based on a
toolchain file (Similar to the functionality provided by
ExternalProject module in CMake). This is repeated from scratch only
if the work hasn't already been done in the binary directory before.
By having more binary dirs than needed, this work is being done an
exponential amount of times which can result in a lot of wasted time
waiting. There are 1 time operations that multiple targets can benefit
from in a single binary tree, instead of 1 per unique target being
invoked.

Sorry to keep responding: I'm just thinking of things as I go and
bringing them up, to shed light on some of the reasoning behind my
suggestions.

On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey <[hidden email]> wrote:

> Sorry I forgot to answer your last set of questions:
>
> CommonLib is indeed 2 things:
>
> * A common (static or shared) library for native code (most of our
> CMake targets specify CommonLib as a link dependency)
> * A common library for Java code (we do specify this as a dependency
> for most java targets in Gradle, specifically those under
> Applications/)
>
> On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]> wrote:
>> Hi Robert,
>>
>> I work with Jom on the Android Studio team, and I would like to clarify a
>> few things to better understand your situation.
>> You mentioned the project is intend to be cross platform.  Normally, in such
>> situation, we expect there to be a single CMake root project to be imported
>> into one of the Android library/application.  However, in your case, there
>> are subprojects with Java code.
>>
>> Are the CMake code in App1/2/3 intended to be cross platform too?  Or are
>> they Android specific code?  If they are meant to be cross platform, how
>> does the Java code works on other platforms?  Or perhaps you added Java
>> binding in those subprojects just for Android?
>>
>> The build.gradle in CommonLib, what kind of Gradle project is that?  From
>> your description, it doesn't look like an Android library project.  Or am I
>> mistaken and it also applies the android library plugin?
>>
>> Raymond
>>
>> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]> wrote:
>>>
>>> + a colleague
>>>
>>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher <[hidden email]>
>>> wrote:
>>>>
>>>> You can find that number like this:
>>>> - x = number of externalNativeBuild.cmake.path in your build.gradle files
>>>> - y = number of gradle configurations (like debug and release)
>>>> - z = number of ABIs that you build
>>>>
>>>> The result is x * y * z. To be more accurate, you should consider y and z
>>>> to be functions of each build.gradle file since these can vary.
>>>>
>>>> There is a second set of folders that hold the stripped versions of the
>>>> .so files that is purely managed by the android gradle plugin, so you might
>>>> consider the answer to be 2 * x * y * z.
>>>>
>>>> Hope this helps.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey <[hidden email]>
>>>> wrote:
>>>>>
>>>>> This definitely a bit better, but still requires the boilerplate in
>>>>> each leaf gradle file. But I can't seriously complain too much. I
>>>>> think I'm more concerned with the implications this has underneath.
>>>>> First, let me ask just to make sure I'm not misunderstanding: Does
>>>>> each `externalNativeBuild` entry essentially mean 1 CMAKE_BINARY_DIR?
>>>>> How many binary dirs do you manage internally and what determines when
>>>>> they get created?
>>>>>
>>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher <[hidden email]>
>>>>> wrote:
>>>>> > Would it work for your scenario to provide properties in the root
>>>>> > build.gradle:
>>>>> >
>>>>> > ext {
>>>>> >     cmakePath = file "CMakeLists.txt"
>>>>> > }
>>>>> >
>>>>> > And then consume them in the leaf app/build.gradle like this?
>>>>> >
>>>>> > externalNativeBuild {
>>>>> >     cmake {
>>>>> >         path cmakePath
>>>>> >     }
>>>>> > }
>>>>> >
>>>>> > It doesn't fully hide the details but it does centralize the
>>>>> > information.
>>>>> >
>>>>> >
>>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>>>>> > <[hidden email]>
>>>>> > wrote:
>>>>> >>
>>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>>>>> >> platforms that use these CMake scripts as well. For example, I run on
>>>>> >> Windows and Linux platforms as well to build the native code. Normal
>>>>> >> CMake behavior is designed to work at a root then go downwards to
>>>>> >> find
>>>>> >> targets. However it seems Gradle wants to start at a subdirectory and
>>>>> >> work its way up to the root, which is opposite of CMake's intended
>>>>> >> behavior IMHO. Not only that but I want to avoid special-casing
>>>>> >> behavior in CMake just for Android's use.
>>>>> >>
>>>>> >> At the moment it feels like (again referring back to my previous
>>>>> >> example structure) that both App2 and App3 each run CMake in
>>>>> >> independent binary directories instead of sharing 1 binary directory
>>>>> >> and building 2 targets inside of it. I prefer this behavior instead,
>>>>> >> especially since it allows CMake to operate as it was intended. I
>>>>> >> think it's a common case that projects will define multiple targets
>>>>> >> starting from a single root, and expect multiple APKs or java
>>>>> >> dependencies to be built within it.
>>>>> >>
>>>>> >> If I'm misunderstanding or making false assumptions please let me
>>>>> >> know.
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher <[hidden email]>
>>>>> >> wrote:
>>>>> >> > Would it work for your situation for the leaf CMakeLists.txt to
>>>>> >> > include
>>>>> >> > the
>>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in the leaf
>>>>> >> > CMakeLists.txt?
>>>>> >> >
>>>>> >> >
>>>>> >> >
>>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>>>>> >> > <[hidden email]>
>>>>> >> > wrote:
>>>>> >> >>
>>>>> >> >> Basically, yes. We have this sort of structure:
>>>>> >> >>
>>>>> >> >> <Root of git clone>/
>>>>> >> >>     Applications/
>>>>> >> >>         App1/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>         App2/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>         App3/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>     CommonLib/
>>>>> >> >>         build.gradle
>>>>> >> >>         CMakeLists.txt
>>>>> >> >>     CMakeLists.txt
>>>>> >> >>
>>>>> >> >> The libs are defined as follows:
>>>>> >> >>
>>>>> >> >> * CommonLib is a static library (java code builds into a library)
>>>>> >> >>     * No dependencies of its own
>>>>> >> >> * App1 is a shared library (java code builds into a library)
>>>>> >> >>     * Dependencies (both java & native): CommonLib
>>>>> >> >> * App2 is a shared library (java code builds into an APK)
>>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>>>>> >> >> * App3 is a shared library (java code builds into an APK)
>>>>> >> >>    * Dependencies (both java & native): CommonLib
>>>>> >> >>
>>>>> >> >> In all cases, CMake must be invoked starting at the root
>>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the same
>>>>> >> >> binary
>>>>> >> >> directory after that. Previously with ANT, I was building all
>>>>> >> >> native
>>>>> >> >> targets first, then moved libs to appropriate directories so that
>>>>> >> >> the
>>>>> >> >> 'ant' command would package the libs.
>>>>> >> >>
>>>>> >> >> For gradle, I wanted to avoid redundantly specifying the root
>>>>> >> >> directory in each leaf-level project directory. Using the example
>>>>> >> >> above, the leaf-level directories in this case would be App1,
>>>>> >> >> App2,
>>>>> >> >> App3, and CommonLib. However I think we only specify the native
>>>>> >> >> CMake
>>>>> >> >> stuff for the java targets that actually output an APK (that would
>>>>> >> >> be
>>>>> >> >> App2 and App3 only).
>>>>> >> >>
>>>>> >> >> The ultimate goal is to specify stuff that doesn't change per
>>>>> >> >> independent "module" of ours at the top level so it is transitive
>>>>> >> >> /
>>>>> >> >> inherited. Then only specify the differences (e.g. the native
>>>>> >> >> CMake
>>>>> >> >> target to build) in the leaf build gradle files. However you
>>>>> >> >> indicated
>>>>> >> >> this isn't possible.
>>>>> >> >>
>>>>> >> >>
>>>>> >> >>
>>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>>>>> >> >> <[hidden email]>
>>>>> >> >> wrote:
>>>>> >> >> > What you're doing already sounds correct. You can't directly
>>>>> >> >> > specify
>>>>> >> >> > CMakeLists.txt from the top-level build.gradle. Recommendation
>>>>> >> >> > is
>>>>> >> >> > that
>>>>> >> >> > it
>>>>> >> >> > should be specified from the build.gradle of the module of the
>>>>> >> >> > APK.
>>>>> >> >> > Is
>>>>> >> >> > the
>>>>> >> >> > issue that you have multiple APK modules that all reference the
>>>>> >> >> > same
>>>>> >> >> > CMake
>>>>> >> >> > libraries?
>>>>> >> >> >
>>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>>>>> >> >> > <[hidden email]>
>>>>> >> >> > wrote:
>>>>> >> >> >>
>>>>> >> >> >> Thanks this is very helpful. The other question I have is: Is
>>>>> >> >> >> there
>>>>> >> >> >> a
>>>>> >> >> >> place to centrally specify the root CMakeLists.txt? Basically,
>>>>> >> >> >> I
>>>>> >> >> >> want
>>>>> >> >> >> to specify the CMake root in 1 place, and have targets (defined
>>>>> >> >> >> further down in subdirectories) that require APK packaging to
>>>>> >> >> >> specify
>>>>> >> >> >> only the native target name that should be built & packaged.
>>>>> >> >> >>
>>>>> >> >> >> At the moment we specify the root CMakeLists.txt by walking up
>>>>> >> >> >> the
>>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think this
>>>>> >> >> >> should
>>>>> >> >> >> be
>>>>> >> >> >> put at the top-level build gradle file if possible. Is this
>>>>> >> >> >> doable
>>>>> >> >> >> at
>>>>> >> >> >> the moment? What is the recommended setup?
>>>>> >> >> >>
>>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>>>>> >> >> >> <[hidden email]>
>>>>> >> >> >> wrote:
>>>>> >> >> >> > Gradle does introspection on the CMake build to find .so
>>>>> >> >> >> > targets
>>>>> >> >> >> > and
>>>>> >> >> >> > those
>>>>> >> >> >> > get packaged.
>>>>> >> >> >> > There is also a special case for stl/runtime .so files from
>>>>> >> >> >> > the
>>>>> >> >> >> > NDK.
>>>>> >> >> >> > Any additional .so files need to specified in build.gradle
>>>>> >> >> >> > using
>>>>> >> >> >> > jniDirs
>>>>> >> >> >> >
>>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>>>>> >> >> >> > <[hidden email]>
>>>>> >> >> >> > wrote:
>>>>> >> >> >> >>
>>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK? I know
>>>>> >> >> >> >> that
>>>>> >> >> >> >> ANT
>>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does Gradle
>>>>> >> >> >> >> do
>>>>> >> >> >> >> some
>>>>> >> >> >> >> introspection into CMake targets to see if outputs are *.so,
>>>>> >> >> >> >> and
>>>>> >> >> >> >> copy
>>>>> >> >> >> >> those to some location if needed? What about libraries like
>>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like to know
>>>>> >> >> >> >> if
>>>>> >> >> >> >> any
>>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs in
>>>>> >> >> >> >> proper
>>>>> >> >> >> >> locations for the APK build step. I had to do this when
>>>>> >> >> >> >> using
>>>>> >> >> >> >> ANT.
>>>>> >> >> >> >>
>>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>>>>> >> >> >> >> <[hidden email]>
>>>>> >> >> >> >> wrote:
>>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>>>>> >> >> >> >> > project
>>>>> >> >> >> >> > module
>>>>> >> >> >> >> > folder
>>>>> >> >> >> >> > (so unique per module per ABI)
>>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you can
>>>>> >> >> >> >> > choose
>>>>> >> >> >> >> > to
>>>>> >> >> >> >> > specify it
>>>>> >> >> >> >> > yourself from the build.gradle. This doc does a pretty
>>>>> >> >> >> >> > good job
>>>>> >> >> >> >> > of
>>>>> >> >> >> >> > explaining which variables are set by Gradle:
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>>>>> >> >> >> >> > Philosophically, we try to set as little as we can get
>>>>> >> >> >> >> > away
>>>>> >> >> >> >> > with.
>>>>> >> >> >> >> > In
>>>>> >> >> >> >> > particular, the section titled "Understanding the CMake
>>>>> >> >> >> >> > build
>>>>> >> >> >> >> > command"
>>>>> >> >> >> >> > lays
>>>>> >> >> >> >> > out exactly what we set. You can also see the folders we
>>>>> >> >> >> >> > specify
>>>>> >> >> >> >> > (one
>>>>> >> >> >> >> > per
>>>>> >> >> >> >> > module per ABI)
>>>>> >> >> >> >> > 3) Not sure I understand this.
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > The other document worth taking a look at (if you haven't
>>>>> >> >> >> >> > already)
>>>>> >> >> >> >> > is:
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>>>>> >> >> >> >> > <[hidden email]>
>>>>> >> >> >> >> > wrote:
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Thanks Jom
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because that's
>>>>> >> >> >> >> >> how
>>>>> >> >> >> >> >> Google's
>>>>> >> >> >> >> >> officially supporting CMake. But it also has debugging
>>>>> >> >> >> >> >> which
>>>>> >> >> >> >> >> is
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> #1
>>>>> >> >> >> >> >> reason for me.
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> However, I'd like to understand a lot more about how the
>>>>> >> >> >> >> >> integration
>>>>> >> >> >> >> >> really happens. For example, I have these questions:
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> 1) How, internally, are CMake build directories managed?
>>>>> >> >> >> >> >> Do
>>>>> >> >> >> >> >> you
>>>>> >> >> >> >> >> generate 1 per unique android project? What about for
>>>>> >> >> >> >> >> each
>>>>> >> >> >> >> >> specific
>>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>>>>> >> >> >> >> >> 2) Last time I looked into CMake integration, things
>>>>> >> >> >> >> >> defined
>>>>> >> >> >> >> >> inside
>>>>> >> >> >> >> >> the CMake scripts were ignored because they are specified
>>>>> >> >> >> >> >> at
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> command line. Namely, all of those settings that are
>>>>> >> >> >> >> >> driven by
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> Gradle configuration (CXX language level was one in
>>>>> >> >> >> >> >> particular
>>>>> >> >> >> >> >> I
>>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I recall
>>>>> >> >> >> >> >> this
>>>>> >> >> >> >> >> being
>>>>> >> >> >> >> >> overridden from outside)?
>>>>> >> >> >> >> >> 3) How redundant is it to configure individual libraries
>>>>> >> >> >> >> >> via
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted to
>>>>> >> >> >> >> >> define
>>>>> >> >> >> >> >> common
>>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle or
>>>>> >> >> >> >> >> settings
>>>>> >> >> >> >> >> file,
>>>>> >> >> >> >> >> and
>>>>> >> >> >> >> >> only define the differences in the actual gradle build
>>>>> >> >> >> >> >> files
>>>>> >> >> >> >> >> for
>>>>> >> >> >> >> >> each
>>>>> >> >> >> >> >> corresponding Java target (like, defining the name of the
>>>>> >> >> >> >> >> native
>>>>> >> >> >> >> >> (shared library) target in Gradle, but the command line
>>>>> >> >> >> >> >> invocation,
>>>>> >> >> >> >> >> -D
>>>>> >> >> >> >> >> CMake settings, etc would all be common and defined at
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> root).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way of
>>>>> >> >> >> >> >> doing
>>>>> >> >> >> >> >> things
>>>>> >> >> >> >> >> and
>>>>> >> >> >> >> >> keep CMake-related settings self-contained to the CMake
>>>>> >> >> >> >> >> scripts
>>>>> >> >> >> >> >> themselves, the better. This also makes cross-platform
>>>>> >> >> >> >> >> easier
>>>>> >> >> >> >> >> (we
>>>>> >> >> >> >> >> build the native code in Windows, for example, so having
>>>>> >> >> >> >> >> settings
>>>>> >> >> >> >> >> specified in the gradle files do not carry over to other
>>>>> >> >> >> >> >> platforms.
>>>>> >> >> >> >> >> Namely, settings that are not platform specific like the
>>>>> >> >> >> >> >> C++
>>>>> >> >> >> >> >> language
>>>>> >> >> >> >> >> level).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> If there's a detailed document / wiki I can read on the
>>>>> >> >> >> >> >> intrinsics
>>>>> >> >> >> >> >> of
>>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd love to
>>>>> >> >> >> >> >> read
>>>>> >> >> >> >> >> it.
>>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your brain as
>>>>> >> >> >> >> >> questions
>>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now and
>>>>> >> >> >> >> >> see how
>>>>> >> >> >> >> >> it
>>>>> >> >> >> >> >> goes. It's just black box for me because unlike option 2,
>>>>> >> >> >> >> >> I
>>>>> >> >> >> >> >> have
>>>>> >> >> >> >> >> very
>>>>> >> >> >> >> >> little control over what happens after building the
>>>>> >> >> >> >> >> shared
>>>>> >> >> >> >> >> libraries,
>>>>> >> >> >> >> >> and to make up for that I need to really get a deep
>>>>> >> >> >> >> >> understanding
>>>>> >> >> >> >> >> of
>>>>> >> >> >> >> >> how it works so I can make sure I code my CMake scripts
>>>>> >> >> >> >> >> properly
>>>>> >> >> >> >> >> for
>>>>> >> >> >> >> >> not only Android, but my other platforms as well
>>>>> >> >> >> >> >> (non-Android
>>>>> >> >> >> >> >> platforms).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Thanks again.
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>>>>> >> >> >> >> >> <[hidden email]>
>>>>> >> >> >> >> >> wrote:
>>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work on
>>>>> >> >> >> >> >> > Android
>>>>> >> >> >> >> >> > Studio
>>>>> >> >> >> >> >> > and
>>>>> >> >> >> >> >> > was
>>>>> >> >> >> >> >> > the one that added CMake support.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and we're
>>>>> >> >> >> >> >> > working
>>>>> >> >> >> >> >> > toward
>>>>> >> >> >> >> >> > getting
>>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't really say
>>>>> >> >> >> >> >> > when
>>>>> >> >> >> >> >> > that
>>>>> >> >> >> >> >> > will
>>>>> >> >> >> >> >> > happen
>>>>> >> >> >> >> >> > but if you can get away with an older CMake for now
>>>>> >> >> >> >> >> > then I'd
>>>>> >> >> >> >> >> > go
>>>>> >> >> >> >> >> > this
>>>>> >> >> >> >> >> > way.
>>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to view
>>>>> >> >> >> >> >> > your
>>>>> >> >> >> >> >> > source
>>>>> >> >> >> >> >> > file
>>>>> >> >> >> >> >> > structure in Android Studio, edit files, and debug
>>>>> >> >> >> >> >> > using the
>>>>> >> >> >> >> >> > built-in
>>>>> >> >> >> >> >> > debugging support.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs setting
>>>>> >> >> >> >> >> > to
>>>>> >> >> >> >> >> > tell
>>>>> >> >> >> >> >> > Android
>>>>> >> >> >> >> >> > Gradle where to pick up your built .so files (see
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>>>>> >> >> >> >> >> > I'm not aware of any projects that use this approach
>>>>> >> >> >> >> >> > but it
>>>>> >> >> >> >> >> > should
>>>>> >> >> >> >> >> > work
>>>>> >> >> >> >> >> > in
>>>>> >> >> >> >> >> > principal.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > I hope this helps,
>>>>> >> >> >> >> >> > Jomo
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>>>>> >> >> >> >> >> > <[hidden email]>
>>>>> >> >> >> >> >> > wrote:
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Right now I have custom targets set to execute the
>>>>> >> >> >> >> >> >> "ant
>>>>> >> >> >> >> >> >> release"
>>>>> >> >> >> >> >> >> command after my native targets are built. Part of
>>>>> >> >> >> >> >> >> that
>>>>> >> >> >> >> >> >> command
>>>>> >> >> >> >> >> >> involves copying *.so files to the libs/armeabi-v7a
>>>>> >> >> >> >> >> >> directory
>>>>> >> >> >> >> >> >> so
>>>>> >> >> >> >> >> >> they
>>>>> >> >> >> >> >> >> get packaged in an APK.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using Android
>>>>> >> >> >> >> >> >> Studio and
>>>>> >> >> >> >> >> >> being
>>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is a few
>>>>> >> >> >> >> >> >> major
>>>>> >> >> >> >> >> >> releases
>>>>> >> >> >> >> >> >> behind. I see that as a negative.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same or
>>>>> >> >> >> >> >> >> similar
>>>>> >> >> >> >> >> >> to
>>>>> >> >> >> >> >> >> what
>>>>> >> >> >> >> >> >> I'm
>>>>> >> >> >> >> >> >> already doing: The custom targets I have would execute
>>>>> >> >> >> >> >> >> gradle
>>>>> >> >> >> >> >> >> as
>>>>> >> >> >> >> >> >> a
>>>>> >> >> >> >> >> >> separate build step, instead of running ant commands.
>>>>> >> >> >> >> >> >> I'm
>>>>> >> >> >> >> >> >> not
>>>>> >> >> >> >> >> >> too
>>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you tell it
>>>>> >> >> >> >> >> >> where
>>>>> >> >> >> >> >> >> your
>>>>> >> >> >> >> >> >> shared libraries are for the APK packaging steps.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using one of
>>>>> >> >> >> >> >> >> these
>>>>> >> >> >> >> >> >> setups
>>>>> >> >> >> >> >> >> successfully? The downside to option 2 is probably no
>>>>> >> >> >> >> >> >> on-device
>>>>> >> >> >> >> >> >> native
>>>>> >> >> >> >> >> >> debugging since Android Studio probably can't handle
>>>>> >> >> >> >> >> >> gradle
>>>>> >> >> >> >> >> >> projects
>>>>> >> >> >> >> >> >> without any external CMake builds set up.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Would like some general direction & advice before I
>>>>> >> >> >> >> >> >> move
>>>>> >> >> >> >> >> >> away
>>>>> >> >> >> >> >> >> from
>>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>>>>> >> >> >> >> >> >> --
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >
>>>>> >> >> >> >
>>>>> >> >> >
>>>>> >> >> >
>>>>> >> >
>>>>> >> >
>>>>> >
>>>>> >
>>>>
>>>>
>>>
>>
--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Jom O'Fisher
Thanks for the write-up Robert. Having thought about it, I don't believe we have a satisfying answer at the gradle level for this kind of organization. In the gradle model module projects are the unit of organization for configurations, C/C++ flags, etc. and that's something we're pretty much stuck with.
Regarding just the redundant build issue, would something like ccache help? I know people have used it with ndk-build with success, I'm not sure about CMake but I don't see why that should make a difference.



On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey <[hidden email]> wrote:
Another reason to reduce the number of binary directories is that
there are different ways of managing third party libraries. One in
particular that we use is to clone a repository into the binary
directory and build all third party libs in real time based on a
toolchain file (Similar to the functionality provided by
ExternalProject module in CMake). This is repeated from scratch only
if the work hasn't already been done in the binary directory before.
By having more binary dirs than needed, this work is being done an
exponential amount of times which can result in a lot of wasted time
waiting. There are 1 time operations that multiple targets can benefit
from in a single binary tree, instead of 1 per unique target being
invoked.

Sorry to keep responding: I'm just thinking of things as I go and
bringing them up, to shed light on some of the reasoning behind my
suggestions.

On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey <[hidden email]> wrote:
> Sorry I forgot to answer your last set of questions:
>
> CommonLib is indeed 2 things:
>
> * A common (static or shared) library for native code (most of our
> CMake targets specify CommonLib as a link dependency)
> * A common library for Java code (we do specify this as a dependency
> for most java targets in Gradle, specifically those under
> Applications/)
>
> On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]> wrote:
>> Hi Robert,
>>
>> I work with Jom on the Android Studio team, and I would like to clarify a
>> few things to better understand your situation.
>> You mentioned the project is intend to be cross platform.  Normally, in such
>> situation, we expect there to be a single CMake root project to be imported
>> into one of the Android library/application.  However, in your case, there
>> are subprojects with Java code.
>>
>> Are the CMake code in App1/2/3 intended to be cross platform too?  Or are
>> they Android specific code?  If they are meant to be cross platform, how
>> does the Java code works on other platforms?  Or perhaps you added Java
>> binding in those subprojects just for Android?
>>
>> The build.gradle in CommonLib, what kind of Gradle project is that?  From
>> your description, it doesn't look like an Android library project.  Or am I
>> mistaken and it also applies the android library plugin?
>>
>> Raymond
>>
>> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]> wrote:
>>>
>>> + a colleague
>>>
>>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher <[hidden email]>
>>> wrote:
>>>>
>>>> You can find that number like this:
>>>> - x = number of externalNativeBuild.cmake.path in your build.gradle files
>>>> - y = number of gradle configurations (like debug and release)
>>>> - z = number of ABIs that you build
>>>>
>>>> The result is x * y * z. To be more accurate, you should consider y and z
>>>> to be functions of each build.gradle file since these can vary.
>>>>
>>>> There is a second set of folders that hold the stripped versions of the
>>>> .so files that is purely managed by the android gradle plugin, so you might
>>>> consider the answer to be 2 * x * y * z.
>>>>
>>>> Hope this helps.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey <[hidden email]>
>>>> wrote:
>>>>>
>>>>> This definitely a bit better, but still requires the boilerplate in
>>>>> each leaf gradle file. But I can't seriously complain too much. I
>>>>> think I'm more concerned with the implications this has underneath.
>>>>> First, let me ask just to make sure I'm not misunderstanding: Does
>>>>> each `externalNativeBuild` entry essentially mean 1 CMAKE_BINARY_DIR?
>>>>> How many binary dirs do you manage internally and what determines when
>>>>> they get created?
>>>>>
>>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher <[hidden email]>
>>>>> wrote:
>>>>> > Would it work for your scenario to provide properties in the root
>>>>> > build.gradle:
>>>>> >
>>>>> > ext {
>>>>> >     cmakePath = file "CMakeLists.txt"
>>>>> > }
>>>>> >
>>>>> > And then consume them in the leaf app/build.gradle like this?
>>>>> >
>>>>> > externalNativeBuild {
>>>>> >     cmake {
>>>>> >         path cmakePath
>>>>> >     }
>>>>> > }
>>>>> >
>>>>> > It doesn't fully hide the details but it does centralize the
>>>>> > information.
>>>>> >
>>>>> >
>>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>>>>> > <[hidden email]>
>>>>> > wrote:
>>>>> >>
>>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>>>>> >> platforms that use these CMake scripts as well. For example, I run on
>>>>> >> Windows and Linux platforms as well to build the native code. Normal
>>>>> >> CMake behavior is designed to work at a root then go downwards to
>>>>> >> find
>>>>> >> targets. However it seems Gradle wants to start at a subdirectory and
>>>>> >> work its way up to the root, which is opposite of CMake's intended
>>>>> >> behavior IMHO. Not only that but I want to avoid special-casing
>>>>> >> behavior in CMake just for Android's use.
>>>>> >>
>>>>> >> At the moment it feels like (again referring back to my previous
>>>>> >> example structure) that both App2 and App3 each run CMake in
>>>>> >> independent binary directories instead of sharing 1 binary directory
>>>>> >> and building 2 targets inside of it. I prefer this behavior instead,
>>>>> >> especially since it allows CMake to operate as it was intended. I
>>>>> >> think it's a common case that projects will define multiple targets
>>>>> >> starting from a single root, and expect multiple APKs or java
>>>>> >> dependencies to be built within it.
>>>>> >>
>>>>> >> If I'm misunderstanding or making false assumptions please let me
>>>>> >> know.
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher <[hidden email]>
>>>>> >> wrote:
>>>>> >> > Would it work for your situation for the leaf CMakeLists.txt to
>>>>> >> > include
>>>>> >> > the
>>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in the leaf
>>>>> >> > CMakeLists.txt?
>>>>> >> >
>>>>> >> >
>>>>> >> >
>>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>>>>> >> > <[hidden email]>
>>>>> >> > wrote:
>>>>> >> >>
>>>>> >> >> Basically, yes. We have this sort of structure:
>>>>> >> >>
>>>>> >> >> <Root of git clone>/
>>>>> >> >>     Applications/
>>>>> >> >>         App1/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>         App2/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>         App3/
>>>>> >> >>             build.gradle
>>>>> >> >>             CMakeLists.txt
>>>>> >> >>     CommonLib/
>>>>> >> >>         build.gradle
>>>>> >> >>         CMakeLists.txt
>>>>> >> >>     CMakeLists.txt
>>>>> >> >>
>>>>> >> >> The libs are defined as follows:
>>>>> >> >>
>>>>> >> >> * CommonLib is a static library (java code builds into a library)
>>>>> >> >>     * No dependencies of its own
>>>>> >> >> * App1 is a shared library (java code builds into a library)
>>>>> >> >>     * Dependencies (both java & native): CommonLib
>>>>> >> >> * App2 is a shared library (java code builds into an APK)
>>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>>>>> >> >> * App3 is a shared library (java code builds into an APK)
>>>>> >> >>    * Dependencies (both java & native): CommonLib
>>>>> >> >>
>>>>> >> >> In all cases, CMake must be invoked starting at the root
>>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the same
>>>>> >> >> binary
>>>>> >> >> directory after that. Previously with ANT, I was building all
>>>>> >> >> native
>>>>> >> >> targets first, then moved libs to appropriate directories so that
>>>>> >> >> the
>>>>> >> >> 'ant' command would package the libs.
>>>>> >> >>
>>>>> >> >> For gradle, I wanted to avoid redundantly specifying the root
>>>>> >> >> directory in each leaf-level project directory. Using the example
>>>>> >> >> above, the leaf-level directories in this case would be App1,
>>>>> >> >> App2,
>>>>> >> >> App3, and CommonLib. However I think we only specify the native
>>>>> >> >> CMake
>>>>> >> >> stuff for the java targets that actually output an APK (that would
>>>>> >> >> be
>>>>> >> >> App2 and App3 only).
>>>>> >> >>
>>>>> >> >> The ultimate goal is to specify stuff that doesn't change per
>>>>> >> >> independent "module" of ours at the top level so it is transitive
>>>>> >> >> /
>>>>> >> >> inherited. Then only specify the differences (e.g. the native
>>>>> >> >> CMake
>>>>> >> >> target to build) in the leaf build gradle files. However you
>>>>> >> >> indicated
>>>>> >> >> this isn't possible.
>>>>> >> >>
>>>>> >> >>
>>>>> >> >>
>>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>>>>> >> >> <[hidden email]>
>>>>> >> >> wrote:
>>>>> >> >> > What you're doing already sounds correct. You can't directly
>>>>> >> >> > specify
>>>>> >> >> > CMakeLists.txt from the top-level build.gradle. Recommendation
>>>>> >> >> > is
>>>>> >> >> > that
>>>>> >> >> > it
>>>>> >> >> > should be specified from the build.gradle of the module of the
>>>>> >> >> > APK.
>>>>> >> >> > Is
>>>>> >> >> > the
>>>>> >> >> > issue that you have multiple APK modules that all reference the
>>>>> >> >> > same
>>>>> >> >> > CMake
>>>>> >> >> > libraries?
>>>>> >> >> >
>>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>>>>> >> >> > <[hidden email]>
>>>>> >> >> > wrote:
>>>>> >> >> >>
>>>>> >> >> >> Thanks this is very helpful. The other question I have is: Is
>>>>> >> >> >> there
>>>>> >> >> >> a
>>>>> >> >> >> place to centrally specify the root CMakeLists.txt? Basically,
>>>>> >> >> >> I
>>>>> >> >> >> want
>>>>> >> >> >> to specify the CMake root in 1 place, and have targets (defined
>>>>> >> >> >> further down in subdirectories) that require APK packaging to
>>>>> >> >> >> specify
>>>>> >> >> >> only the native target name that should be built & packaged.
>>>>> >> >> >>
>>>>> >> >> >> At the moment we specify the root CMakeLists.txt by walking up
>>>>> >> >> >> the
>>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think this
>>>>> >> >> >> should
>>>>> >> >> >> be
>>>>> >> >> >> put at the top-level build gradle file if possible. Is this
>>>>> >> >> >> doable
>>>>> >> >> >> at
>>>>> >> >> >> the moment? What is the recommended setup?
>>>>> >> >> >>
>>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>>>>> >> >> >> <[hidden email]>
>>>>> >> >> >> wrote:
>>>>> >> >> >> > Gradle does introspection on the CMake build to find .so
>>>>> >> >> >> > targets
>>>>> >> >> >> > and
>>>>> >> >> >> > those
>>>>> >> >> >> > get packaged.
>>>>> >> >> >> > There is also a special case for stl/runtime .so files from
>>>>> >> >> >> > the
>>>>> >> >> >> > NDK.
>>>>> >> >> >> > Any additional .so files need to specified in build.gradle
>>>>> >> >> >> > using
>>>>> >> >> >> > jniDirs
>>>>> >> >> >> >
>>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>>>>> >> >> >> > <[hidden email]>
>>>>> >> >> >> > wrote:
>>>>> >> >> >> >>
>>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK? I know
>>>>> >> >> >> >> that
>>>>> >> >> >> >> ANT
>>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does Gradle
>>>>> >> >> >> >> do
>>>>> >> >> >> >> some
>>>>> >> >> >> >> introspection into CMake targets to see if outputs are *.so,
>>>>> >> >> >> >> and
>>>>> >> >> >> >> copy
>>>>> >> >> >> >> those to some location if needed? What about libraries like
>>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like to know
>>>>> >> >> >> >> if
>>>>> >> >> >> >> any
>>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs in
>>>>> >> >> >> >> proper
>>>>> >> >> >> >> locations for the APK build step. I had to do this when
>>>>> >> >> >> >> using
>>>>> >> >> >> >> ANT.
>>>>> >> >> >> >>
>>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>>>>> >> >> >> >> <[hidden email]>
>>>>> >> >> >> >> wrote:
>>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>>>>> >> >> >> >> > project
>>>>> >> >> >> >> > module
>>>>> >> >> >> >> > folder
>>>>> >> >> >> >> > (so unique per module per ABI)
>>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you can
>>>>> >> >> >> >> > choose
>>>>> >> >> >> >> > to
>>>>> >> >> >> >> > specify it
>>>>> >> >> >> >> > yourself from the build.gradle. This doc does a pretty
>>>>> >> >> >> >> > good job
>>>>> >> >> >> >> > of
>>>>> >> >> >> >> > explaining which variables are set by Gradle:
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>>>>> >> >> >> >> > Philosophically, we try to set as little as we can get
>>>>> >> >> >> >> > away
>>>>> >> >> >> >> > with.
>>>>> >> >> >> >> > In
>>>>> >> >> >> >> > particular, the section titled "Understanding the CMake
>>>>> >> >> >> >> > build
>>>>> >> >> >> >> > command"
>>>>> >> >> >> >> > lays
>>>>> >> >> >> >> > out exactly what we set. You can also see the folders we
>>>>> >> >> >> >> > specify
>>>>> >> >> >> >> > (one
>>>>> >> >> >> >> > per
>>>>> >> >> >> >> > module per ABI)
>>>>> >> >> >> >> > 3) Not sure I understand this.
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > The other document worth taking a look at (if you haven't
>>>>> >> >> >> >> > already)
>>>>> >> >> >> >> > is:
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>>>>> >> >> >> >> > <[hidden email]>
>>>>> >> >> >> >> > wrote:
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Thanks Jom
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because that's
>>>>> >> >> >> >> >> how
>>>>> >> >> >> >> >> Google's
>>>>> >> >> >> >> >> officially supporting CMake. But it also has debugging
>>>>> >> >> >> >> >> which
>>>>> >> >> >> >> >> is
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> #1
>>>>> >> >> >> >> >> reason for me.
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> However, I'd like to understand a lot more about how the
>>>>> >> >> >> >> >> integration
>>>>> >> >> >> >> >> really happens. For example, I have these questions:
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> 1) How, internally, are CMake build directories managed?
>>>>> >> >> >> >> >> Do
>>>>> >> >> >> >> >> you
>>>>> >> >> >> >> >> generate 1 per unique android project? What about for
>>>>> >> >> >> >> >> each
>>>>> >> >> >> >> >> specific
>>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>>>>> >> >> >> >> >> 2) Last time I looked into CMake integration, things
>>>>> >> >> >> >> >> defined
>>>>> >> >> >> >> >> inside
>>>>> >> >> >> >> >> the CMake scripts were ignored because they are specified
>>>>> >> >> >> >> >> at
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> command line. Namely, all of those settings that are
>>>>> >> >> >> >> >> driven by
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> Gradle configuration (CXX language level was one in
>>>>> >> >> >> >> >> particular
>>>>> >> >> >> >> >> I
>>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I recall
>>>>> >> >> >> >> >> this
>>>>> >> >> >> >> >> being
>>>>> >> >> >> >> >> overridden from outside)?
>>>>> >> >> >> >> >> 3) How redundant is it to configure individual libraries
>>>>> >> >> >> >> >> via
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted to
>>>>> >> >> >> >> >> define
>>>>> >> >> >> >> >> common
>>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle or
>>>>> >> >> >> >> >> settings
>>>>> >> >> >> >> >> file,
>>>>> >> >> >> >> >> and
>>>>> >> >> >> >> >> only define the differences in the actual gradle build
>>>>> >> >> >> >> >> files
>>>>> >> >> >> >> >> for
>>>>> >> >> >> >> >> each
>>>>> >> >> >> >> >> corresponding Java target (like, defining the name of the
>>>>> >> >> >> >> >> native
>>>>> >> >> >> >> >> (shared library) target in Gradle, but the command line
>>>>> >> >> >> >> >> invocation,
>>>>> >> >> >> >> >> -D
>>>>> >> >> >> >> >> CMake settings, etc would all be common and defined at
>>>>> >> >> >> >> >> the
>>>>> >> >> >> >> >> root).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way of
>>>>> >> >> >> >> >> doing
>>>>> >> >> >> >> >> things
>>>>> >> >> >> >> >> and
>>>>> >> >> >> >> >> keep CMake-related settings self-contained to the CMake
>>>>> >> >> >> >> >> scripts
>>>>> >> >> >> >> >> themselves, the better. This also makes cross-platform
>>>>> >> >> >> >> >> easier
>>>>> >> >> >> >> >> (we
>>>>> >> >> >> >> >> build the native code in Windows, for example, so having
>>>>> >> >> >> >> >> settings
>>>>> >> >> >> >> >> specified in the gradle files do not carry over to other
>>>>> >> >> >> >> >> platforms.
>>>>> >> >> >> >> >> Namely, settings that are not platform specific like the
>>>>> >> >> >> >> >> C++
>>>>> >> >> >> >> >> language
>>>>> >> >> >> >> >> level).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> If there's a detailed document / wiki I can read on the
>>>>> >> >> >> >> >> intrinsics
>>>>> >> >> >> >> >> of
>>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd love to
>>>>> >> >> >> >> >> read
>>>>> >> >> >> >> >> it.
>>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your brain as
>>>>> >> >> >> >> >> questions
>>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now and
>>>>> >> >> >> >> >> see how
>>>>> >> >> >> >> >> it
>>>>> >> >> >> >> >> goes. It's just black box for me because unlike option 2,
>>>>> >> >> >> >> >> I
>>>>> >> >> >> >> >> have
>>>>> >> >> >> >> >> very
>>>>> >> >> >> >> >> little control over what happens after building the
>>>>> >> >> >> >> >> shared
>>>>> >> >> >> >> >> libraries,
>>>>> >> >> >> >> >> and to make up for that I need to really get a deep
>>>>> >> >> >> >> >> understanding
>>>>> >> >> >> >> >> of
>>>>> >> >> >> >> >> how it works so I can make sure I code my CMake scripts
>>>>> >> >> >> >> >> properly
>>>>> >> >> >> >> >> for
>>>>> >> >> >> >> >> not only Android, but my other platforms as well
>>>>> >> >> >> >> >> (non-Android
>>>>> >> >> >> >> >> platforms).
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> Thanks again.
>>>>> >> >> >> >> >>
>>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>>>>> >> >> >> >> >> <[hidden email]>
>>>>> >> >> >> >> >> wrote:
>>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work on
>>>>> >> >> >> >> >> > Android
>>>>> >> >> >> >> >> > Studio
>>>>> >> >> >> >> >> > and
>>>>> >> >> >> >> >> > was
>>>>> >> >> >> >> >> > the one that added CMake support.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and we're
>>>>> >> >> >> >> >> > working
>>>>> >> >> >> >> >> > toward
>>>>> >> >> >> >> >> > getting
>>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't really say
>>>>> >> >> >> >> >> > when
>>>>> >> >> >> >> >> > that
>>>>> >> >> >> >> >> > will
>>>>> >> >> >> >> >> > happen
>>>>> >> >> >> >> >> > but if you can get away with an older CMake for now
>>>>> >> >> >> >> >> > then I'd
>>>>> >> >> >> >> >> > go
>>>>> >> >> >> >> >> > this
>>>>> >> >> >> >> >> > way.
>>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to view
>>>>> >> >> >> >> >> > your
>>>>> >> >> >> >> >> > source
>>>>> >> >> >> >> >> > file
>>>>> >> >> >> >> >> > structure in Android Studio, edit files, and debug
>>>>> >> >> >> >> >> > using the
>>>>> >> >> >> >> >> > built-in
>>>>> >> >> >> >> >> > debugging support.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs setting
>>>>> >> >> >> >> >> > to
>>>>> >> >> >> >> >> > tell
>>>>> >> >> >> >> >> > Android
>>>>> >> >> >> >> >> > Gradle where to pick up your built .so files (see
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>>>>> >> >> >> >> >> > I'm not aware of any projects that use this approach
>>>>> >> >> >> >> >> > but it
>>>>> >> >> >> >> >> > should
>>>>> >> >> >> >> >> > work
>>>>> >> >> >> >> >> > in
>>>>> >> >> >> >> >> > principal.
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > I hope this helps,
>>>>> >> >> >> >> >> > Jomo
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>>>>> >> >> >> >> >> > <[hidden email]>
>>>>> >> >> >> >> >> > wrote:
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Right now I have custom targets set to execute the
>>>>> >> >> >> >> >> >> "ant
>>>>> >> >> >> >> >> >> release"
>>>>> >> >> >> >> >> >> command after my native targets are built. Part of
>>>>> >> >> >> >> >> >> that
>>>>> >> >> >> >> >> >> command
>>>>> >> >> >> >> >> >> involves copying *.so files to the libs/armeabi-v7a
>>>>> >> >> >> >> >> >> directory
>>>>> >> >> >> >> >> >> so
>>>>> >> >> >> >> >> >> they
>>>>> >> >> >> >> >> >> get packaged in an APK.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using Android
>>>>> >> >> >> >> >> >> Studio and
>>>>> >> >> >> >> >> >> being
>>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is a few
>>>>> >> >> >> >> >> >> major
>>>>> >> >> >> >> >> >> releases
>>>>> >> >> >> >> >> >> behind. I see that as a negative.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same or
>>>>> >> >> >> >> >> >> similar
>>>>> >> >> >> >> >> >> to
>>>>> >> >> >> >> >> >> what
>>>>> >> >> >> >> >> >> I'm
>>>>> >> >> >> >> >> >> already doing: The custom targets I have would execute
>>>>> >> >> >> >> >> >> gradle
>>>>> >> >> >> >> >> >> as
>>>>> >> >> >> >> >> >> a
>>>>> >> >> >> >> >> >> separate build step, instead of running ant commands.
>>>>> >> >> >> >> >> >> I'm
>>>>> >> >> >> >> >> >> not
>>>>> >> >> >> >> >> >> too
>>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you tell it
>>>>> >> >> >> >> >> >> where
>>>>> >> >> >> >> >> >> your
>>>>> >> >> >> >> >> >> shared libraries are for the APK packaging steps.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using one of
>>>>> >> >> >> >> >> >> these
>>>>> >> >> >> >> >> >> setups
>>>>> >> >> >> >> >> >> successfully? The downside to option 2 is probably no
>>>>> >> >> >> >> >> >> on-device
>>>>> >> >> >> >> >> >> native
>>>>> >> >> >> >> >> >> debugging since Android Studio probably can't handle
>>>>> >> >> >> >> >> >> gradle
>>>>> >> >> >> >> >> >> projects
>>>>> >> >> >> >> >> >> without any external CMake builds set up.
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> Would like some general direction & advice before I
>>>>> >> >> >> >> >> >> move
>>>>> >> >> >> >> >> >> away
>>>>> >> >> >> >> >> >> from
>>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>>>>> >> >> >> >> >> >> --
>>>>> >> >> >> >> >> >>
>>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >> >
>>>>> >> >> >> >
>>>>> >> >> >> >
>>>>> >> >> >
>>>>> >> >> >
>>>>> >> >
>>>>> >> >
>>>>> >
>>>>> >
>>>>
>>>>
>>>
>>


--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Robert Dailey-2
I'm not sure what you mean by "gradle module projects", but maybe
having some examples of what you mean by "configurations, C++ flags,
etc" might make it more clear.

Question: When specifying "path" for the CMakeLists.txt in the
build.gradle file, how do you know which targets to build? For
example, that run of CMake may generate 100 targets, but only 20 need
to build and be packaged (*.so files) with the APK. Do you just build
"all"? Is there a way to specify the target itself?

Thanks again. I'd still like to know more about what the ideal
organization is. I find it hard to believe that large android projects
rarely break things up into multiple, separate "components" that are
built independently. That's really the gist of what we're dealing with
here. Your typical "hello world" project likely will have only 1
CMakeLists.txt that is pretty self-contained, but all the
documentation I've looked at so far doesn't show the best way to
handle native library dependencies across java projects between
build.gradle files (or maybe I'm just not looking hard enough).

On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]> wrote:

> Thanks for the write-up Robert. Having thought about it, I don't believe we
> have a satisfying answer at the gradle level for this kind of organization.
> In the gradle model module projects are the unit of organization for
> configurations, C/C++ flags, etc. and that's something we're pretty much
> stuck with.
> Regarding just the redundant build issue, would something like ccache help?
> I know people have used it with ndk-build with success, I'm not sure about
> CMake but I don't see why that should make a difference.
>
>
>
> On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey <[hidden email]>
> wrote:
>>
>> Another reason to reduce the number of binary directories is that
>> there are different ways of managing third party libraries. One in
>> particular that we use is to clone a repository into the binary
>> directory and build all third party libs in real time based on a
>> toolchain file (Similar to the functionality provided by
>> ExternalProject module in CMake). This is repeated from scratch only
>> if the work hasn't already been done in the binary directory before.
>> By having more binary dirs than needed, this work is being done an
>> exponential amount of times which can result in a lot of wasted time
>> waiting. There are 1 time operations that multiple targets can benefit
>> from in a single binary tree, instead of 1 per unique target being
>> invoked.
>>
>> Sorry to keep responding: I'm just thinking of things as I go and
>> bringing them up, to shed light on some of the reasoning behind my
>> suggestions.
>>
>> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey <[hidden email]>
>> wrote:
>> > Sorry I forgot to answer your last set of questions:
>> >
>> > CommonLib is indeed 2 things:
>> >
>> > * A common (static or shared) library for native code (most of our
>> > CMake targets specify CommonLib as a link dependency)
>> > * A common library for Java code (we do specify this as a dependency
>> > for most java targets in Gradle, specifically those under
>> > Applications/)
>> >
>> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]> wrote:
>> >> Hi Robert,
>> >>
>> >> I work with Jom on the Android Studio team, and I would like to clarify
>> >> a
>> >> few things to better understand your situation.
>> >> You mentioned the project is intend to be cross platform.  Normally, in
>> >> such
>> >> situation, we expect there to be a single CMake root project to be
>> >> imported
>> >> into one of the Android library/application.  However, in your case,
>> >> there
>> >> are subprojects with Java code.
>> >>
>> >> Are the CMake code in App1/2/3 intended to be cross platform too?  Or
>> >> are
>> >> they Android specific code?  If they are meant to be cross platform,
>> >> how
>> >> does the Java code works on other platforms?  Or perhaps you added Java
>> >> binding in those subprojects just for Android?
>> >>
>> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> From
>> >> your description, it doesn't look like an Android library project.  Or
>> >> am I
>> >> mistaken and it also applies the android library plugin?
>> >>
>> >> Raymond
>> >>
>> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> wrote:
>> >>>
>> >>> + a colleague
>> >>>
>> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher <[hidden email]>
>> >>> wrote:
>> >>>>
>> >>>> You can find that number like this:
>> >>>> - x = number of externalNativeBuild.cmake.path in your build.gradle
>> >>>> files
>> >>>> - y = number of gradle configurations (like debug and release)
>> >>>> - z = number of ABIs that you build
>> >>>>
>> >>>> The result is x * y * z. To be more accurate, you should consider y
>> >>>> and z
>> >>>> to be functions of each build.gradle file since these can vary.
>> >>>>
>> >>>> There is a second set of folders that hold the stripped versions of
>> >>>> the
>> >>>> .so files that is purely managed by the android gradle plugin, so you
>> >>>> might
>> >>>> consider the answer to be 2 * x * y * z.
>> >>>>
>> >>>> Hope this helps.
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >>>> <[hidden email]>
>> >>>> wrote:
>> >>>>>
>> >>>>> This definitely a bit better, but still requires the boilerplate in
>> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >>>>> think I'm more concerned with the implications this has underneath.
>> >>>>> First, let me ask just to make sure I'm not misunderstanding: Does
>> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >>>>> CMAKE_BINARY_DIR?
>> >>>>> How many binary dirs do you manage internally and what determines
>> >>>>> when
>> >>>>> they get created?
>> >>>>>
>> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher <[hidden email]>
>> >>>>> wrote:
>> >>>>> > Would it work for your scenario to provide properties in the root
>> >>>>> > build.gradle:
>> >>>>> >
>> >>>>> > ext {
>> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >>>>> > }
>> >>>>> >
>> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >>>>> >
>> >>>>> > externalNativeBuild {
>> >>>>> >     cmake {
>> >>>>> >         path cmakePath
>> >>>>> >     }
>> >>>>> > }
>> >>>>> >
>> >>>>> > It doesn't fully hide the details but it does centralize the
>> >>>>> > information.
>> >>>>> >
>> >>>>> >
>> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >>>>> > <[hidden email]>
>> >>>>> > wrote:
>> >>>>> >>
>> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >>>>> >> run on
>> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >>>>> >> Normal
>> >>>>> >> CMake behavior is designed to work at a root then go downwards to
>> >>>>> >> find
>> >>>>> >> targets. However it seems Gradle wants to start at a subdirectory
>> >>>>> >> and
>> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >>>>> >> intended
>> >>>>> >> behavior IMHO. Not only that but I want to avoid special-casing
>> >>>>> >> behavior in CMake just for Android's use.
>> >>>>> >>
>> >>>>> >> At the moment it feels like (again referring back to my previous
>> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >>>>> >> independent binary directories instead of sharing 1 binary
>> >>>>> >> directory
>> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >>>>> >> instead,
>> >>>>> >> especially since it allows CMake to operate as it was intended. I
>> >>>>> >> think it's a common case that projects will define multiple
>> >>>>> >> targets
>> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >>>>> >> dependencies to be built within it.
>> >>>>> >>
>> >>>>> >> If I'm misunderstanding or making false assumptions please let me
>> >>>>> >> know.
>> >>>>> >>
>> >>>>> >>
>> >>>>> >>
>> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >>>>> >> <[hidden email]>
>> >>>>> >> wrote:
>> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt to
>> >>>>> >> > include
>> >>>>> >> > the
>> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in the
>> >>>>> >> > leaf
>> >>>>> >> > CMakeLists.txt?
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >>>>> >> > <[hidden email]>
>> >>>>> >> > wrote:
>> >>>>> >> >>
>> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >>>>> >> >>
>> >>>>> >> >> <Root of git clone>/
>> >>>>> >> >>     Applications/
>> >>>>> >> >>         App1/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>         App2/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>         App3/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>     CommonLib/
>> >>>>> >> >>         build.gradle
>> >>>>> >> >>         CMakeLists.txt
>> >>>>> >> >>     CMakeLists.txt
>> >>>>> >> >>
>> >>>>> >> >> The libs are defined as follows:
>> >>>>> >> >>
>> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >>>>> >> >> library)
>> >>>>> >> >>     * No dependencies of its own
>> >>>>> >> >> * App1 is a shared library (java code builds into a library)
>> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >>>>> >> >>
>> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the same
>> >>>>> >> >> binary
>> >>>>> >> >> directory after that. Previously with ANT, I was building all
>> >>>>> >> >> native
>> >>>>> >> >> targets first, then moved libs to appropriate directories so
>> >>>>> >> >> that
>> >>>>> >> >> the
>> >>>>> >> >> 'ant' command would package the libs.
>> >>>>> >> >>
>> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the root
>> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >>>>> >> >> example
>> >>>>> >> >> above, the leaf-level directories in this case would be App1,
>> >>>>> >> >> App2,
>> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >>>>> >> >> native
>> >>>>> >> >> CMake
>> >>>>> >> >> stuff for the java targets that actually output an APK (that
>> >>>>> >> >> would
>> >>>>> >> >> be
>> >>>>> >> >> App2 and App3 only).
>> >>>>> >> >>
>> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change per
>> >>>>> >> >> independent "module" of ours at the top level so it is
>> >>>>> >> >> transitive
>> >>>>> >> >> /
>> >>>>> >> >> inherited. Then only specify the differences (e.g. the native
>> >>>>> >> >> CMake
>> >>>>> >> >> target to build) in the leaf build gradle files. However you
>> >>>>> >> >> indicated
>> >>>>> >> >> this isn't possible.
>> >>>>> >> >>
>> >>>>> >> >>
>> >>>>> >> >>
>> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >>>>> >> >> <[hidden email]>
>> >>>>> >> >> wrote:
>> >>>>> >> >> > What you're doing already sounds correct. You can't directly
>> >>>>> >> >> > specify
>> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >>>>> >> >> > Recommendation
>> >>>>> >> >> > is
>> >>>>> >> >> > that
>> >>>>> >> >> > it
>> >>>>> >> >> > should be specified from the build.gradle of the module of
>> >>>>> >> >> > the
>> >>>>> >> >> > APK.
>> >>>>> >> >> > Is
>> >>>>> >> >> > the
>> >>>>> >> >> > issue that you have multiple APK modules that all reference
>> >>>>> >> >> > the
>> >>>>> >> >> > same
>> >>>>> >> >> > CMake
>> >>>>> >> >> > libraries?
>> >>>>> >> >> >
>> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >>>>> >> >> > <[hidden email]>
>> >>>>> >> >> > wrote:
>> >>>>> >> >> >>
>> >>>>> >> >> >> Thanks this is very helpful. The other question I have is:
>> >>>>> >> >> >> Is
>> >>>>> >> >> >> there
>> >>>>> >> >> >> a
>> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >>>>> >> >> >> Basically,
>> >>>>> >> >> >> I
>> >>>>> >> >> >> want
>> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >>>>> >> >> >> (defined
>> >>>>> >> >> >> further down in subdirectories) that require APK packaging
>> >>>>> >> >> >> to
>> >>>>> >> >> >> specify
>> >>>>> >> >> >> only the native target name that should be built &
>> >>>>> >> >> >> packaged.
>> >>>>> >> >> >>
>> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by walking
>> >>>>> >> >> >> up
>> >>>>> >> >> >> the
>> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think this
>> >>>>> >> >> >> should
>> >>>>> >> >> >> be
>> >>>>> >> >> >> put at the top-level build gradle file if possible. Is this
>> >>>>> >> >> >> doable
>> >>>>> >> >> >> at
>> >>>>> >> >> >> the moment? What is the recommended setup?
>> >>>>> >> >> >>
>> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >>>>> >> >> >> <[hidden email]>
>> >>>>> >> >> >> wrote:
>> >>>>> >> >> >> > Gradle does introspection on the CMake build to find .so
>> >>>>> >> >> >> > targets
>> >>>>> >> >> >> > and
>> >>>>> >> >> >> > those
>> >>>>> >> >> >> > get packaged.
>> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >>>>> >> >> >> > from
>> >>>>> >> >> >> > the
>> >>>>> >> >> >> > NDK.
>> >>>>> >> >> >> > Any additional .so files need to specified in
>> >>>>> >> >> >> > build.gradle
>> >>>>> >> >> >> > using
>> >>>>> >> >> >> > jniDirs
>> >>>>> >> >> >> >
>> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >>>>> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> > wrote:
>> >>>>> >> >> >> >>
>> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK? I
>> >>>>> >> >> >> >> know
>> >>>>> >> >> >> >> that
>> >>>>> >> >> >> >> ANT
>> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >>>>> >> >> >> >> Gradle
>> >>>>> >> >> >> >> do
>> >>>>> >> >> >> >> some
>> >>>>> >> >> >> >> introspection into CMake targets to see if outputs are
>> >>>>> >> >> >> >> *.so,
>> >>>>> >> >> >> >> and
>> >>>>> >> >> >> >> copy
>> >>>>> >> >> >> >> those to some location if needed? What about libraries
>> >>>>> >> >> >> >> like
>> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like to
>> >>>>> >> >> >> >> know
>> >>>>> >> >> >> >> if
>> >>>>> >> >> >> >> any
>> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs in
>> >>>>> >> >> >> >> proper
>> >>>>> >> >> >> >> locations for the APK build step. I had to do this when
>> >>>>> >> >> >> >> using
>> >>>>> >> >> >> >> ANT.
>> >>>>> >> >> >> >>
>> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >>>>> >> >> >> >> <[hidden email]>
>> >>>>> >> >> >> >> wrote:
>> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >>>>> >> >> >> >> > project
>> >>>>> >> >> >> >> > module
>> >>>>> >> >> >> >> > folder
>> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >>>>> >> >> >> >> > can
>> >>>>> >> >> >> >> > choose
>> >>>>> >> >> >> >> > to
>> >>>>> >> >> >> >> > specify it
>> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a pretty
>> >>>>> >> >> >> >> > good job
>> >>>>> >> >> >> >> > of
>> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can get
>> >>>>> >> >> >> >> > away
>> >>>>> >> >> >> >> > with.
>> >>>>> >> >> >> >> > In
>> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >>>>> >> >> >> >> > CMake
>> >>>>> >> >> >> >> > build
>> >>>>> >> >> >> >> > command"
>> >>>>> >> >> >> >> > lays
>> >>>>> >> >> >> >> > out exactly what we set. You can also see the folders
>> >>>>> >> >> >> >> > we
>> >>>>> >> >> >> >> > specify
>> >>>>> >> >> >> >> > (one
>> >>>>> >> >> >> >> > per
>> >>>>> >> >> >> >> > module per ABI)
>> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >>>>> >> >> >> >> > haven't
>> >>>>> >> >> >> >> > already)
>> >>>>> >> >> >> >> > is:
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >>>>> >> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> >> > wrote:
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Thanks Jom
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >>>>> >> >> >> >> >> that's
>> >>>>> >> >> >> >> >> how
>> >>>>> >> >> >> >> >> Google's
>> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >>>>> >> >> >> >> >> debugging
>> >>>>> >> >> >> >> >> which
>> >>>>> >> >> >> >> >> is
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> #1
>> >>>>> >> >> >> >> >> reason for me.
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about how
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> integration
>> >>>>> >> >> >> >> >> really happens. For example, I have these questions:
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >>>>> >> >> >> >> >> managed?
>> >>>>> >> >> >> >> >> Do
>> >>>>> >> >> >> >> >> you
>> >>>>> >> >> >> >> >> generate 1 per unique android project? What about for
>> >>>>> >> >> >> >> >> each
>> >>>>> >> >> >> >> >> specific
>> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration, things
>> >>>>> >> >> >> >> >> defined
>> >>>>> >> >> >> >> >> inside
>> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >>>>> >> >> >> >> >> specified
>> >>>>> >> >> >> >> >> at
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> command line. Namely, all of those settings that are
>> >>>>> >> >> >> >> >> driven by
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one in
>> >>>>> >> >> >> >> >> particular
>> >>>>> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >>>>> >> >> >> >> >> recall
>> >>>>> >> >> >> >> >> this
>> >>>>> >> >> >> >> >> being
>> >>>>> >> >> >> >> >> overridden from outside)?
>> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >>>>> >> >> >> >> >> libraries
>> >>>>> >> >> >> >> >> via
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted to
>> >>>>> >> >> >> >> >> define
>> >>>>> >> >> >> >> >> common
>> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle or
>> >>>>> >> >> >> >> >> settings
>> >>>>> >> >> >> >> >> file,
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >>>>> >> >> >> >> >> build
>> >>>>> >> >> >> >> >> files
>> >>>>> >> >> >> >> >> for
>> >>>>> >> >> >> >> >> each
>> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name of
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> native
>> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >>>>> >> >> >> >> >> line
>> >>>>> >> >> >> >> >> invocation,
>> >>>>> >> >> >> >> >> -D
>> >>>>> >> >> >> >> >> CMake settings, etc would all be common and defined
>> >>>>> >> >> >> >> >> at
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> root).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way of
>> >>>>> >> >> >> >> >> doing
>> >>>>> >> >> >> >> >> things
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >>>>> >> >> >> >> >> CMake
>> >>>>> >> >> >> >> >> scripts
>> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >>>>> >> >> >> >> >> cross-platform
>> >>>>> >> >> >> >> >> easier
>> >>>>> >> >> >> >> >> (we
>> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >>>>> >> >> >> >> >> having
>> >>>>> >> >> >> >> >> settings
>> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >>>>> >> >> >> >> >> other
>> >>>>> >> >> >> >> >> platforms.
>> >>>>> >> >> >> >> >> Namely, settings that are not platform specific like
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> C++
>> >>>>> >> >> >> >> >> language
>> >>>>> >> >> >> >> >> level).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read on
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> intrinsics
>> >>>>> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >>>>> >> >> >> >> >> love to
>> >>>>> >> >> >> >> >> read
>> >>>>> >> >> >> >> >> it.
>> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your brain
>> >>>>> >> >> >> >> >> as
>> >>>>> >> >> >> >> >> questions
>> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> see how
>> >>>>> >> >> >> >> >> it
>> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >>>>> >> >> >> >> >> option 2,
>> >>>>> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> have
>> >>>>> >> >> >> >> >> very
>> >>>>> >> >> >> >> >> little control over what happens after building the
>> >>>>> >> >> >> >> >> shared
>> >>>>> >> >> >> >> >> libraries,
>> >>>>> >> >> >> >> >> and to make up for that I need to really get a deep
>> >>>>> >> >> >> >> >> understanding
>> >>>>> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >>>>> >> >> >> >> >> scripts
>> >>>>> >> >> >> >> >> properly
>> >>>>> >> >> >> >> >> for
>> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >>>>> >> >> >> >> >> (non-Android
>> >>>>> >> >> >> >> >> platforms).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Thanks again.
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >>>>> >> >> >> >> >> <[hidden email]>
>> >>>>> >> >> >> >> >> wrote:
>> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work on
>> >>>>> >> >> >> >> >> > Android
>> >>>>> >> >> >> >> >> > Studio
>> >>>>> >> >> >> >> >> > and
>> >>>>> >> >> >> >> >> > was
>> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >>>>> >> >> >> >> >> > we're
>> >>>>> >> >> >> >> >> > working
>> >>>>> >> >> >> >> >> > toward
>> >>>>> >> >> >> >> >> > getting
>> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't really
>> >>>>> >> >> >> >> >> > say
>> >>>>> >> >> >> >> >> > when
>> >>>>> >> >> >> >> >> > that
>> >>>>> >> >> >> >> >> > will
>> >>>>> >> >> >> >> >> > happen
>> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for now
>> >>>>> >> >> >> >> >> > then I'd
>> >>>>> >> >> >> >> >> > go
>> >>>>> >> >> >> >> >> > this
>> >>>>> >> >> >> >> >> > way.
>> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to view
>> >>>>> >> >> >> >> >> > your
>> >>>>> >> >> >> >> >> > source
>> >>>>> >> >> >> >> >> > file
>> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and debug
>> >>>>> >> >> >> >> >> > using the
>> >>>>> >> >> >> >> >> > built-in
>> >>>>> >> >> >> >> >> > debugging support.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >>>>> >> >> >> >> >> > setting
>> >>>>> >> >> >> >> >> > to
>> >>>>> >> >> >> >> >> > tell
>> >>>>> >> >> >> >> >> > Android
>> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files (see
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >>>>> >> >> >> >> >> > approach
>> >>>>> >> >> >> >> >> > but it
>> >>>>> >> >> >> >> >> > should
>> >>>>> >> >> >> >> >> > work
>> >>>>> >> >> >> >> >> > in
>> >>>>> >> >> >> >> >> > principal.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > I hope this helps,
>> >>>>> >> >> >> >> >> > Jomo
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >>>>> >> >> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> >> >> > wrote:
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute the
>> >>>>> >> >> >> >> >> >> "ant
>> >>>>> >> >> >> >> >> >> release"
>> >>>>> >> >> >> >> >> >> command after my native targets are built. Part of
>> >>>>> >> >> >> >> >> >> that
>> >>>>> >> >> >> >> >> >> command
>> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >>>>> >> >> >> >> >> >> directory
>> >>>>> >> >> >> >> >> >> so
>> >>>>> >> >> >> >> >> >> they
>> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using Android
>> >>>>> >> >> >> >> >> >> Studio and
>> >>>>> >> >> >> >> >> >> being
>> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is a
>> >>>>> >> >> >> >> >> >> few
>> >>>>> >> >> >> >> >> >> major
>> >>>>> >> >> >> >> >> >> releases
>> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same or
>> >>>>> >> >> >> >> >> >> similar
>> >>>>> >> >> >> >> >> >> to
>> >>>>> >> >> >> >> >> >> what
>> >>>>> >> >> >> >> >> >> I'm
>> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >>>>> >> >> >> >> >> >> execute
>> >>>>> >> >> >> >> >> >> gradle
>> >>>>> >> >> >> >> >> >> as
>> >>>>> >> >> >> >> >> >> a
>> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >>>>> >> >> >> >> >> >> commands.
>> >>>>> >> >> >> >> >> >> I'm
>> >>>>> >> >> >> >> >> >> not
>> >>>>> >> >> >> >> >> >> too
>> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you tell
>> >>>>> >> >> >> >> >> >> it
>> >>>>> >> >> >> >> >> >> where
>> >>>>> >> >> >> >> >> >> your
>> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging steps.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using one
>> >>>>> >> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> >> these
>> >>>>> >> >> >> >> >> >> setups
>> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is probably
>> >>>>> >> >> >> >> >> >> no
>> >>>>> >> >> >> >> >> >> on-device
>> >>>>> >> >> >> >> >> >> native
>> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >>>>> >> >> >> >> >> >> handle
>> >>>>> >> >> >> >> >> >> gradle
>> >>>>> >> >> >> >> >> >> projects
>> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Would like some general direction & advice before
>> >>>>> >> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> >> move
>> >>>>> >> >> >> >> >> >> away
>> >>>>> >> >> >> >> >> >> from
>> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >>>>> >> >> >> >> >> >> --
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >
>> >>>>> >> >> >> >
>> >>>>> >> >> >
>> >>>>> >> >> >
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >
>> >>>>> >
>> >>>>
>> >>>>
>> >>>
>> >>
>
>
--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Jom O'Fisher
By gradle module projects, I just mean the leaf build.gradle files as opposed to the root build.gradle. By configurations, I mean Build Types (debug vs release) and Product Flavors (demo vs free vs paid). Hereafter I will use the term "variant" rather than "configuration" to be precise. See this write-up on build variants:


This build matrix is constructed at the leaf build.gradle level. Native build in gradle allows you to set C/C++ flags individually for each variant so that you can define compiler flags (for example, -DFREE_VERSION).

One thing to notice at this stage is that the same CMake target may be built with different compiler flags across different projects, build types, and product flavors. So in the general case, build outputs won't be the same.

You asked which targets build when specifying path. By default, we build all targets that produce an .so. You can override this by setting externalNativeBuild.cmake.targets. For example,

    paid {
      ...
      externalNativeBuild {
        cmake {
          ...
          targets "native-lib-paid"
        }
      }
    }

As for your last question, the model we generally see used is that the main CMakeLists.txt is next to the leaf build.gradle such that this CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt (though they may share common dependencies and settings). Otherwise, multiple APK projects would perform pretty much similar to yours--they would build targets per-leaf project and not share build outputs. As far as I can see your organization is just as valid so long as you only build the targets you need.

Regarding native dependencies between java projects. We generally try to avoid making the CMake build depend on the gradle build (you should be able to replicate the CMake build from the command-line if you set the right flags). At the moment I don't see a way we could make things better without violating that tenet but that could be lack of imagination on my part.

We'll definitely be discussing this use case at our next C++ meeting and I'll also be checking for myself whether ccache will work in this CMake scenario. If ccache does work it seems like the natural level at which to fold identical builds.



On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey <[hidden email]> wrote:
I'm not sure what you mean by "gradle module projects", but maybe
having some examples of what you mean by "configurations, C++ flags,
etc" might make it more clear.

Question: When specifying "path" for the CMakeLists.txt in the
build.gradle file, how do you know which targets to build? For
example, that run of CMake may generate 100 targets, but only 20 need
to build and be packaged (*.so files) with the APK. Do you just build
"all"? Is there a way to specify the target itself?

Thanks again. I'd still like to know more about what the ideal
organization is. I find it hard to believe that large android projects
rarely break things up into multiple, separate "components" that are
built independently. That's really the gist of what we're dealing with
here. Your typical "hello world" project likely will have only 1
CMakeLists.txt that is pretty self-contained, but all the
documentation I've looked at so far doesn't show the best way to
handle native library dependencies across java projects between
build.gradle files (or maybe I'm just not looking hard enough).

On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]> wrote:
> Thanks for the write-up Robert. Having thought about it, I don't believe we
> have a satisfying answer at the gradle level for this kind of organization.
> In the gradle model module projects are the unit of organization for
> configurations, C/C++ flags, etc. and that's something we're pretty much
> stuck with.
> Regarding just the redundant build issue, would something like ccache help?
> I know people have used it with ndk-build with success, I'm not sure about
> CMake but I don't see why that should make a difference.
>
>
>
> On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey <[hidden email]>
> wrote:
>>
>> Another reason to reduce the number of binary directories is that
>> there are different ways of managing third party libraries. One in
>> particular that we use is to clone a repository into the binary
>> directory and build all third party libs in real time based on a
>> toolchain file (Similar to the functionality provided by
>> ExternalProject module in CMake). This is repeated from scratch only
>> if the work hasn't already been done in the binary directory before.
>> By having more binary dirs than needed, this work is being done an
>> exponential amount of times which can result in a lot of wasted time
>> waiting. There are 1 time operations that multiple targets can benefit
>> from in a single binary tree, instead of 1 per unique target being
>> invoked.
>>
>> Sorry to keep responding: I'm just thinking of things as I go and
>> bringing them up, to shed light on some of the reasoning behind my
>> suggestions.
>>
>> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey <[hidden email]>
>> wrote:
>> > Sorry I forgot to answer your last set of questions:
>> >
>> > CommonLib is indeed 2 things:
>> >
>> > * A common (static or shared) library for native code (most of our
>> > CMake targets specify CommonLib as a link dependency)
>> > * A common library for Java code (we do specify this as a dependency
>> > for most java targets in Gradle, specifically those under
>> > Applications/)
>> >
>> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]> wrote:
>> >> Hi Robert,
>> >>
>> >> I work with Jom on the Android Studio team, and I would like to clarify
>> >> a
>> >> few things to better understand your situation.
>> >> You mentioned the project is intend to be cross platform.  Normally, in
>> >> such
>> >> situation, we expect there to be a single CMake root project to be
>> >> imported
>> >> into one of the Android library/application.  However, in your case,
>> >> there
>> >> are subprojects with Java code.
>> >>
>> >> Are the CMake code in App1/2/3 intended to be cross platform too?  Or
>> >> are
>> >> they Android specific code?  If they are meant to be cross platform,
>> >> how
>> >> does the Java code works on other platforms?  Or perhaps you added Java
>> >> binding in those subprojects just for Android?
>> >>
>> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> From
>> >> your description, it doesn't look like an Android library project.  Or
>> >> am I
>> >> mistaken and it also applies the android library plugin?
>> >>
>> >> Raymond
>> >>
>> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> wrote:
>> >>>
>> >>> + a colleague
>> >>>
>> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher <[hidden email]>
>> >>> wrote:
>> >>>>
>> >>>> You can find that number like this:
>> >>>> - x = number of externalNativeBuild.cmake.path in your build.gradle
>> >>>> files
>> >>>> - y = number of gradle configurations (like debug and release)
>> >>>> - z = number of ABIs that you build
>> >>>>
>> >>>> The result is x * y * z. To be more accurate, you should consider y
>> >>>> and z
>> >>>> to be functions of each build.gradle file since these can vary.
>> >>>>
>> >>>> There is a second set of folders that hold the stripped versions of
>> >>>> the
>> >>>> .so files that is purely managed by the android gradle plugin, so you
>> >>>> might
>> >>>> consider the answer to be 2 * x * y * z.
>> >>>>
>> >>>> Hope this helps.
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >>>> <[hidden email]>
>> >>>> wrote:
>> >>>>>
>> >>>>> This definitely a bit better, but still requires the boilerplate in
>> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >>>>> think I'm more concerned with the implications this has underneath.
>> >>>>> First, let me ask just to make sure I'm not misunderstanding: Does
>> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >>>>> CMAKE_BINARY_DIR?
>> >>>>> How many binary dirs do you manage internally and what determines
>> >>>>> when
>> >>>>> they get created?
>> >>>>>
>> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher <[hidden email]>
>> >>>>> wrote:
>> >>>>> > Would it work for your scenario to provide properties in the root
>> >>>>> > build.gradle:
>> >>>>> >
>> >>>>> > ext {
>> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >>>>> > }
>> >>>>> >
>> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >>>>> >
>> >>>>> > externalNativeBuild {
>> >>>>> >     cmake {
>> >>>>> >         path cmakePath
>> >>>>> >     }
>> >>>>> > }
>> >>>>> >
>> >>>>> > It doesn't fully hide the details but it does centralize the
>> >>>>> > information.
>> >>>>> >
>> >>>>> >
>> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >>>>> > <[hidden email]>
>> >>>>> > wrote:
>> >>>>> >>
>> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >>>>> >> run on
>> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >>>>> >> Normal
>> >>>>> >> CMake behavior is designed to work at a root then go downwards to
>> >>>>> >> find
>> >>>>> >> targets. However it seems Gradle wants to start at a subdirectory
>> >>>>> >> and
>> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >>>>> >> intended
>> >>>>> >> behavior IMHO. Not only that but I want to avoid special-casing
>> >>>>> >> behavior in CMake just for Android's use.
>> >>>>> >>
>> >>>>> >> At the moment it feels like (again referring back to my previous
>> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >>>>> >> independent binary directories instead of sharing 1 binary
>> >>>>> >> directory
>> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >>>>> >> instead,
>> >>>>> >> especially since it allows CMake to operate as it was intended. I
>> >>>>> >> think it's a common case that projects will define multiple
>> >>>>> >> targets
>> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >>>>> >> dependencies to be built within it.
>> >>>>> >>
>> >>>>> >> If I'm misunderstanding or making false assumptions please let me
>> >>>>> >> know.
>> >>>>> >>
>> >>>>> >>
>> >>>>> >>
>> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >>>>> >> <[hidden email]>
>> >>>>> >> wrote:
>> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt to
>> >>>>> >> > include
>> >>>>> >> > the
>> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in the
>> >>>>> >> > leaf
>> >>>>> >> > CMakeLists.txt?
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >>>>> >> > <[hidden email]>
>> >>>>> >> > wrote:
>> >>>>> >> >>
>> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >>>>> >> >>
>> >>>>> >> >> <Root of git clone>/
>> >>>>> >> >>     Applications/
>> >>>>> >> >>         App1/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>         App2/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>         App3/
>> >>>>> >> >>             build.gradle
>> >>>>> >> >>             CMakeLists.txt
>> >>>>> >> >>     CommonLib/
>> >>>>> >> >>         build.gradle
>> >>>>> >> >>         CMakeLists.txt
>> >>>>> >> >>     CMakeLists.txt
>> >>>>> >> >>
>> >>>>> >> >> The libs are defined as follows:
>> >>>>> >> >>
>> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >>>>> >> >> library)
>> >>>>> >> >>     * No dependencies of its own
>> >>>>> >> >> * App1 is a shared library (java code builds into a library)
>> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >>>>> >> >>
>> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the same
>> >>>>> >> >> binary
>> >>>>> >> >> directory after that. Previously with ANT, I was building all
>> >>>>> >> >> native
>> >>>>> >> >> targets first, then moved libs to appropriate directories so
>> >>>>> >> >> that
>> >>>>> >> >> the
>> >>>>> >> >> 'ant' command would package the libs.
>> >>>>> >> >>
>> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the root
>> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >>>>> >> >> example
>> >>>>> >> >> above, the leaf-level directories in this case would be App1,
>> >>>>> >> >> App2,
>> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >>>>> >> >> native
>> >>>>> >> >> CMake
>> >>>>> >> >> stuff for the java targets that actually output an APK (that
>> >>>>> >> >> would
>> >>>>> >> >> be
>> >>>>> >> >> App2 and App3 only).
>> >>>>> >> >>
>> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change per
>> >>>>> >> >> independent "module" of ours at the top level so it is
>> >>>>> >> >> transitive
>> >>>>> >> >> /
>> >>>>> >> >> inherited. Then only specify the differences (e.g. the native
>> >>>>> >> >> CMake
>> >>>>> >> >> target to build) in the leaf build gradle files. However you
>> >>>>> >> >> indicated
>> >>>>> >> >> this isn't possible.
>> >>>>> >> >>
>> >>>>> >> >>
>> >>>>> >> >>
>> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >>>>> >> >> <[hidden email]>
>> >>>>> >> >> wrote:
>> >>>>> >> >> > What you're doing already sounds correct. You can't directly
>> >>>>> >> >> > specify
>> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >>>>> >> >> > Recommendation
>> >>>>> >> >> > is
>> >>>>> >> >> > that
>> >>>>> >> >> > it
>> >>>>> >> >> > should be specified from the build.gradle of the module of
>> >>>>> >> >> > the
>> >>>>> >> >> > APK.
>> >>>>> >> >> > Is
>> >>>>> >> >> > the
>> >>>>> >> >> > issue that you have multiple APK modules that all reference
>> >>>>> >> >> > the
>> >>>>> >> >> > same
>> >>>>> >> >> > CMake
>> >>>>> >> >> > libraries?
>> >>>>> >> >> >
>> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >>>>> >> >> > <[hidden email]>
>> >>>>> >> >> > wrote:
>> >>>>> >> >> >>
>> >>>>> >> >> >> Thanks this is very helpful. The other question I have is:
>> >>>>> >> >> >> Is
>> >>>>> >> >> >> there
>> >>>>> >> >> >> a
>> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >>>>> >> >> >> Basically,
>> >>>>> >> >> >> I
>> >>>>> >> >> >> want
>> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >>>>> >> >> >> (defined
>> >>>>> >> >> >> further down in subdirectories) that require APK packaging
>> >>>>> >> >> >> to
>> >>>>> >> >> >> specify
>> >>>>> >> >> >> only the native target name that should be built &
>> >>>>> >> >> >> packaged.
>> >>>>> >> >> >>
>> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by walking
>> >>>>> >> >> >> up
>> >>>>> >> >> >> the
>> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think this
>> >>>>> >> >> >> should
>> >>>>> >> >> >> be
>> >>>>> >> >> >> put at the top-level build gradle file if possible. Is this
>> >>>>> >> >> >> doable
>> >>>>> >> >> >> at
>> >>>>> >> >> >> the moment? What is the recommended setup?
>> >>>>> >> >> >>
>> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >>>>> >> >> >> <[hidden email]>
>> >>>>> >> >> >> wrote:
>> >>>>> >> >> >> > Gradle does introspection on the CMake build to find .so
>> >>>>> >> >> >> > targets
>> >>>>> >> >> >> > and
>> >>>>> >> >> >> > those
>> >>>>> >> >> >> > get packaged.
>> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >>>>> >> >> >> > from
>> >>>>> >> >> >> > the
>> >>>>> >> >> >> > NDK.
>> >>>>> >> >> >> > Any additional .so files need to specified in
>> >>>>> >> >> >> > build.gradle
>> >>>>> >> >> >> > using
>> >>>>> >> >> >> > jniDirs
>> >>>>> >> >> >> >
>> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >>>>> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> > wrote:
>> >>>>> >> >> >> >>
>> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK? I
>> >>>>> >> >> >> >> know
>> >>>>> >> >> >> >> that
>> >>>>> >> >> >> >> ANT
>> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >>>>> >> >> >> >> Gradle
>> >>>>> >> >> >> >> do
>> >>>>> >> >> >> >> some
>> >>>>> >> >> >> >> introspection into CMake targets to see if outputs are
>> >>>>> >> >> >> >> *.so,
>> >>>>> >> >> >> >> and
>> >>>>> >> >> >> >> copy
>> >>>>> >> >> >> >> those to some location if needed? What about libraries
>> >>>>> >> >> >> >> like
>> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like to
>> >>>>> >> >> >> >> know
>> >>>>> >> >> >> >> if
>> >>>>> >> >> >> >> any
>> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs in
>> >>>>> >> >> >> >> proper
>> >>>>> >> >> >> >> locations for the APK build step. I had to do this when
>> >>>>> >> >> >> >> using
>> >>>>> >> >> >> >> ANT.
>> >>>>> >> >> >> >>
>> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >>>>> >> >> >> >> <[hidden email]>
>> >>>>> >> >> >> >> wrote:
>> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >>>>> >> >> >> >> > project
>> >>>>> >> >> >> >> > module
>> >>>>> >> >> >> >> > folder
>> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >>>>> >> >> >> >> > can
>> >>>>> >> >> >> >> > choose
>> >>>>> >> >> >> >> > to
>> >>>>> >> >> >> >> > specify it
>> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a pretty
>> >>>>> >> >> >> >> > good job
>> >>>>> >> >> >> >> > of
>> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can get
>> >>>>> >> >> >> >> > away
>> >>>>> >> >> >> >> > with.
>> >>>>> >> >> >> >> > In
>> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >>>>> >> >> >> >> > CMake
>> >>>>> >> >> >> >> > build
>> >>>>> >> >> >> >> > command"
>> >>>>> >> >> >> >> > lays
>> >>>>> >> >> >> >> > out exactly what we set. You can also see the folders
>> >>>>> >> >> >> >> > we
>> >>>>> >> >> >> >> > specify
>> >>>>> >> >> >> >> > (one
>> >>>>> >> >> >> >> > per
>> >>>>> >> >> >> >> > module per ABI)
>> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >>>>> >> >> >> >> > haven't
>> >>>>> >> >> >> >> > already)
>> >>>>> >> >> >> >> > is:
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >>>>> >> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> >> > wrote:
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Thanks Jom
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >>>>> >> >> >> >> >> that's
>> >>>>> >> >> >> >> >> how
>> >>>>> >> >> >> >> >> Google's
>> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >>>>> >> >> >> >> >> debugging
>> >>>>> >> >> >> >> >> which
>> >>>>> >> >> >> >> >> is
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> #1
>> >>>>> >> >> >> >> >> reason for me.
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about how
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> integration
>> >>>>> >> >> >> >> >> really happens. For example, I have these questions:
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >>>>> >> >> >> >> >> managed?
>> >>>>> >> >> >> >> >> Do
>> >>>>> >> >> >> >> >> you
>> >>>>> >> >> >> >> >> generate 1 per unique android project? What about for
>> >>>>> >> >> >> >> >> each
>> >>>>> >> >> >> >> >> specific
>> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration, things
>> >>>>> >> >> >> >> >> defined
>> >>>>> >> >> >> >> >> inside
>> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >>>>> >> >> >> >> >> specified
>> >>>>> >> >> >> >> >> at
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> command line. Namely, all of those settings that are
>> >>>>> >> >> >> >> >> driven by
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one in
>> >>>>> >> >> >> >> >> particular
>> >>>>> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >>>>> >> >> >> >> >> recall
>> >>>>> >> >> >> >> >> this
>> >>>>> >> >> >> >> >> being
>> >>>>> >> >> >> >> >> overridden from outside)?
>> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >>>>> >> >> >> >> >> libraries
>> >>>>> >> >> >> >> >> via
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted to
>> >>>>> >> >> >> >> >> define
>> >>>>> >> >> >> >> >> common
>> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle or
>> >>>>> >> >> >> >> >> settings
>> >>>>> >> >> >> >> >> file,
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >>>>> >> >> >> >> >> build
>> >>>>> >> >> >> >> >> files
>> >>>>> >> >> >> >> >> for
>> >>>>> >> >> >> >> >> each
>> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name of
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> native
>> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >>>>> >> >> >> >> >> line
>> >>>>> >> >> >> >> >> invocation,
>> >>>>> >> >> >> >> >> -D
>> >>>>> >> >> >> >> >> CMake settings, etc would all be common and defined
>> >>>>> >> >> >> >> >> at
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> root).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way of
>> >>>>> >> >> >> >> >> doing
>> >>>>> >> >> >> >> >> things
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >>>>> >> >> >> >> >> CMake
>> >>>>> >> >> >> >> >> scripts
>> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >>>>> >> >> >> >> >> cross-platform
>> >>>>> >> >> >> >> >> easier
>> >>>>> >> >> >> >> >> (we
>> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >>>>> >> >> >> >> >> having
>> >>>>> >> >> >> >> >> settings
>> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >>>>> >> >> >> >> >> other
>> >>>>> >> >> >> >> >> platforms.
>> >>>>> >> >> >> >> >> Namely, settings that are not platform specific like
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> C++
>> >>>>> >> >> >> >> >> language
>> >>>>> >> >> >> >> >> level).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read on
>> >>>>> >> >> >> >> >> the
>> >>>>> >> >> >> >> >> intrinsics
>> >>>>> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >>>>> >> >> >> >> >> love to
>> >>>>> >> >> >> >> >> read
>> >>>>> >> >> >> >> >> it.
>> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your brain
>> >>>>> >> >> >> >> >> as
>> >>>>> >> >> >> >> >> questions
>> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >>>>> >> >> >> >> >> and
>> >>>>> >> >> >> >> >> see how
>> >>>>> >> >> >> >> >> it
>> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >>>>> >> >> >> >> >> option 2,
>> >>>>> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> have
>> >>>>> >> >> >> >> >> very
>> >>>>> >> >> >> >> >> little control over what happens after building the
>> >>>>> >> >> >> >> >> shared
>> >>>>> >> >> >> >> >> libraries,
>> >>>>> >> >> >> >> >> and to make up for that I need to really get a deep
>> >>>>> >> >> >> >> >> understanding
>> >>>>> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >>>>> >> >> >> >> >> scripts
>> >>>>> >> >> >> >> >> properly
>> >>>>> >> >> >> >> >> for
>> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >>>>> >> >> >> >> >> (non-Android
>> >>>>> >> >> >> >> >> platforms).
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> Thanks again.
>> >>>>> >> >> >> >> >>
>> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >>>>> >> >> >> >> >> <[hidden email]>
>> >>>>> >> >> >> >> >> wrote:
>> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work on
>> >>>>> >> >> >> >> >> > Android
>> >>>>> >> >> >> >> >> > Studio
>> >>>>> >> >> >> >> >> > and
>> >>>>> >> >> >> >> >> > was
>> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >>>>> >> >> >> >> >> > we're
>> >>>>> >> >> >> >> >> > working
>> >>>>> >> >> >> >> >> > toward
>> >>>>> >> >> >> >> >> > getting
>> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't really
>> >>>>> >> >> >> >> >> > say
>> >>>>> >> >> >> >> >> > when
>> >>>>> >> >> >> >> >> > that
>> >>>>> >> >> >> >> >> > will
>> >>>>> >> >> >> >> >> > happen
>> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for now
>> >>>>> >> >> >> >> >> > then I'd
>> >>>>> >> >> >> >> >> > go
>> >>>>> >> >> >> >> >> > this
>> >>>>> >> >> >> >> >> > way.
>> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to view
>> >>>>> >> >> >> >> >> > your
>> >>>>> >> >> >> >> >> > source
>> >>>>> >> >> >> >> >> > file
>> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and debug
>> >>>>> >> >> >> >> >> > using the
>> >>>>> >> >> >> >> >> > built-in
>> >>>>> >> >> >> >> >> > debugging support.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >>>>> >> >> >> >> >> > setting
>> >>>>> >> >> >> >> >> > to
>> >>>>> >> >> >> >> >> > tell
>> >>>>> >> >> >> >> >> > Android
>> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files (see
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >>>>> >> >> >> >> >> > approach
>> >>>>> >> >> >> >> >> > but it
>> >>>>> >> >> >> >> >> > should
>> >>>>> >> >> >> >> >> > work
>> >>>>> >> >> >> >> >> > in
>> >>>>> >> >> >> >> >> > principal.
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > I hope this helps,
>> >>>>> >> >> >> >> >> > Jomo
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >>>>> >> >> >> >> >> > <[hidden email]>
>> >>>>> >> >> >> >> >> > wrote:
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute the
>> >>>>> >> >> >> >> >> >> "ant
>> >>>>> >> >> >> >> >> >> release"
>> >>>>> >> >> >> >> >> >> command after my native targets are built. Part of
>> >>>>> >> >> >> >> >> >> that
>> >>>>> >> >> >> >> >> >> command
>> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >>>>> >> >> >> >> >> >> directory
>> >>>>> >> >> >> >> >> >> so
>> >>>>> >> >> >> >> >> >> they
>> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using Android
>> >>>>> >> >> >> >> >> >> Studio and
>> >>>>> >> >> >> >> >> >> being
>> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is a
>> >>>>> >> >> >> >> >> >> few
>> >>>>> >> >> >> >> >> >> major
>> >>>>> >> >> >> >> >> >> releases
>> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same or
>> >>>>> >> >> >> >> >> >> similar
>> >>>>> >> >> >> >> >> >> to
>> >>>>> >> >> >> >> >> >> what
>> >>>>> >> >> >> >> >> >> I'm
>> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >>>>> >> >> >> >> >> >> execute
>> >>>>> >> >> >> >> >> >> gradle
>> >>>>> >> >> >> >> >> >> as
>> >>>>> >> >> >> >> >> >> a
>> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >>>>> >> >> >> >> >> >> commands.
>> >>>>> >> >> >> >> >> >> I'm
>> >>>>> >> >> >> >> >> >> not
>> >>>>> >> >> >> >> >> >> too
>> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you tell
>> >>>>> >> >> >> >> >> >> it
>> >>>>> >> >> >> >> >> >> where
>> >>>>> >> >> >> >> >> >> your
>> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging steps.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using one
>> >>>>> >> >> >> >> >> >> of
>> >>>>> >> >> >> >> >> >> these
>> >>>>> >> >> >> >> >> >> setups
>> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is probably
>> >>>>> >> >> >> >> >> >> no
>> >>>>> >> >> >> >> >> >> on-device
>> >>>>> >> >> >> >> >> >> native
>> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >>>>> >> >> >> >> >> >> handle
>> >>>>> >> >> >> >> >> >> gradle
>> >>>>> >> >> >> >> >> >> projects
>> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> Would like some general direction & advice before
>> >>>>> >> >> >> >> >> >> I
>> >>>>> >> >> >> >> >> >> move
>> >>>>> >> >> >> >> >> >> away
>> >>>>> >> >> >> >> >> >> from
>> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >>>>> >> >> >> >> >> >> --
>> >>>>> >> >> >> >> >> >>
>> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >> >
>> >>>>> >> >> >> >
>> >>>>> >> >> >> >
>> >>>>> >> >> >
>> >>>>> >> >> >
>> >>>>> >> >
>> >>>>> >> >
>> >>>>> >
>> >>>>> >
>> >>>>
>> >>>>
>> >>>
>> >>
>
>


--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Craig Scott-3


On Thu, Aug 24, 2017 at 5:20 AM, Jom O'Fisher <[hidden email]> wrote:
We'll definitely be discussing this use case at our next C++ meeting and I'll also be checking for myself whether ccache will work in this CMake scenario. If ccache does work it seems like the natural level at which to fold identical builds.

In case it's helpful, the following article discusses how to set up a project for ccache without having to assume ccache has been installed with symlinks, etc. to replace the default compiler:


This approach has saved us a huge amount of time in our builds, including some fairly complex hierarchical projects.

--
Craig Scott
Melbourne, Australia

--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Jom O'Fisher
Thanks Craig, I hadn't found that article yet

On Wed, Aug 23, 2017 at 4:37 PM, Craig Scott <[hidden email]> wrote:


On Thu, Aug 24, 2017 at 5:20 AM, Jom O'Fisher <[hidden email]> wrote:
We'll definitely be discussing this use case at our next C++ meeting and I'll also be checking for myself whether ccache will work in this CMake scenario. If ccache does work it seems like the natural level at which to fold identical builds.

In case it's helpful, the following article discusses how to set up a project for ccache without having to assume ccache has been installed with symlinks, etc. to replace the default compiler:


This approach has saved us a huge amount of time in our builds, including some fairly complex hierarchical projects.

--
Craig Scott
Melbourne, Australia


--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Robert Dailey-2
In reply to this post by Jom O'Fisher
Thanks for explaining, as usual your answers are making things much more clear.

When it's all said and done and considering everything we've discussed
up to this point, I'm fine with how you've architected the CMake
integration with Gradle. I think the way things function is perfectly
fine. My only concern is with a (should I say minor?) implementation
detail: Trying to promote CMAKE_BINARY_DIR sharing where feasible to
do so. Like I mentioned earlier, I believe that the code-behind for
"externalNativeBuild" logic should detect when two "path" files refer
to the same physical CMakeLists.txt file within the same build
configuration and variant, and if true, reuse/share the same
CMAKE_BINARY_DIR instead of generating another one. This seems safe to
me since the only difference is possibly which targets get invoked.
Optimistically, the best case scenario here is that the 2nd
externalNativeBuild has to build nothing and just grab *.so files
already built by the first externalNativeProject (so long as both
point to the same "path" file on filesystem).

Whether or not you decide to specify the "path" at the common ancestor
build.gradle (to make managing the configuration in gradle easier
since the properties will be transitive) or keep it as it is (require
"path" at each leaf build.gradle), you can still check if the same
physical CMakeLists.txt file is being used between multiple leaf
gradle build files.

If ccache is capable of reading build cache between multiple CMake
binary dirs, I think it may solve some aspects of this problem: In
particular, it might solve the build performance problems (you'd still
be building the same libs only once, even across separate
CMAKE_BINARY_DIR, if I understand correctly). But it does not solve
other issues: In particular, custom_target or custom_command logic
that depends on custom timestamp file or caching logic (like, checking
if files already exist in CMAKE_BINARY_DIR, and if not, download them,
install them, etc. (ExternalProject_Add is a prime example)). Also
ccache won't reduce the disk space consumption that would exist due to
having multiple CMAKE_BINARY_DIR instead of consolidating and sharing
them.

Sorry if I'm just repeating myself, but I'm just trying to summarize
my thoughts. The situation is complex so I want to make sure I am not
leaving out any details for when you do finally discuss this
internally.

Thanks and let me know how things end up after your C++ meeting!

On Wed, Aug 23, 2017 at 4:20 PM, Jom O'Fisher <[hidden email]> wrote:

> By gradle module projects, I just mean the leaf build.gradle files as
> opposed to the root build.gradle. By configurations, I mean Build Types
> (debug vs release) and Product Flavors (demo vs free vs paid). Hereafter I
> will use the term "variant" rather than "configuration" to be precise. See
> this write-up on build variants:
>
> https://developer.android.com/studio/build/build-variants.html#build-types
>
> This build matrix is constructed at the leaf build.gradle level. Native
> build in gradle allows you to set C/C++ flags individually for each variant
> so that you can define compiler flags (for example, -DFREE_VERSION).
>
> One thing to notice at this stage is that the same CMake target may be built
> with different compiler flags across different projects, build types, and
> product flavors. So in the general case, build outputs won't be the same.
>
> You asked which targets build when specifying path. By default, we build all
> targets that produce an .so. You can override this by setting
> externalNativeBuild.cmake.targets. For example,
>
>     paid {
>       ...
>       externalNativeBuild {
>         cmake {
>           ...
>           targets "native-lib-paid"
>         }
>       }
>     }
>
> As for your last question, the model we generally see used is that the main
> CMakeLists.txt is next to the leaf build.gradle such that this
> CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt (though
> they may share common dependencies and settings). Otherwise, multiple APK
> projects would perform pretty much similar to yours--they would build
> targets per-leaf project and not share build outputs. As far as I can see
> your organization is just as valid so long as you only build the targets you
> need.
>
> Regarding native dependencies between java projects. We generally try to
> avoid making the CMake build depend on the gradle build (you should be able
> to replicate the CMake build from the command-line if you set the right
> flags). At the moment I don't see a way we could make things better without
> violating that tenet but that could be lack of imagination on my part.
>
> We'll definitely be discussing this use case at our next C++ meeting and
> I'll also be checking for myself whether ccache will work in this CMake
> scenario. If ccache does work it seems like the natural level at which to
> fold identical builds.
>
>
>
> On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey <[hidden email]>
> wrote:
>>
>> I'm not sure what you mean by "gradle module projects", but maybe
>> having some examples of what you mean by "configurations, C++ flags,
>> etc" might make it more clear.
>>
>> Question: When specifying "path" for the CMakeLists.txt in the
>> build.gradle file, how do you know which targets to build? For
>> example, that run of CMake may generate 100 targets, but only 20 need
>> to build and be packaged (*.so files) with the APK. Do you just build
>> "all"? Is there a way to specify the target itself?
>>
>> Thanks again. I'd still like to know more about what the ideal
>> organization is. I find it hard to believe that large android projects
>> rarely break things up into multiple, separate "components" that are
>> built independently. That's really the gist of what we're dealing with
>> here. Your typical "hello world" project likely will have only 1
>> CMakeLists.txt that is pretty self-contained, but all the
>> documentation I've looked at so far doesn't show the best way to
>> handle native library dependencies across java projects between
>> build.gradle files (or maybe I'm just not looking hard enough).
>>
>> On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]>
>> wrote:
>> > Thanks for the write-up Robert. Having thought about it, I don't believe
>> > we
>> > have a satisfying answer at the gradle level for this kind of
>> > organization.
>> > In the gradle model module projects are the unit of organization for
>> > configurations, C/C++ flags, etc. and that's something we're pretty much
>> > stuck with.
>> > Regarding just the redundant build issue, would something like ccache
>> > help?
>> > I know people have used it with ndk-build with success, I'm not sure
>> > about
>> > CMake but I don't see why that should make a difference.
>> >
>> >
>> >
>> > On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> Another reason to reduce the number of binary directories is that
>> >> there are different ways of managing third party libraries. One in
>> >> particular that we use is to clone a repository into the binary
>> >> directory and build all third party libs in real time based on a
>> >> toolchain file (Similar to the functionality provided by
>> >> ExternalProject module in CMake). This is repeated from scratch only
>> >> if the work hasn't already been done in the binary directory before.
>> >> By having more binary dirs than needed, this work is being done an
>> >> exponential amount of times which can result in a lot of wasted time
>> >> waiting. There are 1 time operations that multiple targets can benefit
>> >> from in a single binary tree, instead of 1 per unique target being
>> >> invoked.
>> >>
>> >> Sorry to keep responding: I'm just thinking of things as I go and
>> >> bringing them up, to shed light on some of the reasoning behind my
>> >> suggestions.
>> >>
>> >> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey
>> >> <[hidden email]>
>> >> wrote:
>> >> > Sorry I forgot to answer your last set of questions:
>> >> >
>> >> > CommonLib is indeed 2 things:
>> >> >
>> >> > * A common (static or shared) library for native code (most of our
>> >> > CMake targets specify CommonLib as a link dependency)
>> >> > * A common library for Java code (we do specify this as a dependency
>> >> > for most java targets in Gradle, specifically those under
>> >> > Applications/)
>> >> >
>> >> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]>
>> >> > wrote:
>> >> >> Hi Robert,
>> >> >>
>> >> >> I work with Jom on the Android Studio team, and I would like to
>> >> >> clarify
>> >> >> a
>> >> >> few things to better understand your situation.
>> >> >> You mentioned the project is intend to be cross platform.  Normally,
>> >> >> in
>> >> >> such
>> >> >> situation, we expect there to be a single CMake root project to be
>> >> >> imported
>> >> >> into one of the Android library/application.  However, in your case,
>> >> >> there
>> >> >> are subprojects with Java code.
>> >> >>
>> >> >> Are the CMake code in App1/2/3 intended to be cross platform too?
>> >> >> Or
>> >> >> are
>> >> >> they Android specific code?  If they are meant to be cross platform,
>> >> >> how
>> >> >> does the Java code works on other platforms?  Or perhaps you added
>> >> >> Java
>> >> >> binding in those subprojects just for Android?
>> >> >>
>> >> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> >> From
>> >> >> your description, it doesn't look like an Android library project.
>> >> >> Or
>> >> >> am I
>> >> >> mistaken and it also applies the android library plugin?
>> >> >>
>> >> >> Raymond
>> >> >>
>> >> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> >> wrote:
>> >> >>>
>> >> >>> + a colleague
>> >> >>>
>> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
>> >> >>> <[hidden email]>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> You can find that number like this:
>> >> >>>> - x = number of externalNativeBuild.cmake.path in your
>> >> >>>> build.gradle
>> >> >>>> files
>> >> >>>> - y = number of gradle configurations (like debug and release)
>> >> >>>> - z = number of ABIs that you build
>> >> >>>>
>> >> >>>> The result is x * y * z. To be more accurate, you should consider
>> >> >>>> y
>> >> >>>> and z
>> >> >>>> to be functions of each build.gradle file since these can vary.
>> >> >>>>
>> >> >>>> There is a second set of folders that hold the stripped versions
>> >> >>>> of
>> >> >>>> the
>> >> >>>> .so files that is purely managed by the android gradle plugin, so
>> >> >>>> you
>> >> >>>> might
>> >> >>>> consider the answer to be 2 * x * y * z.
>> >> >>>>
>> >> >>>> Hope this helps.
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >> >>>> <[hidden email]>
>> >> >>>> wrote:
>> >> >>>>>
>> >> >>>>> This definitely a bit better, but still requires the boilerplate
>> >> >>>>> in
>> >> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >> >>>>> think I'm more concerned with the implications this has
>> >> >>>>> underneath.
>> >> >>>>> First, let me ask just to make sure I'm not misunderstanding:
>> >> >>>>> Does
>> >> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >> >>>>> CMAKE_BINARY_DIR?
>> >> >>>>> How many binary dirs do you manage internally and what determines
>> >> >>>>> when
>> >> >>>>> they get created?
>> >> >>>>>
>> >> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher
>> >> >>>>> <[hidden email]>
>> >> >>>>> wrote:
>> >> >>>>> > Would it work for your scenario to provide properties in the
>> >> >>>>> > root
>> >> >>>>> > build.gradle:
>> >> >>>>> >
>> >> >>>>> > ext {
>> >> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >> >>>>> >
>> >> >>>>> > externalNativeBuild {
>> >> >>>>> >     cmake {
>> >> >>>>> >         path cmakePath
>> >> >>>>> >     }
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > It doesn't fully hide the details but it does centralize the
>> >> >>>>> > information.
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >> >>>>> > <[hidden email]>
>> >> >>>>> > wrote:
>> >> >>>>> >>
>> >> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >> >>>>> >> run on
>> >> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >> >>>>> >> Normal
>> >> >>>>> >> CMake behavior is designed to work at a root then go downwards
>> >> >>>>> >> to
>> >> >>>>> >> find
>> >> >>>>> >> targets. However it seems Gradle wants to start at a
>> >> >>>>> >> subdirectory
>> >> >>>>> >> and
>> >> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >> >>>>> >> intended
>> >> >>>>> >> behavior IMHO. Not only that but I want to avoid
>> >> >>>>> >> special-casing
>> >> >>>>> >> behavior in CMake just for Android's use.
>> >> >>>>> >>
>> >> >>>>> >> At the moment it feels like (again referring back to my
>> >> >>>>> >> previous
>> >> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >> >>>>> >> independent binary directories instead of sharing 1 binary
>> >> >>>>> >> directory
>> >> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >> >>>>> >> instead,
>> >> >>>>> >> especially since it allows CMake to operate as it was
>> >> >>>>> >> intended. I
>> >> >>>>> >> think it's a common case that projects will define multiple
>> >> >>>>> >> targets
>> >> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >> >>>>> >> dependencies to be built within it.
>> >> >>>>> >>
>> >> >>>>> >> If I'm misunderstanding or making false assumptions please let
>> >> >>>>> >> me
>> >> >>>>> >> know.
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >> >>>>> >> <[hidden email]>
>> >> >>>>> >> wrote:
>> >> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt
>> >> >>>>> >> > to
>> >> >>>>> >> > include
>> >> >>>>> >> > the
>> >> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in
>> >> >>>>> >> > the
>> >> >>>>> >> > leaf
>> >> >>>>> >> > CMakeLists.txt?
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >> >>>>> >> > <[hidden email]>
>> >> >>>>> >> > wrote:
>> >> >>>>> >> >>
>> >> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >> >>>>> >> >>
>> >> >>>>> >> >> <Root of git clone>/
>> >> >>>>> >> >>     Applications/
>> >> >>>>> >> >>         App1/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App2/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App3/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>     CommonLib/
>> >> >>>>> >> >>         build.gradle
>> >> >>>>> >> >>         CMakeLists.txt
>> >> >>>>> >> >>     CMakeLists.txt
>> >> >>>>> >> >>
>> >> >>>>> >> >> The libs are defined as follows:
>> >> >>>>> >> >>
>> >> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * No dependencies of its own
>> >> >>>>> >> >> * App1 is a shared library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >>
>> >> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the
>> >> >>>>> >> >> same
>> >> >>>>> >> >> binary
>> >> >>>>> >> >> directory after that. Previously with ANT, I was building
>> >> >>>>> >> >> all
>> >> >>>>> >> >> native
>> >> >>>>> >> >> targets first, then moved libs to appropriate directories
>> >> >>>>> >> >> so
>> >> >>>>> >> >> that
>> >> >>>>> >> >> the
>> >> >>>>> >> >> 'ant' command would package the libs.
>> >> >>>>> >> >>
>> >> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the
>> >> >>>>> >> >> root
>> >> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >> >>>>> >> >> example
>> >> >>>>> >> >> above, the leaf-level directories in this case would be
>> >> >>>>> >> >> App1,
>> >> >>>>> >> >> App2,
>> >> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> stuff for the java targets that actually output an APK
>> >> >>>>> >> >> (that
>> >> >>>>> >> >> would
>> >> >>>>> >> >> be
>> >> >>>>> >> >> App2 and App3 only).
>> >> >>>>> >> >>
>> >> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change
>> >> >>>>> >> >> per
>> >> >>>>> >> >> independent "module" of ours at the top level so it is
>> >> >>>>> >> >> transitive
>> >> >>>>> >> >> /
>> >> >>>>> >> >> inherited. Then only specify the differences (e.g. the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> target to build) in the leaf build gradle files. However
>> >> >>>>> >> >> you
>> >> >>>>> >> >> indicated
>> >> >>>>> >> >> this isn't possible.
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >> >>>>> >> >> <[hidden email]>
>> >> >>>>> >> >> wrote:
>> >> >>>>> >> >> > What you're doing already sounds correct. You can't
>> >> >>>>> >> >> > directly
>> >> >>>>> >> >> > specify
>> >> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >> >>>>> >> >> > Recommendation
>> >> >>>>> >> >> > is
>> >> >>>>> >> >> > that
>> >> >>>>> >> >> > it
>> >> >>>>> >> >> > should be specified from the build.gradle of the module
>> >> >>>>> >> >> > of
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > APK.
>> >> >>>>> >> >> > Is
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > issue that you have multiple APK modules that all
>> >> >>>>> >> >> > reference
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > same
>> >> >>>>> >> >> > CMake
>> >> >>>>> >> >> > libraries?
>> >> >>>>> >> >> >
>> >> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >> >>>>> >> >> > <[hidden email]>
>> >> >>>>> >> >> > wrote:
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> Thanks this is very helpful. The other question I have
>> >> >>>>> >> >> >> is:
>> >> >>>>> >> >> >> Is
>> >> >>>>> >> >> >> there
>> >> >>>>> >> >> >> a
>> >> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >> >>>>> >> >> >> Basically,
>> >> >>>>> >> >> >> I
>> >> >>>>> >> >> >> want
>> >> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >> >>>>> >> >> >> (defined
>> >> >>>>> >> >> >> further down in subdirectories) that require APK
>> >> >>>>> >> >> >> packaging
>> >> >>>>> >> >> >> to
>> >> >>>>> >> >> >> specify
>> >> >>>>> >> >> >> only the native target name that should be built &
>> >> >>>>> >> >> >> packaged.
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by
>> >> >>>>> >> >> >> walking
>> >> >>>>> >> >> >> up
>> >> >>>>> >> >> >> the
>> >> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> should
>> >> >>>>> >> >> >> be
>> >> >>>>> >> >> >> put at the top-level build gradle file if possible. Is
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> doable
>> >> >>>>> >> >> >> at
>> >> >>>>> >> >> >> the moment? What is the recommended setup?
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >> >>>>> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> wrote:
>> >> >>>>> >> >> >> > Gradle does introspection on the CMake build to find
>> >> >>>>> >> >> >> > .so
>> >> >>>>> >> >> >> > targets
>> >> >>>>> >> >> >> > and
>> >> >>>>> >> >> >> > those
>> >> >>>>> >> >> >> > get packaged.
>> >> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >> >>>>> >> >> >> > from
>> >> >>>>> >> >> >> > the
>> >> >>>>> >> >> >> > NDK.
>> >> >>>>> >> >> >> > Any additional .so files need to specified in
>> >> >>>>> >> >> >> > build.gradle
>> >> >>>>> >> >> >> > using
>> >> >>>>> >> >> >> > jniDirs
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >> >>>>> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> > wrote:
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK?
>> >> >>>>> >> >> >> >> I
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> that
>> >> >>>>> >> >> >> >> ANT
>> >> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >> >>>>> >> >> >> >> Gradle
>> >> >>>>> >> >> >> >> do
>> >> >>>>> >> >> >> >> some
>> >> >>>>> >> >> >> >> introspection into CMake targets to see if outputs
>> >> >>>>> >> >> >> >> are
>> >> >>>>> >> >> >> >> *.so,
>> >> >>>>> >> >> >> >> and
>> >> >>>>> >> >> >> >> copy
>> >> >>>>> >> >> >> >> those to some location if needed? What about
>> >> >>>>> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> like
>> >> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like
>> >> >>>>> >> >> >> >> to
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> if
>> >> >>>>> >> >> >> >> any
>> >> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs
>> >> >>>>> >> >> >> >> in
>> >> >>>>> >> >> >> >> proper
>> >> >>>>> >> >> >> >> locations for the APK build step. I had to do this
>> >> >>>>> >> >> >> >> when
>> >> >>>>> >> >> >> >> using
>> >> >>>>> >> >> >> >> ANT.
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >> >>>>> >> >> >> >> > project
>> >> >>>>> >> >> >> >> > module
>> >> >>>>> >> >> >> >> > folder
>> >> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >> >>>>> >> >> >> >> > can
>> >> >>>>> >> >> >> >> > choose
>> >> >>>>> >> >> >> >> > to
>> >> >>>>> >> >> >> >> > specify it
>> >> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a
>> >> >>>>> >> >> >> >> > pretty
>> >> >>>>> >> >> >> >> > good job
>> >> >>>>> >> >> >> >> > of
>> >> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can
>> >> >>>>> >> >> >> >> > get
>> >> >>>>> >> >> >> >> > away
>> >> >>>>> >> >> >> >> > with.
>> >> >>>>> >> >> >> >> > In
>> >> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >> >>>>> >> >> >> >> > CMake
>> >> >>>>> >> >> >> >> > build
>> >> >>>>> >> >> >> >> > command"
>> >> >>>>> >> >> >> >> > lays
>> >> >>>>> >> >> >> >> > out exactly what we set. You can also see the
>> >> >>>>> >> >> >> >> > folders
>> >> >>>>> >> >> >> >> > we
>> >> >>>>> >> >> >> >> > specify
>> >> >>>>> >> >> >> >> > (one
>> >> >>>>> >> >> >> >> > per
>> >> >>>>> >> >> >> >> > module per ABI)
>> >> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >> >>>>> >> >> >> >> > haven't
>> >> >>>>> >> >> >> >> > already)
>> >> >>>>> >> >> >> >> > is:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >> >>>>> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks Jom
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >> >>>>> >> >> >> >> >> that's
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> Google's
>> >> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >> >>>>> >> >> >> >> >> debugging
>> >> >>>>> >> >> >> >> >> which
>> >> >>>>> >> >> >> >> >> is
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> #1
>> >> >>>>> >> >> >> >> >> reason for me.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> integration
>> >> >>>>> >> >> >> >> >> really happens. For example, I have these
>> >> >>>>> >> >> >> >> >> questions:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >> >>>>> >> >> >> >> >> managed?
>> >> >>>>> >> >> >> >> >> Do
>> >> >>>>> >> >> >> >> >> you
>> >> >>>>> >> >> >> >> >> generate 1 per unique android project? What about
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> specific
>> >> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration,
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> inside
>> >> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >> >>>>> >> >> >> >> >> specified
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> command line. Namely, all of those settings that
>> >> >>>>> >> >> >> >> >> are
>> >> >>>>> >> >> >> >> >> driven by
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one
>> >> >>>>> >> >> >> >> >> in
>> >> >>>>> >> >> >> >> >> particular
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >> >>>>> >> >> >> >> >> recall
>> >> >>>>> >> >> >> >> >> this
>> >> >>>>> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> overridden from outside)?
>> >> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >> >>>>> >> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> >> via
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted
>> >> >>>>> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> define
>> >> >>>>> >> >> >> >> >> common
>> >> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle
>> >> >>>>> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> file,
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >> >>>>> >> >> >> >> >> build
>> >> >>>>> >> >> >> >> >> files
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >> >>>>> >> >> >> >> >> line
>> >> >>>>> >> >> >> >> >> invocation,
>> >> >>>>> >> >> >> >> >> -D
>> >> >>>>> >> >> >> >> >> CMake settings, etc would all be common and
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> root).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> doing
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >> >>>>> >> >> >> >> >> CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >> >>>>> >> >> >> >> >> cross-platform
>> >> >>>>> >> >> >> >> >> easier
>> >> >>>>> >> >> >> >> >> (we
>> >> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >> >>>>> >> >> >> >> >> having
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >> >>>>> >> >> >> >> >> other
>> >> >>>>> >> >> >> >> >> platforms.
>> >> >>>>> >> >> >> >> >> Namely, settings that are not platform specific
>> >> >>>>> >> >> >> >> >> like
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> C++
>> >> >>>>> >> >> >> >> >> language
>> >> >>>>> >> >> >> >> >> level).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read
>> >> >>>>> >> >> >> >> >> on
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> intrinsics
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >> >>>>> >> >> >> >> >> love to
>> >> >>>>> >> >> >> >> >> read
>> >> >>>>> >> >> >> >> >> it.
>> >> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your
>> >> >>>>> >> >> >> >> >> brain
>> >> >>>>> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> questions
>> >> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> see how
>> >> >>>>> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >> >>>>> >> >> >> >> >> option 2,
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> have
>> >> >>>>> >> >> >> >> >> very
>> >> >>>>> >> >> >> >> >> little control over what happens after building
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> shared
>> >> >>>>> >> >> >> >> >> libraries,
>> >> >>>>> >> >> >> >> >> and to make up for that I need to really get a
>> >> >>>>> >> >> >> >> >> deep
>> >> >>>>> >> >> >> >> >> understanding
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> properly
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >> >>>>> >> >> >> >> >> (non-Android
>> >> >>>>> >> >> >> >> >> platforms).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks again.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work
>> >> >>>>> >> >> >> >> >> > on
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Studio
>> >> >>>>> >> >> >> >> >> > and
>> >> >>>>> >> >> >> >> >> > was
>> >> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >> >>>>> >> >> >> >> >> > we're
>> >> >>>>> >> >> >> >> >> > working
>> >> >>>>> >> >> >> >> >> > toward
>> >> >>>>> >> >> >> >> >> > getting
>> >> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't
>> >> >>>>> >> >> >> >> >> > really
>> >> >>>>> >> >> >> >> >> > say
>> >> >>>>> >> >> >> >> >> > when
>> >> >>>>> >> >> >> >> >> > that
>> >> >>>>> >> >> >> >> >> > will
>> >> >>>>> >> >> >> >> >> > happen
>> >> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for
>> >> >>>>> >> >> >> >> >> > now
>> >> >>>>> >> >> >> >> >> > then I'd
>> >> >>>>> >> >> >> >> >> > go
>> >> >>>>> >> >> >> >> >> > this
>> >> >>>>> >> >> >> >> >> > way.
>> >> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to
>> >> >>>>> >> >> >> >> >> > view
>> >> >>>>> >> >> >> >> >> > your
>> >> >>>>> >> >> >> >> >> > source
>> >> >>>>> >> >> >> >> >> > file
>> >> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and
>> >> >>>>> >> >> >> >> >> > debug
>> >> >>>>> >> >> >> >> >> > using the
>> >> >>>>> >> >> >> >> >> > built-in
>> >> >>>>> >> >> >> >> >> > debugging support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >> >>>>> >> >> >> >> >> > setting
>> >> >>>>> >> >> >> >> >> > to
>> >> >>>>> >> >> >> >> >> > tell
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files
>> >> >>>>> >> >> >> >> >> > (see
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >> >>>>> >> >> >> >> >> > approach
>> >> >>>>> >> >> >> >> >> > but it
>> >> >>>>> >> >> >> >> >> > should
>> >> >>>>> >> >> >> >> >> > work
>> >> >>>>> >> >> >> >> >> > in
>> >> >>>>> >> >> >> >> >> > principal.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > I hope this helps,
>> >> >>>>> >> >> >> >> >> > Jomo
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >> >>>>> >> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute
>> >> >>>>> >> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> >> "ant
>> >> >>>>> >> >> >> >> >> >> release"
>> >> >>>>> >> >> >> >> >> >> command after my native targets are built. Part
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> that
>> >> >>>>> >> >> >> >> >> >> command
>> >> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >> >>>>> >> >> >> >> >> >> directory
>> >> >>>>> >> >> >> >> >> >> so
>> >> >>>>> >> >> >> >> >> >> they
>> >> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using
>> >> >>>>> >> >> >> >> >> >> Android
>> >> >>>>> >> >> >> >> >> >> Studio and
>> >> >>>>> >> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> few
>> >> >>>>> >> >> >> >> >> >> major
>> >> >>>>> >> >> >> >> >> >> releases
>> >> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same
>> >> >>>>> >> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> >> similar
>> >> >>>>> >> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> >> what
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >> >>>>> >> >> >> >> >> >> execute
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >> >>>>> >> >> >> >> >> >> commands.
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> not
>> >> >>>>> >> >> >> >> >> >> too
>> >> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you
>> >> >>>>> >> >> >> >> >> >> tell
>> >> >>>>> >> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> >> where
>> >> >>>>> >> >> >> >> >> >> your
>> >> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging
>> >> >>>>> >> >> >> >> >> >> steps.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using
>> >> >>>>> >> >> >> >> >> >> one
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> these
>> >> >>>>> >> >> >> >> >> >> setups
>> >> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is
>> >> >>>>> >> >> >> >> >> >> probably
>> >> >>>>> >> >> >> >> >> >> no
>> >> >>>>> >> >> >> >> >> >> on-device
>> >> >>>>> >> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >> >>>>> >> >> >> >> >> >> handle
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> projects
>> >> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Would like some general direction & advice
>> >> >>>>> >> >> >> >> >> >> before
>> >> >>>>> >> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> >> move
>> >> >>>>> >> >> >> >> >> >> away
>> >> >>>>> >> >> >> >> >> >> from
>> >> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >> >>>>> >> >> >> >> >> >> --
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>
>> >> >>>>
>> >> >>>
>> >> >>
>> >
>> >
>
>
--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Robert Dailey-2
In reply to this post by Jom O'Fisher
By the way when I try to use "targets", I get a failure. Basically
Gradle doesn't recognize that keyword. I tried singular form as well
("target"), no luck.

I'm running canary build of everything possible. What am I missing?

On Wed, Aug 23, 2017 at 4:20 PM, Jom O'Fisher <[hidden email]> wrote:

> By gradle module projects, I just mean the leaf build.gradle files as
> opposed to the root build.gradle. By configurations, I mean Build Types
> (debug vs release) and Product Flavors (demo vs free vs paid). Hereafter I
> will use the term "variant" rather than "configuration" to be precise. See
> this write-up on build variants:
>
> https://developer.android.com/studio/build/build-variants.html#build-types
>
> This build matrix is constructed at the leaf build.gradle level. Native
> build in gradle allows you to set C/C++ flags individually for each variant
> so that you can define compiler flags (for example, -DFREE_VERSION).
>
> One thing to notice at this stage is that the same CMake target may be built
> with different compiler flags across different projects, build types, and
> product flavors. So in the general case, build outputs won't be the same.
>
> You asked which targets build when specifying path. By default, we build all
> targets that produce an .so. You can override this by setting
> externalNativeBuild.cmake.targets. For example,
>
>     paid {
>       ...
>       externalNativeBuild {
>         cmake {
>           ...
>           targets "native-lib-paid"
>         }
>       }
>     }
>
> As for your last question, the model we generally see used is that the main
> CMakeLists.txt is next to the leaf build.gradle such that this
> CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt (though
> they may share common dependencies and settings). Otherwise, multiple APK
> projects would perform pretty much similar to yours--they would build
> targets per-leaf project and not share build outputs. As far as I can see
> your organization is just as valid so long as you only build the targets you
> need.
>
> Regarding native dependencies between java projects. We generally try to
> avoid making the CMake build depend on the gradle build (you should be able
> to replicate the CMake build from the command-line if you set the right
> flags). At the moment I don't see a way we could make things better without
> violating that tenet but that could be lack of imagination on my part.
>
> We'll definitely be discussing this use case at our next C++ meeting and
> I'll also be checking for myself whether ccache will work in this CMake
> scenario. If ccache does work it seems like the natural level at which to
> fold identical builds.
>
>
>
> On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey <[hidden email]>
> wrote:
>>
>> I'm not sure what you mean by "gradle module projects", but maybe
>> having some examples of what you mean by "configurations, C++ flags,
>> etc" might make it more clear.
>>
>> Question: When specifying "path" for the CMakeLists.txt in the
>> build.gradle file, how do you know which targets to build? For
>> example, that run of CMake may generate 100 targets, but only 20 need
>> to build and be packaged (*.so files) with the APK. Do you just build
>> "all"? Is there a way to specify the target itself?
>>
>> Thanks again. I'd still like to know more about what the ideal
>> organization is. I find it hard to believe that large android projects
>> rarely break things up into multiple, separate "components" that are
>> built independently. That's really the gist of what we're dealing with
>> here. Your typical "hello world" project likely will have only 1
>> CMakeLists.txt that is pretty self-contained, but all the
>> documentation I've looked at so far doesn't show the best way to
>> handle native library dependencies across java projects between
>> build.gradle files (or maybe I'm just not looking hard enough).
>>
>> On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]>
>> wrote:
>> > Thanks for the write-up Robert. Having thought about it, I don't believe
>> > we
>> > have a satisfying answer at the gradle level for this kind of
>> > organization.
>> > In the gradle model module projects are the unit of organization for
>> > configurations, C/C++ flags, etc. and that's something we're pretty much
>> > stuck with.
>> > Regarding just the redundant build issue, would something like ccache
>> > help?
>> > I know people have used it with ndk-build with success, I'm not sure
>> > about
>> > CMake but I don't see why that should make a difference.
>> >
>> >
>> >
>> > On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> Another reason to reduce the number of binary directories is that
>> >> there are different ways of managing third party libraries. One in
>> >> particular that we use is to clone a repository into the binary
>> >> directory and build all third party libs in real time based on a
>> >> toolchain file (Similar to the functionality provided by
>> >> ExternalProject module in CMake). This is repeated from scratch only
>> >> if the work hasn't already been done in the binary directory before.
>> >> By having more binary dirs than needed, this work is being done an
>> >> exponential amount of times which can result in a lot of wasted time
>> >> waiting. There are 1 time operations that multiple targets can benefit
>> >> from in a single binary tree, instead of 1 per unique target being
>> >> invoked.
>> >>
>> >> Sorry to keep responding: I'm just thinking of things as I go and
>> >> bringing them up, to shed light on some of the reasoning behind my
>> >> suggestions.
>> >>
>> >> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey
>> >> <[hidden email]>
>> >> wrote:
>> >> > Sorry I forgot to answer your last set of questions:
>> >> >
>> >> > CommonLib is indeed 2 things:
>> >> >
>> >> > * A common (static or shared) library for native code (most of our
>> >> > CMake targets specify CommonLib as a link dependency)
>> >> > * A common library for Java code (we do specify this as a dependency
>> >> > for most java targets in Gradle, specifically those under
>> >> > Applications/)
>> >> >
>> >> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]>
>> >> > wrote:
>> >> >> Hi Robert,
>> >> >>
>> >> >> I work with Jom on the Android Studio team, and I would like to
>> >> >> clarify
>> >> >> a
>> >> >> few things to better understand your situation.
>> >> >> You mentioned the project is intend to be cross platform.  Normally,
>> >> >> in
>> >> >> such
>> >> >> situation, we expect there to be a single CMake root project to be
>> >> >> imported
>> >> >> into one of the Android library/application.  However, in your case,
>> >> >> there
>> >> >> are subprojects with Java code.
>> >> >>
>> >> >> Are the CMake code in App1/2/3 intended to be cross platform too?
>> >> >> Or
>> >> >> are
>> >> >> they Android specific code?  If they are meant to be cross platform,
>> >> >> how
>> >> >> does the Java code works on other platforms?  Or perhaps you added
>> >> >> Java
>> >> >> binding in those subprojects just for Android?
>> >> >>
>> >> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> >> From
>> >> >> your description, it doesn't look like an Android library project.
>> >> >> Or
>> >> >> am I
>> >> >> mistaken and it also applies the android library plugin?
>> >> >>
>> >> >> Raymond
>> >> >>
>> >> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> >> wrote:
>> >> >>>
>> >> >>> + a colleague
>> >> >>>
>> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
>> >> >>> <[hidden email]>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> You can find that number like this:
>> >> >>>> - x = number of externalNativeBuild.cmake.path in your
>> >> >>>> build.gradle
>> >> >>>> files
>> >> >>>> - y = number of gradle configurations (like debug and release)
>> >> >>>> - z = number of ABIs that you build
>> >> >>>>
>> >> >>>> The result is x * y * z. To be more accurate, you should consider
>> >> >>>> y
>> >> >>>> and z
>> >> >>>> to be functions of each build.gradle file since these can vary.
>> >> >>>>
>> >> >>>> There is a second set of folders that hold the stripped versions
>> >> >>>> of
>> >> >>>> the
>> >> >>>> .so files that is purely managed by the android gradle plugin, so
>> >> >>>> you
>> >> >>>> might
>> >> >>>> consider the answer to be 2 * x * y * z.
>> >> >>>>
>> >> >>>> Hope this helps.
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >> >>>> <[hidden email]>
>> >> >>>> wrote:
>> >> >>>>>
>> >> >>>>> This definitely a bit better, but still requires the boilerplate
>> >> >>>>> in
>> >> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >> >>>>> think I'm more concerned with the implications this has
>> >> >>>>> underneath.
>> >> >>>>> First, let me ask just to make sure I'm not misunderstanding:
>> >> >>>>> Does
>> >> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >> >>>>> CMAKE_BINARY_DIR?
>> >> >>>>> How many binary dirs do you manage internally and what determines
>> >> >>>>> when
>> >> >>>>> they get created?
>> >> >>>>>
>> >> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher
>> >> >>>>> <[hidden email]>
>> >> >>>>> wrote:
>> >> >>>>> > Would it work for your scenario to provide properties in the
>> >> >>>>> > root
>> >> >>>>> > build.gradle:
>> >> >>>>> >
>> >> >>>>> > ext {
>> >> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >> >>>>> >
>> >> >>>>> > externalNativeBuild {
>> >> >>>>> >     cmake {
>> >> >>>>> >         path cmakePath
>> >> >>>>> >     }
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > It doesn't fully hide the details but it does centralize the
>> >> >>>>> > information.
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >> >>>>> > <[hidden email]>
>> >> >>>>> > wrote:
>> >> >>>>> >>
>> >> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >> >>>>> >> run on
>> >> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >> >>>>> >> Normal
>> >> >>>>> >> CMake behavior is designed to work at a root then go downwards
>> >> >>>>> >> to
>> >> >>>>> >> find
>> >> >>>>> >> targets. However it seems Gradle wants to start at a
>> >> >>>>> >> subdirectory
>> >> >>>>> >> and
>> >> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >> >>>>> >> intended
>> >> >>>>> >> behavior IMHO. Not only that but I want to avoid
>> >> >>>>> >> special-casing
>> >> >>>>> >> behavior in CMake just for Android's use.
>> >> >>>>> >>
>> >> >>>>> >> At the moment it feels like (again referring back to my
>> >> >>>>> >> previous
>> >> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >> >>>>> >> independent binary directories instead of sharing 1 binary
>> >> >>>>> >> directory
>> >> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >> >>>>> >> instead,
>> >> >>>>> >> especially since it allows CMake to operate as it was
>> >> >>>>> >> intended. I
>> >> >>>>> >> think it's a common case that projects will define multiple
>> >> >>>>> >> targets
>> >> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >> >>>>> >> dependencies to be built within it.
>> >> >>>>> >>
>> >> >>>>> >> If I'm misunderstanding or making false assumptions please let
>> >> >>>>> >> me
>> >> >>>>> >> know.
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >> >>>>> >> <[hidden email]>
>> >> >>>>> >> wrote:
>> >> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt
>> >> >>>>> >> > to
>> >> >>>>> >> > include
>> >> >>>>> >> > the
>> >> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in
>> >> >>>>> >> > the
>> >> >>>>> >> > leaf
>> >> >>>>> >> > CMakeLists.txt?
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >> >>>>> >> > <[hidden email]>
>> >> >>>>> >> > wrote:
>> >> >>>>> >> >>
>> >> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >> >>>>> >> >>
>> >> >>>>> >> >> <Root of git clone>/
>> >> >>>>> >> >>     Applications/
>> >> >>>>> >> >>         App1/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App2/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App3/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>     CommonLib/
>> >> >>>>> >> >>         build.gradle
>> >> >>>>> >> >>         CMakeLists.txt
>> >> >>>>> >> >>     CMakeLists.txt
>> >> >>>>> >> >>
>> >> >>>>> >> >> The libs are defined as follows:
>> >> >>>>> >> >>
>> >> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * No dependencies of its own
>> >> >>>>> >> >> * App1 is a shared library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >>
>> >> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the
>> >> >>>>> >> >> same
>> >> >>>>> >> >> binary
>> >> >>>>> >> >> directory after that. Previously with ANT, I was building
>> >> >>>>> >> >> all
>> >> >>>>> >> >> native
>> >> >>>>> >> >> targets first, then moved libs to appropriate directories
>> >> >>>>> >> >> so
>> >> >>>>> >> >> that
>> >> >>>>> >> >> the
>> >> >>>>> >> >> 'ant' command would package the libs.
>> >> >>>>> >> >>
>> >> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the
>> >> >>>>> >> >> root
>> >> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >> >>>>> >> >> example
>> >> >>>>> >> >> above, the leaf-level directories in this case would be
>> >> >>>>> >> >> App1,
>> >> >>>>> >> >> App2,
>> >> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> stuff for the java targets that actually output an APK
>> >> >>>>> >> >> (that
>> >> >>>>> >> >> would
>> >> >>>>> >> >> be
>> >> >>>>> >> >> App2 and App3 only).
>> >> >>>>> >> >>
>> >> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change
>> >> >>>>> >> >> per
>> >> >>>>> >> >> independent "module" of ours at the top level so it is
>> >> >>>>> >> >> transitive
>> >> >>>>> >> >> /
>> >> >>>>> >> >> inherited. Then only specify the differences (e.g. the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> target to build) in the leaf build gradle files. However
>> >> >>>>> >> >> you
>> >> >>>>> >> >> indicated
>> >> >>>>> >> >> this isn't possible.
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >> >>>>> >> >> <[hidden email]>
>> >> >>>>> >> >> wrote:
>> >> >>>>> >> >> > What you're doing already sounds correct. You can't
>> >> >>>>> >> >> > directly
>> >> >>>>> >> >> > specify
>> >> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >> >>>>> >> >> > Recommendation
>> >> >>>>> >> >> > is
>> >> >>>>> >> >> > that
>> >> >>>>> >> >> > it
>> >> >>>>> >> >> > should be specified from the build.gradle of the module
>> >> >>>>> >> >> > of
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > APK.
>> >> >>>>> >> >> > Is
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > issue that you have multiple APK modules that all
>> >> >>>>> >> >> > reference
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > same
>> >> >>>>> >> >> > CMake
>> >> >>>>> >> >> > libraries?
>> >> >>>>> >> >> >
>> >> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >> >>>>> >> >> > <[hidden email]>
>> >> >>>>> >> >> > wrote:
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> Thanks this is very helpful. The other question I have
>> >> >>>>> >> >> >> is:
>> >> >>>>> >> >> >> Is
>> >> >>>>> >> >> >> there
>> >> >>>>> >> >> >> a
>> >> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >> >>>>> >> >> >> Basically,
>> >> >>>>> >> >> >> I
>> >> >>>>> >> >> >> want
>> >> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >> >>>>> >> >> >> (defined
>> >> >>>>> >> >> >> further down in subdirectories) that require APK
>> >> >>>>> >> >> >> packaging
>> >> >>>>> >> >> >> to
>> >> >>>>> >> >> >> specify
>> >> >>>>> >> >> >> only the native target name that should be built &
>> >> >>>>> >> >> >> packaged.
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by
>> >> >>>>> >> >> >> walking
>> >> >>>>> >> >> >> up
>> >> >>>>> >> >> >> the
>> >> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> should
>> >> >>>>> >> >> >> be
>> >> >>>>> >> >> >> put at the top-level build gradle file if possible. Is
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> doable
>> >> >>>>> >> >> >> at
>> >> >>>>> >> >> >> the moment? What is the recommended setup?
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >> >>>>> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> wrote:
>> >> >>>>> >> >> >> > Gradle does introspection on the CMake build to find
>> >> >>>>> >> >> >> > .so
>> >> >>>>> >> >> >> > targets
>> >> >>>>> >> >> >> > and
>> >> >>>>> >> >> >> > those
>> >> >>>>> >> >> >> > get packaged.
>> >> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >> >>>>> >> >> >> > from
>> >> >>>>> >> >> >> > the
>> >> >>>>> >> >> >> > NDK.
>> >> >>>>> >> >> >> > Any additional .so files need to specified in
>> >> >>>>> >> >> >> > build.gradle
>> >> >>>>> >> >> >> > using
>> >> >>>>> >> >> >> > jniDirs
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >> >>>>> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> > wrote:
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK?
>> >> >>>>> >> >> >> >> I
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> that
>> >> >>>>> >> >> >> >> ANT
>> >> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >> >>>>> >> >> >> >> Gradle
>> >> >>>>> >> >> >> >> do
>> >> >>>>> >> >> >> >> some
>> >> >>>>> >> >> >> >> introspection into CMake targets to see if outputs
>> >> >>>>> >> >> >> >> are
>> >> >>>>> >> >> >> >> *.so,
>> >> >>>>> >> >> >> >> and
>> >> >>>>> >> >> >> >> copy
>> >> >>>>> >> >> >> >> those to some location if needed? What about
>> >> >>>>> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> like
>> >> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like
>> >> >>>>> >> >> >> >> to
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> if
>> >> >>>>> >> >> >> >> any
>> >> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs
>> >> >>>>> >> >> >> >> in
>> >> >>>>> >> >> >> >> proper
>> >> >>>>> >> >> >> >> locations for the APK build step. I had to do this
>> >> >>>>> >> >> >> >> when
>> >> >>>>> >> >> >> >> using
>> >> >>>>> >> >> >> >> ANT.
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >> >>>>> >> >> >> >> > project
>> >> >>>>> >> >> >> >> > module
>> >> >>>>> >> >> >> >> > folder
>> >> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >> >>>>> >> >> >> >> > can
>> >> >>>>> >> >> >> >> > choose
>> >> >>>>> >> >> >> >> > to
>> >> >>>>> >> >> >> >> > specify it
>> >> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a
>> >> >>>>> >> >> >> >> > pretty
>> >> >>>>> >> >> >> >> > good job
>> >> >>>>> >> >> >> >> > of
>> >> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can
>> >> >>>>> >> >> >> >> > get
>> >> >>>>> >> >> >> >> > away
>> >> >>>>> >> >> >> >> > with.
>> >> >>>>> >> >> >> >> > In
>> >> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >> >>>>> >> >> >> >> > CMake
>> >> >>>>> >> >> >> >> > build
>> >> >>>>> >> >> >> >> > command"
>> >> >>>>> >> >> >> >> > lays
>> >> >>>>> >> >> >> >> > out exactly what we set. You can also see the
>> >> >>>>> >> >> >> >> > folders
>> >> >>>>> >> >> >> >> > we
>> >> >>>>> >> >> >> >> > specify
>> >> >>>>> >> >> >> >> > (one
>> >> >>>>> >> >> >> >> > per
>> >> >>>>> >> >> >> >> > module per ABI)
>> >> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >> >>>>> >> >> >> >> > haven't
>> >> >>>>> >> >> >> >> > already)
>> >> >>>>> >> >> >> >> > is:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >> >>>>> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks Jom
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >> >>>>> >> >> >> >> >> that's
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> Google's
>> >> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >> >>>>> >> >> >> >> >> debugging
>> >> >>>>> >> >> >> >> >> which
>> >> >>>>> >> >> >> >> >> is
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> #1
>> >> >>>>> >> >> >> >> >> reason for me.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> integration
>> >> >>>>> >> >> >> >> >> really happens. For example, I have these
>> >> >>>>> >> >> >> >> >> questions:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >> >>>>> >> >> >> >> >> managed?
>> >> >>>>> >> >> >> >> >> Do
>> >> >>>>> >> >> >> >> >> you
>> >> >>>>> >> >> >> >> >> generate 1 per unique android project? What about
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> specific
>> >> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration,
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> inside
>> >> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >> >>>>> >> >> >> >> >> specified
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> command line. Namely, all of those settings that
>> >> >>>>> >> >> >> >> >> are
>> >> >>>>> >> >> >> >> >> driven by
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one
>> >> >>>>> >> >> >> >> >> in
>> >> >>>>> >> >> >> >> >> particular
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >> >>>>> >> >> >> >> >> recall
>> >> >>>>> >> >> >> >> >> this
>> >> >>>>> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> overridden from outside)?
>> >> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >> >>>>> >> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> >> via
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted
>> >> >>>>> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> define
>> >> >>>>> >> >> >> >> >> common
>> >> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle
>> >> >>>>> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> file,
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >> >>>>> >> >> >> >> >> build
>> >> >>>>> >> >> >> >> >> files
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >> >>>>> >> >> >> >> >> line
>> >> >>>>> >> >> >> >> >> invocation,
>> >> >>>>> >> >> >> >> >> -D
>> >> >>>>> >> >> >> >> >> CMake settings, etc would all be common and
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> root).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> doing
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >> >>>>> >> >> >> >> >> CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >> >>>>> >> >> >> >> >> cross-platform
>> >> >>>>> >> >> >> >> >> easier
>> >> >>>>> >> >> >> >> >> (we
>> >> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >> >>>>> >> >> >> >> >> having
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >> >>>>> >> >> >> >> >> other
>> >> >>>>> >> >> >> >> >> platforms.
>> >> >>>>> >> >> >> >> >> Namely, settings that are not platform specific
>> >> >>>>> >> >> >> >> >> like
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> C++
>> >> >>>>> >> >> >> >> >> language
>> >> >>>>> >> >> >> >> >> level).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read
>> >> >>>>> >> >> >> >> >> on
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> intrinsics
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >> >>>>> >> >> >> >> >> love to
>> >> >>>>> >> >> >> >> >> read
>> >> >>>>> >> >> >> >> >> it.
>> >> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your
>> >> >>>>> >> >> >> >> >> brain
>> >> >>>>> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> questions
>> >> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> see how
>> >> >>>>> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >> >>>>> >> >> >> >> >> option 2,
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> have
>> >> >>>>> >> >> >> >> >> very
>> >> >>>>> >> >> >> >> >> little control over what happens after building
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> shared
>> >> >>>>> >> >> >> >> >> libraries,
>> >> >>>>> >> >> >> >> >> and to make up for that I need to really get a
>> >> >>>>> >> >> >> >> >> deep
>> >> >>>>> >> >> >> >> >> understanding
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> properly
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >> >>>>> >> >> >> >> >> (non-Android
>> >> >>>>> >> >> >> >> >> platforms).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks again.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work
>> >> >>>>> >> >> >> >> >> > on
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Studio
>> >> >>>>> >> >> >> >> >> > and
>> >> >>>>> >> >> >> >> >> > was
>> >> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >> >>>>> >> >> >> >> >> > we're
>> >> >>>>> >> >> >> >> >> > working
>> >> >>>>> >> >> >> >> >> > toward
>> >> >>>>> >> >> >> >> >> > getting
>> >> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't
>> >> >>>>> >> >> >> >> >> > really
>> >> >>>>> >> >> >> >> >> > say
>> >> >>>>> >> >> >> >> >> > when
>> >> >>>>> >> >> >> >> >> > that
>> >> >>>>> >> >> >> >> >> > will
>> >> >>>>> >> >> >> >> >> > happen
>> >> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for
>> >> >>>>> >> >> >> >> >> > now
>> >> >>>>> >> >> >> >> >> > then I'd
>> >> >>>>> >> >> >> >> >> > go
>> >> >>>>> >> >> >> >> >> > this
>> >> >>>>> >> >> >> >> >> > way.
>> >> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to
>> >> >>>>> >> >> >> >> >> > view
>> >> >>>>> >> >> >> >> >> > your
>> >> >>>>> >> >> >> >> >> > source
>> >> >>>>> >> >> >> >> >> > file
>> >> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and
>> >> >>>>> >> >> >> >> >> > debug
>> >> >>>>> >> >> >> >> >> > using the
>> >> >>>>> >> >> >> >> >> > built-in
>> >> >>>>> >> >> >> >> >> > debugging support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >> >>>>> >> >> >> >> >> > setting
>> >> >>>>> >> >> >> >> >> > to
>> >> >>>>> >> >> >> >> >> > tell
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files
>> >> >>>>> >> >> >> >> >> > (see
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >> >>>>> >> >> >> >> >> > approach
>> >> >>>>> >> >> >> >> >> > but it
>> >> >>>>> >> >> >> >> >> > should
>> >> >>>>> >> >> >> >> >> > work
>> >> >>>>> >> >> >> >> >> > in
>> >> >>>>> >> >> >> >> >> > principal.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > I hope this helps,
>> >> >>>>> >> >> >> >> >> > Jomo
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >> >>>>> >> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute
>> >> >>>>> >> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> >> "ant
>> >> >>>>> >> >> >> >> >> >> release"
>> >> >>>>> >> >> >> >> >> >> command after my native targets are built. Part
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> that
>> >> >>>>> >> >> >> >> >> >> command
>> >> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >> >>>>> >> >> >> >> >> >> directory
>> >> >>>>> >> >> >> >> >> >> so
>> >> >>>>> >> >> >> >> >> >> they
>> >> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using
>> >> >>>>> >> >> >> >> >> >> Android
>> >> >>>>> >> >> >> >> >> >> Studio and
>> >> >>>>> >> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> few
>> >> >>>>> >> >> >> >> >> >> major
>> >> >>>>> >> >> >> >> >> >> releases
>> >> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same
>> >> >>>>> >> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> >> similar
>> >> >>>>> >> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> >> what
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >> >>>>> >> >> >> >> >> >> execute
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >> >>>>> >> >> >> >> >> >> commands.
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> not
>> >> >>>>> >> >> >> >> >> >> too
>> >> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you
>> >> >>>>> >> >> >> >> >> >> tell
>> >> >>>>> >> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> >> where
>> >> >>>>> >> >> >> >> >> >> your
>> >> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging
>> >> >>>>> >> >> >> >> >> >> steps.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using
>> >> >>>>> >> >> >> >> >> >> one
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> these
>> >> >>>>> >> >> >> >> >> >> setups
>> >> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is
>> >> >>>>> >> >> >> >> >> >> probably
>> >> >>>>> >> >> >> >> >> >> no
>> >> >>>>> >> >> >> >> >> >> on-device
>> >> >>>>> >> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >> >>>>> >> >> >> >> >> >> handle
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> projects
>> >> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Would like some general direction & advice
>> >> >>>>> >> >> >> >> >> >> before
>> >> >>>>> >> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> >> move
>> >> >>>>> >> >> >> >> >> >> away
>> >> >>>>> >> >> >> >> >> >> from
>> >> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >> >>>>> >> >> >> >> >> >> --
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>
>> >> >>>>
>> >> >>>
>> >> >>
>> >
>> >
>
>
--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Jom O'Fisher
Targets are specified per-Variation so they need to go under the variation-specific section. Probably something like this:

                        defaultConfig {
                          externalNativeBuild {
                            cmake {
                              targets "library1", "library2"
                            }
                          }
                        }

That should work for you. Let me know.

On Fri, Aug 25, 2017 at 2:42 PM, Robert Dailey <[hidden email]> wrote:
By the way when I try to use "targets", I get a failure. Basically
Gradle doesn't recognize that keyword. I tried singular form as well
("target"), no luck.

I'm running canary build of everything possible. What am I missing?

On Wed, Aug 23, 2017 at 4:20 PM, Jom O'Fisher <[hidden email]> wrote:
> By gradle module projects, I just mean the leaf build.gradle files as
> opposed to the root build.gradle. By configurations, I mean Build Types
> (debug vs release) and Product Flavors (demo vs free vs paid). Hereafter I
> will use the term "variant" rather than "configuration" to be precise. See
> this write-up on build variants:
>
> https://developer.android.com/studio/build/build-variants.html#build-types
>
> This build matrix is constructed at the leaf build.gradle level. Native
> build in gradle allows you to set C/C++ flags individually for each variant
> so that you can define compiler flags (for example, -DFREE_VERSION).
>
> One thing to notice at this stage is that the same CMake target may be built
> with different compiler flags across different projects, build types, and
> product flavors. So in the general case, build outputs won't be the same.
>
> You asked which targets build when specifying path. By default, we build all
> targets that produce an .so. You can override this by setting
> externalNativeBuild.cmake.targets. For example,
>
>     paid {
>       ...
>       externalNativeBuild {
>         cmake {
>           ...
>           targets "native-lib-paid"
>         }
>       }
>     }
>
> As for your last question, the model we generally see used is that the main
> CMakeLists.txt is next to the leaf build.gradle such that this
> CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt (though
> they may share common dependencies and settings). Otherwise, multiple APK
> projects would perform pretty much similar to yours--they would build
> targets per-leaf project and not share build outputs. As far as I can see
> your organization is just as valid so long as you only build the targets you
> need.
>
> Regarding native dependencies between java projects. We generally try to
> avoid making the CMake build depend on the gradle build (you should be able
> to replicate the CMake build from the command-line if you set the right
> flags). At the moment I don't see a way we could make things better without
> violating that tenet but that could be lack of imagination on my part.
>
> We'll definitely be discussing this use case at our next C++ meeting and
> I'll also be checking for myself whether ccache will work in this CMake
> scenario. If ccache does work it seems like the natural level at which to
> fold identical builds.
>
>
>
> On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey <[hidden email]>
> wrote:
>>
>> I'm not sure what you mean by "gradle module projects", but maybe
>> having some examples of what you mean by "configurations, C++ flags,
>> etc" might make it more clear.
>>
>> Question: When specifying "path" for the CMakeLists.txt in the
>> build.gradle file, how do you know which targets to build? For
>> example, that run of CMake may generate 100 targets, but only 20 need
>> to build and be packaged (*.so files) with the APK. Do you just build
>> "all"? Is there a way to specify the target itself?
>>
>> Thanks again. I'd still like to know more about what the ideal
>> organization is. I find it hard to believe that large android projects
>> rarely break things up into multiple, separate "components" that are
>> built independently. That's really the gist of what we're dealing with
>> here. Your typical "hello world" project likely will have only 1
>> CMakeLists.txt that is pretty self-contained, but all the
>> documentation I've looked at so far doesn't show the best way to
>> handle native library dependencies across java projects between
>> build.gradle files (or maybe I'm just not looking hard enough).
>>
>> On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]>
>> wrote:
>> > Thanks for the write-up Robert. Having thought about it, I don't believe
>> > we
>> > have a satisfying answer at the gradle level for this kind of
>> > organization.
>> > In the gradle model module projects are the unit of organization for
>> > configurations, C/C++ flags, etc. and that's something we're pretty much
>> > stuck with.
>> > Regarding just the redundant build issue, would something like ccache
>> > help?
>> > I know people have used it with ndk-build with success, I'm not sure
>> > about
>> > CMake but I don't see why that should make a difference.
>> >
>> >
>> >
>> > On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> Another reason to reduce the number of binary directories is that
>> >> there are different ways of managing third party libraries. One in
>> >> particular that we use is to clone a repository into the binary
>> >> directory and build all third party libs in real time based on a
>> >> toolchain file (Similar to the functionality provided by
>> >> ExternalProject module in CMake). This is repeated from scratch only
>> >> if the work hasn't already been done in the binary directory before.
>> >> By having more binary dirs than needed, this work is being done an
>> >> exponential amount of times which can result in a lot of wasted time
>> >> waiting. There are 1 time operations that multiple targets can benefit
>> >> from in a single binary tree, instead of 1 per unique target being
>> >> invoked.
>> >>
>> >> Sorry to keep responding: I'm just thinking of things as I go and
>> >> bringing them up, to shed light on some of the reasoning behind my
>> >> suggestions.
>> >>
>> >> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey
>> >> <[hidden email]>
>> >> wrote:
>> >> > Sorry I forgot to answer your last set of questions:
>> >> >
>> >> > CommonLib is indeed 2 things:
>> >> >
>> >> > * A common (static or shared) library for native code (most of our
>> >> > CMake targets specify CommonLib as a link dependency)
>> >> > * A common library for Java code (we do specify this as a dependency
>> >> > for most java targets in Gradle, specifically those under
>> >> > Applications/)
>> >> >
>> >> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]>
>> >> > wrote:
>> >> >> Hi Robert,
>> >> >>
>> >> >> I work with Jom on the Android Studio team, and I would like to
>> >> >> clarify
>> >> >> a
>> >> >> few things to better understand your situation.
>> >> >> You mentioned the project is intend to be cross platform.  Normally,
>> >> >> in
>> >> >> such
>> >> >> situation, we expect there to be a single CMake root project to be
>> >> >> imported
>> >> >> into one of the Android library/application.  However, in your case,
>> >> >> there
>> >> >> are subprojects with Java code.
>> >> >>
>> >> >> Are the CMake code in App1/2/3 intended to be cross platform too?
>> >> >> Or
>> >> >> are
>> >> >> they Android specific code?  If they are meant to be cross platform,
>> >> >> how
>> >> >> does the Java code works on other platforms?  Or perhaps you added
>> >> >> Java
>> >> >> binding in those subprojects just for Android?
>> >> >>
>> >> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> >> From
>> >> >> your description, it doesn't look like an Android library project.
>> >> >> Or
>> >> >> am I
>> >> >> mistaken and it also applies the android library plugin?
>> >> >>
>> >> >> Raymond
>> >> >>
>> >> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> >> wrote:
>> >> >>>
>> >> >>> + a colleague
>> >> >>>
>> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
>> >> >>> <[hidden email]>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> You can find that number like this:
>> >> >>>> - x = number of externalNativeBuild.cmake.path in your
>> >> >>>> build.gradle
>> >> >>>> files
>> >> >>>> - y = number of gradle configurations (like debug and release)
>> >> >>>> - z = number of ABIs that you build
>> >> >>>>
>> >> >>>> The result is x * y * z. To be more accurate, you should consider
>> >> >>>> y
>> >> >>>> and z
>> >> >>>> to be functions of each build.gradle file since these can vary.
>> >> >>>>
>> >> >>>> There is a second set of folders that hold the stripped versions
>> >> >>>> of
>> >> >>>> the
>> >> >>>> .so files that is purely managed by the android gradle plugin, so
>> >> >>>> you
>> >> >>>> might
>> >> >>>> consider the answer to be 2 * x * y * z.
>> >> >>>>
>> >> >>>> Hope this helps.
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >> >>>> <[hidden email]>
>> >> >>>> wrote:
>> >> >>>>>
>> >> >>>>> This definitely a bit better, but still requires the boilerplate
>> >> >>>>> in
>> >> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >> >>>>> think I'm more concerned with the implications this has
>> >> >>>>> underneath.
>> >> >>>>> First, let me ask just to make sure I'm not misunderstanding:
>> >> >>>>> Does
>> >> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >> >>>>> CMAKE_BINARY_DIR?
>> >> >>>>> How many binary dirs do you manage internally and what determines
>> >> >>>>> when
>> >> >>>>> they get created?
>> >> >>>>>
>> >> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher
>> >> >>>>> <[hidden email]>
>> >> >>>>> wrote:
>> >> >>>>> > Would it work for your scenario to provide properties in the
>> >> >>>>> > root
>> >> >>>>> > build.gradle:
>> >> >>>>> >
>> >> >>>>> > ext {
>> >> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >> >>>>> >
>> >> >>>>> > externalNativeBuild {
>> >> >>>>> >     cmake {
>> >> >>>>> >         path cmakePath
>> >> >>>>> >     }
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > It doesn't fully hide the details but it does centralize the
>> >> >>>>> > information.
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >> >>>>> > <[hidden email]>
>> >> >>>>> > wrote:
>> >> >>>>> >>
>> >> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >> >>>>> >> run on
>> >> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >> >>>>> >> Normal
>> >> >>>>> >> CMake behavior is designed to work at a root then go downwards
>> >> >>>>> >> to
>> >> >>>>> >> find
>> >> >>>>> >> targets. However it seems Gradle wants to start at a
>> >> >>>>> >> subdirectory
>> >> >>>>> >> and
>> >> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >> >>>>> >> intended
>> >> >>>>> >> behavior IMHO. Not only that but I want to avoid
>> >> >>>>> >> special-casing
>> >> >>>>> >> behavior in CMake just for Android's use.
>> >> >>>>> >>
>> >> >>>>> >> At the moment it feels like (again referring back to my
>> >> >>>>> >> previous
>> >> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >> >>>>> >> independent binary directories instead of sharing 1 binary
>> >> >>>>> >> directory
>> >> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >> >>>>> >> instead,
>> >> >>>>> >> especially since it allows CMake to operate as it was
>> >> >>>>> >> intended. I
>> >> >>>>> >> think it's a common case that projects will define multiple
>> >> >>>>> >> targets
>> >> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >> >>>>> >> dependencies to be built within it.
>> >> >>>>> >>
>> >> >>>>> >> If I'm misunderstanding or making false assumptions please let
>> >> >>>>> >> me
>> >> >>>>> >> know.
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >> >>>>> >> <[hidden email]>
>> >> >>>>> >> wrote:
>> >> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt
>> >> >>>>> >> > to
>> >> >>>>> >> > include
>> >> >>>>> >> > the
>> >> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in
>> >> >>>>> >> > the
>> >> >>>>> >> > leaf
>> >> >>>>> >> > CMakeLists.txt?
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >> >>>>> >> > <[hidden email]>
>> >> >>>>> >> > wrote:
>> >> >>>>> >> >>
>> >> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >> >>>>> >> >>
>> >> >>>>> >> >> <Root of git clone>/
>> >> >>>>> >> >>     Applications/
>> >> >>>>> >> >>         App1/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App2/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App3/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>     CommonLib/
>> >> >>>>> >> >>         build.gradle
>> >> >>>>> >> >>         CMakeLists.txt
>> >> >>>>> >> >>     CMakeLists.txt
>> >> >>>>> >> >>
>> >> >>>>> >> >> The libs are defined as follows:
>> >> >>>>> >> >>
>> >> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * No dependencies of its own
>> >> >>>>> >> >> * App1 is a shared library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >>
>> >> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the
>> >> >>>>> >> >> same
>> >> >>>>> >> >> binary
>> >> >>>>> >> >> directory after that. Previously with ANT, I was building
>> >> >>>>> >> >> all
>> >> >>>>> >> >> native
>> >> >>>>> >> >> targets first, then moved libs to appropriate directories
>> >> >>>>> >> >> so
>> >> >>>>> >> >> that
>> >> >>>>> >> >> the
>> >> >>>>> >> >> 'ant' command would package the libs.
>> >> >>>>> >> >>
>> >> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the
>> >> >>>>> >> >> root
>> >> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >> >>>>> >> >> example
>> >> >>>>> >> >> above, the leaf-level directories in this case would be
>> >> >>>>> >> >> App1,
>> >> >>>>> >> >> App2,
>> >> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> stuff for the java targets that actually output an APK
>> >> >>>>> >> >> (that
>> >> >>>>> >> >> would
>> >> >>>>> >> >> be
>> >> >>>>> >> >> App2 and App3 only).
>> >> >>>>> >> >>
>> >> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change
>> >> >>>>> >> >> per
>> >> >>>>> >> >> independent "module" of ours at the top level so it is
>> >> >>>>> >> >> transitive
>> >> >>>>> >> >> /
>> >> >>>>> >> >> inherited. Then only specify the differences (e.g. the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> target to build) in the leaf build gradle files. However
>> >> >>>>> >> >> you
>> >> >>>>> >> >> indicated
>> >> >>>>> >> >> this isn't possible.
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >> >>>>> >> >> <[hidden email]>
>> >> >>>>> >> >> wrote:
>> >> >>>>> >> >> > What you're doing already sounds correct. You can't
>> >> >>>>> >> >> > directly
>> >> >>>>> >> >> > specify
>> >> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >> >>>>> >> >> > Recommendation
>> >> >>>>> >> >> > is
>> >> >>>>> >> >> > that
>> >> >>>>> >> >> > it
>> >> >>>>> >> >> > should be specified from the build.gradle of the module
>> >> >>>>> >> >> > of
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > APK.
>> >> >>>>> >> >> > Is
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > issue that you have multiple APK modules that all
>> >> >>>>> >> >> > reference
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > same
>> >> >>>>> >> >> > CMake
>> >> >>>>> >> >> > libraries?
>> >> >>>>> >> >> >
>> >> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >> >>>>> >> >> > <[hidden email]>
>> >> >>>>> >> >> > wrote:
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> Thanks this is very helpful. The other question I have
>> >> >>>>> >> >> >> is:
>> >> >>>>> >> >> >> Is
>> >> >>>>> >> >> >> there
>> >> >>>>> >> >> >> a
>> >> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >> >>>>> >> >> >> Basically,
>> >> >>>>> >> >> >> I
>> >> >>>>> >> >> >> want
>> >> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >> >>>>> >> >> >> (defined
>> >> >>>>> >> >> >> further down in subdirectories) that require APK
>> >> >>>>> >> >> >> packaging
>> >> >>>>> >> >> >> to
>> >> >>>>> >> >> >> specify
>> >> >>>>> >> >> >> only the native target name that should be built &
>> >> >>>>> >> >> >> packaged.
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by
>> >> >>>>> >> >> >> walking
>> >> >>>>> >> >> >> up
>> >> >>>>> >> >> >> the
>> >> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> should
>> >> >>>>> >> >> >> be
>> >> >>>>> >> >> >> put at the top-level build gradle file if possible. Is
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> doable
>> >> >>>>> >> >> >> at
>> >> >>>>> >> >> >> the moment? What is the recommended setup?
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >> >>>>> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> wrote:
>> >> >>>>> >> >> >> > Gradle does introspection on the CMake build to find
>> >> >>>>> >> >> >> > .so
>> >> >>>>> >> >> >> > targets
>> >> >>>>> >> >> >> > and
>> >> >>>>> >> >> >> > those
>> >> >>>>> >> >> >> > get packaged.
>> >> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >> >>>>> >> >> >> > from
>> >> >>>>> >> >> >> > the
>> >> >>>>> >> >> >> > NDK.
>> >> >>>>> >> >> >> > Any additional .so files need to specified in
>> >> >>>>> >> >> >> > build.gradle
>> >> >>>>> >> >> >> > using
>> >> >>>>> >> >> >> > jniDirs
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >> >>>>> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> > wrote:
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK?
>> >> >>>>> >> >> >> >> I
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> that
>> >> >>>>> >> >> >> >> ANT
>> >> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >> >>>>> >> >> >> >> Gradle
>> >> >>>>> >> >> >> >> do
>> >> >>>>> >> >> >> >> some
>> >> >>>>> >> >> >> >> introspection into CMake targets to see if outputs
>> >> >>>>> >> >> >> >> are
>> >> >>>>> >> >> >> >> *.so,
>> >> >>>>> >> >> >> >> and
>> >> >>>>> >> >> >> >> copy
>> >> >>>>> >> >> >> >> those to some location if needed? What about
>> >> >>>>> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> like
>> >> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like
>> >> >>>>> >> >> >> >> to
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> if
>> >> >>>>> >> >> >> >> any
>> >> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs
>> >> >>>>> >> >> >> >> in
>> >> >>>>> >> >> >> >> proper
>> >> >>>>> >> >> >> >> locations for the APK build step. I had to do this
>> >> >>>>> >> >> >> >> when
>> >> >>>>> >> >> >> >> using
>> >> >>>>> >> >> >> >> ANT.
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >> >>>>> >> >> >> >> > project
>> >> >>>>> >> >> >> >> > module
>> >> >>>>> >> >> >> >> > folder
>> >> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >> >>>>> >> >> >> >> > can
>> >> >>>>> >> >> >> >> > choose
>> >> >>>>> >> >> >> >> > to
>> >> >>>>> >> >> >> >> > specify it
>> >> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a
>> >> >>>>> >> >> >> >> > pretty
>> >> >>>>> >> >> >> >> > good job
>> >> >>>>> >> >> >> >> > of
>> >> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can
>> >> >>>>> >> >> >> >> > get
>> >> >>>>> >> >> >> >> > away
>> >> >>>>> >> >> >> >> > with.
>> >> >>>>> >> >> >> >> > In
>> >> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >> >>>>> >> >> >> >> > CMake
>> >> >>>>> >> >> >> >> > build
>> >> >>>>> >> >> >> >> > command"
>> >> >>>>> >> >> >> >> > lays
>> >> >>>>> >> >> >> >> > out exactly what we set. You can also see the
>> >> >>>>> >> >> >> >> > folders
>> >> >>>>> >> >> >> >> > we
>> >> >>>>> >> >> >> >> > specify
>> >> >>>>> >> >> >> >> > (one
>> >> >>>>> >> >> >> >> > per
>> >> >>>>> >> >> >> >> > module per ABI)
>> >> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >> >>>>> >> >> >> >> > haven't
>> >> >>>>> >> >> >> >> > already)
>> >> >>>>> >> >> >> >> > is:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >> >>>>> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks Jom
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >> >>>>> >> >> >> >> >> that's
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> Google's
>> >> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >> >>>>> >> >> >> >> >> debugging
>> >> >>>>> >> >> >> >> >> which
>> >> >>>>> >> >> >> >> >> is
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> #1
>> >> >>>>> >> >> >> >> >> reason for me.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> integration
>> >> >>>>> >> >> >> >> >> really happens. For example, I have these
>> >> >>>>> >> >> >> >> >> questions:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >> >>>>> >> >> >> >> >> managed?
>> >> >>>>> >> >> >> >> >> Do
>> >> >>>>> >> >> >> >> >> you
>> >> >>>>> >> >> >> >> >> generate 1 per unique android project? What about
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> specific
>> >> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration,
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> inside
>> >> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >> >>>>> >> >> >> >> >> specified
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> command line. Namely, all of those settings that
>> >> >>>>> >> >> >> >> >> are
>> >> >>>>> >> >> >> >> >> driven by
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one
>> >> >>>>> >> >> >> >> >> in
>> >> >>>>> >> >> >> >> >> particular
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >> >>>>> >> >> >> >> >> recall
>> >> >>>>> >> >> >> >> >> this
>> >> >>>>> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> overridden from outside)?
>> >> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >> >>>>> >> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> >> via
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted
>> >> >>>>> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> define
>> >> >>>>> >> >> >> >> >> common
>> >> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle
>> >> >>>>> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> file,
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >> >>>>> >> >> >> >> >> build
>> >> >>>>> >> >> >> >> >> files
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >> >>>>> >> >> >> >> >> line
>> >> >>>>> >> >> >> >> >> invocation,
>> >> >>>>> >> >> >> >> >> -D
>> >> >>>>> >> >> >> >> >> CMake settings, etc would all be common and
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> root).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> doing
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >> >>>>> >> >> >> >> >> CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >> >>>>> >> >> >> >> >> cross-platform
>> >> >>>>> >> >> >> >> >> easier
>> >> >>>>> >> >> >> >> >> (we
>> >> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >> >>>>> >> >> >> >> >> having
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >> >>>>> >> >> >> >> >> other
>> >> >>>>> >> >> >> >> >> platforms.
>> >> >>>>> >> >> >> >> >> Namely, settings that are not platform specific
>> >> >>>>> >> >> >> >> >> like
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> C++
>> >> >>>>> >> >> >> >> >> language
>> >> >>>>> >> >> >> >> >> level).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read
>> >> >>>>> >> >> >> >> >> on
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> intrinsics
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >> >>>>> >> >> >> >> >> love to
>> >> >>>>> >> >> >> >> >> read
>> >> >>>>> >> >> >> >> >> it.
>> >> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your
>> >> >>>>> >> >> >> >> >> brain
>> >> >>>>> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> questions
>> >> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> see how
>> >> >>>>> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >> >>>>> >> >> >> >> >> option 2,
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> have
>> >> >>>>> >> >> >> >> >> very
>> >> >>>>> >> >> >> >> >> little control over what happens after building
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> shared
>> >> >>>>> >> >> >> >> >> libraries,
>> >> >>>>> >> >> >> >> >> and to make up for that I need to really get a
>> >> >>>>> >> >> >> >> >> deep
>> >> >>>>> >> >> >> >> >> understanding
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> properly
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >> >>>>> >> >> >> >> >> (non-Android
>> >> >>>>> >> >> >> >> >> platforms).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks again.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work
>> >> >>>>> >> >> >> >> >> > on
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Studio
>> >> >>>>> >> >> >> >> >> > and
>> >> >>>>> >> >> >> >> >> > was
>> >> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >> >>>>> >> >> >> >> >> > we're
>> >> >>>>> >> >> >> >> >> > working
>> >> >>>>> >> >> >> >> >> > toward
>> >> >>>>> >> >> >> >> >> > getting
>> >> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't
>> >> >>>>> >> >> >> >> >> > really
>> >> >>>>> >> >> >> >> >> > say
>> >> >>>>> >> >> >> >> >> > when
>> >> >>>>> >> >> >> >> >> > that
>> >> >>>>> >> >> >> >> >> > will
>> >> >>>>> >> >> >> >> >> > happen
>> >> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for
>> >> >>>>> >> >> >> >> >> > now
>> >> >>>>> >> >> >> >> >> > then I'd
>> >> >>>>> >> >> >> >> >> > go
>> >> >>>>> >> >> >> >> >> > this
>> >> >>>>> >> >> >> >> >> > way.
>> >> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to
>> >> >>>>> >> >> >> >> >> > view
>> >> >>>>> >> >> >> >> >> > your
>> >> >>>>> >> >> >> >> >> > source
>> >> >>>>> >> >> >> >> >> > file
>> >> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and
>> >> >>>>> >> >> >> >> >> > debug
>> >> >>>>> >> >> >> >> >> > using the
>> >> >>>>> >> >> >> >> >> > built-in
>> >> >>>>> >> >> >> >> >> > debugging support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >> >>>>> >> >> >> >> >> > setting
>> >> >>>>> >> >> >> >> >> > to
>> >> >>>>> >> >> >> >> >> > tell
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files
>> >> >>>>> >> >> >> >> >> > (see
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >> >>>>> >> >> >> >> >> > approach
>> >> >>>>> >> >> >> >> >> > but it
>> >> >>>>> >> >> >> >> >> > should
>> >> >>>>> >> >> >> >> >> > work
>> >> >>>>> >> >> >> >> >> > in
>> >> >>>>> >> >> >> >> >> > principal.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > I hope this helps,
>> >> >>>>> >> >> >> >> >> > Jomo
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >> >>>>> >> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute
>> >> >>>>> >> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> >> "ant
>> >> >>>>> >> >> >> >> >> >> release"
>> >> >>>>> >> >> >> >> >> >> command after my native targets are built. Part
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> that
>> >> >>>>> >> >> >> >> >> >> command
>> >> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >> >>>>> >> >> >> >> >> >> directory
>> >> >>>>> >> >> >> >> >> >> so
>> >> >>>>> >> >> >> >> >> >> they
>> >> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using
>> >> >>>>> >> >> >> >> >> >> Android
>> >> >>>>> >> >> >> >> >> >> Studio and
>> >> >>>>> >> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> few
>> >> >>>>> >> >> >> >> >> >> major
>> >> >>>>> >> >> >> >> >> >> releases
>> >> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same
>> >> >>>>> >> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> >> similar
>> >> >>>>> >> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> >> what
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >> >>>>> >> >> >> >> >> >> execute
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >> >>>>> >> >> >> >> >> >> commands.
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> not
>> >> >>>>> >> >> >> >> >> >> too
>> >> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you
>> >> >>>>> >> >> >> >> >> >> tell
>> >> >>>>> >> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> >> where
>> >> >>>>> >> >> >> >> >> >> your
>> >> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging
>> >> >>>>> >> >> >> >> >> >> steps.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using
>> >> >>>>> >> >> >> >> >> >> one
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> these
>> >> >>>>> >> >> >> >> >> >> setups
>> >> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is
>> >> >>>>> >> >> >> >> >> >> probably
>> >> >>>>> >> >> >> >> >> >> no
>> >> >>>>> >> >> >> >> >> >> on-device
>> >> >>>>> >> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >> >>>>> >> >> >> >> >> >> handle
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> projects
>> >> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Would like some general direction & advice
>> >> >>>>> >> >> >> >> >> >> before
>> >> >>>>> >> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> >> move
>> >> >>>>> >> >> >> >> >> >> away
>> >> >>>>> >> >> >> >> >> >> from
>> >> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >> >>>>> >> >> >> >> >> >> --
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>
>> >> >>>>
>> >> >>>
>> >> >>
>> >
>> >
>
>


--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Jom O'Fisher
Hi again Robert,
Would you be able to give me an estimate of how many APK projects you have, roughly which open source projects you reference via CMake add_subdirectories, and whether you have any variants beyond the default Debug and Release? If possible I'd like to approximate your project layout so we can study it in more closely with an eye toward making the experience better for this kind of layout.





On Fri, Aug 25, 2017 at 2:46 PM, Jom O'Fisher <[hidden email]> wrote:
Targets are specified per-Variation so they need to go under the variation-specific section. Probably something like this:

                        defaultConfig {
                          externalNativeBuild {
                            cmake {
                              targets "library1", "library2"
                            }
                          }
                        }

That should work for you. Let me know.

On Fri, Aug 25, 2017 at 2:42 PM, Robert Dailey <[hidden email]> wrote:
By the way when I try to use "targets", I get a failure. Basically
Gradle doesn't recognize that keyword. I tried singular form as well
("target"), no luck.

I'm running canary build of everything possible. What am I missing?

On Wed, Aug 23, 2017 at 4:20 PM, Jom O'Fisher <[hidden email]> wrote:
> By gradle module projects, I just mean the leaf build.gradle files as
> opposed to the root build.gradle. By configurations, I mean Build Types
> (debug vs release) and Product Flavors (demo vs free vs paid). Hereafter I
> will use the term "variant" rather than "configuration" to be precise. See
> this write-up on build variants:
>
> https://developer.android.com/studio/build/build-variants.html#build-types
>
> This build matrix is constructed at the leaf build.gradle level. Native
> build in gradle allows you to set C/C++ flags individually for each variant
> so that you can define compiler flags (for example, -DFREE_VERSION).
>
> One thing to notice at this stage is that the same CMake target may be built
> with different compiler flags across different projects, build types, and
> product flavors. So in the general case, build outputs won't be the same.
>
> You asked which targets build when specifying path. By default, we build all
> targets that produce an .so. You can override this by setting
> externalNativeBuild.cmake.targets. For example,
>
>     paid {
>       ...
>       externalNativeBuild {
>         cmake {
>           ...
>           targets "native-lib-paid"
>         }
>       }
>     }
>
> As for your last question, the model we generally see used is that the main
> CMakeLists.txt is next to the leaf build.gradle such that this
> CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt (though
> they may share common dependencies and settings). Otherwise, multiple APK
> projects would perform pretty much similar to yours--they would build
> targets per-leaf project and not share build outputs. As far as I can see
> your organization is just as valid so long as you only build the targets you
> need.
>
> Regarding native dependencies between java projects. We generally try to
> avoid making the CMake build depend on the gradle build (you should be able
> to replicate the CMake build from the command-line if you set the right
> flags). At the moment I don't see a way we could make things better without
> violating that tenet but that could be lack of imagination on my part.
>
> We'll definitely be discussing this use case at our next C++ meeting and
> I'll also be checking for myself whether ccache will work in this CMake
> scenario. If ccache does work it seems like the natural level at which to
> fold identical builds.
>
>
>
> On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey <[hidden email]>
> wrote:
>>
>> I'm not sure what you mean by "gradle module projects", but maybe
>> having some examples of what you mean by "configurations, C++ flags,
>> etc" might make it more clear.
>>
>> Question: When specifying "path" for the CMakeLists.txt in the
>> build.gradle file, how do you know which targets to build? For
>> example, that run of CMake may generate 100 targets, but only 20 need
>> to build and be packaged (*.so files) with the APK. Do you just build
>> "all"? Is there a way to specify the target itself?
>>
>> Thanks again. I'd still like to know more about what the ideal
>> organization is. I find it hard to believe that large android projects
>> rarely break things up into multiple, separate "components" that are
>> built independently. That's really the gist of what we're dealing with
>> here. Your typical "hello world" project likely will have only 1
>> CMakeLists.txt that is pretty self-contained, but all the
>> documentation I've looked at so far doesn't show the best way to
>> handle native library dependencies across java projects between
>> build.gradle files (or maybe I'm just not looking hard enough).
>>
>> On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]>
>> wrote:
>> > Thanks for the write-up Robert. Having thought about it, I don't believe
>> > we
>> > have a satisfying answer at the gradle level for this kind of
>> > organization.
>> > In the gradle model module projects are the unit of organization for
>> > configurations, C/C++ flags, etc. and that's something we're pretty much
>> > stuck with.
>> > Regarding just the redundant build issue, would something like ccache
>> > help?
>> > I know people have used it with ndk-build with success, I'm not sure
>> > about
>> > CMake but I don't see why that should make a difference.
>> >
>> >
>> >
>> > On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> Another reason to reduce the number of binary directories is that
>> >> there are different ways of managing third party libraries. One in
>> >> particular that we use is to clone a repository into the binary
>> >> directory and build all third party libs in real time based on a
>> >> toolchain file (Similar to the functionality provided by
>> >> ExternalProject module in CMake). This is repeated from scratch only
>> >> if the work hasn't already been done in the binary directory before.
>> >> By having more binary dirs than needed, this work is being done an
>> >> exponential amount of times which can result in a lot of wasted time
>> >> waiting. There are 1 time operations that multiple targets can benefit
>> >> from in a single binary tree, instead of 1 per unique target being
>> >> invoked.
>> >>
>> >> Sorry to keep responding: I'm just thinking of things as I go and
>> >> bringing them up, to shed light on some of the reasoning behind my
>> >> suggestions.
>> >>
>> >> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey
>> >> <[hidden email]>
>> >> wrote:
>> >> > Sorry I forgot to answer your last set of questions:
>> >> >
>> >> > CommonLib is indeed 2 things:
>> >> >
>> >> > * A common (static or shared) library for native code (most of our
>> >> > CMake targets specify CommonLib as a link dependency)
>> >> > * A common library for Java code (we do specify this as a dependency
>> >> > for most java targets in Gradle, specifically those under
>> >> > Applications/)
>> >> >
>> >> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]>
>> >> > wrote:
>> >> >> Hi Robert,
>> >> >>
>> >> >> I work with Jom on the Android Studio team, and I would like to
>> >> >> clarify
>> >> >> a
>> >> >> few things to better understand your situation.
>> >> >> You mentioned the project is intend to be cross platform.  Normally,
>> >> >> in
>> >> >> such
>> >> >> situation, we expect there to be a single CMake root project to be
>> >> >> imported
>> >> >> into one of the Android library/application.  However, in your case,
>> >> >> there
>> >> >> are subprojects with Java code.
>> >> >>
>> >> >> Are the CMake code in App1/2/3 intended to be cross platform too?
>> >> >> Or
>> >> >> are
>> >> >> they Android specific code?  If they are meant to be cross platform,
>> >> >> how
>> >> >> does the Java code works on other platforms?  Or perhaps you added
>> >> >> Java
>> >> >> binding in those subprojects just for Android?
>> >> >>
>> >> >> The build.gradle in CommonLib, what kind of Gradle project is that?
>> >> >> From
>> >> >> your description, it doesn't look like an Android library project.
>> >> >> Or
>> >> >> am I
>> >> >> mistaken and it also applies the android library plugin?
>> >> >>
>> >> >> Raymond
>> >> >>
>> >> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher <[hidden email]>
>> >> >> wrote:
>> >> >>>
>> >> >>> + a colleague
>> >> >>>
>> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
>> >> >>> <[hidden email]>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> You can find that number like this:
>> >> >>>> - x = number of externalNativeBuild.cmake.path in your
>> >> >>>> build.gradle
>> >> >>>> files
>> >> >>>> - y = number of gradle configurations (like debug and release)
>> >> >>>> - z = number of ABIs that you build
>> >> >>>>
>> >> >>>> The result is x * y * z. To be more accurate, you should consider
>> >> >>>> y
>> >> >>>> and z
>> >> >>>> to be functions of each build.gradle file since these can vary.
>> >> >>>>
>> >> >>>> There is a second set of folders that hold the stripped versions
>> >> >>>> of
>> >> >>>> the
>> >> >>>> .so files that is purely managed by the android gradle plugin, so
>> >> >>>> you
>> >> >>>> might
>> >> >>>> consider the answer to be 2 * x * y * z.
>> >> >>>>
>> >> >>>> Hope this helps.
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>> >> >>>> <[hidden email]>
>> >> >>>> wrote:
>> >> >>>>>
>> >> >>>>> This definitely a bit better, but still requires the boilerplate
>> >> >>>>> in
>> >> >>>>> each leaf gradle file. But I can't seriously complain too much. I
>> >> >>>>> think I'm more concerned with the implications this has
>> >> >>>>> underneath.
>> >> >>>>> First, let me ask just to make sure I'm not misunderstanding:
>> >> >>>>> Does
>> >> >>>>> each `externalNativeBuild` entry essentially mean 1
>> >> >>>>> CMAKE_BINARY_DIR?
>> >> >>>>> How many binary dirs do you manage internally and what determines
>> >> >>>>> when
>> >> >>>>> they get created?
>> >> >>>>>
>> >> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher
>> >> >>>>> <[hidden email]>
>> >> >>>>> wrote:
>> >> >>>>> > Would it work for your scenario to provide properties in the
>> >> >>>>> > root
>> >> >>>>> > build.gradle:
>> >> >>>>> >
>> >> >>>>> > ext {
>> >> >>>>> >     cmakePath = file "CMakeLists.txt"
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > And then consume them in the leaf app/build.gradle like this?
>> >> >>>>> >
>> >> >>>>> > externalNativeBuild {
>> >> >>>>> >     cmake {
>> >> >>>>> >         path cmakePath
>> >> >>>>> >     }
>> >> >>>>> > }
>> >> >>>>> >
>> >> >>>>> > It doesn't fully hide the details but it does centralize the
>> >> >>>>> > information.
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>> >> >>>>> > <[hidden email]>
>> >> >>>>> > wrote:
>> >> >>>>> >>
>> >> >>>>> >> I wouldn't want to do that, it's too convoluted. I have other
>> >> >>>>> >> platforms that use these CMake scripts as well. For example, I
>> >> >>>>> >> run on
>> >> >>>>> >> Windows and Linux platforms as well to build the native code.
>> >> >>>>> >> Normal
>> >> >>>>> >> CMake behavior is designed to work at a root then go downwards
>> >> >>>>> >> to
>> >> >>>>> >> find
>> >> >>>>> >> targets. However it seems Gradle wants to start at a
>> >> >>>>> >> subdirectory
>> >> >>>>> >> and
>> >> >>>>> >> work its way up to the root, which is opposite of CMake's
>> >> >>>>> >> intended
>> >> >>>>> >> behavior IMHO. Not only that but I want to avoid
>> >> >>>>> >> special-casing
>> >> >>>>> >> behavior in CMake just for Android's use.
>> >> >>>>> >>
>> >> >>>>> >> At the moment it feels like (again referring back to my
>> >> >>>>> >> previous
>> >> >>>>> >> example structure) that both App2 and App3 each run CMake in
>> >> >>>>> >> independent binary directories instead of sharing 1 binary
>> >> >>>>> >> directory
>> >> >>>>> >> and building 2 targets inside of it. I prefer this behavior
>> >> >>>>> >> instead,
>> >> >>>>> >> especially since it allows CMake to operate as it was
>> >> >>>>> >> intended. I
>> >> >>>>> >> think it's a common case that projects will define multiple
>> >> >>>>> >> targets
>> >> >>>>> >> starting from a single root, and expect multiple APKs or java
>> >> >>>>> >> dependencies to be built within it.
>> >> >>>>> >>
>> >> >>>>> >> If I'm misunderstanding or making false assumptions please let
>> >> >>>>> >> me
>> >> >>>>> >> know.
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >>
>> >> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>> >> >>>>> >> <[hidden email]>
>> >> >>>>> >> wrote:
>> >> >>>>> >> > Would it work for your situation for the leaf CMakeLists.txt
>> >> >>>>> >> > to
>> >> >>>>> >> > include
>> >> >>>>> >> > the
>> >> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic in
>> >> >>>>> >> > the
>> >> >>>>> >> > leaf
>> >> >>>>> >> > CMakeLists.txt?
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>> >> >>>>> >> > <[hidden email]>
>> >> >>>>> >> > wrote:
>> >> >>>>> >> >>
>> >> >>>>> >> >> Basically, yes. We have this sort of structure:
>> >> >>>>> >> >>
>> >> >>>>> >> >> <Root of git clone>/
>> >> >>>>> >> >>     Applications/
>> >> >>>>> >> >>         App1/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App2/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>         App3/
>> >> >>>>> >> >>             build.gradle
>> >> >>>>> >> >>             CMakeLists.txt
>> >> >>>>> >> >>     CommonLib/
>> >> >>>>> >> >>         build.gradle
>> >> >>>>> >> >>         CMakeLists.txt
>> >> >>>>> >> >>     CMakeLists.txt
>> >> >>>>> >> >>
>> >> >>>>> >> >> The libs are defined as follows:
>> >> >>>>> >> >>
>> >> >>>>> >> >> * CommonLib is a static library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * No dependencies of its own
>> >> >>>>> >> >> * App1 is a shared library (java code builds into a
>> >> >>>>> >> >> library)
>> >> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >> * App2 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>> >> >>>>> >> >> * App3 is a shared library (java code builds into an APK)
>> >> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>> >> >>>>> >> >>
>> >> >>>>> >> >> In all cases, CMake must be invoked starting at the root
>> >> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from the
>> >> >>>>> >> >> same
>> >> >>>>> >> >> binary
>> >> >>>>> >> >> directory after that. Previously with ANT, I was building
>> >> >>>>> >> >> all
>> >> >>>>> >> >> native
>> >> >>>>> >> >> targets first, then moved libs to appropriate directories
>> >> >>>>> >> >> so
>> >> >>>>> >> >> that
>> >> >>>>> >> >> the
>> >> >>>>> >> >> 'ant' command would package the libs.
>> >> >>>>> >> >>
>> >> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying the
>> >> >>>>> >> >> root
>> >> >>>>> >> >> directory in each leaf-level project directory. Using the
>> >> >>>>> >> >> example
>> >> >>>>> >> >> above, the leaf-level directories in this case would be
>> >> >>>>> >> >> App1,
>> >> >>>>> >> >> App2,
>> >> >>>>> >> >> App3, and CommonLib. However I think we only specify the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> stuff for the java targets that actually output an APK
>> >> >>>>> >> >> (that
>> >> >>>>> >> >> would
>> >> >>>>> >> >> be
>> >> >>>>> >> >> App2 and App3 only).
>> >> >>>>> >> >>
>> >> >>>>> >> >> The ultimate goal is to specify stuff that doesn't change
>> >> >>>>> >> >> per
>> >> >>>>> >> >> independent "module" of ours at the top level so it is
>> >> >>>>> >> >> transitive
>> >> >>>>> >> >> /
>> >> >>>>> >> >> inherited. Then only specify the differences (e.g. the
>> >> >>>>> >> >> native
>> >> >>>>> >> >> CMake
>> >> >>>>> >> >> target to build) in the leaf build gradle files. However
>> >> >>>>> >> >> you
>> >> >>>>> >> >> indicated
>> >> >>>>> >> >> this isn't possible.
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >>
>> >> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>> >> >>>>> >> >> <[hidden email]>
>> >> >>>>> >> >> wrote:
>> >> >>>>> >> >> > What you're doing already sounds correct. You can't
>> >> >>>>> >> >> > directly
>> >> >>>>> >> >> > specify
>> >> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>> >> >>>>> >> >> > Recommendation
>> >> >>>>> >> >> > is
>> >> >>>>> >> >> > that
>> >> >>>>> >> >> > it
>> >> >>>>> >> >> > should be specified from the build.gradle of the module
>> >> >>>>> >> >> > of
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > APK.
>> >> >>>>> >> >> > Is
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > issue that you have multiple APK modules that all
>> >> >>>>> >> >> > reference
>> >> >>>>> >> >> > the
>> >> >>>>> >> >> > same
>> >> >>>>> >> >> > CMake
>> >> >>>>> >> >> > libraries?
>> >> >>>>> >> >> >
>> >> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>> >> >>>>> >> >> > <[hidden email]>
>> >> >>>>> >> >> > wrote:
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> Thanks this is very helpful. The other question I have
>> >> >>>>> >> >> >> is:
>> >> >>>>> >> >> >> Is
>> >> >>>>> >> >> >> there
>> >> >>>>> >> >> >> a
>> >> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>> >> >>>>> >> >> >> Basically,
>> >> >>>>> >> >> >> I
>> >> >>>>> >> >> >> want
>> >> >>>>> >> >> >> to specify the CMake root in 1 place, and have targets
>> >> >>>>> >> >> >> (defined
>> >> >>>>> >> >> >> further down in subdirectories) that require APK
>> >> >>>>> >> >> >> packaging
>> >> >>>>> >> >> >> to
>> >> >>>>> >> >> >> specify
>> >> >>>>> >> >> >> only the native target name that should be built &
>> >> >>>>> >> >> >> packaged.
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by
>> >> >>>>> >> >> >> walking
>> >> >>>>> >> >> >> up
>> >> >>>>> >> >> >> the
>> >> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I think
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> should
>> >> >>>>> >> >> >> be
>> >> >>>>> >> >> >> put at the top-level build gradle file if possible. Is
>> >> >>>>> >> >> >> this
>> >> >>>>> >> >> >> doable
>> >> >>>>> >> >> >> at
>> >> >>>>> >> >> >> the moment? What is the recommended setup?
>> >> >>>>> >> >> >>
>> >> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>> >> >>>>> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> wrote:
>> >> >>>>> >> >> >> > Gradle does introspection on the CMake build to find
>> >> >>>>> >> >> >> > .so
>> >> >>>>> >> >> >> > targets
>> >> >>>>> >> >> >> > and
>> >> >>>>> >> >> >> > those
>> >> >>>>> >> >> >> > get packaged.
>> >> >>>>> >> >> >> > There is also a special case for stl/runtime .so files
>> >> >>>>> >> >> >> > from
>> >> >>>>> >> >> >> > the
>> >> >>>>> >> >> >> > NDK.
>> >> >>>>> >> >> >> > Any additional .so files need to specified in
>> >> >>>>> >> >> >> > build.gradle
>> >> >>>>> >> >> >> > using
>> >> >>>>> >> >> >> > jniDirs
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>> >> >>>>> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> > wrote:
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an APK?
>> >> >>>>> >> >> >> >> I
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> that
>> >> >>>>> >> >> >> >> ANT
>> >> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>". Does
>> >> >>>>> >> >> >> >> Gradle
>> >> >>>>> >> >> >> >> do
>> >> >>>>> >> >> >> >> some
>> >> >>>>> >> >> >> >> introspection into CMake targets to see if outputs
>> >> >>>>> >> >> >> >> are
>> >> >>>>> >> >> >> >> *.so,
>> >> >>>>> >> >> >> >> and
>> >> >>>>> >> >> >> >> copy
>> >> >>>>> >> >> >> >> those to some location if needed? What about
>> >> >>>>> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> like
>> >> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd like
>> >> >>>>> >> >> >> >> to
>> >> >>>>> >> >> >> >> know
>> >> >>>>> >> >> >> >> if
>> >> >>>>> >> >> >> >> any
>> >> >>>>> >> >> >> >> manual copy steps are needed in CMake to put outputs
>> >> >>>>> >> >> >> >> in
>> >> >>>>> >> >> >> >> proper
>> >> >>>>> >> >> >> >> locations for the APK build step. I had to do this
>> >> >>>>> >> >> >> >> when
>> >> >>>>> >> >> >> >> using
>> >> >>>>> >> >> >> >> ANT.
>> >> >>>>> >> >> >> >>
>> >> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under the
>> >> >>>>> >> >> >> >> > project
>> >> >>>>> >> >> >> >> > module
>> >> >>>>> >> >> >> >> > folder
>> >> >>>>> >> >> >> >> > (so unique per module per ABI)
>> >> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though you
>> >> >>>>> >> >> >> >> > can
>> >> >>>>> >> >> >> >> > choose
>> >> >>>>> >> >> >> >> > to
>> >> >>>>> >> >> >> >> > specify it
>> >> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a
>> >> >>>>> >> >> >> >> > pretty
>> >> >>>>> >> >> >> >> > good job
>> >> >>>>> >> >> >> >> > of
>> >> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>> >> >>>>> >> >> >> >> > Philosophically, we try to set as little as we can
>> >> >>>>> >> >> >> >> > get
>> >> >>>>> >> >> >> >> > away
>> >> >>>>> >> >> >> >> > with.
>> >> >>>>> >> >> >> >> > In
>> >> >>>>> >> >> >> >> > particular, the section titled "Understanding the
>> >> >>>>> >> >> >> >> > CMake
>> >> >>>>> >> >> >> >> > build
>> >> >>>>> >> >> >> >> > command"
>> >> >>>>> >> >> >> >> > lays
>> >> >>>>> >> >> >> >> > out exactly what we set. You can also see the
>> >> >>>>> >> >> >> >> > folders
>> >> >>>>> >> >> >> >> > we
>> >> >>>>> >> >> >> >> > specify
>> >> >>>>> >> >> >> >> > (one
>> >> >>>>> >> >> >> >> > per
>> >> >>>>> >> >> >> >> > module per ABI)
>> >> >>>>> >> >> >> >> > 3) Not sure I understand this.
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > The other document worth taking a look at (if you
>> >> >>>>> >> >> >> >> > haven't
>> >> >>>>> >> >> >> >> > already)
>> >> >>>>> >> >> >> >> > is:
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>> >> >>>>> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks Jom
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply because
>> >> >>>>> >> >> >> >> >> that's
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> Google's
>> >> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>> >> >>>>> >> >> >> >> >> debugging
>> >> >>>>> >> >> >> >> >> which
>> >> >>>>> >> >> >> >> >> is
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> #1
>> >> >>>>> >> >> >> >> >> reason for me.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> However, I'd like to understand a lot more about
>> >> >>>>> >> >> >> >> >> how
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> integration
>> >> >>>>> >> >> >> >> >> really happens. For example, I have these
>> >> >>>>> >> >> >> >> >> questions:
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> 1) How, internally, are CMake build directories
>> >> >>>>> >> >> >> >> >> managed?
>> >> >>>>> >> >> >> >> >> Do
>> >> >>>>> >> >> >> >> >> you
>> >> >>>>> >> >> >> >> >> generate 1 per unique android project? What about
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> specific
>> >> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>> >> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration,
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> inside
>> >> >>>>> >> >> >> >> >> the CMake scripts were ignored because they are
>> >> >>>>> >> >> >> >> >> specified
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> command line. Namely, all of those settings that
>> >> >>>>> >> >> >> >> >> are
>> >> >>>>> >> >> >> >> >> driven by
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was one
>> >> >>>>> >> >> >> >> >> in
>> >> >>>>> >> >> >> >> >> particular
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but I
>> >> >>>>> >> >> >> >> >> recall
>> >> >>>>> >> >> >> >> >> this
>> >> >>>>> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> overridden from outside)?
>> >> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>> >> >>>>> >> >> >> >> >> libraries
>> >> >>>>> >> >> >> >> >> via
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I wanted
>> >> >>>>> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> define
>> >> >>>>> >> >> >> >> >> common
>> >> >>>>> >> >> >> >> >> stuff for CMake / native code at the root gradle
>> >> >>>>> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> file,
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> only define the differences in the actual gradle
>> >> >>>>> >> >> >> >> >> build
>> >> >>>>> >> >> >> >> >> files
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> each
>> >> >>>>> >> >> >> >> >> corresponding Java target (like, defining the name
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the command
>> >> >>>>> >> >> >> >> >> line
>> >> >>>>> >> >> >> >> >> invocation,
>> >> >>>>> >> >> >> >> >> -D
>> >> >>>>> >> >> >> >> >> CMake settings, etc would all be common and
>> >> >>>>> >> >> >> >> >> defined
>> >> >>>>> >> >> >> >> >> at
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> root).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's way
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> doing
>> >> >>>>> >> >> >> >> >> things
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to the
>> >> >>>>> >> >> >> >> >> CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> themselves, the better. This also makes
>> >> >>>>> >> >> >> >> >> cross-platform
>> >> >>>>> >> >> >> >> >> easier
>> >> >>>>> >> >> >> >> >> (we
>> >> >>>>> >> >> >> >> >> build the native code in Windows, for example, so
>> >> >>>>> >> >> >> >> >> having
>> >> >>>>> >> >> >> >> >> settings
>> >> >>>>> >> >> >> >> >> specified in the gradle files do not carry over to
>> >> >>>>> >> >> >> >> >> other
>> >> >>>>> >> >> >> >> >> platforms.
>> >> >>>>> >> >> >> >> >> Namely, settings that are not platform specific
>> >> >>>>> >> >> >> >> >> like
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> C++
>> >> >>>>> >> >> >> >> >> language
>> >> >>>>> >> >> >> >> >> level).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can read
>> >> >>>>> >> >> >> >> >> on
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> intrinsics
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio, I'd
>> >> >>>>> >> >> >> >> >> love to
>> >> >>>>> >> >> >> >> >> read
>> >> >>>>> >> >> >> >> >> it.
>> >> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick your
>> >> >>>>> >> >> >> >> >> brain
>> >> >>>>> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> questions
>> >> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for now
>> >> >>>>> >> >> >> >> >> and
>> >> >>>>> >> >> >> >> >> see how
>> >> >>>>> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> goes. It's just black box for me because unlike
>> >> >>>>> >> >> >> >> >> option 2,
>> >> >>>>> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> have
>> >> >>>>> >> >> >> >> >> very
>> >> >>>>> >> >> >> >> >> little control over what happens after building
>> >> >>>>> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> shared
>> >> >>>>> >> >> >> >> >> libraries,
>> >> >>>>> >> >> >> >> >> and to make up for that I need to really get a
>> >> >>>>> >> >> >> >> >> deep
>> >> >>>>> >> >> >> >> >> understanding
>> >> >>>>> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> how it works so I can make sure I code my CMake
>> >> >>>>> >> >> >> >> >> scripts
>> >> >>>>> >> >> >> >> >> properly
>> >> >>>>> >> >> >> >> >> for
>> >> >>>>> >> >> >> >> >> not only Android, but my other platforms as well
>> >> >>>>> >> >> >> >> >> (non-Android
>> >> >>>>> >> >> >> >> >> platforms).
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> Thanks again.
>> >> >>>>> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>> >> >>>>> >> >> >> >> >> <[hidden email]>
>> >> >>>>> >> >> >> >> >> wrote:
>> >> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I work
>> >> >>>>> >> >> >> >> >> > on
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Studio
>> >> >>>>> >> >> >> >> >> > and
>> >> >>>>> >> >> >> >> >> > was
>> >> >>>>> >> >> >> >> >> > the one that added CMake support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work and
>> >> >>>>> >> >> >> >> >> > we're
>> >> >>>>> >> >> >> >> >> > working
>> >> >>>>> >> >> >> >> >> > toward
>> >> >>>>> >> >> >> >> >> > getting
>> >> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't
>> >> >>>>> >> >> >> >> >> > really
>> >> >>>>> >> >> >> >> >> > say
>> >> >>>>> >> >> >> >> >> > when
>> >> >>>>> >> >> >> >> >> > that
>> >> >>>>> >> >> >> >> >> > will
>> >> >>>>> >> >> >> >> >> > happen
>> >> >>>>> >> >> >> >> >> > but if you can get away with an older CMake for
>> >> >>>>> >> >> >> >> >> > now
>> >> >>>>> >> >> >> >> >> > then I'd
>> >> >>>>> >> >> >> >> >> > go
>> >> >>>>> >> >> >> >> >> > this
>> >> >>>>> >> >> >> >> >> > way.
>> >> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you to
>> >> >>>>> >> >> >> >> >> > view
>> >> >>>>> >> >> >> >> >> > your
>> >> >>>>> >> >> >> >> >> > source
>> >> >>>>> >> >> >> >> >> > file
>> >> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and
>> >> >>>>> >> >> >> >> >> > debug
>> >> >>>>> >> >> >> >> >> > using the
>> >> >>>>> >> >> >> >> >> > built-in
>> >> >>>>> >> >> >> >> >> > debugging support.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > To get option (2) to work, you can use jniDirs
>> >> >>>>> >> >> >> >> >> > setting
>> >> >>>>> >> >> >> >> >> > to
>> >> >>>>> >> >> >> >> >> > tell
>> >> >>>>> >> >> >> >> >> > Android
>> >> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files
>> >> >>>>> >> >> >> >> >> > (see
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>> >> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>> >> >>>>> >> >> >> >> >> > approach
>> >> >>>>> >> >> >> >> >> > but it
>> >> >>>>> >> >> >> >> >> > should
>> >> >>>>> >> >> >> >> >> > work
>> >> >>>>> >> >> >> >> >> > in
>> >> >>>>> >> >> >> >> >> > principal.
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > I hope this helps,
>> >> >>>>> >> >> >> >> >> > Jomo
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert Dailey
>> >> >>>>> >> >> >> >> >> > <[hidden email]>
>> >> >>>>> >> >> >> >> >> > wrote:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Right now I have custom targets set to execute
>> >> >>>>> >> >> >> >> >> >> the
>> >> >>>>> >> >> >> >> >> >> "ant
>> >> >>>>> >> >> >> >> >> >> release"
>> >> >>>>> >> >> >> >> >> >> command after my native targets are built. Part
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> that
>> >> >>>>> >> >> >> >> >> >> command
>> >> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>> >> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>> >> >>>>> >> >> >> >> >> >> directory
>> >> >>>>> >> >> >> >> >> >> so
>> >> >>>>> >> >> >> >> >> >> they
>> >> >>>>> >> >> >> >> >> >> get packaged in an APK.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> When switching to gradle, I have two options:
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using
>> >> >>>>> >> >> >> >> >> >> Android
>> >> >>>>> >> >> >> >> >> >> Studio and
>> >> >>>>> >> >> >> >> >> >> being
>> >> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which is
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> few
>> >> >>>>> >> >> >> >> >> >> major
>> >> >>>>> >> >> >> >> >> >> releases
>> >> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the same
>> >> >>>>> >> >> >> >> >> >> or
>> >> >>>>> >> >> >> >> >> >> similar
>> >> >>>>> >> >> >> >> >> >> to
>> >> >>>>> >> >> >> >> >> >> what
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> already doing: The custom targets I have would
>> >> >>>>> >> >> >> >> >> >> execute
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> as
>> >> >>>>> >> >> >> >> >> >> a
>> >> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>> >> >>>>> >> >> >> >> >> >> commands.
>> >> >>>>> >> >> >> >> >> >> I'm
>> >> >>>>> >> >> >> >> >> >> not
>> >> >>>>> >> >> >> >> >> >> too
>> >> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how you
>> >> >>>>> >> >> >> >> >> >> tell
>> >> >>>>> >> >> >> >> >> >> it
>> >> >>>>> >> >> >> >> >> >> where
>> >> >>>>> >> >> >> >> >> >> your
>> >> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging
>> >> >>>>> >> >> >> >> >> >> steps.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone using
>> >> >>>>> >> >> >> >> >> >> one
>> >> >>>>> >> >> >> >> >> >> of
>> >> >>>>> >> >> >> >> >> >> these
>> >> >>>>> >> >> >> >> >> >> setups
>> >> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is
>> >> >>>>> >> >> >> >> >> >> probably
>> >> >>>>> >> >> >> >> >> >> no
>> >> >>>>> >> >> >> >> >> >> on-device
>> >> >>>>> >> >> >> >> >> >> native
>> >> >>>>> >> >> >> >> >> >> debugging since Android Studio probably can't
>> >> >>>>> >> >> >> >> >> >> handle
>> >> >>>>> >> >> >> >> >> >> gradle
>> >> >>>>> >> >> >> >> >> >> projects
>> >> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> Would like some general direction & advice
>> >> >>>>> >> >> >> >> >> >> before
>> >> >>>>> >> >> >> >> >> >> I
>> >> >>>>> >> >> >> >> >> >> move
>> >> >>>>> >> >> >> >> >> >> away
>> >> >>>>> >> >> >> >> >> >> from
>> >> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>> >> >>>>> >> >> >> >> >> >> --
>> >> >>>>> >> >> >> >> >> >>
>> >> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >> >
>> >> >>>>> >> >
>> >> >>>>> >> >
>> >> >>>>> >
>> >> >>>>> >
>> >> >>>>
>> >> >>>>
>> >> >>>
>> >> >>
>> >
>> >
>
>



--

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/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: CMake + Gradle for Android

Robert Dailey-2
I could probably do you one better, and just give you a stripped-down
version of our repository. Basically, I'd remove all our C++ and Java
source code but leave the CMake scripts and such intact somehow. It
would take me some time to do this, though. Would this be helpful for
you?

In the meantime, when I get into the office tomorrow I'll answer your
questions directly with as much detail as possible. Would you like me
to contact you personally from this point on or should we keep the
conversation on the CMake list?

On Fri, Aug 25, 2017 at 7:20 PM, Jom O'Fisher <[hidden email]> wrote:

> Hi again Robert,
> Would you be able to give me an estimate of how many APK projects you have,
> roughly which open source projects you reference via CMake
> add_subdirectories, and whether you have any variants beyond the default
> Debug and Release? If possible I'd like to approximate your project layout
> so we can study it in more closely with an eye toward making the experience
> better for this kind of layout.
>
>
>
>
>
> On Fri, Aug 25, 2017 at 2:46 PM, Jom O'Fisher <[hidden email]> wrote:
>>
>> Targets are specified per-Variation so they need to go under the
>> variation-specific section. Probably something like this:
>>
>>                         defaultConfig {
>>                           externalNativeBuild {
>>                             cmake {
>>                               targets "library1", "library2"
>>                             }
>>                           }
>>                         }
>>
>> That should work for you. Let me know.
>>
>> On Fri, Aug 25, 2017 at 2:42 PM, Robert Dailey <[hidden email]>
>> wrote:
>>>
>>> By the way when I try to use "targets", I get a failure. Basically
>>> Gradle doesn't recognize that keyword. I tried singular form as well
>>> ("target"), no luck.
>>>
>>> I'm running canary build of everything possible. What am I missing?
>>>
>>> On Wed, Aug 23, 2017 at 4:20 PM, Jom O'Fisher <[hidden email]>
>>> wrote:
>>> > By gradle module projects, I just mean the leaf build.gradle files as
>>> > opposed to the root build.gradle. By configurations, I mean Build Types
>>> > (debug vs release) and Product Flavors (demo vs free vs paid).
>>> > Hereafter I
>>> > will use the term "variant" rather than "configuration" to be precise.
>>> > See
>>> > this write-up on build variants:
>>> >
>>> >
>>> > https://developer.android.com/studio/build/build-variants.html#build-types
>>> >
>>> > This build matrix is constructed at the leaf build.gradle level. Native
>>> > build in gradle allows you to set C/C++ flags individually for each
>>> > variant
>>> > so that you can define compiler flags (for example, -DFREE_VERSION).
>>> >
>>> > One thing to notice at this stage is that the same CMake target may be
>>> > built
>>> > with different compiler flags across different projects, build types,
>>> > and
>>> > product flavors. So in the general case, build outputs won't be the
>>> > same.
>>> >
>>> > You asked which targets build when specifying path. By default, we
>>> > build all
>>> > targets that produce an .so. You can override this by setting
>>> > externalNativeBuild.cmake.targets. For example,
>>> >
>>> >     paid {
>>> >       ...
>>> >       externalNativeBuild {
>>> >         cmake {
>>> >           ...
>>> >           targets "native-lib-paid"
>>> >         }
>>> >       }
>>> >     }
>>> >
>>> > As for your last question, the model we generally see used is that the
>>> > main
>>> > CMakeLists.txt is next to the leaf build.gradle such that this
>>> > CMakeLists.txt doesn't couple with peer APK project CMakeLists.txt
>>> > (though
>>> > they may share common dependencies and settings). Otherwise, multiple
>>> > APK
>>> > projects would perform pretty much similar to yours--they would build
>>> > targets per-leaf project and not share build outputs. As far as I can
>>> > see
>>> > your organization is just as valid so long as you only build the
>>> > targets you
>>> > need.
>>> >
>>> > Regarding native dependencies between java projects. We generally try
>>> > to
>>> > avoid making the CMake build depend on the gradle build (you should be
>>> > able
>>> > to replicate the CMake build from the command-line if you set the right
>>> > flags). At the moment I don't see a way we could make things better
>>> > without
>>> > violating that tenet but that could be lack of imagination on my part.
>>> >
>>> > We'll definitely be discussing this use case at our next C++ meeting
>>> > and
>>> > I'll also be checking for myself whether ccache will work in this CMake
>>> > scenario. If ccache does work it seems like the natural level at which
>>> > to
>>> > fold identical builds.
>>> >
>>> >
>>> >
>>> > On Wed, Aug 23, 2017 at 1:03 PM, Robert Dailey
>>> > <[hidden email]>
>>> > wrote:
>>> >>
>>> >> I'm not sure what you mean by "gradle module projects", but maybe
>>> >> having some examples of what you mean by "configurations, C++ flags,
>>> >> etc" might make it more clear.
>>> >>
>>> >> Question: When specifying "path" for the CMakeLists.txt in the
>>> >> build.gradle file, how do you know which targets to build? For
>>> >> example, that run of CMake may generate 100 targets, but only 20 need
>>> >> to build and be packaged (*.so files) with the APK. Do you just build
>>> >> "all"? Is there a way to specify the target itself?
>>> >>
>>> >> Thanks again. I'd still like to know more about what the ideal
>>> >> organization is. I find it hard to believe that large android projects
>>> >> rarely break things up into multiple, separate "components" that are
>>> >> built independently. That's really the gist of what we're dealing with
>>> >> here. Your typical "hello world" project likely will have only 1
>>> >> CMakeLists.txt that is pretty self-contained, but all the
>>> >> documentation I've looked at so far doesn't show the best way to
>>> >> handle native library dependencies across java projects between
>>> >> build.gradle files (or maybe I'm just not looking hard enough).
>>> >>
>>> >> On Wed, Aug 23, 2017 at 1:02 PM, Jom O'Fisher <[hidden email]>
>>> >> wrote:
>>> >> > Thanks for the write-up Robert. Having thought about it, I don't
>>> >> > believe
>>> >> > we
>>> >> > have a satisfying answer at the gradle level for this kind of
>>> >> > organization.
>>> >> > In the gradle model module projects are the unit of organization for
>>> >> > configurations, C/C++ flags, etc. and that's something we're pretty
>>> >> > much
>>> >> > stuck with.
>>> >> > Regarding just the redundant build issue, would something like
>>> >> > ccache
>>> >> > help?
>>> >> > I know people have used it with ndk-build with success, I'm not sure
>>> >> > about
>>> >> > CMake but I don't see why that should make a difference.
>>> >> >
>>> >> >
>>> >> >
>>> >> > On Tue, Aug 22, 2017 at 10:27 AM, Robert Dailey
>>> >> > <[hidden email]>
>>> >> > wrote:
>>> >> >>
>>> >> >> Another reason to reduce the number of binary directories is that
>>> >> >> there are different ways of managing third party libraries. One in
>>> >> >> particular that we use is to clone a repository into the binary
>>> >> >> directory and build all third party libs in real time based on a
>>> >> >> toolchain file (Similar to the functionality provided by
>>> >> >> ExternalProject module in CMake). This is repeated from scratch
>>> >> >> only
>>> >> >> if the work hasn't already been done in the binary directory
>>> >> >> before.
>>> >> >> By having more binary dirs than needed, this work is being done an
>>> >> >> exponential amount of times which can result in a lot of wasted
>>> >> >> time
>>> >> >> waiting. There are 1 time operations that multiple targets can
>>> >> >> benefit
>>> >> >> from in a single binary tree, instead of 1 per unique target being
>>> >> >> invoked.
>>> >> >>
>>> >> >> Sorry to keep responding: I'm just thinking of things as I go and
>>> >> >> bringing them up, to shed light on some of the reasoning behind my
>>> >> >> suggestions.
>>> >> >>
>>> >> >> On Tue, Aug 22, 2017 at 9:26 AM, Robert Dailey
>>> >> >> <[hidden email]>
>>> >> >> wrote:
>>> >> >> > Sorry I forgot to answer your last set of questions:
>>> >> >> >
>>> >> >> > CommonLib is indeed 2 things:
>>> >> >> >
>>> >> >> > * A common (static or shared) library for native code (most of
>>> >> >> > our
>>> >> >> > CMake targets specify CommonLib as a link dependency)
>>> >> >> > * A common library for Java code (we do specify this as a
>>> >> >> > dependency
>>> >> >> > for most java targets in Gradle, specifically those under
>>> >> >> > Applications/)
>>> >> >> >
>>> >> >> > On Mon, Aug 21, 2017 at 6:20 PM, Raymond Chiu <[hidden email]>
>>> >> >> > wrote:
>>> >> >> >> Hi Robert,
>>> >> >> >>
>>> >> >> >> I work with Jom on the Android Studio team, and I would like to
>>> >> >> >> clarify
>>> >> >> >> a
>>> >> >> >> few things to better understand your situation.
>>> >> >> >> You mentioned the project is intend to be cross platform.
>>> >> >> >> Normally,
>>> >> >> >> in
>>> >> >> >> such
>>> >> >> >> situation, we expect there to be a single CMake root project to
>>> >> >> >> be
>>> >> >> >> imported
>>> >> >> >> into one of the Android library/application.  However, in your
>>> >> >> >> case,
>>> >> >> >> there
>>> >> >> >> are subprojects with Java code.
>>> >> >> >>
>>> >> >> >> Are the CMake code in App1/2/3 intended to be cross platform
>>> >> >> >> too?
>>> >> >> >> Or
>>> >> >> >> are
>>> >> >> >> they Android specific code?  If they are meant to be cross
>>> >> >> >> platform,
>>> >> >> >> how
>>> >> >> >> does the Java code works on other platforms?  Or perhaps you
>>> >> >> >> added
>>> >> >> >> Java
>>> >> >> >> binding in those subprojects just for Android?
>>> >> >> >>
>>> >> >> >> The build.gradle in CommonLib, what kind of Gradle project is
>>> >> >> >> that?
>>> >> >> >> From
>>> >> >> >> your description, it doesn't look like an Android library
>>> >> >> >> project.
>>> >> >> >> Or
>>> >> >> >> am I
>>> >> >> >> mistaken and it also applies the android library plugin?
>>> >> >> >>
>>> >> >> >> Raymond
>>> >> >> >>
>>> >> >> >> On Mon, Aug 21, 2017 at 3:34 PM, Jom O'Fisher
>>> >> >> >> <[hidden email]>
>>> >> >> >> wrote:
>>> >> >> >>>
>>> >> >> >>> + a colleague
>>> >> >> >>>
>>> >> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
>>> >> >> >>> <[hidden email]>
>>> >> >> >>> wrote:
>>> >> >> >>>>
>>> >> >> >>>> You can find that number like this:
>>> >> >> >>>> - x = number of externalNativeBuild.cmake.path in your
>>> >> >> >>>> build.gradle
>>> >> >> >>>> files
>>> >> >> >>>> - y = number of gradle configurations (like debug and release)
>>> >> >> >>>> - z = number of ABIs that you build
>>> >> >> >>>>
>>> >> >> >>>> The result is x * y * z. To be more accurate, you should
>>> >> >> >>>> consider
>>> >> >> >>>> y
>>> >> >> >>>> and z
>>> >> >> >>>> to be functions of each build.gradle file since these can
>>> >> >> >>>> vary.
>>> >> >> >>>>
>>> >> >> >>>> There is a second set of folders that hold the stripped
>>> >> >> >>>> versions
>>> >> >> >>>> of
>>> >> >> >>>> the
>>> >> >> >>>> .so files that is purely managed by the android gradle plugin,
>>> >> >> >>>> so
>>> >> >> >>>> you
>>> >> >> >>>> might
>>> >> >> >>>> consider the answer to be 2 * x * y * z.
>>> >> >> >>>>
>>> >> >> >>>> Hope this helps.
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>> On Mon, Aug 21, 2017 at 2:41 PM, Robert Dailey
>>> >> >> >>>> <[hidden email]>
>>> >> >> >>>> wrote:
>>> >> >> >>>>>
>>> >> >> >>>>> This definitely a bit better, but still requires the
>>> >> >> >>>>> boilerplate
>>> >> >> >>>>> in
>>> >> >> >>>>> each leaf gradle file. But I can't seriously complain too
>>> >> >> >>>>> much. I
>>> >> >> >>>>> think I'm more concerned with the implications this has
>>> >> >> >>>>> underneath.
>>> >> >> >>>>> First, let me ask just to make sure I'm not misunderstanding:
>>> >> >> >>>>> Does
>>> >> >> >>>>> each `externalNativeBuild` entry essentially mean 1
>>> >> >> >>>>> CMAKE_BINARY_DIR?
>>> >> >> >>>>> How many binary dirs do you manage internally and what
>>> >> >> >>>>> determines
>>> >> >> >>>>> when
>>> >> >> >>>>> they get created?
>>> >> >> >>>>>
>>> >> >> >>>>> On Mon, Aug 21, 2017 at 2:35 PM, Jom O'Fisher
>>> >> >> >>>>> <[hidden email]>
>>> >> >> >>>>> wrote:
>>> >> >> >>>>> > Would it work for your scenario to provide properties in
>>> >> >> >>>>> > the
>>> >> >> >>>>> > root
>>> >> >> >>>>> > build.gradle:
>>> >> >> >>>>> >
>>> >> >> >>>>> > ext {
>>> >> >> >>>>> >     cmakePath = file "CMakeLists.txt"
>>> >> >> >>>>> > }
>>> >> >> >>>>> >
>>> >> >> >>>>> > And then consume them in the leaf app/build.gradle like
>>> >> >> >>>>> > this?
>>> >> >> >>>>> >
>>> >> >> >>>>> > externalNativeBuild {
>>> >> >> >>>>> >     cmake {
>>> >> >> >>>>> >         path cmakePath
>>> >> >> >>>>> >     }
>>> >> >> >>>>> > }
>>> >> >> >>>>> >
>>> >> >> >>>>> > It doesn't fully hide the details but it does centralize
>>> >> >> >>>>> > the
>>> >> >> >>>>> > information.
>>> >> >> >>>>> >
>>> >> >> >>>>> >
>>> >> >> >>>>> > On Mon, Aug 21, 2017 at 11:20 AM, Robert Dailey
>>> >> >> >>>>> > <[hidden email]>
>>> >> >> >>>>> > wrote:
>>> >> >> >>>>> >>
>>> >> >> >>>>> >> I wouldn't want to do that, it's too convoluted. I have
>>> >> >> >>>>> >> other
>>> >> >> >>>>> >> platforms that use these CMake scripts as well. For
>>> >> >> >>>>> >> example, I
>>> >> >> >>>>> >> run on
>>> >> >> >>>>> >> Windows and Linux platforms as well to build the native
>>> >> >> >>>>> >> code.
>>> >> >> >>>>> >> Normal
>>> >> >> >>>>> >> CMake behavior is designed to work at a root then go
>>> >> >> >>>>> >> downwards
>>> >> >> >>>>> >> to
>>> >> >> >>>>> >> find
>>> >> >> >>>>> >> targets. However it seems Gradle wants to start at a
>>> >> >> >>>>> >> subdirectory
>>> >> >> >>>>> >> and
>>> >> >> >>>>> >> work its way up to the root, which is opposite of CMake's
>>> >> >> >>>>> >> intended
>>> >> >> >>>>> >> behavior IMHO. Not only that but I want to avoid
>>> >> >> >>>>> >> special-casing
>>> >> >> >>>>> >> behavior in CMake just for Android's use.
>>> >> >> >>>>> >>
>>> >> >> >>>>> >> At the moment it feels like (again referring back to my
>>> >> >> >>>>> >> previous
>>> >> >> >>>>> >> example structure) that both App2 and App3 each run CMake
>>> >> >> >>>>> >> in
>>> >> >> >>>>> >> independent binary directories instead of sharing 1 binary
>>> >> >> >>>>> >> directory
>>> >> >> >>>>> >> and building 2 targets inside of it. I prefer this
>>> >> >> >>>>> >> behavior
>>> >> >> >>>>> >> instead,
>>> >> >> >>>>> >> especially since it allows CMake to operate as it was
>>> >> >> >>>>> >> intended. I
>>> >> >> >>>>> >> think it's a common case that projects will define
>>> >> >> >>>>> >> multiple
>>> >> >> >>>>> >> targets
>>> >> >> >>>>> >> starting from a single root, and expect multiple APKs or
>>> >> >> >>>>> >> java
>>> >> >> >>>>> >> dependencies to be built within it.
>>> >> >> >>>>> >>
>>> >> >> >>>>> >> If I'm misunderstanding or making false assumptions please
>>> >> >> >>>>> >> let
>>> >> >> >>>>> >> me
>>> >> >> >>>>> >> know.
>>> >> >> >>>>> >>
>>> >> >> >>>>> >>
>>> >> >> >>>>> >>
>>> >> >> >>>>> >> On Mon, Aug 21, 2017 at 12:00 PM, Jom O'Fisher
>>> >> >> >>>>> >> <[hidden email]>
>>> >> >> >>>>> >> wrote:
>>> >> >> >>>>> >> > Would it work for your situation for the leaf
>>> >> >> >>>>> >> > CMakeLists.txt
>>> >> >> >>>>> >> > to
>>> >> >> >>>>> >> > include
>>> >> >> >>>>> >> > the
>>> >> >> >>>>> >> > root CMakeLists.txt? Then have the leaf-specific logic
>>> >> >> >>>>> >> > in
>>> >> >> >>>>> >> > the
>>> >> >> >>>>> >> > leaf
>>> >> >> >>>>> >> > CMakeLists.txt?
>>> >> >> >>>>> >> >
>>> >> >> >>>>> >> >
>>> >> >> >>>>> >> >
>>> >> >> >>>>> >> > On Mon, Aug 21, 2017 at 9:33 AM, Robert Dailey
>>> >> >> >>>>> >> > <[hidden email]>
>>> >> >> >>>>> >> > wrote:
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> Basically, yes. We have this sort of structure:
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> <Root of git clone>/
>>> >> >> >>>>> >> >>     Applications/
>>> >> >> >>>>> >> >>         App1/
>>> >> >> >>>>> >> >>             build.gradle
>>> >> >> >>>>> >> >>             CMakeLists.txt
>>> >> >> >>>>> >> >>         App2/
>>> >> >> >>>>> >> >>             build.gradle
>>> >> >> >>>>> >> >>             CMakeLists.txt
>>> >> >> >>>>> >> >>         App3/
>>> >> >> >>>>> >> >>             build.gradle
>>> >> >> >>>>> >> >>             CMakeLists.txt
>>> >> >> >>>>> >> >>     CommonLib/
>>> >> >> >>>>> >> >>         build.gradle
>>> >> >> >>>>> >> >>         CMakeLists.txt
>>> >> >> >>>>> >> >>     CMakeLists.txt
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> The libs are defined as follows:
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> * CommonLib is a static library (java code builds into
>>> >> >> >>>>> >> >> a
>>> >> >> >>>>> >> >> library)
>>> >> >> >>>>> >> >>     * No dependencies of its own
>>> >> >> >>>>> >> >> * App1 is a shared library (java code builds into a
>>> >> >> >>>>> >> >> library)
>>> >> >> >>>>> >> >>     * Dependencies (both java & native): CommonLib
>>> >> >> >>>>> >> >> * App2 is a shared library (java code builds into an
>>> >> >> >>>>> >> >> APK)
>>> >> >> >>>>> >> >>    * Dependencies (both java & native): App1, CommonLib
>>> >> >> >>>>> >> >> * App3 is a shared library (java code builds into an
>>> >> >> >>>>> >> >> APK)
>>> >> >> >>>>> >> >>    * Dependencies (both java & native): CommonLib
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> In all cases, CMake must be invoked starting at the
>>> >> >> >>>>> >> >> root
>>> >> >> >>>>> >> >> CMakeLists.txt 1 time. Each target can be built from
>>> >> >> >>>>> >> >> the
>>> >> >> >>>>> >> >> same
>>> >> >> >>>>> >> >> binary
>>> >> >> >>>>> >> >> directory after that. Previously with ANT, I was
>>> >> >> >>>>> >> >> building
>>> >> >> >>>>> >> >> all
>>> >> >> >>>>> >> >> native
>>> >> >> >>>>> >> >> targets first, then moved libs to appropriate
>>> >> >> >>>>> >> >> directories
>>> >> >> >>>>> >> >> so
>>> >> >> >>>>> >> >> that
>>> >> >> >>>>> >> >> the
>>> >> >> >>>>> >> >> 'ant' command would package the libs.
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> For gradle, I wanted to avoid redundantly specifying
>>> >> >> >>>>> >> >> the
>>> >> >> >>>>> >> >> root
>>> >> >> >>>>> >> >> directory in each leaf-level project directory. Using
>>> >> >> >>>>> >> >> the
>>> >> >> >>>>> >> >> example
>>> >> >> >>>>> >> >> above, the leaf-level directories in this case would be
>>> >> >> >>>>> >> >> App1,
>>> >> >> >>>>> >> >> App2,
>>> >> >> >>>>> >> >> App3, and CommonLib. However I think we only specify
>>> >> >> >>>>> >> >> the
>>> >> >> >>>>> >> >> native
>>> >> >> >>>>> >> >> CMake
>>> >> >> >>>>> >> >> stuff for the java targets that actually output an APK
>>> >> >> >>>>> >> >> (that
>>> >> >> >>>>> >> >> would
>>> >> >> >>>>> >> >> be
>>> >> >> >>>>> >> >> App2 and App3 only).
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> The ultimate goal is to specify stuff that doesn't
>>> >> >> >>>>> >> >> change
>>> >> >> >>>>> >> >> per
>>> >> >> >>>>> >> >> independent "module" of ours at the top level so it is
>>> >> >> >>>>> >> >> transitive
>>> >> >> >>>>> >> >> /
>>> >> >> >>>>> >> >> inherited. Then only specify the differences (e.g. the
>>> >> >> >>>>> >> >> native
>>> >> >> >>>>> >> >> CMake
>>> >> >> >>>>> >> >> target to build) in the leaf build gradle files.
>>> >> >> >>>>> >> >> However
>>> >> >> >>>>> >> >> you
>>> >> >> >>>>> >> >> indicated
>>> >> >> >>>>> >> >> this isn't possible.
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >>
>>> >> >> >>>>> >> >> On Mon, Aug 21, 2017 at 11:11 AM, Jom O'Fisher
>>> >> >> >>>>> >> >> <[hidden email]>
>>> >> >> >>>>> >> >> wrote:
>>> >> >> >>>>> >> >> > What you're doing already sounds correct. You can't
>>> >> >> >>>>> >> >> > directly
>>> >> >> >>>>> >> >> > specify
>>> >> >> >>>>> >> >> > CMakeLists.txt from the top-level build.gradle.
>>> >> >> >>>>> >> >> > Recommendation
>>> >> >> >>>>> >> >> > is
>>> >> >> >>>>> >> >> > that
>>> >> >> >>>>> >> >> > it
>>> >> >> >>>>> >> >> > should be specified from the build.gradle of the
>>> >> >> >>>>> >> >> > module
>>> >> >> >>>>> >> >> > of
>>> >> >> >>>>> >> >> > the
>>> >> >> >>>>> >> >> > APK.
>>> >> >> >>>>> >> >> > Is
>>> >> >> >>>>> >> >> > the
>>> >> >> >>>>> >> >> > issue that you have multiple APK modules that all
>>> >> >> >>>>> >> >> > reference
>>> >> >> >>>>> >> >> > the
>>> >> >> >>>>> >> >> > same
>>> >> >> >>>>> >> >> > CMake
>>> >> >> >>>>> >> >> > libraries?
>>> >> >> >>>>> >> >> >
>>> >> >> >>>>> >> >> > On Mon, Aug 21, 2017 at 9:00 AM, Robert Dailey
>>> >> >> >>>>> >> >> > <[hidden email]>
>>> >> >> >>>>> >> >> > wrote:
>>> >> >> >>>>> >> >> >>
>>> >> >> >>>>> >> >> >> Thanks this is very helpful. The other question I
>>> >> >> >>>>> >> >> >> have
>>> >> >> >>>>> >> >> >> is:
>>> >> >> >>>>> >> >> >> Is
>>> >> >> >>>>> >> >> >> there
>>> >> >> >>>>> >> >> >> a
>>> >> >> >>>>> >> >> >> place to centrally specify the root CMakeLists.txt?
>>> >> >> >>>>> >> >> >> Basically,
>>> >> >> >>>>> >> >> >> I
>>> >> >> >>>>> >> >> >> want
>>> >> >> >>>>> >> >> >> to specify the CMake root in 1 place, and have
>>> >> >> >>>>> >> >> >> targets
>>> >> >> >>>>> >> >> >> (defined
>>> >> >> >>>>> >> >> >> further down in subdirectories) that require APK
>>> >> >> >>>>> >> >> >> packaging
>>> >> >> >>>>> >> >> >> to
>>> >> >> >>>>> >> >> >> specify
>>> >> >> >>>>> >> >> >> only the native target name that should be built &
>>> >> >> >>>>> >> >> >> packaged.
>>> >> >> >>>>> >> >> >>
>>> >> >> >>>>> >> >> >> At the moment we specify the root CMakeLists.txt by
>>> >> >> >>>>> >> >> >> walking
>>> >> >> >>>>> >> >> >> up
>>> >> >> >>>>> >> >> >> the
>>> >> >> >>>>> >> >> >> tree, paths like "../../../../CMakeLists.txt". I
>>> >> >> >>>>> >> >> >> think
>>> >> >> >>>>> >> >> >> this
>>> >> >> >>>>> >> >> >> should
>>> >> >> >>>>> >> >> >> be
>>> >> >> >>>>> >> >> >> put at the top-level build gradle file if possible.
>>> >> >> >>>>> >> >> >> Is
>>> >> >> >>>>> >> >> >> this
>>> >> >> >>>>> >> >> >> doable
>>> >> >> >>>>> >> >> >> at
>>> >> >> >>>>> >> >> >> the moment? What is the recommended setup?
>>> >> >> >>>>> >> >> >>
>>> >> >> >>>>> >> >> >> On Mon, Aug 21, 2017 at 9:37 AM, Jom O'Fisher
>>> >> >> >>>>> >> >> >> <[hidden email]>
>>> >> >> >>>>> >> >> >> wrote:
>>> >> >> >>>>> >> >> >> > Gradle does introspection on the CMake build to
>>> >> >> >>>>> >> >> >> > find
>>> >> >> >>>>> >> >> >> > .so
>>> >> >> >>>>> >> >> >> > targets
>>> >> >> >>>>> >> >> >> > and
>>> >> >> >>>>> >> >> >> > those
>>> >> >> >>>>> >> >> >> > get packaged.
>>> >> >> >>>>> >> >> >> > There is also a special case for stl/runtime .so
>>> >> >> >>>>> >> >> >> > files
>>> >> >> >>>>> >> >> >> > from
>>> >> >> >>>>> >> >> >> > the
>>> >> >> >>>>> >> >> >> > NDK.
>>> >> >> >>>>> >> >> >> > Any additional .so files need to specified in
>>> >> >> >>>>> >> >> >> > build.gradle
>>> >> >> >>>>> >> >> >> > using
>>> >> >> >>>>> >> >> >> > jniDirs
>>> >> >> >>>>> >> >> >> >
>>> >> >> >>>>> >> >> >> > On Mon, Aug 21, 2017 at 7:30 AM, Robert Dailey
>>> >> >> >>>>> >> >> >> > <[hidden email]>
>>> >> >> >>>>> >> >> >> > wrote:
>>> >> >> >>>>> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> How exactly does Gradle package *.so files in an
>>> >> >> >>>>> >> >> >> >> APK?
>>> >> >> >>>>> >> >> >> >> I
>>> >> >> >>>>> >> >> >> >> know
>>> >> >> >>>>> >> >> >> >> that
>>> >> >> >>>>> >> >> >> >> ANT
>>> >> >> >>>>> >> >> >> >> used to do this for any libs under "libs/<ABI>".
>>> >> >> >>>>> >> >> >> >> Does
>>> >> >> >>>>> >> >> >> >> Gradle
>>> >> >> >>>>> >> >> >> >> do
>>> >> >> >>>>> >> >> >> >> some
>>> >> >> >>>>> >> >> >> >> introspection into CMake targets to see if
>>> >> >> >>>>> >> >> >> >> outputs
>>> >> >> >>>>> >> >> >> >> are
>>> >> >> >>>>> >> >> >> >> *.so,
>>> >> >> >>>>> >> >> >> >> and
>>> >> >> >>>>> >> >> >> >> copy
>>> >> >> >>>>> >> >> >> >> those to some location if needed? What about
>>> >> >> >>>>> >> >> >> >> libraries
>>> >> >> >>>>> >> >> >> >> like
>>> >> >> >>>>> >> >> >> >> libgnustl_shared.so that come with the NDK? I'd
>>> >> >> >>>>> >> >> >> >> like
>>> >> >> >>>>> >> >> >> >> to
>>> >> >> >>>>> >> >> >> >> know
>>> >> >> >>>>> >> >> >> >> if
>>> >> >> >>>>> >> >> >> >> any
>>> >> >> >>>>> >> >> >> >> manual copy steps are needed in CMake to put
>>> >> >> >>>>> >> >> >> >> outputs
>>> >> >> >>>>> >> >> >> >> in
>>> >> >> >>>>> >> >> >> >> proper
>>> >> >> >>>>> >> >> >> >> locations for the APK build step. I had to do
>>> >> >> >>>>> >> >> >> >> this
>>> >> >> >>>>> >> >> >> >> when
>>> >> >> >>>>> >> >> >> >> using
>>> >> >> >>>>> >> >> >> >> ANT.
>>> >> >> >>>>> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> On Mon, Aug 7, 2017 at 6:16 PM, Jom O'Fisher
>>> >> >> >>>>> >> >> >> >> <[hidden email]>
>>> >> >> >>>>> >> >> >> >> wrote:
>>> >> >> >>>>> >> >> >> >> > 1) There is a folder created for each ABI under
>>> >> >> >>>>> >> >> >> >> > the
>>> >> >> >>>>> >> >> >> >> > project
>>> >> >> >>>>> >> >> >> >> > module
>>> >> >> >>>>> >> >> >> >> > folder
>>> >> >> >>>>> >> >> >> >> > (so unique per module per ABI)
>>> >> >> >>>>> >> >> >> >> > 2) Gradle doesn't specify language level though
>>> >> >> >>>>> >> >> >> >> > you
>>> >> >> >>>>> >> >> >> >> > can
>>> >> >> >>>>> >> >> >> >> > choose
>>> >> >> >>>>> >> >> >> >> > to
>>> >> >> >>>>> >> >> >> >> > specify it
>>> >> >> >>>>> >> >> >> >> > yourself from the build.gradle. This doc does a
>>> >> >> >>>>> >> >> >> >> > pretty
>>> >> >> >>>>> >> >> >> >> > good job
>>> >> >> >>>>> >> >> >> >> > of
>>> >> >> >>>>> >> >> >> >> > explaining which variables are set by Gradle:
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> > https://developer.android.com/ndk/guides/cmake.html#variables.
>>> >> >> >>>>> >> >> >> >> > Philosophically, we try to set as little as we
>>> >> >> >>>>> >> >> >> >> > can
>>> >> >> >>>>> >> >> >> >> > get
>>> >> >> >>>>> >> >> >> >> > away
>>> >> >> >>>>> >> >> >> >> > with.
>>> >> >> >>>>> >> >> >> >> > In
>>> >> >> >>>>> >> >> >> >> > particular, the section titled "Understanding
>>> >> >> >>>>> >> >> >> >> > the
>>> >> >> >>>>> >> >> >> >> > CMake
>>> >> >> >>>>> >> >> >> >> > build
>>> >> >> >>>>> >> >> >> >> > command"
>>> >> >> >>>>> >> >> >> >> > lays
>>> >> >> >>>>> >> >> >> >> > out exactly what we set. You can also see the
>>> >> >> >>>>> >> >> >> >> > folders
>>> >> >> >>>>> >> >> >> >> > we
>>> >> >> >>>>> >> >> >> >> > specify
>>> >> >> >>>>> >> >> >> >> > (one
>>> >> >> >>>>> >> >> >> >> > per
>>> >> >> >>>>> >> >> >> >> > module per ABI)
>>> >> >> >>>>> >> >> >> >> > 3) Not sure I understand this.
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> > The other document worth taking a look at (if
>>> >> >> >>>>> >> >> >> >> > you
>>> >> >> >>>>> >> >> >> >> > haven't
>>> >> >> >>>>> >> >> >> >> > already)
>>> >> >> >>>>> >> >> >> >> > is:
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> > https://developer.android.com/studio/projects/add-native-code.html
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> > On Mon, Aug 7, 2017 at 3:35 PM, Robert Dailey
>>> >> >> >>>>> >> >> >> >> > <[hidden email]>
>>> >> >> >>>>> >> >> >> >> > wrote:
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> Thanks Jom
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> Honestly, I prefer option 1 to work simply
>>> >> >> >>>>> >> >> >> >> >> because
>>> >> >> >>>>> >> >> >> >> >> that's
>>> >> >> >>>>> >> >> >> >> >> how
>>> >> >> >>>>> >> >> >> >> >> Google's
>>> >> >> >>>>> >> >> >> >> >> officially supporting CMake. But it also has
>>> >> >> >>>>> >> >> >> >> >> debugging
>>> >> >> >>>>> >> >> >> >> >> which
>>> >> >> >>>>> >> >> >> >> >> is
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> #1
>>> >> >> >>>>> >> >> >> >> >> reason for me.
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> However, I'd like to understand a lot more
>>> >> >> >>>>> >> >> >> >> >> about
>>> >> >> >>>>> >> >> >> >> >> how
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> integration
>>> >> >> >>>>> >> >> >> >> >> really happens. For example, I have these
>>> >> >> >>>>> >> >> >> >> >> questions:
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> 1) How, internally, are CMake build
>>> >> >> >>>>> >> >> >> >> >> directories
>>> >> >> >>>>> >> >> >> >> >> managed?
>>> >> >> >>>>> >> >> >> >> >> Do
>>> >> >> >>>>> >> >> >> >> >> you
>>> >> >> >>>>> >> >> >> >> >> generate 1 per unique android project? What
>>> >> >> >>>>> >> >> >> >> >> about
>>> >> >> >>>>> >> >> >> >> >> for
>>> >> >> >>>>> >> >> >> >> >> each
>>> >> >> >>>>> >> >> >> >> >> specific
>>> >> >> >>>>> >> >> >> >> >> platform (x86, armeabi-v7a, etc)?
>>> >> >> >>>>> >> >> >> >> >> 2) Last time I looked into CMake integration,
>>> >> >> >>>>> >> >> >> >> >> things
>>> >> >> >>>>> >> >> >> >> >> defined
>>> >> >> >>>>> >> >> >> >> >> inside
>>> >> >> >>>>> >> >> >> >> >> the CMake scripts were ignored because they
>>> >> >> >>>>> >> >> >> >> >> are
>>> >> >> >>>>> >> >> >> >> >> specified
>>> >> >> >>>>> >> >> >> >> >> at
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> command line. Namely, all of those settings
>>> >> >> >>>>> >> >> >> >> >> that
>>> >> >> >>>>> >> >> >> >> >> are
>>> >> >> >>>>> >> >> >> >> >> driven by
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> Gradle configuration (CXX language level was
>>> >> >> >>>>> >> >> >> >> >> one
>>> >> >> >>>>> >> >> >> >> >> in
>>> >> >> >>>>> >> >> >> >> >> particular
>>> >> >> >>>>> >> >> >> >> >> I
>>> >> >> >>>>> >> >> >> >> >> think; I specify C++14 support via CMake, but
>>> >> >> >>>>> >> >> >> >> >> I
>>> >> >> >>>>> >> >> >> >> >> recall
>>> >> >> >>>>> >> >> >> >> >> this
>>> >> >> >>>>> >> >> >> >> >> being
>>> >> >> >>>>> >> >> >> >> >> overridden from outside)?
>>> >> >> >>>>> >> >> >> >> >> 3) How redundant is it to configure individual
>>> >> >> >>>>> >> >> >> >> >> libraries
>>> >> >> >>>>> >> >> >> >> >> via
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> gradle scripts? In my previous attempts, I
>>> >> >> >>>>> >> >> >> >> >> wanted
>>> >> >> >>>>> >> >> >> >> >> to
>>> >> >> >>>>> >> >> >> >> >> define
>>> >> >> >>>>> >> >> >> >> >> common
>>> >> >> >>>>> >> >> >> >> >> stuff for CMake / native code at the root
>>> >> >> >>>>> >> >> >> >> >> gradle
>>> >> >> >>>>> >> >> >> >> >> or
>>> >> >> >>>>> >> >> >> >> >> settings
>>> >> >> >>>>> >> >> >> >> >> file,
>>> >> >> >>>>> >> >> >> >> >> and
>>> >> >> >>>>> >> >> >> >> >> only define the differences in the actual
>>> >> >> >>>>> >> >> >> >> >> gradle
>>> >> >> >>>>> >> >> >> >> >> build
>>> >> >> >>>>> >> >> >> >> >> files
>>> >> >> >>>>> >> >> >> >> >> for
>>> >> >> >>>>> >> >> >> >> >> each
>>> >> >> >>>>> >> >> >> >> >> corresponding Java target (like, defining the
>>> >> >> >>>>> >> >> >> >> >> name
>>> >> >> >>>>> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> native
>>> >> >> >>>>> >> >> >> >> >> (shared library) target in Gradle, but the
>>> >> >> >>>>> >> >> >> >> >> command
>>> >> >> >>>>> >> >> >> >> >> line
>>> >> >> >>>>> >> >> >> >> >> invocation,
>>> >> >> >>>>> >> >> >> >> >> -D
>>> >> >> >>>>> >> >> >> >> >> CMake settings, etc would all be common and
>>> >> >> >>>>> >> >> >> >> >> defined
>>> >> >> >>>>> >> >> >> >> >> at
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> root).
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> The TLDR is, the closer we can stay to CMake's
>>> >> >> >>>>> >> >> >> >> >> way
>>> >> >> >>>>> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> doing
>>> >> >> >>>>> >> >> >> >> >> things
>>> >> >> >>>>> >> >> >> >> >> and
>>> >> >> >>>>> >> >> >> >> >> keep CMake-related settings self-contained to
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> CMake
>>> >> >> >>>>> >> >> >> >> >> scripts
>>> >> >> >>>>> >> >> >> >> >> themselves, the better. This also makes
>>> >> >> >>>>> >> >> >> >> >> cross-platform
>>> >> >> >>>>> >> >> >> >> >> easier
>>> >> >> >>>>> >> >> >> >> >> (we
>>> >> >> >>>>> >> >> >> >> >> build the native code in Windows, for example,
>>> >> >> >>>>> >> >> >> >> >> so
>>> >> >> >>>>> >> >> >> >> >> having
>>> >> >> >>>>> >> >> >> >> >> settings
>>> >> >> >>>>> >> >> >> >> >> specified in the gradle files do not carry
>>> >> >> >>>>> >> >> >> >> >> over to
>>> >> >> >>>>> >> >> >> >> >> other
>>> >> >> >>>>> >> >> >> >> >> platforms.
>>> >> >> >>>>> >> >> >> >> >> Namely, settings that are not platform
>>> >> >> >>>>> >> >> >> >> >> specific
>>> >> >> >>>>> >> >> >> >> >> like
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> C++
>>> >> >> >>>>> >> >> >> >> >> language
>>> >> >> >>>>> >> >> >> >> >> level).
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> If there's a detailed document / wiki I can
>>> >> >> >>>>> >> >> >> >> >> read
>>> >> >> >>>>> >> >> >> >> >> on
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> intrinsics
>>> >> >> >>>>> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> CMake integration in Gradle / Android Studio,
>>> >> >> >>>>> >> >> >> >> >> I'd
>>> >> >> >>>>> >> >> >> >> >> love to
>>> >> >> >>>>> >> >> >> >> >> read
>>> >> >> >>>>> >> >> >> >> >> it.
>>> >> >> >>>>> >> >> >> >> >> Otherwise, I hope you won't mind if I pick
>>> >> >> >>>>> >> >> >> >> >> your
>>> >> >> >>>>> >> >> >> >> >> brain
>>> >> >> >>>>> >> >> >> >> >> as
>>> >> >> >>>>> >> >> >> >> >> questions
>>> >> >> >>>>> >> >> >> >> >> come up. I think I'm going to try option 1 for
>>> >> >> >>>>> >> >> >> >> >> now
>>> >> >> >>>>> >> >> >> >> >> and
>>> >> >> >>>>> >> >> >> >> >> see how
>>> >> >> >>>>> >> >> >> >> >> it
>>> >> >> >>>>> >> >> >> >> >> goes. It's just black box for me because
>>> >> >> >>>>> >> >> >> >> >> unlike
>>> >> >> >>>>> >> >> >> >> >> option 2,
>>> >> >> >>>>> >> >> >> >> >> I
>>> >> >> >>>>> >> >> >> >> >> have
>>> >> >> >>>>> >> >> >> >> >> very
>>> >> >> >>>>> >> >> >> >> >> little control over what happens after
>>> >> >> >>>>> >> >> >> >> >> building
>>> >> >> >>>>> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> shared
>>> >> >> >>>>> >> >> >> >> >> libraries,
>>> >> >> >>>>> >> >> >> >> >> and to make up for that I need to really get a
>>> >> >> >>>>> >> >> >> >> >> deep
>>> >> >> >>>>> >> >> >> >> >> understanding
>>> >> >> >>>>> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> how it works so I can make sure I code my
>>> >> >> >>>>> >> >> >> >> >> CMake
>>> >> >> >>>>> >> >> >> >> >> scripts
>>> >> >> >>>>> >> >> >> >> >> properly
>>> >> >> >>>>> >> >> >> >> >> for
>>> >> >> >>>>> >> >> >> >> >> not only Android, but my other platforms as
>>> >> >> >>>>> >> >> >> >> >> well
>>> >> >> >>>>> >> >> >> >> >> (non-Android
>>> >> >> >>>>> >> >> >> >> >> platforms).
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> Thanks again.
>>> >> >> >>>>> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> On Mon, Aug 7, 2017 at 5:12 PM, Jom O'Fisher
>>> >> >> >>>>> >> >> >> >> >> <[hidden email]>
>>> >> >> >>>>> >> >> >> >> >> wrote:
>>> >> >> >>>>> >> >> >> >> >> > Either option can work fine. Disclosure: I
>>> >> >> >>>>> >> >> >> >> >> > work
>>> >> >> >>>>> >> >> >> >> >> > on
>>> >> >> >>>>> >> >> >> >> >> > Android
>>> >> >> >>>>> >> >> >> >> >> > Studio
>>> >> >> >>>>> >> >> >> >> >> > and
>>> >> >> >>>>> >> >> >> >> >> > was
>>> >> >> >>>>> >> >> >> >> >> > the one that added CMake support.
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> > Option (1) is the way it's designed to work
>>> >> >> >>>>> >> >> >> >> >> > and
>>> >> >> >>>>> >> >> >> >> >> > we're
>>> >> >> >>>>> >> >> >> >> >> > working
>>> >> >> >>>>> >> >> >> >> >> > toward
>>> >> >> >>>>> >> >> >> >> >> > getting
>>> >> >> >>>>> >> >> >> >> >> > rid of the need for the CMake fork. I can't
>>> >> >> >>>>> >> >> >> >> >> > really
>>> >> >> >>>>> >> >> >> >> >> > say
>>> >> >> >>>>> >> >> >> >> >> > when
>>> >> >> >>>>> >> >> >> >> >> > that
>>> >> >> >>>>> >> >> >> >> >> > will
>>> >> >> >>>>> >> >> >> >> >> > happen
>>> >> >> >>>>> >> >> >> >> >> > but if you can get away with an older CMake
>>> >> >> >>>>> >> >> >> >> >> > for
>>> >> >> >>>>> >> >> >> >> >> > now
>>> >> >> >>>>> >> >> >> >> >> > then I'd
>>> >> >> >>>>> >> >> >> >> >> > go
>>> >> >> >>>>> >> >> >> >> >> > this
>>> >> >> >>>>> >> >> >> >> >> > way.
>>> >> >> >>>>> >> >> >> >> >> > As you mentioned, option (1) will allow you
>>> >> >> >>>>> >> >> >> >> >> > to
>>> >> >> >>>>> >> >> >> >> >> > view
>>> >> >> >>>>> >> >> >> >> >> > your
>>> >> >> >>>>> >> >> >> >> >> > source
>>> >> >> >>>>> >> >> >> >> >> > file
>>> >> >> >>>>> >> >> >> >> >> > structure in Android Studio, edit files, and
>>> >> >> >>>>> >> >> >> >> >> > debug
>>> >> >> >>>>> >> >> >> >> >> > using the
>>> >> >> >>>>> >> >> >> >> >> > built-in
>>> >> >> >>>>> >> >> >> >> >> > debugging support.
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> > To get option (2) to work, you can use
>>> >> >> >>>>> >> >> >> >> >> > jniDirs
>>> >> >> >>>>> >> >> >> >> >> > setting
>>> >> >> >>>>> >> >> >> >> >> > to
>>> >> >> >>>>> >> >> >> >> >> > tell
>>> >> >> >>>>> >> >> >> >> >> > Android
>>> >> >> >>>>> >> >> >> >> >> > Gradle where to pick up your built .so files
>>> >> >> >>>>> >> >> >> >> >> > (see
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> > https://stackoverflow.com/questions/21255125/how-can-i-add-so-files-to-an-android-library-project-using-gradle-0-7).
>>> >> >> >>>>> >> >> >> >> >> > I'm not aware of any projects that use this
>>> >> >> >>>>> >> >> >> >> >> > approach
>>> >> >> >>>>> >> >> >> >> >> > but it
>>> >> >> >>>>> >> >> >> >> >> > should
>>> >> >> >>>>> >> >> >> >> >> > work
>>> >> >> >>>>> >> >> >> >> >> > in
>>> >> >> >>>>> >> >> >> >> >> > principal.
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> > I hope this helps,
>>> >> >> >>>>> >> >> >> >> >> > Jomo
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> > On Mon, Aug 7, 2017 at 11:09 AM, Robert
>>> >> >> >>>>> >> >> >> >> >> > Dailey
>>> >> >> >>>>> >> >> >> >> >> > <[hidden email]>
>>> >> >> >>>>> >> >> >> >> >> > wrote:
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> Right now I have custom targets set to
>>> >> >> >>>>> >> >> >> >> >> >> execute
>>> >> >> >>>>> >> >> >> >> >> >> the
>>> >> >> >>>>> >> >> >> >> >> >> "ant
>>> >> >> >>>>> >> >> >> >> >> >> release"
>>> >> >> >>>>> >> >> >> >> >> >> command after my native targets are built.
>>> >> >> >>>>> >> >> >> >> >> >> Part
>>> >> >> >>>>> >> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> >> that
>>> >> >> >>>>> >> >> >> >> >> >> command
>>> >> >> >>>>> >> >> >> >> >> >> involves copying *.so files to the
>>> >> >> >>>>> >> >> >> >> >> >> libs/armeabi-v7a
>>> >> >> >>>>> >> >> >> >> >> >> directory
>>> >> >> >>>>> >> >> >> >> >> >> so
>>> >> >> >>>>> >> >> >> >> >> >> they
>>> >> >> >>>>> >> >> >> >> >> >> get packaged in an APK.
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> When switching to gradle, I have two
>>> >> >> >>>>> >> >> >> >> >> >> options:
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> 1. Gradle drives CMake: This means using
>>> >> >> >>>>> >> >> >> >> >> >> Android
>>> >> >> >>>>> >> >> >> >> >> >> Studio and
>>> >> >> >>>>> >> >> >> >> >> >> being
>>> >> >> >>>>> >> >> >> >> >> >> locked down to Google's fork of CMake which
>>> >> >> >>>>> >> >> >> >> >> >> is
>>> >> >> >>>>> >> >> >> >> >> >> a
>>> >> >> >>>>> >> >> >> >> >> >> few
>>> >> >> >>>>> >> >> >> >> >> >> major
>>> >> >> >>>>> >> >> >> >> >> >> releases
>>> >> >> >>>>> >> >> >> >> >> >> behind. I see that as a negative.
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> 2. CMake drives Gradle: This would be the
>>> >> >> >>>>> >> >> >> >> >> >> same
>>> >> >> >>>>> >> >> >> >> >> >> or
>>> >> >> >>>>> >> >> >> >> >> >> similar
>>> >> >> >>>>> >> >> >> >> >> >> to
>>> >> >> >>>>> >> >> >> >> >> >> what
>>> >> >> >>>>> >> >> >> >> >> >> I'm
>>> >> >> >>>>> >> >> >> >> >> >> already doing: The custom targets I have
>>> >> >> >>>>> >> >> >> >> >> >> would
>>> >> >> >>>>> >> >> >> >> >> >> execute
>>> >> >> >>>>> >> >> >> >> >> >> gradle
>>> >> >> >>>>> >> >> >> >> >> >> as
>>> >> >> >>>>> >> >> >> >> >> >> a
>>> >> >> >>>>> >> >> >> >> >> >> separate build step, instead of running ant
>>> >> >> >>>>> >> >> >> >> >> >> commands.
>>> >> >> >>>>> >> >> >> >> >> >> I'm
>>> >> >> >>>>> >> >> >> >> >> >> not
>>> >> >> >>>>> >> >> >> >> >> >> too
>>> >> >> >>>>> >> >> >> >> >> >> familiar with Gradle, so I'm not sure how
>>> >> >> >>>>> >> >> >> >> >> >> you
>>> >> >> >>>>> >> >> >> >> >> >> tell
>>> >> >> >>>>> >> >> >> >> >> >> it
>>> >> >> >>>>> >> >> >> >> >> >> where
>>> >> >> >>>>> >> >> >> >> >> >> your
>>> >> >> >>>>> >> >> >> >> >> >> shared libraries are for the APK packaging
>>> >> >> >>>>> >> >> >> >> >> >> steps.
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> Which does everyone recommend? Is anyone
>>> >> >> >>>>> >> >> >> >> >> >> using
>>> >> >> >>>>> >> >> >> >> >> >> one
>>> >> >> >>>>> >> >> >> >> >> >> of
>>> >> >> >>>>> >> >> >> >> >> >> these
>>> >> >> >>>>> >> >> >> >> >> >> setups
>>> >> >> >>>>> >> >> >> >> >> >> successfully? The downside to option 2 is
>>> >> >> >>>>> >> >> >> >> >> >> probably
>>> >> >> >>>>> >> >> >> >> >> >> no
>>> >> >> >>>>> >> >> >> >> >> >> on-device
>>> >> >> >>>>> >> >> >> >> >> >> native
>>> >> >> >>>>> >> >> >> >> >> >> debugging since Android Studio probably
>>> >> >> >>>>> >> >> >> >> >> >> can't
>>> >> >> >>>>> >> >> >> >> >> >> handle
>>> >> >> >>>>> >> >> >> >> >> >> gradle
>>> >> >> >>>>> >> >> >> >> >> >> projects
>>> >> >> >>>>> >> >> >> >> >> >> without any external CMake builds set up.
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> Would like some general direction & advice
>>> >> >> >>>>> >> >> >> >> >> >> before
>>> >> >> >>>>> >> >> >> >> >> >> I
>>> >> >> >>>>> >> >> >> >> >> >> move
>>> >> >> >>>>> >> >> >> >> >> >> away
>>> >> >> >>>>> >> >> >> >> >> >> from
>>> >> >> >>>>> >> >> >> >> >> >> ANT. Thanks in advance.
>>> >> >> >>>>> >> >> >> >> >> >> --
>>> >> >> >>>>> >> >> >> >> >> >>
>>> >> >> >>>>> >> >> >> >> >> >> 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/mailman/listinfo/cmake
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >> >
>>> >> >> >>>>> >> >> >> >
>>> >> >> >>>>> >> >> >> >
>>> >> >> >>>>> >> >> >
>>> >> >> >>>>> >> >> >
>>> >> >> >>>>> >> >
>>> >> >> >>>>> >> >
>>> >> >> >>>>> >
>>> >> >> >>>>> >
>>> >> >> >>>>
>>> >> >> >>>>
>>> >> >> >>>
>>> >> >> >>
>>> >> >
>>> >> >
>>> >
>>> >
>>
>>
>
--

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/mailman/listinfo/cmake
12