Skip to content
This repository was archived by the owner on Dec 14, 2023. It is now read-only.

Commit b897081

Browse files
committed
Overhaul bootstrap.sh script:
- Initial support for build variants (e.g., LTO, sanitizers). - Build libgo deps from bootstrap script. We will need to do this for build variants. - Filter everything from libgo's make output except package names. This makes the output much easier to read.
1 parent 23dea24 commit b897081

File tree

7 files changed

+179
-71
lines changed

7 files changed

+179
-71
lines changed

Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ check-libgo: bootstrap
1414
check-llgo: bootstrap
1515
$(llvmdir)/bin/llvm-lit -s test
1616

17-
workdir/.bootstrap-stamp: workdir/.update-libgo-stamp workdir/.update-clang-stamp bootstrap.sh build/*.go cmd/gllgo/*.go cmd/cc-wrapper/*.go debug/*.go irgen/*.go ssaopt/*.go
17+
workdir/.bootstrap-stamp: workdir/.build-libgodeps-stamp bootstrap.sh build/*.go cmd/gllgo/*.go cmd/cc-wrapper/*.go debug/*.go irgen/*.go ssaopt/*.go
1818
./bootstrap.sh $(bootstrap) -j$(j)
1919

20+
workdir/.build-libgodeps-stamp: workdir/.update-clang-stamp workdir/.update-libgo-stamp bootstrap.sh
21+
./bootstrap.sh libgodeps -j$(j)
22+
2023
workdir/.update-clang-stamp: update_clang.sh
2124
./update_clang.sh
2225

23-
workdir/.update-libgo-stamp: workdir/.update-clang-stamp update_libgo.sh
26+
workdir/.update-libgo-stamp: update_libgo.sh
2427
./update_libgo.sh
2528

2629
.SUFFIXES:

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ If you built a newer GCC following the linked instructions above, you will need
2222
export LD_LIBRARY_PATH=/path/to/gcc-inst/lib64:$LD_LIBRARY_PATH
2323
export CC=`which gcc`
2424
export CXX=`which g++`
25+
export LIBGO_CFLAGS=--gcc-toolchain=/path/to/gcc-inst
2526

2627
To build and install llgo:
2728

bootstrap.sh

+117-52
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
#!/bin/sh -e
1+
#!/usr/bin/env bash
2+
3+
set -e
24

35
llgodir=$(dirname "$0")
46
llgodir=$(cd "$llgodir" && pwd)
@@ -7,73 +9,136 @@ workdir=$llgodir/workdir
79
gofrontenddir=$workdir/gofrontend
810
gofrontend_builddir=$workdir/gofrontend_build
911

10-
bootstrap_type="$1"
11-
shift
12-
13-
case "$bootstrap_type" in
14-
quick | full)
12+
case "$1" in
13+
libgodeps | quick | full)
14+
bootstrap_type="$1"
15+
shift
1516
;;
1617

1718
*)
18-
echo "Bootstrap type must be 'quick' or 'full'"
19-
exit 1
2019
;;
2120
esac
2221

23-
configure_flags="--disable-multilib --without-libatomic"
22+
llgo_cc="${LIBGO_CC:-$workdir/clang_build/bin/clang} $LIBGO_CFLAGS"
23+
llgo_cxx="${LIBGO_CXX:-$workdir/clang_build/bin/clang++} $LIBGO_CFLAGS"
24+
25+
build_libgodeps() {
26+
local cflags="$1"
27+
local destdir="$2"
28+
local variantname="$3"
29+
local makeflags="$4"
30+
31+
for d in libbacktrace libffi ; do
32+
rm -rf $destdir/$d
33+
mkdir -p $destdir/$d
34+
case $d in
35+
libbacktrace)
36+
config_flags="--enable-host-shared"
37+
;;
38+
*)
39+
config_flags=""
40+
;;
41+
esac
42+
43+
echo "# Configuring $variantname $d."
44+
(cd $destdir/$d && CC="$llgo_cc $cflags" $gofrontenddir/$d/configure --disable-multilib $config_flags > $workdir/${d}-config.log 2>&1 || (echo "# Configure failed, see $workdir/${d}-config.log" && exit 1))
45+
echo "# Building $variantname $d."
46+
make -C $destdir/$d $makeflags > $workdir/${d}-make.log 2>&1 || (echo "# Build failed, see $workdir/${d}-make.log" && exit 1)
47+
done
48+
}
49+
50+
build_libgo_stage() {
51+
local goc="$1"
52+
local cflags="$2"
53+
local gocflags="$3"
54+
local destdir="$4"
55+
local variantname="$5"
56+
local makeflags="$6"
57+
58+
# Wrap Clang in a program that understands -fgo-dump-spec and -fplan9-extensions.
59+
libgo_cc="$llgo_cc $cflags"
60+
libgo_wrapped_cc="env REAL_CC=$(echo $libgo_cc | sed -e 's/ /@SPACE@/g') $workdir/cc-wrapper"
61+
62+
mkdir -p $destdir
63+
echo "# Configuring $variantname libgo."
64+
(cd $destdir && $gofrontenddir/libgo/configure --disable-multilib --without-libatomic CC="$libgo_wrapped_cc" GOC="$goc -no-prefix $GOCFLAGS $gocflags" > $workdir/${variantname}-config.log 2>&1 || (echo "# Configure failed, see $workdir/${variantname}-config.log" && exit 1))
65+
echo "# Building $variantname libgo."
66+
make -C $destdir $makeflags 2>&1 | tee $workdir/${variantname}-make.log | $workdir/makefilter
67+
test "${PIPESTATUS[0]}" = "0" || (echo "# Build failed, see $workdir/${variantname}-make.log" && exit 1)
68+
echo
69+
}
70+
71+
build_libgo_variant() {
72+
local goc="$1"
73+
local cflags="$2"
74+
local gocflags="$3"
75+
local variantname="$4"
76+
local makeflags="$5"
77+
78+
local destdir="$workdir/gofrontend_build_$variantname"
79+
rm -rf $destdir
80+
build_libgodeps "$cflags" "$destdir" "$variantname" "$makeflags"
81+
build_libgo_stage "$goc" "$cflags" "$gocflags" "$destdir/libgo" "$variantname" "$makeflags"
82+
}
83+
84+
if [ "$bootstrap_type" = "libgodeps" ]; then
85+
build_libgodeps "$LIBGO_CFLAGS" "$gofrontend_builddir" "normal" "$*"
86+
touch $workdir/.build-libgodeps-stamp
87+
exit 0
88+
fi
2489

25-
# Wrap Clang in a program that understands -fgo-dump-spec and -fplan9-extensions.
26-
(cd $llgodir/cmd/cc-wrapper && go build -o $workdir/cc-wrapper)
27-
libgo_wrapped_cc="$(echo "${LIBGO_CC:-$workdir/clang_build/bin/clang}" | sed -e 's/ /@SPACE@/g')"
28-
libgo_cc="env REAL_CC=${libgo_wrapped_cc} $workdir/cc-wrapper"
90+
if [ "$bootstrap_type" != "" ]; then
91+
# Clean up any previous libgo stages.
92+
rm -rf $gofrontend_builddir/libgo* $workdir/gofrontend_build_*
2993

30-
# Clean up any previous libgo stages.
31-
rm -rf $gofrontend_builddir/libgo*
94+
echo "# Building helper programs."
95+
(cd $llgodir/cmd/cc-wrapper && go build -o $workdir/cc-wrapper)
96+
(cd $llgodir/cmd/makefilter && go build -o $workdir/makefilter)
3297

33-
# Build a stage1 compiler with gc.
34-
(cd $llgodir/cmd/gllgo && go build -o $workdir/gllgo-stage1)
98+
# Build a stage1 compiler with gc.
99+
echo "# Building stage1 compiler."
100+
(cd $llgodir/cmd/gllgo && go build -o $workdir/gllgo-stage1)
35101

36-
# Build libgo with the stage1 compiler.
37-
mkdir -p $gofrontend_builddir/libgo-stage1
38-
(cd $gofrontend_builddir/libgo-stage1 && $gofrontenddir/libgo/configure $configure_flags CC="$libgo_cc" GOC="$workdir/gllgo-stage1 -no-prefix")
39-
make -C $gofrontend_builddir/libgo-stage1 "$@"
102+
# Build libgo with the stage1 compiler.
103+
build_libgo_stage $workdir/gllgo-stage1 "" "" $gofrontend_builddir/libgo-stage1 stage1 "$*"
40104

41-
# Set up a directory which when added to $PATH causes "gccgo" to resolve
42-
# to our stage1 compiler. This is necessary because the logic in "go build"
43-
# for locating the compiler is fixed.
44-
mkdir -p $gofrontend_builddir/stage1-path
45-
ln -sf $workdir/gllgo-stage1 $gofrontend_builddir/stage1-path/gccgo
105+
# Set up a directory which when added to $PATH causes "gccgo" to resolve
106+
# to our stage1 compiler. This is necessary because the logic in "go build"
107+
# for locating the compiler is fixed.
108+
mkdir -p $gofrontend_builddir/stage1-path
109+
ln -sf $workdir/gllgo-stage1 $gofrontend_builddir/stage1-path/gccgo
46110

47-
# Build a stage2 compiler using the stage1 compiler and libgo.
48-
gllgoflags="-no-prefix -L$gofrontend_builddir/libgo-stage1 -L$gofrontend_builddir/libgo-stage1/.libs -static-libgo"
49-
(cd $llgodir/cmd/gllgo && PATH=$gofrontend_builddir/stage1-path:$PATH go build -compiler gccgo -gccgoflags "$gllgoflags" -o $workdir/gllgo-stage2)
111+
# Build a stage2 compiler using the stage1 compiler and libgo.
112+
echo "# Building stage2 compiler."
113+
gllgoflags="-no-prefix -L$gofrontend_builddir/libgo-stage1 -L$gofrontend_builddir/libgo-stage1/.libs -static-libgo $GOCFLAGS"
114+
(cd $llgodir/cmd/gllgo && PATH=$gofrontend_builddir/stage1-path:$PATH CC="$llgo_cc" CXX="$llgo_cxx" go build -compiler gccgo -gccgoflags "$gllgoflags" -o $workdir/gllgo-stage2)
50115

51-
# If this is a quick bootstrap, do not rebuild libgo with the stage2 compiler.
52-
# Instead, use the stage1 libgo.
116+
# If this is a quick bootstrap, do not rebuild libgo with the stage2 compiler.
117+
# Instead, use the stage1 libgo.
53118

54-
if [ "$bootstrap_type" == "full" ] ; then
55-
# Build libgo with the stage2 compiler.
56-
mkdir -p $gofrontend_builddir/libgo-stage2
57-
(cd $gofrontend_builddir/libgo-stage2 && $gofrontenddir/libgo/configure $configure_flags CC="$libgo_cc" GOC="$workdir/gllgo-stage2 -no-prefix")
58-
make -C $gofrontend_builddir/libgo-stage2 "$@"
119+
if [ "$bootstrap_type" == "full" ] ; then
120+
# Build libgo with the stage2 compiler.
121+
build_libgo_stage $workdir/gllgo-stage2 "" "" $gofrontent_builddir/libgo-stage2 stage2 "$*"
59122

60-
# Set up $gllgoflags to use the stage2 libgo.
61-
gllgoflags="-no-prefix -L$gofrontend_builddir/libgo-stage2 -L$gofrontend_builddir/libgo-stage2/.libs -static-libgo"
62-
fi
123+
# Set up $gllgoflags to use the stage2 libgo.
124+
gllgoflags="-no-prefix -L$gofrontend_builddir/libgo-stage2 -L$gofrontend_builddir/libgo-stage2/.libs -static-libgo $GOCFLAGS"
125+
fi
63126

64-
# Set up a directory which when added to $PATH causes "gccgo" to resolve
65-
# to our stage2 compiler.
66-
mkdir -p $gofrontend_builddir/stage2-path
67-
ln -sf $workdir/gllgo-stage2 $gofrontend_builddir/stage2-path/gccgo
127+
# Set up a directory which when added to $PATH causes "gccgo" to resolve
128+
# to our stage2 compiler.
129+
mkdir -p $gofrontend_builddir/stage2-path
130+
ln -sf $workdir/gllgo-stage2 $gofrontend_builddir/stage2-path/gccgo
68131

69-
# Build the stage3 compiler.
70-
(cd $llgodir/cmd/gllgo && PATH=$gofrontend_builddir/stage2-path:$PATH go build -compiler gccgo -gccgoflags "$gllgoflags" -o $workdir/gllgo-stage3)
132+
# Build the stage3 compiler.
133+
echo "# Building stage3 compiler."
134+
(cd $llgodir/cmd/gllgo && PATH=$gofrontend_builddir/stage2-path:$PATH CC="$llgo_cc" CXX="$llgo_cxx" go build -compiler gccgo -gccgoflags "$gllgoflags" -o $workdir/gllgo-stage3)
71135

72-
# Strip the compiler binaries. The binaries are currently only
73-
# expected to compare equal modulo debug info.
74-
strip -R .note.gnu.build-id -o $workdir/gllgo-stage2.stripped $workdir/gllgo-stage2
75-
strip -R .note.gnu.build-id -o $workdir/gllgo-stage3.stripped $workdir/gllgo-stage3
136+
# Strip the compiler binaries. The binaries are currently only
137+
# expected to compare equal modulo debug info.
138+
strip -R .note.gnu.build-id -o $workdir/gllgo-stage2.stripped $workdir/gllgo-stage2
139+
strip -R .note.gnu.build-id -o $workdir/gllgo-stage3.stripped $workdir/gllgo-stage3
76140

77-
cmp $workdir/gllgo-stage2.stripped $workdir/gllgo-stage3.stripped && \
78-
echo "Bootstrap completed successfully" && touch $workdir/.bootstrap-stamp && exit 0 || \
79-
echo "Bootstrap failed, binaries differ" && exit 1
141+
cmp $workdir/gllgo-stage2.stripped $workdir/gllgo-stage3.stripped && \
142+
echo "# Bootstrap completed successfully." && touch $workdir/.bootstrap-stamp || \
143+
(echo "# Bootstrap failed, binaries differ." && exit 1)
144+
fi

cmd/gllgo/gllgo.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,14 @@ func getDataInlineAsm(data []byte) string {
381381
return string(edata[0 : j+2])
382382
}
383383

384+
// Get the lib-relative path to the standard libraries for the given driver
385+
// options. This is normally '.' but can vary for cross compilation, LTO,
386+
// sanitizers etc.
387+
func getVariantDir(opts *driverOptions) string {
388+
path := "."
389+
return path
390+
}
391+
384392
func performAction(opts *driverOptions, kind actionKind, inputs []string, output string) error {
385393
switch kind {
386394
case actionPrint:
@@ -391,8 +399,7 @@ func performAction(opts *driverOptions, kind actionKind, inputs []string, output
391399
os.Stdout.Write(out)
392400
return err
393401
case "-print-multi-os-directory":
394-
// TODO(pcc): Vary this for cross-compilation.
395-
fmt.Println(".")
402+
fmt.Println(getVariantDir(opts))
396403
return nil
397404
case "--version":
398405
displayVersion()
@@ -541,7 +548,7 @@ func performAction(opts *driverOptions, kind actionKind, inputs []string, output
541548
linkerPath = opts.bprefix + "gcc"
542549

543550
if opts.prefix != "" {
544-
libdir := filepath.Join(opts.prefix, "lib")
551+
libdir := filepath.Join(opts.prefix, "lib", getVariantDir(opts))
545552
args = append(args, "-L", libdir)
546553
if !opts.staticLibgo {
547554
args = append(args, "-Wl,-rpath,"+libdir)

cmd/makefilter/main.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"io"
6+
"os"
7+
"strings"
8+
)
9+
10+
// A simple filter program which improves the readability of libgo's build
11+
// output by filtering out everything except the package names.
12+
func main() {
13+
stdin := bufio.NewReader(os.Stdin)
14+
pkgs := make(map[string]struct{})
15+
for {
16+
line, err := stdin.ReadString('\n')
17+
if err == io.EOF {
18+
return
19+
} else if err != nil {
20+
panic("read error: " + err.Error())
21+
}
22+
line = line[0 : len(line)-1]
23+
if strings.HasPrefix(line, "libtool: compile:") {
24+
words := strings.Split(line, " ")
25+
for _, word := range words {
26+
if strings.HasPrefix(word, "-fgo-pkgpath=") {
27+
pkg := word[13:]
28+
if _, ok := pkgs[pkg]; !ok {
29+
os.Stdout.WriteString(pkg + "\n")
30+
pkgs[pkg] = struct{}{}
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}

install.sh

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ else
2424
make -C $gofrontend_builddir/libgo-stage1 install "prefix=$prefix"
2525
fi
2626

27+
# Install the build variant libraries, but not the export data, which is shared
28+
# between variants.
29+
for i in $workdir/gofrontend_build_*/libgo ; do
30+
if [ -d $i ] ; then
31+
make -C $i install-toolexeclibLIBRARIES install-toolexeclibLTLIBRARIES \
32+
"prefix=$prefix"
33+
fi
34+
done
35+
2736
# Set up the symlink required by llgo-go.
2837
mkdir -p "$prefix/lib/llgo/go-path"
2938
ln -sf ../../../bin/llgo "$prefix/lib/llgo/go-path/gccgo"

update_libgo.sh

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/bin/sh -e
22

3-
# Fetch libgo and its dependencies, and build the dependencies.
4-
# We build libgo itself while bootstrapping.
3+
# Fetch libgo and its dependencies.
54

65
llgodir=$(dirname "$0")
76
llgodir=$(cd "$llgodir" && pwd)
@@ -14,7 +13,6 @@ gccrev=209880
1413

1514
workdir=$llgodir/workdir
1615
gofrontenddir=$workdir/gofrontend
17-
gofrontend_builddir=$workdir/gofrontend_build
1816

1917
mkdir -p $workdir
2018
if [ -d $gofrontenddir/.hg ] ; then
@@ -54,17 +52,6 @@ echo "#define IS_ABSOLUTE_PATH(path) ((path)[0] == '/')" > $gofrontenddir/includ
5452

5553
for d in libbacktrace libffi ; do
5654
svn co -r $gccrev $gccrepo/$d $gofrontenddir/$d
57-
mkdir -p $gofrontend_builddir/$d
58-
case $d in
59-
libbacktrace)
60-
config_flags="--enable-host-shared"
61-
;;
62-
*)
63-
config_flags=""
64-
;;
65-
esac
66-
(cd $gofrontend_builddir/$d && CC="${LIBGO_CC:-$workdir/clang_build/bin/clang}" $gofrontenddir/$d/configure --disable-multilib $config_flags)
67-
make -C $gofrontend_builddir/$d -j4
6855
done
6956

7057
touch $workdir/.update-libgo-stamp

0 commit comments

Comments
 (0)