33set -eu
44set -o pipefail
55
6+ readonly ROOT_DIR=" $( cd " $( dirname " ${0} " ) /.." && pwd) "
67readonly PROGDIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
78readonly BUILDPACKDIR=" $( cd " ${PROGDIR} /.." && pwd) "
89
10+ # shellcheck source=SCRIPTDIR/.util/print.sh
11+ source " ${ROOT_DIR} /scripts/.util/print.sh"
12+
913function main() {
14+ local targets=()
1015 while [[ " ${# } " != 0 ]]; do
1116 case " ${1} " in
1217 --help|-h)
@@ -15,6 +20,11 @@ function main() {
1520 exit 0
1621 ;;
1722
23+ --target)
24+ targets+=(" ${2} " )
25+ shift 2
26+ ;;
27+
1828 " " )
1929 # skip if the argument is empty
2030 shift 1
@@ -25,10 +35,86 @@ function main() {
2535 esac
2636 done
2737
38+ if [[ ${# targets[@]} -eq 0 ]]; then
39+ # Read targets from buildpack.toml
40+ local buildpack_toml=" ${BUILDPACKDIR} /buildpack.toml"
41+ if [[ -f " ${buildpack_toml} " ]]; then
42+ util::print::info " Reading targets from ${buildpack_toml} ..."
43+ # Parse [[targets]] sections from buildpack.toml
44+ local in_targets=false
45+ local current_os=" "
46+ local current_arch=" "
47+
48+ while IFS= read -r line || [[ -n " ${line} " ]]; do
49+ # Check if we're entering a targets section
50+ if [[ " ${line} " =~ ^\[\[ targets\]\] ]]; then
51+ # Save previous target if we have both os and arch
52+ if [[ " ${in_targets} " == true && -n " ${current_os} " && -n " ${current_arch} " ]]; then
53+ targets+=(" ${current_os} /${current_arch} " )
54+ fi
55+ in_targets=true
56+ current_os=" "
57+ current_arch=" "
58+ elif [[ " ${in_targets} " == true ]]; then
59+ # Check if we're leaving the targets section (next section starts)
60+ if [[ " ${line} " =~ ^\[\[ ]] && ! [[ " ${line} " =~ ^\[\[ targets\]\] ]]; then
61+ # Save current target before leaving
62+ if [[ -n " ${current_os} " && -n " ${current_arch} " ]]; then
63+ targets+=(" ${current_os} /${current_arch} " )
64+ fi
65+ in_targets=false
66+ current_os=" "
67+ current_arch=" "
68+ # Extract os value
69+ elif [[ " ${line} " =~ ^[[:space:]]* os[[:space:]]* = [[:space:]]* \" ([^\" ]+)\" ]]; then
70+ current_os=" ${BASH_REMATCH[1]} "
71+ # If we already have arch, add the target immediately
72+ if [[ -n " ${current_arch} " ]]; then
73+ targets+=(" ${current_os} /${current_arch} " )
74+ current_os=" "
75+ current_arch=" "
76+ fi
77+ # Extract arch value
78+ elif [[ " ${line} " =~ ^[[:space:]]* arch[[:space:]]* = [[:space:]]* \" ([^\" ]+)\" ]]; then
79+ current_arch=" ${BASH_REMATCH[1]} "
80+ # If we already have os, add the target immediately
81+ if [[ -n " ${current_os} " ]]; then
82+ targets+=(" ${current_os} /${current_arch} " )
83+ current_os=" "
84+ current_arch=" "
85+ fi
86+ fi
87+ fi
88+ done < " ${buildpack_toml} "
89+
90+ # Handle last target if we ended while still in targets section
91+ if [[ " ${in_targets} " == true && -n " ${current_os} " && -n " ${current_arch} " ]]; then
92+ targets+=(" ${current_os} /${current_arch} " )
93+ fi
94+
95+ if [[ ${# targets[@]} -gt 0 ]]; then
96+ util::print::info " Found ${# targets[@]} target(s) in buildpack.toml: ${targets[*]} "
97+ else
98+ # Fallback to default if no targets found
99+ targets=(" linux/amd64" )
100+ util::print::info " No targets found in buildpack.toml, using default: linux/amd64"
101+ fi
102+ else
103+ # Fallback to default if buildpack.toml not found
104+ targets=(" linux/amd64" )
105+ util::print::info " buildpack.toml not found, using default target: linux/amd64"
106+ fi
107+ fi
108+
28109 mkdir -p " ${BUILDPACKDIR} /bin"
29110
30111 run::build
31112 cmd::build
113+
114+ # # For backwards compatibility with amd64 wokflows
115+ if [[ ${# targets[@]} -eq 1 && " ${targets[0]} " == " linux/amd64" ]]; then
116+ cp -r " ${BUILDPACKDIR} /linux/amd64/bin/" " ${BUILDPACKDIR} /"
117+ fi
32118}
33119
34120function usage() {
@@ -38,39 +124,50 @@ build.sh [OPTIONS]
38124Builds the buildpack executables.
39125
40126OPTIONS
41- --help -h prints the command usage
127+ --target strings Target platforms to build for.
128+ Targets should be in the format '[os][/arch][/variant]'.
129+ - To specify two different architectures: '--target "linux/amd64" --target "linux/arm64"'
130+ If not provided, targets will be read from buildpack.toml [[targets]] sections.
131+ --help -h prints the command usage
42132USAGE
43133}
44134
45135function run::build() {
46136 if [[ -f " ${BUILDPACKDIR} /run/main.go" ]]; then
47- pushd " ${BUILDPACKDIR} /bin" > /dev/null || return
48- printf " %s" " Building run... "
137+ pushd " ${BUILDPACKDIR} " > /dev/null || return
138+ for target in " ${targets[@]} " ; do
139+ platform=$( echo " ${target} " | cut -d ' /' -f1)
140+ arch=$( echo " ${target} " | cut -d' /' -f2)
49141
50- GOOS=linux \
51- CGO_ENABLED=0 \
52- go build \
53- -ldflags=" -s -w" \
54- -o " run" \
55- " ${BUILDPACKDIR} /run"
142+ util::print::title " Building run... for platform: ${platform} and arch: ${arch} "
143+
144+ GOOS=$platform \
145+ GOARCH=$arch \
146+ CGO_ENABLED=0 \
147+ go build \
148+ -ldflags=" -s -w" \
149+ -o " ${platform} /${arch} /bin/run" \
150+ " ${BUILDPACKDIR} /run"
56151
57- echo " Success!"
152+ echo " Success!"
58153
59- names=(" detect" )
154+ names=(" detect" )
60155
61- if [ -f " ${BUILDPACKDIR} /extension.toml" ]; then
62- names+=(" generate" )
63- else
64- names+=(" build" )
65- fi
156+ if [ -f " ${BUILDPACKDIR} /extension.toml" ]; then
157+ names+=(" generate" )
158+ else
159+ names+=(" build" )
160+ fi
66161
67- for name in " ${names[@]} " ; do
68- printf " %s" " Linking ${name} ... "
162+ for name in " ${names[@]} " ; do
163+ printf " %s" " Linking ${name} ... "
69164
70- ln -sf " run" " ${name} "
165+ ln -fs " run" " ${platform} / ${arch} /bin/ ${name} "
71166
72- echo " Success!"
167+ echo " Success!"
168+ done
73169 done
170+
74171 popd > /dev/null || return
75172 fi
76173}
@@ -80,21 +177,26 @@ function cmd::build() {
80177 local name
81178 for src in " ${BUILDPACKDIR} " /cmd/* ; do
82179 name=" $( basename " ${src} " ) "
83-
84- if [[ -f " ${src} /main.go" ]]; then
85- printf " %s" " Building ${name} ... "
86-
87- GOOS=" linux" \
88- CGO_ENABLED=0 \
89- go build \
90- -ldflags=" -s -w" \
91- -o " ${BUILDPACKDIR} /bin/${name} " \
92- " ${src} /main.go"
93-
94- echo " Success!"
95- else
96- printf " %s" " Skipping ${name} ... "
97- fi
180+ for target in " ${targets[@]} " ; do
181+ platform=$( echo " ${target} " | cut -d ' /' -f1)
182+ arch=$( echo " ${target} " | cut -d' /' -f2)
183+
184+ if [[ -f " ${src} /main.go" ]]; then
185+ util::print::title " Building ${name} ... for platform: ${platform} and arch: ${arch} "
186+
187+ GOOS=$platform \
188+ GOARCH=$arch \
189+ CGO_ENABLED=0 \
190+ go build \
191+ -ldflags=" -s -w" \
192+ -o " ${BUILDPACKDIR} /${platform} /${arch} /bin/${name} " \
193+ " ${src} /main.go"
194+
195+ echo " Success!"
196+ else
197+ printf " %s" " Skipping ${name} ... "
198+ fi
199+ done
98200 done
99201 fi
100202}
0 commit comments