Am Dienstag, 27. November 2018, 19:55:56 CET schrieb Eric Noulard: > Le mar. 27 nov. 2018 à 11:28, Rolf Eike Beer <e...@sf-mail.de> a écrit : > > Am 2018-11-09 10:04, schrieb Torsten Robitzki: > > > 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... > > > 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 () > > 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. > 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. 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. > 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. > 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. > 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: 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. > 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. > > 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
signature.asc
Description: This is a digitally signed message part.
-- 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