On Fri, 2018-10-26 at 11:09 +0200, Rolf Eike Beer wrote: > ... Hi Eike,
Thank you for writing. I agree that my approach is a bit brutish and aim to revise/reduce it to a minimum example. My goal was to describe a process that is uniform between compilers, easily automated, and less likely to break between CMake releases. > So, the 2 things that I do not understand why you need them at > all: > > -why do the bootstrap thing and move compilers? Just build a > recent CMake with your host toolchain, package that, and drop > it into the build container. The need for the host compiler > should be gone at this point While it would make sense to build a complete (sufficiently- recent) CMake that performs the final build, I have not had consistent success (using the same exact compilers and systems) in doing so. For example, even specifying all of the settings as in your 'toolchain.cmake' file (below in this email), omitting the 'CMAKE_SYSTEM_NAME=Linux' part: ... cmake-3.12.3/Utilities/cmcurl/lib/strerror.c:32:6: error: #error "strerror_r MUST be either POSIX, glibc or vxworks-style" ... and the build fatally aborts. If we add this back, ... CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: ... which means, potentially, that each future release of CMake may require updates to the script. I'm not sure if there's a way to cache all of these variables at once? CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: KWSYS_LFS_WORKS (advanced) KWSYS_LFS_WORKS__TRYRUN_OUTPUT (advanced) CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: HAVE_FSETXATTR_5 (advanced) HAVE_FSETXATTR_5__TRYRUN_OUTPUT (advanced) CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: HAVE_GLIBC_STRERROR_R (advanced) HAVE_GLIBC_STRERROR_R__TRYRUN_OUTPUT (advanced) CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: HAVE_POSIX_STRERROR_R (advanced) HAVE_POSIX_STRERROR_R__TRYRUN_OUTPUT (advanced) CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately: HAVE_POLL_FINE_EXITCODE (advanced) HAVE_POLL_FINE_EXITCODE__TRYRUN_OUTPUT (advanced) So it is certainly possible to do this... assuming you are able to obtain a recent copy of CMake for your build platform: # In an empty 'build/' directory in the root of CMake source: $ cmake .. \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_C_COMPILER=/bin/gcc `# cross` \ -DCMAKE_C_FLAGS="-static --static -g0 -s -Os" \ -DCMAKE_CXX_COMPILER=/bin/g++ `# cross` \ -DCMAKE_CXX_FLAGS="-static --static -g0 -s -Os" \ -DCMAKE_FIND_ROOT_PATH=/armv7l-linux-musleabihf `# cross` \ -DCMAKE_SYSROOT=/armv7l-linux-musleabihf `# cross` \ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \ -DKWSYS_LFS_WORKS=ON \ -DKWSYS_LFS_WORKS__TRYRUN_OUTPUT="" \ -DHAVE_FSETXATTR_5=ON \ -DHAVE_FSETXATTR_5__TRYRUN_OUTPUT="" \ -DHAVE_GLIBC_STRERROR_R=OFF `# because musl` \ -DHAVE_GLIBC_STRERROR_R__TRYRUN_OUTPUT="" \ -DHAVE_POSIX_STRERROR_R=ON `# because musl` \ -DHAVE_POSIX_STRERROR_R__TRYRUN_OUTPUT="" \ -DHAVE_POLL_FINE_EXITCODE=ON \ -DHAVE_POLL_FINE_EXITCODE__TRYRUN_OUTPUT="" ... CMake Warning: Manually-specified variables were not used by the project: KWSYS_LFS_WORKS__TRYRUN_OUTPUT ... $ make -j$(nproc) $ make install $ file /usr/local/bin * cmake: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped cpack: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped ctest: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, stripped > > -why do you need to overwrite the compiler with the target > compiler? Just drop it anywhere and tell CMake with CC and CXX > variables where it is. Or better, pass it a toolchain file > like mine: Specifically because it would either require defining all of the above variables, including toolchain path(s), or running some sort of script or command like 'sed' to attempt to replace all hard-coded occurrences of the original toolchain. You can see that there are many: $ cd ~/cmake-3.12.3/build $ grep -r "/bin/g++" . | wc -l 1247 (This 'grep' command actually takes longer than building CMake!) This would be further complicated by having to escape toolchain paths if they are not in similar locations, and could be messy. > > === toolchain.cmake === > set(CMAKE_SYSTEM_NAME Linux) > set(CMAKE_SYSTEM_PROCESSOR arm) > > # specify the cross compiler > set(CMAKE_C_COMPILER /opt/emlix/test/bin/arm-unknown-linux- > gnueabi-gcc) > set(CMAKE_CXX_COMPILER > /opt/emlix/test/bin/arm-unknown-linux-gnueabi-g++) > > # where is the target environment > set(CMAKE_FIND_ROOT_PATH /opt/emlix/test/sysroot) > set(CMAKE_SYSROOT /opt/emlix/test/sysroot) > > # search for programs in the build host directories > set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) > # for libraries and headers in the target directories > set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) > set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) > set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) > === > > I'm pretty sure you may find some rough edges, especially if > you do not want to have the dependencies pre-build but use the > embedded copies and do static builds with them. But otherwise > you should hopefully be able to simplify your setup a lot. Once all this is done, how can this be easily automated? Pasting in the appropriate 'CMAKE_SYSTEM_NAME' (and others) via some script? Is it possible to determine the 'HAVE_' and '_WORKS' variables ahead of time (which ones are actually need TRY_RUN)? In summary, while I agree my original method could be simplified, I propose it for the following reasons: (1) Avoid building two full CMake binaries (one for build system and one for target host system) (2) Avoid breakage between CMake versions, if new tests are are added, as script automation would become difficult (3) As an alternative to the "standard" approach which you mention, as some users may have difficulty in determining exactly how to populate these variables. > Eike > -- The approach outlined in this email (based off of yours) might work for Windows (MinGW) builds. I will try it for the remaining architectures which did not work with the original approach. ZV -- 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