Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 1 | From 5641452a24f76c5dafa3749a542fcac93f77390f Mon Sep 17 00:00:00 2001 |
| 2 | From: Khem Raj <raj.khem@gmail.com> |
| 3 | Date: Wed, 18 Mar 2015 00:42:58 +0000 |
| 4 | Subject: [PATCH] eglibc: Cross building and testing instructions |
| 5 | |
| 6 | Ported from eglibc |
| 7 | Upstream-Status: Pending |
| 8 | |
| 9 | Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| 10 | --- |
| 11 | GLIBC.cross-building | 383 +++++++++++++++++++++++++++++++++++++++++++ |
| 12 | GLIBC.cross-testing | 205 +++++++++++++++++++++++ |
| 13 | 2 files changed, 588 insertions(+) |
| 14 | create mode 100644 GLIBC.cross-building |
| 15 | create mode 100644 GLIBC.cross-testing |
| 16 | |
| 17 | diff --git a/GLIBC.cross-building b/GLIBC.cross-building |
| 18 | new file mode 100644 |
| 19 | index 0000000000..e6e0da1aaf |
| 20 | --- /dev/null |
| 21 | +++ b/GLIBC.cross-building |
| 22 | @@ -0,0 +1,383 @@ |
| 23 | + -*- mode: text -*- |
| 24 | + |
| 25 | + Cross-Compiling GLIBC |
| 26 | + Jim Blandy <jimb@codesourcery.com> |
| 27 | + |
| 28 | + |
| 29 | +Introduction |
| 30 | + |
| 31 | +Most GNU tools have a simple build procedure: you run their |
| 32 | +'configure' script, and then you run 'make'. Unfortunately, the |
| 33 | +process of cross-compiling the GNU C library is quite a bit more |
| 34 | +involved: |
| 35 | + |
| 36 | +1) Build a cross-compiler, with certain facilities disabled. |
| 37 | + |
| 38 | +2) Configure the C library using the compiler you built in step 1). |
| 39 | + Build a few of the C run-time object files, but not the rest of the |
| 40 | + library. Install the library's header files and the run-time |
| 41 | + object files, and create a dummy libc.so. |
| 42 | + |
| 43 | +3) Build a second cross-compiler, using the header files and object |
| 44 | + files you installed in step 2. |
| 45 | + |
| 46 | +4) Configure, build, and install a fresh C library, using the compiler |
| 47 | + built in step 3. |
| 48 | + |
| 49 | +5) Build a third cross-compiler, based on the C library built in step 4. |
| 50 | + |
| 51 | +The reason for this complexity is that, although GCC and the GNU C |
| 52 | +library are distributed separately, they are not actually independent |
| 53 | +of each other: GCC requires the C library's headers and some object |
| 54 | +files to compile its own libraries, while the C library depends on |
| 55 | +GCC's libraries. GLIBC includes features and bug fixes to the stock |
| 56 | +GNU C library that simplify this process, but the fundamental |
| 57 | +interdependency stands. |
| 58 | + |
| 59 | +In this document, we explain how to cross-compile an GLIBC/GCC pair |
| 60 | +from source. Our intended audience is developers who are already |
| 61 | +familiar with the GNU toolchain and comfortable working with |
| 62 | +cross-development tools. While we do present a worked example to |
| 63 | +accompany the explanation, for clarity's sake we do not cover many of |
| 64 | +the options available to cross-toolchain users. |
| 65 | + |
| 66 | + |
| 67 | +Preparation |
| 68 | + |
| 69 | +GLIBC requires recent versions of the GNU binutils, GCC, and the |
| 70 | +Linux kernel. The web page <http://www.eglibc.org/prerequisites> |
| 71 | +documents the current requirements, and lists patches needed for |
| 72 | +certain target architectures. As of this writing, these build |
| 73 | +instructions have been tested with binutils 2.22.51, GCC 4.6.2, |
| 74 | +and Linux 3.1. |
| 75 | + |
| 76 | +First, let's set some variables, to simplify later commands. We'll |
| 77 | +build GLIBC and GCC for an ARM target, known to the Linux kernel |
| 78 | +as 'arm', and we'll do the build on an Intel x86_64 Linux box: |
| 79 | + |
| 80 | + $ build=x86_64-pc-linux-gnu |
| 81 | + $ host=$build |
| 82 | + $ target=arm-none-linux-gnueabi |
| 83 | + $ linux_arch=arm |
| 84 | + |
| 85 | +We're using the aforementioned versions of Binutils, GCC, and Linux: |
| 86 | + |
| 87 | + $ binutilsv=binutils-2.22.51 |
| 88 | + $ gccv=gcc-4.6.2 |
| 89 | + $ linuxv=linux-3.1 |
| 90 | + |
| 91 | +We're carrying out the entire process under '~/cross-build', which |
| 92 | +contains unpacked source trees for binutils, gcc, and linux kernel, |
| 93 | +along with GLIBC svn trunk (which can be checked-out with |
| 94 | +'svn co http://www.eglibc.org/svn/trunk eglibc'): |
| 95 | + |
| 96 | + $ top=$HOME/cross-build/$target |
| 97 | + $ src=$HOME/cross-build/src |
| 98 | + $ ls $src |
| 99 | + binutils-2.22.51 glibc gcc-4.6.2 linux-3.1 |
| 100 | + |
| 101 | +We're going to place our build directories in a subdirectory 'obj', |
| 102 | +we'll install the cross-development toolchain in 'tools', and we'll |
| 103 | +place our sysroot (containing files to be installed on the target |
| 104 | +system) in 'sysroot': |
| 105 | + |
| 106 | + $ obj=$top/obj |
| 107 | + $ tools=$top/tools |
| 108 | + $ sysroot=$top/sysroot |
| 109 | + |
| 110 | + |
| 111 | +Binutils |
| 112 | + |
| 113 | +Configuring and building binutils for the target is straightforward: |
| 114 | + |
| 115 | + $ mkdir -p $obj/binutils |
| 116 | + $ cd $obj/binutils |
| 117 | + $ $src/$binutilsv/configure \ |
| 118 | + > --target=$target \ |
| 119 | + > --prefix=$tools \ |
| 120 | + > --with-sysroot=$sysroot |
| 121 | + $ make |
| 122 | + $ make install |
| 123 | + |
| 124 | + |
| 125 | +The First GCC |
| 126 | + |
| 127 | +For our work, we need a cross-compiler targeting an ARM Linux |
| 128 | +system. However, that configuration includes the shared library |
| 129 | +'libgcc_s.so', which is compiled against the GLIBC headers (which we |
| 130 | +haven't installed yet) and linked against 'libc.so' (which we haven't |
| 131 | +built yet). |
| 132 | + |
| 133 | +Fortunately, there are configuration options for GCC which tell it not |
| 134 | +to build 'libgcc_s.so'. The '--without-headers' option is supposed to |
| 135 | +take care of this, but its implementation is incomplete, so you must |
| 136 | +also configure with the '--with-newlib' option. While '--with-newlib' |
| 137 | +appears to mean "Use the Newlib C library", its effect is to tell the |
| 138 | +GCC build machinery, "Don't assume there is a C library available." |
| 139 | + |
| 140 | +We also need to disable some of the libraries that would normally be |
| 141 | +built along with GCC, and specify that only the compiler for the C |
| 142 | +language is needed. |
| 143 | + |
| 144 | +So, we create a build directory, configure, make, and install. |
| 145 | + |
| 146 | + $ mkdir -p $obj/gcc1 |
| 147 | + $ cd $obj/gcc1 |
| 148 | + $ $src/$gccv/configure \ |
| 149 | + > --target=$target \ |
| 150 | + > --prefix=$tools \ |
| 151 | + > --without-headers --with-newlib \ |
| 152 | + > --disable-shared --disable-threads --disable-libssp \ |
| 153 | + > --disable-libgomp --disable-libmudflap --disable-libquadmath \ |
| 154 | + > --disable-decimal-float --disable-libffi \ |
| 155 | + > --enable-languages=c |
| 156 | + $ PATH=$tools/bin:$PATH make |
| 157 | + $ PATH=$tools/bin:$PATH make install |
| 158 | + |
| 159 | + |
| 160 | +Linux Kernel Headers |
| 161 | + |
| 162 | +To configure GLIBC, we also need Linux kernel headers in place. |
| 163 | +Fortunately, the Linux makefiles have a target that installs them for |
| 164 | +us. Since the process does modify the source tree a bit, we make a |
| 165 | +copy first: |
| 166 | + |
| 167 | + $ cp -r $src/$linuxv $obj/linux |
| 168 | + $ cd $obj/linux |
| 169 | + |
| 170 | +Now we're ready to install the headers into the sysroot: |
| 171 | + |
| 172 | + $ PATH=$tools/bin:$PATH \ |
| 173 | + > make headers_install \ |
| 174 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ |
| 175 | + > INSTALL_HDR_PATH=$sysroot/usr |
| 176 | + |
| 177 | + |
| 178 | +GLIBC Headers and Preliminary Objects |
| 179 | + |
| 180 | +Using the cross-compiler we've just built, we can now configure GLIBC |
| 181 | +well enough to install the headers and build the object files that the |
| 182 | +full cross-compiler will need: |
| 183 | + |
| 184 | + $ mkdir -p $obj/glibc-headers |
| 185 | + $ cd $obj/glibc-headers |
| 186 | + $ BUILD_CC=gcc \ |
| 187 | + > CC=$tools/bin/$target-gcc \ |
| 188 | + > CXX=$tools/bin/$target-g++ \ |
| 189 | + > AR=$tools/bin/$target-ar \ |
| 190 | + > RANLIB=$tools/bin/$target-ranlib \ |
| 191 | + > $src/glibc/libc/configure \ |
| 192 | + > --prefix=/usr \ |
| 193 | + > --with-headers=$sysroot/usr/include \ |
| 194 | + > --build=$build \ |
| 195 | + > --host=$target \ |
| 196 | + > --disable-profile --without-gd --without-cvs \ |
| 197 | + > --enable-add-ons=nptl,libidn,../ports |
| 198 | + |
| 199 | +The option '--prefix=/usr' may look strange, but you should never |
| 200 | +configure GLIBC with a prefix other than '/usr': in various places, |
| 201 | +GLIBC's build system checks whether the prefix is '/usr', and does |
| 202 | +special handling only if that is the case. Unless you use this |
| 203 | +prefix, you will get a sysroot that does not use the standard Linux |
| 204 | +directory layouts and cannot be used as a basis for the root |
| 205 | +filesystem on your target system compatibly with normal GLIBC |
| 206 | +installations. |
| 207 | + |
| 208 | +The '--with-headers' option tells GLIBC where the Linux headers have |
| 209 | +been installed. |
| 210 | + |
| 211 | +The '--enable-add-ons=nptl,libidn,../ports' option tells GLIBC to look |
| 212 | +for the listed glibc add-ons. Most notably the ports add-on (located |
| 213 | +just above the libc sources in the GLIBC svn tree) is required to |
| 214 | +support ARM targets. |
| 215 | + |
| 216 | +We can now use the 'install-headers' makefile target to install the |
| 217 | +headers: |
| 218 | + |
| 219 | + $ make install-headers install_root=$sysroot \ |
| 220 | + > install-bootstrap-headers=yes |
| 221 | + |
| 222 | +The 'install_root' variable indicates where the files should actually |
| 223 | +be installed; its value is treated as the parent of the '--prefix' |
| 224 | +directory we passed to the configure script, so the headers will go in |
| 225 | +'$sysroot/usr/include'. The 'install-bootstrap-headers' variable |
| 226 | +requests special handling for certain tricky header files. |
| 227 | + |
| 228 | +Next, there are a few object files needed to link shared libraries, |
| 229 | +which we build and install by hand: |
| 230 | + |
| 231 | + $ mkdir -p $sysroot/usr/lib |
| 232 | + $ make csu/subdir_lib |
| 233 | + $ cp csu/crt1.o csu/crti.o csu/crtn.o $sysroot/usr/lib |
| 234 | + |
| 235 | +Finally, 'libgcc_s.so' requires a 'libc.so' to link against. However, |
| 236 | +since we will never actually execute its code, it doesn't matter what |
| 237 | +it contains. So, treating '/dev/null' as a C source file, we produce |
| 238 | +a dummy 'libc.so' in one step: |
| 239 | + |
| 240 | + $ $tools/bin/$target-gcc -nostdlib -nostartfiles -shared -x c /dev/null \ |
| 241 | + > -o $sysroot/usr/lib/libc.so |
| 242 | + |
| 243 | + |
| 244 | +The Second GCC |
| 245 | + |
| 246 | +With the GLIBC headers and selected object files installed, we can |
| 247 | +now build a GCC that is capable of compiling GLIBC. We configure, |
| 248 | +build, and install the second GCC, again building only the C compiler, |
| 249 | +and avoiding libraries we won't use: |
| 250 | + |
| 251 | + $ mkdir -p $obj/gcc2 |
| 252 | + $ cd $obj/gcc2 |
| 253 | + $ $src/$gccv/configure \ |
| 254 | + > --target=$target \ |
| 255 | + > --prefix=$tools \ |
| 256 | + > --with-sysroot=$sysroot \ |
| 257 | + > --disable-libssp --disable-libgomp --disable-libmudflap \ |
| 258 | + > --disable-libffi --disable-libquadmath \ |
| 259 | + > --enable-languages=c |
| 260 | + $ PATH=$tools/bin:$PATH make |
| 261 | + $ PATH=$tools/bin:$PATH make install |
| 262 | + |
| 263 | + |
| 264 | +GLIBC, Complete |
| 265 | + |
| 266 | +With the second compiler built and installed, we're now ready for the |
| 267 | +full GLIBC build: |
| 268 | + |
| 269 | + $ mkdir -p $obj/glibc |
| 270 | + $ cd $obj/glibc |
| 271 | + $ BUILD_CC=gcc \ |
| 272 | + > CC=$tools/bin/$target-gcc \ |
| 273 | + > CXX=$tools/bin/$target-g++ \ |
| 274 | + > AR=$tools/bin/$target-ar \ |
| 275 | + > RANLIB=$tools/bin/$target-ranlib \ |
| 276 | + > $src/glibc/libc/configure \ |
| 277 | + > --prefix=/usr \ |
| 278 | + > --with-headers=$sysroot/usr/include \ |
| 279 | + > --with-kconfig=$obj/linux/scripts/kconfig \ |
| 280 | + > --build=$build \ |
| 281 | + > --host=$target \ |
| 282 | + > --disable-profile --without-gd --without-cvs \ |
| 283 | + > --enable-add-ons=nptl,libidn,../ports |
| 284 | + |
| 285 | +Note the additional '--with-kconfig' option. This tells GLIBC where to |
| 286 | +find the host config tools used by the kernel 'make config' and 'make |
| 287 | +menuconfig'. These tools can be re-used by GLIBC for its own 'make |
| 288 | +*config' support, which will create 'option-groups.config' for you. |
| 289 | +But first make sure those tools have been built by running some |
| 290 | +dummy 'make *config' calls in the kernel directory: |
| 291 | + |
| 292 | + $ cd $obj/linux |
| 293 | + $ PATH=$tools/bin:$PATH make config \ |
| 294 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ |
| 295 | + $ PATH=$tools/bin:$PATH make menuconfig \ |
| 296 | + > ARCH=$linux_arch CROSS_COMPILE=$target- \ |
| 297 | + |
| 298 | +Now we can configure and build the full GLIBC: |
| 299 | + |
| 300 | + $ cd $obj/glibc |
| 301 | + $ PATH=$tools/bin:$PATH make defconfig |
| 302 | + $ PATH=$tools/bin:$PATH make menuconfig |
| 303 | + $ PATH=$tools/bin:$PATH make |
| 304 | + $ PATH=$tools/bin:$PATH make install install_root=$sysroot |
| 305 | + |
| 306 | +At this point, we have a complete GLIBC installation in '$sysroot', |
| 307 | +with header files, library files, and most of the C runtime startup |
| 308 | +files in place. |
| 309 | + |
| 310 | + |
| 311 | +The Third GCC |
| 312 | + |
| 313 | +Finally, we recompile GCC against this full installation, enabling |
| 314 | +whatever languages and libraries we would like to use: |
| 315 | + |
| 316 | + $ mkdir -p $obj/gcc3 |
| 317 | + $ cd $obj/gcc3 |
| 318 | + $ $src/$gccv/configure \ |
| 319 | + > --target=$target \ |
| 320 | + > --prefix=$tools \ |
| 321 | + > --with-sysroot=$sysroot \ |
| 322 | + > --enable-__cxa_atexit \ |
| 323 | + > --disable-libssp --disable-libgomp --disable-libmudflap \ |
| 324 | + > --enable-languages=c,c++ |
| 325 | + $ PATH=$tools/bin:$PATH make |
| 326 | + $ PATH=$tools/bin:$PATH make install |
| 327 | + |
| 328 | +The '--enable-__cxa_atexit' option tells GCC what sort of C++ |
| 329 | +destructor support to expect from the C library; it's required with |
| 330 | +GLIBC. |
| 331 | + |
| 332 | +And since GCC's installation process isn't designed to help construct |
| 333 | +sysroot trees, we must manually copy certain libraries into place in |
| 334 | +the sysroot. |
| 335 | + |
| 336 | + $ cp -d $tools/$target/lib/libgcc_s.so* $sysroot/lib |
| 337 | + $ cp -d $tools/$target/lib/libstdc++.so* $sysroot/usr/lib |
| 338 | + |
| 339 | + |
| 340 | +Trying Things Out |
| 341 | + |
| 342 | +At this point, '$tools' contains a cross toolchain ready to use |
| 343 | +the GLIBC installation in '$sysroot': |
| 344 | + |
| 345 | + $ cat > hello.c <<EOF |
| 346 | + > #include <stdio.h> |
| 347 | + > int |
| 348 | + > main (int argc, char **argv) |
| 349 | + > { |
| 350 | + > puts ("Hello, world!"); |
| 351 | + > return 0; |
| 352 | + > } |
| 353 | + > EOF |
| 354 | + $ $tools/bin/$target-gcc -Wall hello.c -o hello |
| 355 | + $ cat > c++-hello.cc <<EOF |
| 356 | + > #include <iostream> |
| 357 | + > int |
| 358 | + > main (int argc, char **argv) |
| 359 | + > { |
| 360 | + > std::cout << "Hello, C++ world!" << std::endl; |
| 361 | + > return 0; |
| 362 | + > } |
| 363 | + > EOF |
| 364 | + $ $tools/bin/$target-g++ -Wall c++-hello.cc -o c++-hello |
| 365 | + |
| 366 | + |
| 367 | +We can use 'readelf' to verify that these are indeed executables for |
| 368 | +our target, using our dynamic linker: |
| 369 | + |
| 370 | + $ $tools/bin/$target-readelf -hl hello |
| 371 | + ELF Header: |
| 372 | + ... |
| 373 | + Type: EXEC (Executable file) |
| 374 | + Machine: ARM |
| 375 | + |
| 376 | + ... |
| 377 | + Program Headers: |
| 378 | + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align |
| 379 | + PHDR 0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4 |
| 380 | + INTERP 0x000134 0x00008134 0x00008134 0x00013 0x00013 R 0x1 |
| 381 | + [Requesting program interpreter: /lib/ld-linux.so.3] |
| 382 | + LOAD 0x000000 0x00008000 0x00008000 0x0042c 0x0042c R E 0x8000 |
| 383 | + ... |
| 384 | + |
| 385 | +Looking at the dynamic section of the installed 'libgcc_s.so', we see |
| 386 | +that the 'NEEDED' entry for the C library does include the '.6' |
| 387 | +suffix, indicating that was linked against our fully build GLIBC, and |
| 388 | +not our dummy 'libc.so': |
| 389 | + |
| 390 | + $ $tools/bin/$target-readelf -d $sysroot/lib/libgcc_s.so.1 |
| 391 | + Dynamic section at offset 0x1083c contains 24 entries: |
| 392 | + Tag Type Name/Value |
| 393 | + 0x00000001 (NEEDED) Shared library: [libc.so.6] |
| 394 | + 0x0000000e (SONAME) Library soname: [libgcc_s.so.1] |
| 395 | + ... |
| 396 | + |
| 397 | + |
| 398 | +And on the target machine, we can run our programs: |
| 399 | + |
| 400 | + $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \ |
| 401 | + > ./hello |
| 402 | + Hello, world! |
| 403 | + $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \ |
| 404 | + > ./c++-hello |
| 405 | + Hello, C++ world! |
| 406 | diff --git a/GLIBC.cross-testing b/GLIBC.cross-testing |
| 407 | new file mode 100644 |
| 408 | index 0000000000..b67b468466 |
| 409 | --- /dev/null |
| 410 | +++ b/GLIBC.cross-testing |
| 411 | @@ -0,0 +1,205 @@ |
| 412 | + -*- mode: text -*- |
| 413 | + |
| 414 | + Cross-Testing With GLIBC |
| 415 | + Jim Blandy <jimb@codesourcery.com> |
| 416 | + |
| 417 | + |
| 418 | +Introduction |
| 419 | + |
| 420 | +Developers writing software for embedded systems often use a desktop |
| 421 | +or other similarly capable computer for development, but need to run |
| 422 | +tests on the embedded system, or perhaps on a simulator. When |
| 423 | +configured for cross-compilation, the stock GNU C library simply |
| 424 | +disables running tests altogether: the command 'make tests' builds |
| 425 | +test programs, but does not run them. GLIBC, however, provides |
| 426 | +facilities for compiling tests and generating data files on the build |
| 427 | +system, but running the test programs themselves on a remote system or |
| 428 | +simulator. |
| 429 | + |
| 430 | + |
| 431 | +Test environment requirements |
| 432 | + |
| 433 | +The test environment must meet certain conditions for GLIBC's |
| 434 | +cross-testing facilities to work: |
| 435 | + |
| 436 | +- Shared filesystems. The 'build' system, on which you configure and |
| 437 | + compile GLIBC, and the 'host' system, on which you intend to run |
| 438 | + GLIBC, must share a filesystem containing the GLIBC build and |
| 439 | + source trees. Files must appear at the same paths on both systems. |
| 440 | + |
| 441 | +- Remote-shell like invocation. There must be a way to run a program |
| 442 | + on the host system from the build system, passing it properly quoted |
| 443 | + command-line arguments, setting environment variables, and |
| 444 | + inheriting the caller's standard input and output. |
| 445 | + |
| 446 | + |
| 447 | +Usage |
| 448 | + |
| 449 | +To use GLIBC's cross-testing support, provide values for the |
| 450 | +following Make variables when you invoke 'make': |
| 451 | + |
| 452 | +- cross-test-wrapper |
| 453 | + |
| 454 | + This should be the name of the cross-testing wrapper command, along |
| 455 | + with any arguments. |
| 456 | + |
| 457 | +- cross-localedef |
| 458 | + |
| 459 | + This should be the name of a cross-capable localedef program, like |
| 460 | + that included in the GLIBC 'localedef' module, along with any |
| 461 | + arguments needed. |
| 462 | + |
| 463 | +These are each explained in detail below. |
| 464 | + |
| 465 | + |
| 466 | +The Cross-Testing Wrapper |
| 467 | + |
| 468 | +To run test programs reliably, the stock GNU C library takes care to |
| 469 | +ensure that test programs use the newly compiled dynamic linker and |
| 470 | +shared libraries, and never the host system's installed libraries. To |
| 471 | +accomplish this, it runs the tests by explicitly invoking the dynamic |
| 472 | +linker from the build tree, passing it a list of build tree |
| 473 | +directories to search for shared libraries, followed by the name of |
| 474 | +the executable to run and its arguments. |
| 475 | + |
| 476 | +For example, where one might normally run a test program like this: |
| 477 | + |
| 478 | + $ ./tst-foo arg1 arg2 |
| 479 | + |
| 480 | +the GNU C library might run that program like this: |
| 481 | + |
| 482 | + $ $objdir/elf/ld-linux.so.3 --library-path $objdir \ |
| 483 | + ./tst-foo arg1 arg2 |
| 484 | + |
| 485 | +(where $objdir is the path to the top of the build tree, and the |
| 486 | +trailing backslash indicates a continuation of the command). In other |
| 487 | +words, each test program invocation is 'wrapped up' inside an explicit |
| 488 | +invocation of the dynamic linker, which must itself execute the test |
| 489 | +program, having loaded shared libraries from the appropriate |
| 490 | +directories. |
| 491 | + |
| 492 | +To support cross-testing, GLIBC allows the developer to optionally |
| 493 | +set the 'cross-test-wrapper' Make variable to another wrapper command, |
| 494 | +to which it passes the entire dynamic linker invocation shown above as |
| 495 | +arguments. For example, if the developer supplies a wrapper of |
| 496 | +'my-wrapper hostname', then GLIBC would run the test above as |
| 497 | +follows: |
| 498 | + |
| 499 | + $ my-wrapper hostname \ |
| 500 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ |
| 501 | + ./tst-foo arg1 arg2 |
| 502 | + |
| 503 | +The 'my-wrapper' command is responsible for executing the command |
| 504 | +given on the host system. |
| 505 | + |
| 506 | +Since tests are run in varying directories, the wrapper should either |
| 507 | +be in your command search path, or 'cross-test-wrapper' should give an |
| 508 | +absolute path for the wrapper. |
| 509 | + |
| 510 | +The wrapper must meet several requirements: |
| 511 | + |
| 512 | +- It must preserve the current directory. As explained above, the |
| 513 | + build directory tree must be visible on both the build and host |
| 514 | + systems, at the same path. The test wrapper must ensure that the |
| 515 | + current directory it inherits is also inherited by the dynamic |
| 516 | + linker (and thus the test program itself). |
| 517 | + |
| 518 | +- It must preserve environment variables' values. Many GLIBC tests |
| 519 | + set environment variables for test runs; in native testing, it |
| 520 | + invokes programs like this: |
| 521 | + |
| 522 | + $ GCONV_PATH=$objdir/iconvdata \ |
| 523 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ |
| 524 | + ./tst-foo arg1 arg2 |
| 525 | + |
| 526 | + With the cross-testing wrapper, that invocation becomes: |
| 527 | + |
| 528 | + $ GCONV_PATH=$objdir/iconvdata \ |
| 529 | + my-wrapper hostname \ |
| 530 | + $objdir/elf/ld-linux.so.3 --library-path $objdir \ |
| 531 | + ./tst-foo arg1 arg2 |
| 532 | + |
| 533 | + Here, 'my-wrapper' must ensure that the value it sees for |
| 534 | + 'GCONV_PATH' will be seen by the dynamic linker, and thus 'tst-foo' |
| 535 | + itself. (The wrapper supplied with GLIBC simply preserves the |
| 536 | + values of *all* enviroment variables, with a fixed set of |
| 537 | + exceptions.) |
| 538 | + |
| 539 | + If your wrapper is a shell script, take care to correctly propagate |
| 540 | + environment variables whose values contain spaces and shell |
| 541 | + metacharacters. |
| 542 | + |
| 543 | +- It must pass the command's arguments, unmodified. The arguments |
| 544 | + seen by the test program should be exactly those seen by the wrapper |
| 545 | + (after whatever arguments are given to the wrapper itself). The |
| 546 | + GLIBC test framework performs all needed shell word splitting and |
| 547 | + expansion (wildcard expansion, parameter substitution, and so on) |
| 548 | + before invoking the wrapper; further expansion may break the tests. |
| 549 | + |
| 550 | + |
| 551 | +The 'cross-test-ssh.sh' script |
| 552 | + |
| 553 | +If you want to use 'ssh' (or something sufficiently similar) to run |
| 554 | +test programs on your host system, GLIBC includes a shell script, |
| 555 | +'scripts/cross-test-ssh.sh', which you can use as your wrapper |
| 556 | +command. This script takes care of setting the test command's current |
| 557 | +directory, propagating environment variable values, and carrying |
| 558 | +command-line arguments, all across an 'ssh' connection. You may even |
| 559 | +supply an alternative to 'ssh' on the command line, if needed. |
| 560 | + |
| 561 | +For more details, pass 'cross-test-ssh.sh' the '--help' option. |
| 562 | + |
| 563 | + |
| 564 | +The Cross-Compiling Locale Definition Command |
| 565 | + |
| 566 | +Some GLIBC tests rely on locales generated especially for the test |
| 567 | +process. In a native configuration, these tests simply run the |
| 568 | +'localedef' command built by the normal GLIBC build process, |
| 569 | +'locale/localedef', to process and install their locales. However, in |
| 570 | +a cross-compiling configuration, this 'localedef' is built for the |
| 571 | +host system, not the build system, and since it requires quite a bit |
| 572 | +of memory to run (we have seen it fail on systems with 64MiB of |
| 573 | +memory), it may not be practical to run it on the host system. |
| 574 | + |
| 575 | +If set, GLIBC uses the 'cross-localedef' Make variable as the command |
| 576 | +to run on the build system to process and install locales. The |
| 577 | +localedef program built from the GLIBC 'localedef' module is |
| 578 | +suitable. |
| 579 | + |
| 580 | +The value of 'cross-localedef' may also include command-line arguments |
| 581 | +to be passed to the program; if you are using GLIBC's 'localedef', |
| 582 | +you may include endianness and 'uint32_t' alignment arguments here. |
| 583 | + |
| 584 | + |
| 585 | +Example |
| 586 | + |
| 587 | +In developing GLIBC's cross-testing facility, we invoked 'make' with |
| 588 | +the following script: |
| 589 | + |
| 590 | + #!/bin/sh |
| 591 | + |
| 592 | + srcdir=... |
| 593 | + test_hostname=... |
| 594 | + localedefdir=... |
| 595 | + cross_gxx=...-g++ |
| 596 | + |
| 597 | + wrapper="$srcdir/scripts/cross-test-ssh.sh $test_hostname" |
| 598 | + localedef="$localedefdir/localedef --little-endian --uint32-align=4" |
| 599 | + |
| 600 | + make cross-test-wrapper="$wrapper" \ |
| 601 | + cross-localedef="$localedef" \ |
| 602 | + CXX="$cross_gxx" \ |
| 603 | + "$@" |
| 604 | + |
| 605 | + |
| 606 | +Other Cross-Testing Concerns |
| 607 | + |
| 608 | +Here are notes on some other issues which you may encounter in running |
| 609 | +the GLIBC tests in a cross-compiling environment: |
| 610 | + |
| 611 | +- Some tests require a C++ cross-compiler; you should set the 'CXX' |
| 612 | + Make variable to the name of an appropriate cross-compiler. |
| 613 | + |
| 614 | +- Some tests require access to libstdc++.so.6 and libgcc_s.so.1; we |
| 615 | + simply place copies of these libraries in the top GLIBC build |
| 616 | + directory. |