release.sh: handle nouveau srv_path/etc. like other projects
[xorg-util-modular.git] / build.sh
blob01c396d44b453161e6b89ffa651655182506a1d8
1 #!/bin/sh
2 # ===========================================================================
4 # NAME
5 # build.sh - extract, configure, build and install the X Window System
7 # SYNOPSIS
8 # build.sh [options] [prefix]
9 # build.sh [-L]
11 # DESCRIPTION
12 # The script ultimate goal is to build all of the X Window and some of its
13 # dependencies from source.
15 # X.Org Modular Tree Developer's Guide
17 # Please consult the guide at http://www.x.org/wiki/ModularDevelopersGuide
18 # It provides detailed instructions on the build tools to install, where to
19 # find the script and how to invoke it.
21 # The X Window System Source Code
23 # The source code is hosted by freedesktop.org and is composed of over 200
24 # modules under the git source code management system. X.Org releases are
25 # available at http://www.x.org/releases/ in the form of software packages.
27 # Basic Operation
29 # The script goes through its list of modules to build. If the source code is
30 # not on disk, it attempts to obtain it from git if the --clone option is
31 # specified. If not, it looks for a package archive file on disk. If it is
32 # still not found, the module is skipped.
34 # The script then runs the appropriate configure script, either autogen.sh
35 # for git modules or the autoconf generated configure script for package
36 # archives.
38 # FEATURES
39 # Over time, functionality have been added to help building a large
40 # number modules. Progress report, handling build breaks, supporting the
41 # GNU Build System features, final build report, and so on.
43 # Building from a Custom Modules List
45 # Starting from the list generated using the -L option, remove unwanted
46 # modules. You may also add your own module or add specific configure
47 # options for some modules to meet your configuration needs. Using the
48 # --modfile option, your list replaces the built-in list of the script.
50 # Resuming Build After a Break
52 # The script can resume building at the last point of failure. This saves a
53 # lot of build time as the modules already built are skipped. The --autoresume
54 # option can be used with --modfile such that only the modules you care about
55 # are built and revisited until successful completion.
57 # Specifying Custom Build Commands
59 # By default, the script invokes the make program with the target "all" and
60 # "install". Some options like -c, -D, or -d alter the targets the make
61 # program builds, but you can specify your own command instead. Using the
62 # --cmd option, provide a different make or git command.
64 # Specifying Configuration Options to Specific Modules
66 # In the modulesfile used by the --modfile option, add any configuration
67 # options you want to pass to the modules as it gets configures by autoconf.
68 # Write the configure options next to the module name in the file.
69 # It could be something like --enable-strict-compilation for example.
71 # OPTIONS
72 # -a Do NOT run auto config tools (autogen.sh, configure)
73 # -b Use .build.unknown build directory
74 # -c Run make clean in addition to "all install"
75 # -D Run make dist in addition to "all install"
76 # -d Run make distcheck in addition "all install"
77 # -g Compile and link with debug information
78 # -L Just list modules to build
79 # -h, --help Display this help and exit successfully
80 # -n Do not quit after error; just print error message
81 # -o module/component
82 # Build just this module/component
83 # -p Update source code before building (git pull --rebase)
84 # -s sudo The command name providing superuser privilege
85 # --autoresume resumefile
86 # Append module being built to, and autoresume from, resumefile
87 # --check Run make check in addition "all install"
88 # --clone Clone non-existing repositories (uses \$GITROOT if set)
89 # --cmd command
90 # Execute arbitrary git, gmake, or make command
91 # --confflags options
92 # Pass options to autgen.sh/configure of all modules
93 # --modfile modulesfile
94 # Only process the module/components specified in modulesfile
95 # Any text after, and on the same line as, the module/component
96 # is assumed to be configuration options for the configuration
97 # of each module/component specifically
98 # --retry-v1 Remake 'all' on failure with Automake silent rules disabled
100 # PREFIX
101 # An absolute filename where GNU "make" will install binaries, libraries and
102 # other installable files. The value is passed to Autoconf through the
103 # --prefix option.
105 # FILES
106 # resumefile
107 # When using --autoresume, the script reads and skips modules tagged with
108 # "PASS" and resume building at the module tagged with "FAIL". The resumefile
109 # file is not intended to be user edited.
111 # modulesfile
112 # When using --modfile, the script replaces its internal modules list with
113 # the list contained in the file. This allows you to build only the modules
114 # you care about and to add third party modules or modules you create.
115 # It is helpful to initialized the file using the -L option.#
117 # ENVIRONMENT
118 # Environment variables specific to build.sh:
120 # PREFIX Install architecture-independent files in PREFIX [/usr/local]
121 # Each module/components is invoked with --prefix
122 # EPREFIX Install architecture-dependent files in EPREFIX [PREFIX]
123 # Each module/components is invoked with --exec-prefix
124 # BINDIR Install user executables [EPREFIX/bin]
125 # Each module/components is invoked with --bindir
126 # DATAROOTDIR Install read-only arch-independent data root [PREFIX/share]
127 # Each module/components is invoked with --datarootdir
128 # DATADIR Install read-only architecture-independent data [DATAROOTDIR]
129 # Each module/components is invoked with --datadir
130 # LIBDIR Install object code libraries [EPREFIX/lib]
131 # Each module/components is invoked with --libdir
132 # LOCALSTATEDIR
133 # Modifiable single-machine data [PREFIX/var]
134 # Each module/components is invoked with --localstatedir
135 # QUIET Do not print messages saying which checks are being made
136 # Each module/components is invoked with --quite
137 # GITROOT Source code repository path [git://anongit.freedesktop.org/git]
138 # Optional when using --clone to update source code before building
139 # CONFFLAGS Configure options to pass to all Autoconf configure scripts
140 # Refer to 'configure --help' from any module/components
142 # Environment variables defined by the GNU Build System:
144 # ACLOCAL The aclocal cmd name [aclocal -I ${DESTDIR}/${DATADIR}/aclocal]
145 # DESTDIR Path to the staging area where installed objects are relocated
146 # MAKE The name of the make command [make]
147 # MAKEFLAGS Options to pass to all $(MAKE) invocations
148 # CC C compiler command
149 # CFLAGS C compiler flags
150 # LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
151 # nonstandard directory <lib dir>
152 # CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
153 # you have headers in a nonstandard directory <include dir>
154 # CPP C preprocessor
156 # Environment variables defined by the shell:
157 # PATH List of directories that the shell searches for commands
158 # $DESTDIR/$BINDIR is prepended
160 # Environment variables defined by the dynamic linker:
161 # LD_LIBRARY_PATH
162 # List directories that the linker searches for shared objects
163 # $DESTDIR/$LIBDIR is prepended
165 # Environment variables defined by the pkg-config system:
167 # PKG_CONFIG_PATH
168 # List directories that pkg-config searches for libraries
169 # $DESTDIR/$DATADIR/pkgconfig and
170 # $DESTDIR/$LIBDIR/pkgconfig are prepended
172 # PORTABILITY
173 # This script is intended to run on any platform supported by X.Org.
174 # The script must be able to run in a Bourne shell.
176 # ===========================================================================
178 envoptions() {
179 cat << EOF
180 Environment variables specific to build.sh:
181 PREFIX Install architecture-independent files in PREFIX [/usr/local]
182 Each module/components is invoked with --prefix
183 EPREFIX Install architecture-dependent files in EPREFIX [PREFIX]
184 Each module/components is invoked with --exec-prefix
185 BINDIR Install user executables [EPREFIX/bin]
186 Each module/components is invoked with --bindir
187 DATAROOTDIR Install read-only arch-independent data root [PREFIX/share]
188 Each module/components is invoked with --datarootdir
189 DATADIR Install read-only architecture-independent data [DATAROOTDIR]
190 Each module/components is invoked with --datadir
191 LIBDIR Install object code libraries [EPREFIX/lib]
192 Each module/components is invoked with --libdir
193 LOCALSTATEDIR
194 Modifiable single-machine data [PREFIX/var]
195 Each module/components is invoked with --localstatedir
196 QUIET Do not print messages saying which checks are being made
197 Each module/components is invoked with --quite
198 GITROOT Source code repository path [git://anongit.freedesktop.org/git]
199 Optional when using --clone to update source code before building
200 CONFFLAGS Configure options to pass to all Autoconf configure scripts
201 Refer to 'configure --help' from any module/components
203 Environment variables defined by the GNU Build System:
204 ACLOCAL The aclocal cmd name [aclocal -I \${DESTDIR}/\${DATADIR}/aclocal]
205 DESTDIR Path to the staging area where installed objects are relocated
206 MAKE The name of the make command [make]
207 MAKEFLAGS Options to pass to all \$(MAKE) invocations
208 CC C compiler command
209 CFLAGS C compiler flags
210 LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
211 nonstandard directory <lib dir>
212 CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
213 you have headers in a nonstandard directory <include dir>
214 CPP C preprocessor
216 Environment variables defined by the shell:
217 PATH List of directories that the shell searches for commands
218 \$DESTDIR/\$BINDIR is prepended
220 Environment variables defined by the dynamic linker:
221 LD_LIBRARY_PATH
222 List directories that the linker searches for shared objects
223 \$DESTDIR/\$LIBDIR is prepended
225 Environment variables defined by the pkg-config system:
226 PKG_CONFIG_PATH
227 List directories that pkg-config searches for libraries
228 \$DESTDIR/\$DATADIR/pkgconfig and
229 \$DESTDIR/\$LIBDIR/pkgconfig are prepended
233 setup_buildenv() {
235 # Remember if the user had supplied a value through env var or cmd line
236 # A value from cmd line takes precedence of the shell environment
237 PREFIX_USER=${PREFIX:+yes}
238 EPREFIX_USER=${EPREFIX:+yes}
239 BINDIR_USER=${BINDIR:+yes}
240 DATAROOTDIR_USER=${DATAROOTDIR:+yes}
241 DATADIR_USER=${DATADIR:+yes}
242 LIBDIR_USER=${LIBDIR:+yes}
243 LOCALSTATEDIR_USER=${LOCALSTATEDIR:+yes}
245 # Assign a default value if no value was supplied by the user
246 PREFIX=${PREFIX:-/usr/local}
247 EPREFIX=${EPREFIX:-$PREFIX}
248 BINDIR=${BINDIR:-$EPREFIX/bin}
249 DATAROOTDIR=${DATAROOTDIR:-$PREFIX/share}
250 DATADIR=${DATADIR:-$DATAROOTDIR}
251 LIBDIR=${LIBDIR:-$EPREFIX/lib}
252 LOCALSTATEDIR=${LOCALSTATEDIR:-$PREFIX/var}
254 # Support previous usage of LIBDIR which was a subdir relative to PREFIX
255 # We use EPREFIX as this is what PREFIX really meant at the time
256 if [ X"$LIBDIR" != X ]; then
257 if [ X"`expr $LIBDIR : "\(.\)"`" != X/ ]; then
258 echo ""
259 echo "Warning: this usage of \$LIBDIR is deprecated. Use a full path name."
260 echo "The supplied value \"$LIBDIR\" has been replaced with $EPREFIX/$LIBDIR."
261 echo ""
262 LIBDIR=$EPREFIX/$LIBDIR
266 # All directories variables must be full path names
267 check_full_path $PREFIX PREFIX
268 check_full_path $EPREFIX EPREFIX
269 check_full_path $BINDIR BINDIR
270 check_full_path $DATAROOTDIR DATAROOTDIR
271 check_full_path $DATADIR DATADIR
272 check_full_path $LIBDIR LIBDIR
273 check_full_path $LOCALSTATEDIR LOCALSTATEDIR
275 # This will catch the case where user forgets to set PREFIX
276 # and does not have write permission in the /usr/local default location
277 check_writable_dir ${DESTDIR}${PREFIX} PREFIX
279 # Must create local aclocal dir or aclocal fails
280 ACLOCAL_LOCALDIR="${DESTDIR}${DATADIR}/aclocal"
281 $SUDO mkdir -p ${ACLOCAL_LOCALDIR}
283 # The following is required to make aclocal find our .m4 macros
284 ACLOCAL=${ACLOCAL:="aclocal"}
285 ACLOCAL="${ACLOCAL} -I ${ACLOCAL_LOCALDIR}"
286 export ACLOCAL
288 # The following is required to make pkg-config find our .pc metadata files
289 PKG_CONFIG_PATH=${DESTDIR}${DATADIR}/pkgconfig:${DESTDIR}${LIBDIR}/pkgconfig${PKG_CONFIG_PATH+:$PKG_CONFIG_PATH}
290 export PKG_CONFIG_PATH
292 # Set the library path so that locally built libs will be found by apps
293 LD_LIBRARY_PATH=${DESTDIR}${LIBDIR}${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}
294 export LD_LIBRARY_PATH
296 # Set the path so that locally built apps will be found and used
297 PATH=${DESTDIR}${BINDIR}${PATH+:$PATH}
298 export PATH
300 # Choose which make program to use
301 MAKE=${MAKE:="make"}
303 # Create the log file directory
304 $SUDO mkdir -p ${DESTDIR}${LOCALSTATEDIR}/log
307 # explain where a failure occurred
308 # if you find this message in the build output it can help tell you where the failure occurred
309 # arguments:
310 # $1 - which command failed
311 # $2 - module
312 # $3 - component
313 # returns:
314 # (irrelevant)
315 failed() {
316 cmd=$1
317 module=$2
318 component=$3
319 echo "build.sh: \"$cmd\" failed on $module${component:+/}$component"
320 failed_components="$failed_components $module${component:+/}$component"
323 # print a pretty title to separate the processing of each module
324 # arguments:
325 # $1 - module
326 # $2 - component
327 # $3 - configuration options
328 # returns:
329 # (irrelevant)
330 module_title() {
331 module=$1
332 component=$2
333 confopts="$3"
334 # preconds
335 if [ X"$module" = X ]; then
336 return
339 echo ""
340 echo "======================================================================"
341 echo "== Processing: \"$module${component:+/}$component\""
342 echo "== configuration options: $CONFFLAGS $confopts"
345 # Search for tarballs in either cwd or under a module directory
346 # The tarball is always extracted in either one of these locations:
347 # - modules with components: under the module subdir (e.g lib/libX11-1.4.0)
348 # - modules without components: under cwd (e.g xserver-1.14.0)
349 # The tarballs are expected to be under one of the locations described above
350 # The location of the tarball does not dictate where it is extracted
351 # arguments:
352 # $1 - module
353 # $2 - component
354 # returns:
355 # 0 - good (either no tarballs or successful extract)
356 # 1 - bad
357 checkfortars() {
358 module=$1
359 component=$2
361 # The package stem is the part of the tar file name that identifies
362 # the git module archived source. Ex: xclock, pixman, libX11
363 # For modules without components, the module name is used by default.
364 pkg_stem=${component:-$module}
366 # Handle special cases where the module or component directory
367 # does not match the package name and/or the package root dir
368 case $module in
369 "data")
370 case $component in
371 "cursors") pkg_stem="xcursor-themes" ;;
372 "bitmaps") pkg_stem="xbitmaps" ;;
373 esac
375 "font")
376 if [ X"$component" != X"encodings" ]; then
377 pkg_stem="font-$component"
380 "lib")
381 case $component in
382 "libXRes") pkg_stem="libXres" ;;
383 "libxtrans") pkg_stem="xtrans" ;;
384 esac
386 "proto")
387 case $component in
388 "x11proto") pkg_stem="xproto" ;;
389 esac
391 "util")
392 case $component in
393 "cf") pkg_stem="xorg-cf-files" ;;
394 "macros") pkg_stem="util-macros" ;;
395 esac
397 "xcb")
398 case $component in
399 "proto")
400 pkg_stem="xcb-proto"
402 "pthread-stubs")
403 pkg_stem="libpthread-stubs"
405 "libxcb")
406 pkg_stem="libxcb"
408 util*)
409 pkg_stem="xcb-$component"
411 esac
413 "mesa")
414 case $component in
415 "drm")
416 pkg_stem="libdrm"
418 "mesa")
419 pkg_stem="MesaLib"
421 esac
423 "xserver")
424 pkg_stem="xorg-server"
426 esac
428 # Search for tarballs in both the module and the src top directory
429 for ii in $module .; do
430 for jj in bz2 gz xz; do
432 # Select from the list the last tarball with a specific pkg_stem
433 pkg_tarfile=`ls -1rt $ii/$pkg_stem-[0-9]*.tar.$jj 2> /dev/null | tail -n 1`
435 # Extract the tarball under the module directory
436 # For modules without components, extract in top level dir
437 if [ X"$pkg_tarfile" != X ]; then
439 # Get the package version and archived toplevel directory
440 pkg_version=`echo $pkg_tarfile | sed 's,.*'$pkg_stem'-\(.*\)\.tar\.'$jj',\1,'`
441 pkg_root_dir="$pkg_stem-$pkg_version"
442 pkg_root_dir=`echo $pkg_root_dir | sed 's,MesaLib,Mesa,'`
444 # Find where to extract the tar file
445 old_srcdir=$SRCDIR
446 if [ X"$component" = X ]; then
447 # For modules with no components (i.e xserver)
448 pkg_extract_dir="."
449 SRCDIR=$pkg_root_dir
450 else
451 # For modules with components (i.e xcb/proto or lib/libXi)
452 pkg_extract_dir=$module
453 SRCDIR=$module/$pkg_root_dir
456 if [ ! -d $SRCDIR ]; then
457 mkdir -p $module
458 case $jj in
459 "bz2")
460 pkg_tar_opts=xjf
462 "gz")
463 pkg_tar_opts=xzf
465 "xz")
466 pkg_tar_opts=xJf
468 esac
469 tar $pkg_tar_opts $pkg_tarfile -C $pkg_extract_dir
470 if [ $? -ne 0 ]; then
471 SRCDIR=${old_srcdir}
472 echo "Unable to extract $pkg_tarfile for $module module"
473 failed tar $module $component
474 return 1
477 return 0
479 done
480 done
482 return 0
485 # perform a clone of a git repository
486 # this function provides the mapping between module/component names
487 # and their location in the fd.o repository
488 # arguments:
489 # $1 - module
490 # $2 - component (optional)
491 # returns:
492 # 0 - good
493 # 1 - bad
494 clone() {
495 module=$1
496 component=$2
497 # preconds
498 if [ X"$module" = X ]; then
499 echo "clone() required first argument is missing"
500 return 1
503 case $module in
504 "pixman")
505 BASEDIR=""
507 "xcb")
508 BASEDIR=""
510 "mesa")
511 BASEDIR=""
513 "xkeyboard-config")
514 BASEDIR=""
516 "libevdev")
517 BASEDIR=""
519 "libinput")
520 BASEDIR="wayland/"
523 BASEDIR="xorg/"
525 esac
527 DIR="$module${component:+/}$component"
528 GITROOT=${GITROOT:="git://anongit.freedesktop.org/git"}
530 if [ ! -d "$DIR" ]; then
531 git clone "$GITROOT/$BASEDIR$DIR" "$DIR"
532 if [ $? -ne 0 ]; then
533 echo "Failed to clone $module${component:+/}$component. Ignoring."
534 clonefailed_components="$clonefailed_components $module${component:+/}$component"
535 return 1
537 old_pwd=`pwd`
538 cd $DIR
539 if [ $? -ne 0 ]; then
540 echo "Failed to cd to $module${component:+/}$component. Ignoring."
541 clonefailed_components="$clonefailed_components $module${component:+/}$component"
542 return 1
543 return 1
545 git submodule init
546 if [ $? -ne 0 ]; then
547 echo "Failed to initialize $module${component:+/}$component submodule. Ignoring."
548 clonefailed_components="$clonefailed_components $module${component:+/}$component"
549 return 1
551 git submodule update
552 if [ $? -ne 0 ]; then
553 echo "Failed to update $module${component:+/}$component submodule. Ignoring."
554 clonefailed_components="$clonefailed_components $module${component:+/}$component"
555 return 1
557 cd ${old_pwd}
558 else
559 echo "git cannot clone into an existing directory $module${component:+/}$component"
560 return 1
563 return 0
566 # perform processing of each module/component
567 # arguments:
568 # $1 - module
569 # $2 - component
570 # $3 - configure options
571 # returns:
572 # 0 - good
573 # 1 - bad
574 process() {
575 needs_config=0
577 module=$1
578 component=$2
579 confopts="$3"
580 # preconds
581 if [ X"$module" = X ]; then
582 echo "process() required first argument is missing"
583 return 1
586 module_title $module "$component" "$confopts"
588 SRCDIR=""
589 CONFCMD=""
590 if [ -f $module${component:+/}$component/autogen.sh ]; then
591 SRCDIR="$module${component:+/}$component"
592 CONFCMD="autogen.sh"
593 elif [ X"$CLONE" != X ]; then
594 clone $module $component
595 if [ $? -eq 0 ]; then
596 SRCDIR="$module${component:+/}$component"
597 CONFCMD="autogen.sh"
599 needs_config=1
600 else
601 checkfortars $module $component
602 if [ $? -eq 0 ]; then
603 if [ X"$SRCDIR" = X ]; then
604 echo "$module${component:+/}$component does not exist, skipping."
605 nonexistent_components="$nonexistent_components $module${component:+/}$component"
606 return 0
608 CONFCMD="configure"
609 else
610 return 1
614 old_pwd=`pwd`
615 cd $SRCDIR
616 if [ $? -ne 0 ]; then
617 failed cd1 $module $component
618 return 1
621 if [ X"$GITCMD" != X ]; then
622 $GITCMD
623 rtn=$?
624 cd $old_pwd
626 if [ $rtn -ne 0 ]; then
627 failed "$GITCMD" $module $component
628 return 1
630 return 0
633 if [ X"$PULL" != X ]; then
634 git pull --rebase
635 if [ $? -ne 0 ]; then
636 failed "git pull" $module $component
637 cd $old_pwd
638 return 1
640 # The parent module knows which commit the submodule should be at
641 git submodule update
642 if [ $? -ne 0 ]; then
643 failed "git submodule update" $module $component
644 return 1
648 # Build outside source directory
649 if [ X"$DIR_ARCH" != X ] ; then
650 mkdir -p "$DIR_ARCH"
651 if [ $? -ne 0 ]; then
652 failed mkdir $module $component
653 cd $old_pwd
654 return 1
656 cd "$DIR_ARCH"
657 if [ $? -ne 0 ]; then
658 failed cd2 $module $component
659 cd ${old_pwd}
660 return 1
664 # Use "sh autogen.sh" since some scripts are not executable in CVS
665 if [ $needs_config -eq 1 ] || [ X"$NOAUTOGEN" = X ]; then
666 sh ${DIR_CONFIG}/${CONFCMD} \
667 ${PREFIX_USER:+--prefix="$PREFIX"} \
668 ${EPREFIX_USER:+--exec-prefix="$EPREFIX"} \
669 ${BINDIR_USER:+--bindir="$BINDIR"} \
670 ${DATAROOTDIR_USER:+--datarootdir="$DATAROOTDIR"} \
671 ${DATADIR_USER:+--datadir="$DATADIR"} \
672 ${LIBDIR_USER:+--libdir="$LIBDIR"} \
673 ${LOCALSTATEDIR_USER:+--localstatedir="$LOCALSTATEDIR"} \
674 ${QUIET:+--quiet} \
675 ${CONFFLAGS} $confopts \
676 ${CC:+CC="$CC"} \
677 ${CPP:+CPP="$CPP"} \
678 ${CPPFLAGS:+CPPFLAGS="$CPPFLAGS"} \
679 ${CFLAGS:+CFLAGS="$CFLAGS"} \
680 ${LDFLAGS:+LDFLAGS="$LDFLAGS"}
681 if [ $? -ne 0 ]; then
682 failed ${CONFCMD} $module $component
683 cd $old_pwd
684 return 1
688 # A custom 'make' target list was supplied through --cmd option
689 if [ X"$MAKECMD" != X ]; then
690 ${MAKE} $MAKEFLAGS $MAKECMD
691 rtn=$?
692 cd $old_pwd
694 if [ $rtn -ne 0 ]; then
695 failed "$MAKE $MAKEFLAGS $MAKECMD" $module $component
696 return 1
698 return 0
701 ${MAKE} $MAKEFLAGS
702 if [ $? -ne 0 ]; then
703 # Rerun with Automake silent rules disabled to see failing gcc statement
704 if [ X"$RETRY_VERBOSE" != X ]; then
705 echo ""
706 echo "build.sh: Rebuilding $component with Automake silent rules disabled"
707 ${MAKE} $MAKEFLAGS V=1
709 failed "$MAKE $MAKEFLAGS" $module $component
710 cd $old_pwd
711 return 1
714 if [ X"$CHECK" != X ]; then
715 ${MAKE} $MAKEFLAGS check
716 if [ $? -ne 0 ]; then
717 failed "$MAKE $MAKEFLAGS check" $module $component
718 cd $old_pwd
719 return 1
723 if [ X"$CLEAN" != X ]; then
724 ${MAKE} $MAKEFLAGS clean
725 if [ $? -ne 0 ]; then
726 failed "$MAKE $MAKEFLAGS clean" $module $component
727 cd $old_pwd
728 return 1
732 if [ X"$DIST" != X ]; then
733 ${MAKE} $MAKEFLAGS dist
734 if [ $? -ne 0 ]; then
735 failed "$MAKE $MAKEFLAGS dist" $module $component
736 cd $old_pwd
737 return 1
741 if [ X"$DISTCHECK" != X ]; then
742 ${MAKE} $MAKEFLAGS distcheck
743 if [ $? -ne 0 ]; then
744 failed "$MAKE $MAKEFLAGS distcheck" $module $component
745 cd $old_pwd
746 return 1
750 $SUDO env LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${MAKE} $MAKEFLAGS install
751 if [ $? -ne 0 ]; then
752 failed "$SUDO env LD_LIBRARY_PATH=$LD_LIBRARY_PATH $MAKE $MAKEFLAGS install" $module $component
753 cd $old_pwd
754 return 1
757 cd ${old_pwd}
759 return 0
762 # process each module/component and handle:
763 # LISTONLY, RESUME, NOQUIT, and BUILD_ONE
764 # arguments:
765 # $1 - module
766 # $2 - component
767 # $3 - configure options
768 # returns:
769 # 0 - good
770 # 1 - bad
771 build() {
772 module=$1
773 component=$2
774 confopts="$3"
775 if [ X"$LISTONLY" != X ]; then
776 echo "$module${component:+/}$component"
777 return 0
780 if [ X"$RESUME" != X ]; then
781 if [ X"$RESUME" = X"$module${component:+/}$component" ]; then
782 unset RESUME
783 # Resume build at this module
784 else
785 echo "Skipping $module${component:+/}$component..."
786 return 0
790 process $module "$component" "$confopts"
791 process_rtn=$?
792 if [ X"$BUILT_MODULES_FILE" != X ]; then
793 if [ $process_rtn -ne 0 ]; then
794 echo "FAIL: $module${component:+/}$component" >> $BUILT_MODULES_FILE
795 else
796 echo "PASS: $module${component:+/}$component" >> $BUILT_MODULES_FILE
800 if [ $process_rtn -ne 0 ]; then
801 echo "build.sh: error processing: \"$module${component:+/}$component\""
802 if [ X"$NOQUIT" = X ]; then
803 exit 1
805 return $process_rtn
808 if [ X"$BUILD_ONE" != X ]; then
809 echo "Single-component build complete"
810 exit 0
815 # just process the sub-projects supplied in the given file ($MODFILE)
816 # in the order in which they are found in the list
817 # (prerequisites and ordering are the responsibility of the user)
818 # globals used:
819 # $MODFILE - readable file containing list of modules to process
820 # and their optional configuration options
821 # arguments:
822 # (none)
823 # returns:
824 # 0 - good
825 # 1 - bad
826 process_module_file() {
827 # preconds
828 if [ X"$MODFILE" = X ]; then
829 echo "internal process_module_file() error, \$MODFILE is empty"
830 return 1
832 if [ ! -r "$MODFILE" ]; then
833 echo "module file '$MODFILE' is not readable or does not exist"
834 return 1
837 # read from input file, skipping blank and comment lines
838 while read line; do
839 # skip blank lines
840 if [ X"$line" = X ]; then
841 continue
844 # skip comment lines
845 echo "$line" | grep "^#" > /dev/null
846 if [ $? -eq 0 ]; then
847 continue
850 # parse each line to extract module, component and options name
851 field1=`echo $line | cut -d' ' -f1`
852 module=`echo $field1 | cut -d'/' -f1`
853 component=`echo $field1 | cut -d'/' -s -f2`
854 confopts=`echo $line | cut -d' ' -s -f2-`
856 build $module "$component" "$confopts"
858 done <"$MODFILE"
860 return 0
863 usage() {
864 basename="`expr "//$0" : '.*/\([^/]*\)'`"
865 echo "Usage: $basename [options] [prefix]"
866 echo "Options:"
867 echo " -a Do NOT run auto config tools (autogen.sh, configure)"
868 echo " -b Use .build.unknown build directory"
869 echo " -c Run make clean in addition to \"all install\""
870 echo " -D Run make dist in addition to \"all install\""
871 echo " -d Run make distcheck in addition \"all install\""
872 echo " -g Compile and link with debug information"
873 echo " -h, --help Display this help and exit successfully"
874 echo " -n Do not quit after error; just print error message"
875 echo " -o module/component"
876 echo " Build just this module/component"
877 echo " -p Update source code before building (git pull --rebase)"
878 echo " -s sudo The command name providing superuser privilege"
879 echo " --autoresume resumefile"
880 echo " Append module being built to, and autoresume from, <file>"
881 echo " --check Run make check in addition \"all install\""
882 echo " --clone Clone non-existing repositories (uses \$GITROOT if set)"
883 echo " --cmd command"
884 echo " Execute arbitrary git, gmake, or make command"
885 echo " --confflags options"
886 echo " Pass options to autgen.sh/configure of all modules"
887 echo " --modfile modulefile"
888 echo " Only process the module/components specified in modulefile"
889 echo " Any text after, and on the same line as, the module/component"
890 echo " is assumed to be configuration options for the configuration"
891 echo " of each module/component specifically"
892 echo " --retry-v1 Remake 'all' on failure with Automake silent rules disabled"
893 echo ""
894 echo "Usage: $basename -L"
895 echo " -L Just list modules to build"
896 echo ""
897 envoptions
900 # Ensure the named variable value contains a full path name
901 # arguments:
902 # $1 - the variable value (the path to examine)
903 # $2 - the name of the variable
904 # returns:
905 # returns nothing or exit on error with message
906 check_full_path () {
907 path=$1
908 varname=$2
909 if [ X"`expr $path : "\(.\)"`" != X/ ]; then
910 echo "The path \"$path\" supplied by \"$varname\" must be a full path name"
911 echo ""
912 usage
913 exit 1
917 # Ensure the named variable value contains a writable directory
918 # arguments:
919 # $1 - the variable value (the path to examine)
920 # $2 - the name of the variable
921 # returns:
922 # returns nothing or exit on error with message
923 check_writable_dir () {
924 path=$1
925 varname=$2
926 if [ X"$SUDO" = X ]; then
927 if [ ! -d "$path" ] || [ ! -w "$path" ]; then
928 echo "The path \"$path\" supplied by \"$varname\" must be a writable directory"
929 echo ""
930 usage
931 exit 1
936 # perform sanity checks on cmdline args which require arguments
937 # arguments:
938 # $1 - the option being examined
939 # $2 - the argument to the option
940 # returns:
941 # if it returns, everything is good
942 # otherwise it exit's
943 required_arg() {
944 option=$1
945 arg=$2
946 # preconds
947 if [ X"$option" = X ]; then
948 echo "internal required_arg() error, missing first argument"
949 exit 1
952 # check for an argument
953 if [ X"$arg" = X ]; then
954 echo "the '$option' option is missing its required argument"
955 echo ""
956 usage
957 exit 1
960 # does the argument look like an option?
961 echo $arg | grep "^-" > /dev/null
962 if [ $? -eq 0 ]; then
963 echo "the argument '$arg' of option '$option' looks like an option itself"
964 echo ""
965 usage
966 exit 1
970 #==============================================================================
971 # Build All Modules
972 # Globals:
973 # HOST_OS HOST_CPU
974 # Arguments:
975 # None
976 # Returns:
977 # None
978 #==============================================================================
979 build_all_modules() {
981 build util macros
982 build font util
983 build doc xorg-sgml-doctools
984 build doc xorg-docs
985 case $HOST_OS in
986 Darwin) build proto applewmproto;;
987 CYGWIN*) build proto windowswmproto;;
988 esac
989 build proto bigreqsproto
990 build proto compositeproto
991 build proto damageproto
992 build proto dmxproto
993 build proto dri2proto
994 build proto dri3proto
995 build proto fixesproto
996 build proto fontsproto
997 build proto glproto
998 build proto inputproto
999 build proto kbproto
1000 build proto presentproto
1001 build proto randrproto
1002 build proto recordproto
1003 build proto renderproto
1004 build proto resourceproto
1005 build proto scrnsaverproto
1006 build proto videoproto
1007 build proto x11proto
1008 build proto xcmiscproto
1009 build proto xextproto
1010 build proto xf86bigfontproto
1011 build proto xf86dgaproto
1012 build proto xf86driproto
1013 build proto xf86vidmodeproto
1014 build proto xineramaproto
1015 build xcb proto
1016 # Required by mesa and depends on xproto
1017 build util makedepend
1018 build lib libxtrans
1019 build lib libXau
1020 build lib libXdmcp
1021 build xcb pthread-stubs
1022 build xcb libxcb
1023 build xcb util
1024 build xcb util-image
1025 build xcb util-keysyms
1026 build xcb util-renderutil
1027 build xcb util-wm
1028 build lib libX11
1029 build lib libXext
1030 case $HOST_OS in
1031 Darwin) build lib libAppleWM;;
1032 CYGWIN*) build lib libWindowsWM;;
1033 esac
1034 build lib libdmx
1035 build lib libfontenc
1036 build lib libFS
1037 build lib libICE
1038 build lib libSM
1039 build lib libXt
1040 build lib libXmu
1041 build lib libXpm
1042 build lib libXaw
1043 build lib libXaw3d
1044 build lib libXfixes
1045 build lib libXcomposite
1046 build lib libXrender
1047 build lib libXdamage
1048 build lib libXcursor
1049 build lib libXfont
1050 build lib libXft
1051 build lib libXi
1052 build lib libXinerama
1053 build lib libxkbfile
1054 build lib libXrandr
1055 build lib libXRes
1056 build lib libXScrnSaver
1057 case $HOST_OS in
1058 Linux)
1059 build lib libxshmfence
1061 esac
1062 build lib libXtst
1063 build lib libXv
1064 build lib libXvMC
1065 build lib libXxf86dga
1066 build lib libXxf86vm
1067 build lib libpciaccess
1068 build pixman ""
1069 build mesa drm
1070 build mesa mesa
1071 build data bitmaps
1072 build app appres
1073 build app bdftopcf
1074 build app beforelight
1075 build app bitmap
1076 build app editres
1077 build app fonttosfnt
1078 build app fslsfonts
1079 build app fstobdf
1080 build app iceauth
1081 build app ico
1082 build app listres
1083 build app luit
1084 build app mkcomposecache
1085 build app mkfontdir
1086 build app mkfontscale
1087 build app oclock
1088 build app rgb
1089 build app rendercheck
1090 build app rstart
1091 build app scripts
1092 build app sessreg
1093 build app setxkbmap
1094 build app showfont
1095 build app smproxy
1096 build app twm
1097 build app viewres
1098 build app x11perf
1099 build app xauth
1100 build app xbacklight
1101 build app xbiff
1102 build app xcalc
1103 build app xclipboard
1104 build app xclock
1105 build app xcmsdb
1106 build app xconsole
1107 build app xcursorgen
1108 build app xdbedizzy
1109 build app xditview
1110 build app xdm
1111 build app xdpyinfo
1112 build app xdriinfo
1113 build app xedit
1114 build app xev
1115 build app xeyes
1116 build app xf86dga
1117 build app xfd
1118 build app xfontsel
1119 build app xfs
1120 build app xfsinfo
1121 build app xgamma
1122 build app xgc
1123 build app xhost
1124 build app xinit
1125 build app xinput
1126 build app xkbcomp
1127 build app xkbevd
1128 build app xkbprint
1129 build app xkbutils
1130 build app xkill
1131 build app xload
1132 build app xlogo
1133 build app xlsatoms
1134 build app xlsclients
1135 build app xlsfonts
1136 build app xmag
1137 build app xman
1138 build app xmessage
1139 build app xmh
1140 build app xmodmap
1141 build app xmore
1142 build app xpr
1143 build app xprop
1144 build app xrandr
1145 build app xrdb
1146 build app xrefresh
1147 build app xscope
1148 build app xset
1149 build app xsetmode
1150 build app xsetroot
1151 build app xsm
1152 build app xstdcmap
1153 build app xvidtune
1154 build app xvinfo
1155 build app xwd
1156 build app xwininfo
1157 build app xwud
1158 build xserver ""
1159 case $HOST_OS in
1160 Linux)
1161 build libevdev ""
1162 build libinput ""
1164 esac
1165 case $HOST_OS in
1166 Linux)
1167 build driver xf86-input-evdev
1168 build driver xf86-input-joystick
1169 build driver xf86-input-libinput
1171 FreeBSD | NetBSD | OpenBSD | Dragonfly | GNU/kFreeBSD)
1172 build driver xf86-input-joystick
1174 esac
1175 case $HOST_CPU in
1176 i*86 | amd64 | x86_64 | i86pc)
1177 build driver xf86-input-vmmouse
1179 esac
1180 case $HOST_OS in
1181 Darwin)
1184 build driver xf86-input-keyboard
1185 build driver xf86-input-mouse
1186 build driver xf86-input-synaptics
1187 build driver xf86-input-void
1188 case $HOST_OS in
1189 FreeBSD)
1190 case $HOST_CPU in
1191 sparc64)
1192 build driver xf86-video-sunffb
1194 esac
1196 NetBSD | OpenBSD)
1197 build driver xf86-video-wsfb
1198 build driver xf86-video-sunffb
1200 Linux)
1201 build driver xf86-video-sisusb
1202 build driver xf86-video-sunffb
1203 build driver xf86-video-v4l
1204 build driver xf86-video-xgixp
1205 case $HOST_CPU in
1206 i*86)
1207 # AMD Geode CPU. Driver contains 32 bit assembler code
1208 build driver xf86-video-geode
1210 esac
1212 esac
1213 case $HOST_CPU in
1214 sparc | sparc64)
1215 build driver xf86-video-suncg14
1216 build driver xf86-video-suncg3
1217 build driver xf86-video-suncg6
1218 build driver xf86-video-sunleo
1219 build driver xf86-video-suntcx
1221 i*86 | amd64 | x86_64 | i86pc)
1222 build driver xf86-video-i740
1223 build driver xf86-video-intel
1225 esac
1226 build driver xf86-video-apm
1227 build driver xf86-video-ark
1228 build driver xf86-video-ast
1229 build driver xf86-video-ati
1230 build driver xf86-video-chips
1231 build driver xf86-video-cirrus
1232 build driver xf86-video-dummy
1233 build driver xf86-video-fbdev
1234 build driver xf86-video-glint
1235 build driver xf86-video-i128
1236 build driver xf86-video-mach64
1237 build driver xf86-video-mga
1238 build driver xf86-video-neomagic
1239 build driver xf86-video-nested
1240 build driver xf86-video-nv
1241 build driver xf86-video-rendition
1242 build driver xf86-video-r128
1243 build driver xf86-video-s3
1244 build driver xf86-video-s3virge
1245 build driver xf86-video-savage
1246 build driver xf86-video-siliconmotion
1247 build driver xf86-video-sis
1248 build driver xf86-video-tdfx
1249 build driver xf86-video-tga
1250 build driver xf86-video-trident
1251 build driver xf86-video-tseng
1252 build driver xf86-video-vesa
1253 build driver xf86-video-vmware
1254 build driver xf86-video-voodoo
1256 esac
1257 build data cursors
1258 build font encodings
1259 build font adobe-100dpi
1260 build font adobe-75dpi
1261 build font adobe-utopia-100dpi
1262 build font adobe-utopia-75dpi
1263 build font adobe-utopia-type1
1264 build font arabic-misc
1265 build font bh-100dpi
1266 build font bh-75dpi
1267 build font bh-lucidatypewriter-100dpi
1268 build font bh-lucidatypewriter-75dpi
1269 build font bh-ttf
1270 build font bh-type1
1271 build font bitstream-100dpi
1272 build font bitstream-75dpi
1273 build font bitstream-type1
1274 build font cronyx-cyrillic
1275 build font cursor-misc
1276 build font daewoo-misc
1277 build font dec-misc
1278 build font ibm-type1
1279 build font isas-misc
1280 build font jis-misc
1281 build font micro-misc
1282 build font misc-cyrillic
1283 build font misc-ethiopic
1284 build font misc-meltho
1285 build font misc-misc
1286 build font mutt-misc
1287 build font schumacher-misc
1288 build font screen-cyrillic
1289 build font sony-misc
1290 build font sun-misc
1291 build font winitzki-cyrillic
1292 build font xfree86-type1
1293 build font alias
1294 build util cf
1295 build util imake
1296 build util gccmakedep
1297 build util lndir
1298 build xkeyboard-config ""
1299 return 0
1303 #------------------------------------------------------------------------------
1304 # Script main line
1305 #------------------------------------------------------------------------------
1307 # Initialize variables controlling end of run reports
1308 failed_components=""
1309 nonexistent_components=""
1310 clonefailed_components=""
1312 # Set variables supporting multiple binaries for a single source tree
1313 HAVE_ARCH="`uname -i`"
1314 DIR_ARCH=""
1315 DIR_CONFIG="."
1317 # Set variables for conditionally building some components
1318 HOST_OS=`uname -s`
1319 export HOST_OS
1320 HOST_CPU=`uname -m`
1321 export HOST_CPU
1323 # Process command line args
1324 while [ $# != 0 ]
1326 case $1 in
1328 NOAUTOGEN=1
1331 DIR_ARCH=".build.$HAVE_ARCH"
1332 DIR_CONFIG=".."
1335 CLEAN=1
1338 DIST=1
1341 DISTCHECK=1
1344 CFLAGS="${CFLAGS} -g3 -O0"
1346 -h|--help)
1347 usage
1348 exit 0
1351 LISTONLY=1
1354 NOQUIT=1
1357 if [ -n "$BUILT_MODULES_FILE" ]; then
1358 echo "The '-o' and '--autoresume' options are mutually exclusive."
1359 usage
1360 exit 1
1362 required_arg $1 $2
1363 shift
1364 RESUME=`echo $1 | sed "s,/$,,"`
1365 BUILD_ONE=1
1368 PULL=1
1371 required_arg $1 $2
1372 shift
1373 SUDO=$1
1375 --autoresume)
1376 if [ -n "$BUILD_ONE" ]; then
1377 echo "The '-o' and '--autoresume' options are mutually exclusive."
1378 usage
1379 exit 1
1381 required_arg $1 $2
1382 shift
1383 BUILT_MODULES_FILE=$1
1385 --check)
1386 CHECK=1
1388 --clone)
1389 CLONE=1
1391 --cmd)
1392 required_arg $1 $2
1393 shift
1394 cmd1=`echo $1 | cut -d' ' -f1`
1395 cmd2=`echo $1 | cut -d' ' -f2`
1397 # verify the command exists
1398 which $cmd1 > /dev/null 2>&1
1399 if [ $? -ne 0 ]; then
1400 echo "The specified command '$cmd1' does not appear to exist"
1401 echo ""
1402 usage
1403 exit 1
1406 case X"$cmd1" in
1407 X"git")
1408 GITCMD=$1
1410 X"make" | X"gmake")
1411 MAKECMD=$cmd2
1414 echo "The script can only process 'make', 'gmake', or 'git' commands"
1415 echo "It can't process '$cmd1' commands"
1416 echo ""
1417 usage
1418 exit 1
1420 esac
1422 --confflags)
1423 shift
1424 CONFFLAGS=$1
1426 --modfile)
1427 required_arg $1 $2
1428 shift
1429 if [ ! -r "$1" ]; then
1430 echo "can't find/read file '$1'"
1431 exit 1
1433 MODFILE=$1
1435 --retry-v1)
1436 RETRY_VERBOSE=1
1439 if [ X"$too_many" = Xyes ]; then
1440 echo "unrecognized and/or too many command-line arguments"
1441 echo " PREFIX: $PREFIX"
1442 echo " Extra arguments: $1"
1443 echo ""
1444 usage
1445 exit 1
1448 # check that 'prefix' doesn't look like an option
1449 echo $1 | grep "^-" > /dev/null
1450 if [ $? -eq 0 ]; then
1451 echo "'prefix' appears to be an option"
1452 echo ""
1453 usage
1454 exit 1
1457 PREFIX=$1
1458 too_many=yes
1460 esac
1462 shift
1463 done
1465 # All user input has been obtained, set-up the user shell variables
1466 if [ X"$LISTONLY" = X ]; then
1467 setup_buildenv
1468 echo "Building to run $HOST_OS / $HOST_CPU ($HOST)"
1469 date
1472 # if there is a BUILT_MODULES_FILE
1473 # then start off by checking for and trying to build any modules which failed
1474 # and aren't the last line
1475 if [ X"$BUILT_MODULES_FILE" != X -a -r "$BUILT_MODULES_FILE" ]; then
1476 built_lines=`cat $BUILT_MODULES_FILE | wc -l | sed 's:^ *::'`
1477 built_lines_m1=`expr $built_lines - 1`
1478 orig_BUILT_MODULES_FILE=$BUILT_MODULES_FILE
1479 unset BUILT_MODULES_FILE
1480 curline=1
1481 while read line; do
1482 built_status=`echo $line | cut -c-6`
1483 if [ X"$built_status" = X"FAIL: " ]; then
1484 line=`echo $line | cut -c7-`
1485 field1=`echo $line | cut -d' ' -f1`
1486 module=`echo $field1 | cut -d'/' -f1`
1487 component=`echo $field1 | cut -d'/' -s -f2`
1488 confopts=`echo $line | cut -d' ' -s -f2-`
1490 build_ret=""
1492 # quick check for the module in $MODFILE (if present)
1493 if [ X"$MODFILE" = X ]; then
1494 build $module "$component" "$confopts"
1495 if [ $? -eq 0 ]; then
1496 build_ret="PASS"
1498 else
1499 cat $MODFILE | grep "$module${component:+/}$component" > /dev/null
1500 if [ $? -eq 0 ]; then
1501 build $module "$component" "$confopts"
1502 if [ $? -eq 0 ]; then
1503 build_ret="PASS"
1508 if [ X"$build_ret" = X"PASS" ]; then
1509 built_temp=`mktemp`
1510 if [ $? -ne 0 ]; then
1511 echo "can't create tmp file, $orig_BUILT_MODULES_FILE not modified"
1512 else
1513 head -n `expr $curline - 1` $orig_BUILT_MODULES_FILE > $built_temp
1514 echo "PASS: $module${component:+/}$component" >> $built_temp
1515 tail -n `expr $built_lines - $curline` $orig_BUILT_MODULES_FILE >> $built_temp
1516 mv $built_temp $orig_BUILT_MODULES_FILE
1520 if [ $curline -eq $built_lines_m1 ]; then
1521 break
1523 curline=`expr $curline + 1`
1524 done <"$orig_BUILT_MODULES_FILE"
1526 BUILT_MODULES_FILE=$orig_BUILT_MODULES_FILE
1527 RESUME=`tail -n 1 $BUILT_MODULES_FILE | cut -c7-`
1529 # remove last line of $BUILT_MODULES_FILE
1530 # to avoid a duplicate entry
1531 built_temp=`mktemp`
1532 if [ $? -ne 0 ]; then
1533 echo "can't create tmp file, last built item will be duplicated"
1534 else
1535 head -n $built_lines_m1 $BUILT_MODULES_FILE > $built_temp
1536 mv $built_temp $BUILT_MODULES_FILE
1540 if [ X"$MODFILE" = X ]; then
1541 build_all_modules
1542 else
1543 process_module_file
1546 if [ X"$LISTONLY" != X ]; then
1547 exit 0
1550 # Print the end date/time to compare with the start date/time
1551 date
1553 # Report about components that failed for one reason or another
1554 if [ X"$nonexistent_components" != X ]; then
1555 echo ""
1556 echo "***** Skipped components (not available) *****"
1557 echo "Could neither find a git repository (at the <module/component> paths)"
1558 echo "or a tarball (at the <module/> paths or ./) for:"
1559 echo " <module/component>"
1560 for mod in $nonexistent_components; do
1561 echo " $mod"
1562 done
1563 echo "You may want to provide the --clone option to build.sh"
1564 echo "to automatically git-clone the missing components"
1565 echo ""
1568 if [ X"$failed_components" != X ]; then
1569 echo ""
1570 echo "***** Failed components *****"
1571 for mod in $failed_components; do
1572 echo " $mod"
1573 done
1574 echo ""
1577 if [ X"$CLONE" != X ] && [ X"$clonefailed_components" != X ]; then
1578 echo ""
1579 echo "***** Components failed to clone *****"
1580 for mod in $clonefailed_components; do
1581 echo " $mod"
1582 done
1583 echo ""