[CMake] CMake + Gradle for Android

Jom O'Fisher jomofisher at gmail.com
Fri Aug 25 17:46:40 EDT 2017


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 <rcdailey.lists at gmail.com>
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 <jomofisher at gmail.com>
> 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 <rcdailey.lists at gmail.com
> >
> > 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 <jomofisher at gmail.com>
> >> 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
> >> > <rcdailey.lists at gmail.com>
> >> > 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
> >> >> <rcdailey.lists at gmail.com>
> >> >> 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 <chiur at google.com>
> >> >> > 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 <
> jomofisher at gmail.com>
> >> >> >> wrote:
> >> >> >>>
> >> >> >>> + a colleague
> >> >> >>>
> >> >> >>> On Mon, Aug 21, 2017 at 3:11 PM, Jom O'Fisher
> >> >> >>> <jomofisher at gmail.com>
> >> >> >>> 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
> >> >> >>>> <rcdailey.lists at gmail.com>
> >> >> >>>> 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
> >> >> >>>>> <jomofisher at gmail.com>
> >> >> >>>>> 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
> >> >> >>>>> > <rcdailey.lists at gmail.com>
> >> >> >>>>> > 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
> >> >> >>>>> >> <jomofisher at gmail.com>
> >> >> >>>>> >> 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
> >> >> >>>>> >> > <rcdailey.lists at gmail.com>
> >> >> >>>>> >> > 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
> >> >> >>>>> >> >> <jomofisher at gmail.com>
> >> >> >>>>> >> >> 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
> >> >> >>>>> >> >> > <rcdailey.lists at gmail.com>
> >> >> >>>>> >> >> > 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
> >> >> >>>>> >> >> >> <jomofisher at gmail.com>
> >> >> >>>>> >> >> >> 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
> >> >> >>>>> >> >> >> > <rcdailey.lists at gmail.com>
> >> >> >>>>> >> >> >> > 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
> >> >> >>>>> >> >> >> >> <jomofisher at gmail.com>
> >> >> >>>>> >> >> >> >> 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
> >> >> >>>>> >> >> >> >> > <rcdailey.lists at gmail.com>
> >> >> >>>>> >> >> >> >> > 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
> >> >> >>>>> >> >> >> >> >> <jomofisher at gmail.com>
> >> >> >>>>> >> >> >> >> >> 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
> >> >> >>>>> >> >> >> >> >> > <rcdailey.lists at gmail.com>
> >> >> >>>>> >> >> >> >> >> > 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
> >> >> >>>>> >> >> >> >> >> >
> >> >> >>>>> >> >> >> >> >> >
> >> >> >>>>> >> >> >> >> >
> >> >> >>>>> >> >> >> >> >
> >> >> >>>>> >> >> >> >
> >> >> >>>>> >> >> >> >
> >> >> >>>>> >> >> >
> >> >> >>>>> >> >> >
> >> >> >>>>> >> >
> >> >> >>>>> >> >
> >> >> >>>>> >
> >> >> >>>>> >
> >> >> >>>>
> >> >> >>>>
> >> >> >>>
> >> >> >>
> >> >
> >> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20170825/776fe3a6/attachment-0001.html>


More information about the CMake mailing list