[cmake-developers] [CMake] dependencies of cross compiliations

Craig Scott craig.scott at crascit.com
Mon Dec 10 05:22:31 EST 2018

On Mon, Dec 10, 2018 at 7:57 PM Eric Noulard <eric.noulard at gmail.com> wrote:

> Le dim. 9 déc. 2018 à 12:24, Craig Scott <craig.scott at crascit.com> a
> écrit :
>> On Tue, Dec 4, 2018 at 6:56 PM Torsten Robitzki <Torsten at robitzki.de>
>> wrote:
>>> > Am 27.11.2018 um 19:55 schrieb Eric Noulard <eric.noulard at gmail.com>:
>>> >
>>> > My assumption are:
>>> >  a) when you cross-compile your build is a "whole" and you shouldn't
>>> have to setup some superbuild
>>> >    structure for building host tools ht_exe and another for target1
>>> tool t1t_exe and another one for target2 tool t2t_exe.
>>> >
>>> >  b) what you want is to build:
>>> >      ht_exe for the host
>>> >      possibly use ht_exe during the build to generate some [source]
>>> file
>>> >      t1t_exe for the [cross]target1
>>> >      t2t_exe for the [cross]target2
>>> >
>>> >  c)  you seldomly compile the same source for the host AND the target,
>>> but it may happen.
>>> In case, you are doing unit tests, it’s normal to have the same code
>>> running in a test on the host platform and in the final binary on the
>>> target.
>>> I think, having more than 1 target platform becomes more and more normal
>>> as it becomes more usual to have multiple microcontrollers in a project.
> Yes that's why I thought it was worth going further than host + target,
> but host + tgt1 + tg2 + ....
>>> Previously, I have encoded this in the build type. So instead of just
>>> having Debug and Release, I had HOST_Debug, HOST_Release NRF51_Debug,
>>> NRF51_Release, STM8_Debug, STM8_Release and so on. It doesn’t annoy me very
>>> much, that I have to run CMake 3 times to get all the binaries for a
>>> release build. The problem that I have, are dependencies between this
>>> builds. If I write a tool that (for example) generates source files for one
>>> of the target platforms, the build for the host platform must run before
>>> the build for that target platform. And when I make changes to that tool, I
>>> want the build to regenerate the generated source files.
>>> Keeping track of this dependencies to solve this kind of ordering issues
>>> and to allow minimum rebuilds, is the main purpose of any build system. To
>>> solve this with CMake, I think we need a way to define the dependencies
>>> between build types (in the example above, from the generator from the host
>>> build to the generated source file in one of the target builds) and CMake
>>> needs to know the build directory for all build types (not only the
>>> current).
>> Perhaps a superbuild would be the cleanest approach here? The host tools
>> would be one subproject and the cross-compile builds would depend on the
>> host tools' build. You could then choose to build everything via the top
>> level superbuild or just work on one of the subprojects if that's all you
>> needed once the initial tools build had been done. You could even set up as
>> many different sub-projects for the different architectures as needed.
>> Packaging would require a little more work, but it shouldn't be
>> prohibitively so.
> I guess the tough part is to find a [light] way to specify dependencies
> between host target build and the various target builds.
>> Another alternative is the approach described in this stackoverflow
>> article
>> <https://stackoverflow.com/questions/36084785/building-a-tool-immediately-so-it-can-be-used-later-in-same-cmake-run>
>> which performs the host tools build off to the side in a secondary build
>> during configure. This works well when the host tools don't change much (we
>> use it extensively at work with very large, complex hierarchical projects).
>> It wouldn't help though if you need to build more than one cross-compiled
>> architecture.
>> > The wish-season is coming up, so that's sort of what I would like to
>>> > have. Now it's your turn. No bikeshedding please, only deliveries ;)
>>> How about ``add_dependencies()`` allowing me to define dependencies
>>> between different build types? :-)
>> A superbuild would already give you the equivalent capability.
> Not as easy as it seems right?
> I bet you know it well as you listed the dependencies shortcoming of
> adding dependencies for External_ProjectAdd in your book (§27.1.4).

For a strict superbuild arrangement, handling straight dependencies to get
build order correct is not too bad. This is what I was thinking of with my
earlier comment that super builds essentially give you the equivalent
capability as just using add_dependencies(). You can also usually define
CMAKE_PREFIX_PATH to pass sub-project install locations between the
sub-projects and they each find what they need from the others without much
further help. The top level superbuild is then really just specifying which
sub-projects depend on which other ones. That does require a little bit of
boilerplate, agreed, but not crazy amounts.

Where it starts getting out of hand is when you want to have a main build
that directly wants/needs to refer to targets from sub-projects brought in
by ExternalProject. Then you have to go working out where everything is
without much help from CMake and that can be a soul-destroying exercise for
complex multi-platform projects. Packaging suffers from this if done from
the top superbuild project, but the difficulty can sometimes be reduced by
doing the packaging itself as another subproject and importing what it
needs from the others (you can then use the various imported targets, etc.
to locate things), but it's still not particularly clean.

But yes, I'm agreeing with you, it isn't all that simple once you start
considering the full software delivery process (i.e. going beyond more than
just getting things to build).

Craig Scott
Melbourne, Australia

New book released: Professional CMake: A Practical Guide
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake-developers/attachments/20181210/43b32fd5/attachment-0001.html>

More information about the cmake-developers mailing list