[CMake] [HOWTO] Easily Cross-Compile CMake (with xstatic)
Rolf Eike Beer
eike at sf-mail.de
Fri Oct 26 15:48:21 EDT 2018
Zach van Rijn wrote:
> 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"
> ...
That's exactly what I meant with:
> > Well, it did not, but that was just because the embedded curl tries to do
> > some try_run() things that do not work. Since I already have a cross-curl
> > library at hand I decided to just use that, and things worked.
> 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:
> ...
You can instead just pass the expected codes, you just have to pass them as
cache variables using "-C cache_file".
> # 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
You need to pass things like CMAKE_SYSTEM_NAME in the toolchain file in order
to get the cross-build mode properly initialized, passing them on the
commandline is not enough.
> 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:
No, you start in a clean build directory and pass the initial CMake invocation
the toolchain file with -D CMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake. CMake
will then know only this compiler, and will find the other programs using the
same triplet. Have one build dir per target, and one toolchain file per
target. Maybe it's only one toolchain file that you need, when they differ
only in the target triplet, which can then be placed e.g. in an environment
variable before the first build.
> 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)
You do, bootstrapping builds a CMake binary. Not a full-featured one, but
still. And you can reuse them for every target.
> (2) Avoid breakage between CMake versions, if new tests are
> are added, as script automation would become difficult
These should not differ between patch releases, and the differences between
minor versions should also be pretty minimal.
> (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.
"-C"
Eike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part.
URL: <https://cmake.org/pipermail/cmake/attachments/20181026/c8deb058/attachment.sig>
More information about the CMake
mailing list