Re: [cmake-developers] [CMake] dependencies of cross compiliations
Le mar. 27 nov. 2018 à 11:28, Rolf Eike Beer 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") 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
Re: [cmake-developers] [CMake] building host tools during cross compiliations (was: dependencies of cross compiliations)
On 11/27/18 5:28 AM, Rolf Eike Beer wrote: > 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. [snip] > 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
Re: [cmake-developers] [CMake] dependencies of cross compiliations
> 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. On Tue, Nov 27, 2018, 10:28 AM Rolf Eike Beer 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'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
Re: [cmake-developers] [CMake] dependencies of cross compiliations
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'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