Discussion:
[cmake-developers] [CMake] dependencies of cross compiliations
Rolf Eike Beer
2018-11-27 10:28:02 UTC
Permalink
Hi,
I hope this question was not asked before. I work in the embedded
field and there it is usually to have at least two different build
platforms. The Host platform, where unit tests are build (and where
CMake is running) and an embedded Target platform, where targets are
build with a cross compiler. Sometimes such a system comes with
self-written tools that are build and run on the Host platform to
build a target for the embedded Target platform (adding meta data to a
binary to be used by a bootloader for example).
Usually I have two different build folders, one for the Host platform
and one for the Target platform, using different calls to cmake to
choose from a set of tools and targets. But when using this approach,
it is necessary that the Host platform build ran before the Target
platform build, so that tools that are required for the Target
platform are build during the Host target build.
One solution I’ve came up with, is to build the required tools during
the Target platform build, using an add_custom_target() to invoke the
Target compiler directly. This works fine, as long as the tools are
basically build just out of a couple of files.
What would be the „CMake-Way“ to add the tools (that have to be build
on the Target platform) as dependency to targets that have to be build
for the Target (cross compile) platform?
TL;DR: there is not "good" way yet. But there should be one.

I'm hijacking this and move it to the developers list, because that is
something "big", and we need to think about how to do that. I find it
important to correctly solve this as it would simplify a lot of things.
Especially given that Qt is thinking to use CMake to build Qt itself,
which I bet all of us would love to see. But they will be after us if we
don't offer a solution for this. And given the increasing amount of
cross-setups these days I'm sure that a lot of other people would
benefit.

My first idea was to have something like add_host_executable(), which
would only be called when this is not CMAKE_CROSSCOMPILING, but at the
end I think this clutters things too much.

Then I came up with:

add_host_build("relative source dir" "build dir" [VARS])

This would create an entirely new CMake scope (with it's own
CMakeCache.txt and the like) in "${CMAKE_CURRENT_BUILD_DIR}/build dir",
and would not take the CMAKE_TOOLCHAIN_FILE into account. People are
free to pass "." as relative source dir in case they want to start at
top level, but they may as well pass "tools", "generators" or whatever
they call it. This is not intended to be called multiple times from the
same project as it would scan for compiler and environment once for
every call, but doing so does no harm beyond being slow(er) and the
targets of one such sub-build not being visible to the others.

My idea would be that things added by add_executable() inside such a
sub-build are visible as targets from the outer build. Other things like
libraries and the like need not to be, they can't be linked in the outer
world. The user is free to build with shared libs inside, and running
the things from the build tree would result in the correct freshly build
libs being picked up because of RPATH or whatever. There is no install
of those targets possible from the outer build, this can entirely be
managed from the host build. Of course one must be possible to set
variables on the host build, that's where VARS comes into play. This
holds a list of variable names that will be passed to the hostbuild. No
values, to avoid all sorts of quoting issues. Helpful would be a special
variable for CMAKE_INSTALL_PREFIX as this needs a bit of attention (and
a non-sysroot thing prefix in the toolchain file). Confused? Granted,
here is an example:

if (CMAKE_CROSSCOMPILING)
set(HOST_INSTALL_DIR "/some/where")
add_host_build(. host HOST_INSTALL_DIR)
endif ()
add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin) # installs both the host and the
target tool!
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND
magic) # will call the host build
if (NOT CMAKE_HOST_BUILD)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)
endif ()

This should end up in a layout like this:

/tmp/install/prefix/tools/bin/magic.exe # Windows host
/tmp/install/prefix/sysroot/usr/bin/magic # Unix guest
/tmp/install/prefix/sysroot/usr/bin/foo

The toolchain file would look somehow like this:

set(CMAKE_HOST_PREFIX prefix
set(CMAKE_SYSROOT ${CMAKE_HOST_PREFIX}/sysroot)

and the CMake command would look like this:

cmake -D CMAKE_TOOLCHAIN_FILE=tc.cmake -D CMAKE_INSTALL_PREFIX=/usr -D
CMAKE_HOST_INSTALL_PREFIX=tools ...

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 ;)

Eike
--
--
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:
https://cmake.org/mailman/listinfo/cmake-
Ray Donnelly
2018-11-27 10:36:51 UTC
Permalink
Post by Rolf Eike Beer
which I bet all of us would love to see.
This is not correct. I would strongly prefer they continue with QBS
instead. Cmake is defacto, but very suboptional.
Post by Rolf Eike Beer
Hi,
I hope this question was not asked before. I work in the embedded
field and there it is usually to have at least two different build
platforms. The Host platform, where unit tests are build (and where
CMake is running) and an embedded Target platform, where targets are
build with a cross compiler. Sometimes such a system comes with
self-written tools that are build and run on the Host platform to
build a target for the embedded Target platform (adding meta data to a
binary to be used by a bootloader for example).
Usually I have two different build folders, one for the Host platform
and one for the Target platform, using different calls to cmake to
choose from a set of tools and targets. But when using this approach,
it is necessary that the Host platform build ran before the Target
platform build, so that tools that are required for the Target
platform are build during the Host target build.
One solution I’ve came up with, is to build the required tools during
the Target platform build, using an add_custom_target() to invoke the
Target compiler directly. This works fine, as long as the tools are
basically build just out of a couple of files.
What would be the „CMake-Way“ to add the tools (that have to be build
on the Target platform) as dependency to targets that have to be build
for the Target (cross compile) platform?
TL;DR: there is not "good" way yet. But there should be one.
I'm hijacking this and move it to the developers list, because that is
something "big", and we need to think about how to do that. I find it
important to correctly solve this as it would simplify a lot of things.
Especially given that Qt is thinking to use CMake to build Qt itself,
which I bet all of us would love to see. But they will be after us if we
don't offer a solution for this. And given the increasing amount of
cross-setups these days I'm sure that a lot of other people would
benefit.
My first idea was to have something like add_host_executable(), which
would only be called when this is not CMAKE_CROSSCOMPILING, but at the
end I think this clutters things too much.
add_host_build("relative source dir" "build dir" [VARS])
This would create an entirely new CMake scope (with it's own
CMakeCache.txt and the like) in "${CMAKE_CURRENT_BUILD_DIR}/build dir",
and would not take the CMAKE_TOOLCHAIN_FILE into account. People are
free to pass "." as relative source dir in case they want to start at
top level, but they may as well pass "tools", "generators" or whatever
they call it. This is not intended to be called multiple times from the
same project as it would scan for compiler and environment once for
every call, but doing so does no harm beyond being slow(er) and the
targets of one such sub-build not being visible to the others.
My idea would be that things added by add_executable() inside such a
sub-build are visible as targets from the outer build. Other things like
libraries and the like need not to be, they can't be linked in the outer
world. The user is free to build with shared libs inside, and running
the things from the build tree would result in the correct freshly build
libs being picked up because of RPATH or whatever. There is no install
of those targets possible from the outer build, this can entirely be
managed from the host build. Of course one must be possible to set
variables on the host build, that's where VARS comes into play. This
holds a list of variable names that will be passed to the hostbuild. No
values, to avoid all sorts of quoting issues. Helpful would be a special
variable for CMAKE_INSTALL_PREFIX as this needs a bit of attention (and
a non-sysroot thing prefix in the toolchain file). Confused? Granted,
if (CMAKE_CROSSCOMPILING)
set(HOST_INSTALL_DIR "/some/where")
add_host_build(. host HOST_INSTALL_DIR)
endif ()
add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin) # installs both the host and the
target tool!
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND
magic) # will call the host build
if (NOT CMAKE_HOST_BUILD)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)
endif ()
/tmp/install/prefix/tools/bin/magic.exe # Windows host
/tmp/install/prefix/sysroot/usr/bin/magic # Unix guest
/tmp/install/prefix/sysroot/usr/bin/foo
set(CMAKE_HOST_PREFIX prefix
set(CMAKE_SYSROOT ${CMAKE_HOST_PREFIX}/sysroot)
cmake -D CMAKE_TOOLCHAIN_FILE=tc.cmake -D CMAKE_INSTALL_PREFIX=/usr -D
CMAKE_HOST_INSTALL_PREFIX=tools ...
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 ;)
Eike
--
--
Powered by www.kitware.com
http://www.cmake.org/Wiki/CMake_FAQ
Kitware offers various services to support the CMake community. For more
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
https://cmake.org/mailman/listinfo/cmake
Jean-Michaël Celerier
2018-11-27 11:55:57 UTC
Permalink
Post by Ray Donnelly
Cmake is defacto, but very suboptional.
(I suppose you meant suboptimal).

well yes, that's why people like Eike are trying to do stuff to improve it.

QBS is also fairly suboptimal in my opinion even if the language is
cleaner - had my share of bugs (sometimes meaning that I couldn't run a
build at all) with some projects using it (namely OpenFrameworks) and
ended up using CMake ports which were much more reliable.
Brad King
2018-11-27 12:01:36 UTC
Permalink
Post by Rolf Eike Beer
add_host_build("relative source dir" "build dir" [VARS])
This would create an entirely new CMake scope (with it's own
CMakeCache.txt and the like) in "${CMAKE_CURRENT_BUILD_DIR}/build dir",
and would not take the CMAKE_TOOLCHAIN_FILE into account.
[snip]
Post by Rolf Eike Beer
My idea would be that things added by add_executable() inside such a
sub-build are visible as targets from the outer build.
For reference, some projects are already using the ExternalProject
module to approximate that approach and bring in the host tools as
imported executable targets. The actual host build is viewed as
a custom target from the cross-compiled project.

-Brad
--
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:
https://cmake.org/mailman/listinfo/cmake-developers
Eric Noulard
2018-11-27 18:55:56 UTC
Permalink
Post by Rolf Eike Beer
Hi,
I hope this question was not asked before. I work in the embedded
field and there it is usually to have at least two different build
platforms. The Host platform, where unit tests are build (and where
CMake is running) and an embedded Target platform, where targets are
build with a cross compiler. Sometimes such a system comes with
self-written tools that are build and run on the Host platform to
build a target for the embedded Target platform (adding meta data to a
binary to be used by a bootloader for example).
Usually I have two different build folders, one for the Host platform
and one for the Target platform, using different calls to cmake to
choose from a set of tools and targets. But when using this approach,
it is necessary that the Host platform build ran before the Target
platform build, so that tools that are required for the Target
platform are build during the Host target build.
One solution I’ve came up with, is to build the required tools during
the Target platform build, using an add_custom_target() to invoke the
Target compiler directly. This works fine, as long as the tools are
basically build just out of a couple of files.
What would be the „CMake-Way“ to add the tools (that have to be build
on the Target platform) as dependency to targets that have to be build
for the Target (cross compile) platform?
TL;DR: there is not "good" way yet. But there should be one.
I do agree with that quote I was quite surprised (a long time ago) that
CMake did not support cross-compiling.
Back then I was using recursive hand-written makefiles for cross-compiling.
When I wanted to build
the whole thing I only had to hit "make" and wait.

Moreover I think CMake cross-compiling support was biased by the fact CMake
wasn't designed for that initially.
Please don't take my remark as bare criticism I am using CMake for a long
time now, I do like CMake very much
and I was pleased to see the cross-compiling support coming.

However from my point of view and my cross-compiling experience when you
cross-compile you have:

1) the host compiler which is used to compile "host tools"
2) the target compiler (may be several of them) to "cross-compile"

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.

And you want to build all that stuff with a single configure+build command
AND take advantage
of fast and efficient parallel build for the **whole build**. I don't want
to

cd /build/for/host
ninja
cd /build/for/target1
ninja
etc...
Post by Rolf Eike Beer
Helpful would be a special
variable for CMAKE_INSTALL_PREFIX as this needs a bit of attention (and
a non-sysroot thing prefix in the toolchain file). Confused? Granted,
if (CMAKE_CROSSCOMPILING)
set(HOST_INSTALL_DIR "/some/where")
add_host_build(. host HOST_INSTALL_DIR)
endif ()
add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin) # installs both the host and the
target tool!
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND
magic) # will call the host build
if (NOT CMAKE_HOST_BUILD)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)
endif ()
I get your point but I think we may try a more declarative way.

add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND magic)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)

set_target_properties(magic PROPERTIES BUILD_TARGET "host;cross_target1")
set_target_properties(foo PROPERTIES BUILD_TARGET "cross_target1")

after that we know that `magic` is to be built both for "host" and
"cross_target1" whereas
`foo` is only for "cross_target1".

before that we may have to "declaratively" define what is cross_target1
(and may be cross_target2) with something like:

enable_cross_target(NAME cross_target1 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target1-toolchain.cmake)
enable_cross_target(NAME cross_target2 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target2-toolchain.cmake)
and assume "host" builtin target is the one coming from the command line.

each define_cross_target(..) will create a separate subdir in the build
tree (much like CMAKE_CFG_INTDIR is working for multi-config generators)
may something like ${CMAKE_CURRENT_BINARY_DIR}/${CROSS_TARGET_NAME} if we
assume cross target name are unique.

all cmake command (install, add_executable, add_library, etc...) shall know
that a target is to be build for the host and/or cross target1
and/or cross target2 etc...

add_custom_command COMMAND argument refering to a built target
always refer to "host target" because there is usually no need (or mean) to
execute cross target during the build anyway.

in the end you will have a project which specify all the target (exe, lib,
custom) the usual declarative "modern CMake" way
and you won't have your CMakeLists.txt filled with

IF(CMAKE_CROSSCOMPILING)

IF(NOT CMAKE_HOST_BUILD)

controls.

if you need cross_target specific CMAKE_XXXX variables, they should either
go in the target toolchain file
or should be put in with
cross_target_set(cross_target1 VARIABLE CMAKE_INSTALL_PREFIX "/opt/target1")

You may even decide that if a "build target" is not enabled because you
have something like:

if (CROSS_BUILD_TARGET1)
enable_cross_target(NAME cross_target1 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target1-toolchain.cmake)
endif()

if (CROSS_BUILD_TARGET2)
enable_cross_target(NAME cross_target2 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target2-toolchain.cmake)
endif()

The build could succeed and emit some warning telling that some "cross
target" were not built.
Post by Rolf Eike Beer
/tmp/install/prefix/tools/bin/magic.exe # Windows host
/tmp/install/prefix/sysroot/usr/bin/magic # Unix guest
/tmp/install/prefix/sysroot/usr/bin/foo
set(CMAKE_HOST_PREFIX prefix
set(CMAKE_SYSROOT ${CMAKE_HOST_PREFIX}/sysroot)
cmake -D CMAKE_TOOLCHAIN_FILE=tc.cmake -D CMAKE_INSTALL_PREFIX=/usr -D
CMAKE_HOST_INSTALL_PREFIX=tools ...
I think that most of the time specifying the toolchain on the command line
drives you to some superbuild structure.
Post by Rolf Eike Beer
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 ;)
I wish an integrated multi-target cross building support in CMake with
little or no flow-control scripting command in the CMakeLists.txt.
--
Eric
Rolf Eike Beer
2018-11-28 20:02:52 UTC
Permalink
Post by Eric Noulard
Post by Rolf Eike Beer
Hi,
I hope this question was not asked before. I work in the embedded
field and there it is usually to have at least two different build
platforms. The Host platform, where unit tests are build (and where
CMake is running) and an embedded Target platform, where targets are
build with a cross compiler. Sometimes such a system comes with
self-written tools that are build and run on the Host platform to
build a target for the embedded Target platform (adding meta data to a
binary to be used by a bootloader for example).
Usually I have two different build folders, one for the Host platform
and one for the Target platform, using different calls to cmake to
choose from a set of tools and targets. But when using this approach,
it is necessary that the Host platform build ran before the Target
platform build, so that tools that are required for the Target
platform are build during the Host target build.
One solution I’ve came up with, is to build the required tools during
the Target platform build, using an add_custom_target() to invoke the
Target compiler directly. This works fine, as long as the tools are
basically build just out of a couple of files.
What would be the „CMake-Way“ to add the tools (that have to be build
on the Target platform) as dependency to targets that have to be build
for the Target (cross compile) platform?
TL;DR: there is not "good" way yet. But there should be one.
I do agree with that quote I was quite surprised (a long time ago) that
CMake did not support cross-compiling.
Back then I was using recursive hand-written makefiles for cross-compiling.
When I wanted to build
the whole thing I only had to hit "make" and wait.
Moreover I think CMake cross-compiling support was biased by the fact CMake
wasn't designed for that initially.
Please don't take my remark as bare criticism I am using CMake for a long
time now, I do like CMake very much
and I was pleased to see the cross-compiling support coming.
However from my point of view and my cross-compiling experience when you
1) the host compiler which is used to compile "host tools"
2) the target compiler (may be several of them) to "cross-compile"
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.
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.
And you want to build all that stuff with a single configure+build command
AND take advantage
of fast and efficient parallel build for the **whole build**. I don't want
to
cd /build/for/host
ninja
cd /build/for/target1
ninja
etc...
Post by Rolf Eike Beer
Helpful would be a special
variable for CMAKE_INSTALL_PREFIX as this needs a bit of attention (and
a non-sysroot thing prefix in the toolchain file). Confused? Granted,
if (CMAKE_CROSSCOMPILING)
set(HOST_INSTALL_DIR "/some/where")
add_host_build(. host HOST_INSTALL_DIR)
endif ()
add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin) # installs both the host and the
target tool!
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND
magic) # will call the host build
if (NOT CMAKE_HOST_BUILD)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)
endif ()
I get your point but I think we may try a more declarative way.
add_executable(magic magic.cpp)
install(TARGETS magic DESTINATION bin)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp COMMAND magic)
add_executable(foo ${CMAKE_CURRENT_BUILD_DIR}/foo.cpp)
install(TARGETS foo DESTINATION bin)
set_target_properties(magic PROPERTIES BUILD_TARGET "host;cross_target1")
set_target_properties(foo PROPERTIES BUILD_TARGET "cross_target1")
That makes sense in general. We would need generator expressions for those to
be able to e.g. selectively include sources into one or the other build.
Post by Eric Noulard
after that we know that `magic` is to be built both for "host" and
"cross_target1" whereas
`foo` is only for "cross_target1".
before that we may have to "declaratively" define what is cross_target1
enable_cross_target(NAME cross_target1 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target1-toolchain.cmake)
enable_cross_target(NAME cross_target2 TOOLCHAIN ${CMAKE_CURRENT_SOURCE
_DIR}/cmake/target2-toolchain.cmake)
and assume "host" builtin target is the one coming from the command line.
each define_cross_target(..) will create a separate subdir in the build
tree (much like CMAKE_CFG_INTDIR is working for multi-config generators)
may something like ${CMAKE_CURRENT_BINARY_DIR}/${CROSS_TARGET_NAME} if we
assume cross target name are unique.
That would mean we would need something like "-D
CMAKE_TOOLCHAIN_FILES=foo.cmake,bar.cmake" to pass multiple of them. In
general you invert what I have said, having the host directory on the outside.
That makes sense if you have multiple cross-targets in the same build tree.

But: I'm not sure I'm into this. It may make sense for some projects, but less
for others, e.g. if the generators are target-specific. How do I tell CMake
that this is not possible? I would go for the simple way and say: host tools
are build with the target tools. If you have multiple targets, then you have
multiple build dirs, the host tools are build multiple times.
Post by Eric Noulard
all cmake command (install, add_executable, add_library, etc...) shall know
that a target is to be build for the host and/or cross target1
and/or cross target2 etc...
add_custom_command COMMAND argument refering to a built target
always refer to "host target" because there is usually no need (or mean) to
execute cross target during the build anyway.
Yes.
Post by Eric Noulard
in the end you will have a project which specify all the target (exe, lib,
custom) the usual declarative "modern CMake" way
and you won't have your CMakeLists.txt filled with
IF(CMAKE_CROSSCOMPILING)
IF(NOT CMAKE_HOST_BUILD)
controls.
We will need some of those at the end anyway. Let's stay with Qt: they need a
host libpng to build some whatever helpers for QtWebEngine, as well as a
target one. Both of course need to be kept separated, and one may acually
decide to search for host dependencies with less flags, other versions or
whatever.
Post by Eric Noulard
if you need cross_target specific CMAKE_XXXX variables, they should either
go in the target toolchain file
or should be put in with
cross_target_set(cross_target1 VARIABLE CMAKE_INSTALL_PREFIX "/opt/target1")
You may even decide that if a "build target" is not enabled because you
And here things are getting messy. If we stick with one-target-per-builddir as
we already do for say 32 and 64 bit now the code will get cleaner.
Post by Eric Noulard
I think that most of the time specifying the toolchain on the command line
drives you to some superbuild structure.
Which is not bad by itself, but I would like to see that CMake can provide
things that avoid people reinventing the boilerplate code, and probably
getting them wrong at least 80% of the time. Like they would do with
dependencies and other things if they would write their Makefiles by hand
instead of using CMake, just one level higher.
Post by Eric Noulard
Post by Rolf Eike Beer
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 ;)
I wish an integrated multi-target cross building support in CMake with
little or no flow-control scripting command in the CMakeLists.txt.
That would mean introducing HOST and TARGET flags to every find_* call, I'm
not sure if that is cleaner than explicit if()'s. But I'm not fundamentally
opposed to it, I'm just not sure it's worth the effort.

Eike
Torsten Robitzki
2018-12-04 07:56:07 UTC
Permalink
Post by Eric Noulard
1) the host compiler which is used to compile "host tools"
2) the target compiler (may be several of them) to "cross-compile"
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.
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.

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).
Post by Eric Noulard
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? :-)

best regards,
Torsten

Loading...