@@ -22,6 +22,25 @@ shopt -s extglob
2222SKIP_CLEAN=1
2323BUILD_ALL_DEBUG=0
2424SCALA213=0
25+ UNSHIM_FAST=0
26+ UNSHIM_PARALLEL_WORLD_ONLY=0
27+ UNSHIM_REUSE_BUILT_JARS=0
28+ UNSHIM_ALLOWLIST_ONLY=0
29+
30+ SCRIPT_DIR=$( cd " $( dirname " ${BASH_SOURCE[0]} " ) " > /dev/null 2>&1 && pwd)
31+ SOURCE_DIR=$( cd " $SCRIPT_DIR /.." > /dev/null 2>&1 && pwd)
32+
33+ function first_pom_value() {
34+ local key=" $1 "
35+ local pom=" $2 "
36+ sed -n " 0,/<$key >/{s|.*<$key >\([^<]*\)</$key >.*|\1|p}" " $pom " | head -n 1
37+ }
38+
39+ function last_pom_value() {
40+ local key=" $1 "
41+ local pom=" $2 "
42+ sed -n " s|.*<$key >\([^<]*\)</$key >.*|\1|p" " $pom " | tail -n 1
43+ }
2544
2645function join_by { local IFS=" $1 " ; shift ; echo " $* " ; }
2746
@@ -56,6 +75,14 @@ function print_usage() {
5675 echo " repackage the dist module artifact using installed dependencies"
5776 echo " --scala213"
5877 echo " build 2.13 shims"
78+ echo " --unshim-fast"
79+ echo " skip Maven checks/docs, tests, build metadata, coverage, enforcer, and snapshot refresh for repeated unshim/dist iteration"
80+ echo " --parallel-world-only, --unshim-parallel-world-only"
81+ echo " build analyzer-only parallel-world output without the final Maven dist invocation"
82+ echo " --unshim-reuse-built-jars"
83+ echo " with --unshim-fast --parallel-world-only, skip shim Maven builds and reuse existing target jars"
84+ echo " --unshim-allowlist-only"
85+ echo " imply --unshim-fast --parallel-world-only --unshim-reuse-built-jars and require only unshim allowlist changes"
5986}
6087
6188function bloopInstall() {
@@ -148,6 +175,25 @@ case "$1" in
148175 SCALA213=1
149176 ;;
150177
178+ --unshim-fast|--fast-unshim)
179+ UNSHIM_FAST=1
180+ ;;
181+
182+ --parallel-world-only|--unshim-parallel-world-only)
183+ UNSHIM_PARALLEL_WORLD_ONLY=1
184+ ;;
185+
186+ --unshim-reuse-built-jars)
187+ UNSHIM_REUSE_BUILT_JARS=1
188+ ;;
189+
190+ --unshim-allowlist-only)
191+ UNSHIM_ALLOWLIST_ONLY=1
192+ UNSHIM_FAST=1
193+ UNSHIM_PARALLEL_WORLD_ONLY=1
194+ UNSHIM_REUSE_BUILT_JARS=1
195+ ;;
196+
151197--rebuild-dist-only)
152198 SKIP_DIST_DEPS=" 1"
153199 MODULE=" dist"
@@ -174,14 +220,70 @@ if [[ "$DIST_PROFILE" == *Scala213 ]]; then
174220 SCALA213=1
175221fi
176222
223+ if [[ " $UNSHIM_PARALLEL_WORLD_ONLY " == " 1" ]]; then
224+ FINAL_OP=" generate-resources"
225+ MODULE=" ${MODULE:- dist} "
226+ fi
227+
177228MVN=${MVN:- " mvn" }
178229# include options to mvn command
179230export MVN=" $MVN -Dmaven.wagon.http.retryHandler.count=3 ${MVN_OPT} "
231+ if [[ " $UNSHIM_FAST " == " 1" ]]; then
232+ export MAVEN_REFRESH_OPT=" --no-snapshot-updates"
233+ export MVN_FAST_SKIP_OPTS=" -Dmaven.test.skip=true -Drat.skip=true -Dmaven.scalastyle.skip=true -Dmaven.scaladoc.skip=true -Dmaven.javadoc.skip=true -Ddist.jar.compress=false -Djacoco.skip=true -Denforcer.skip=true -Drapids.build.info.skip=true -Dignore.shim.revisions.check=true"
234+ else
235+ export MAVEN_REFRESH_OPT=" -U"
236+ export MVN_FAST_SKIP_OPTS=" "
237+ fi
238+ export UNSHIM_FAST
239+ export UNSHIM_PARALLEL_WORLD_ONLY
240+ export UNSHIM_ALLOWLIST_ONLY
241+
242+ if [[ " $UNSHIM_REUSE_BUILT_JARS " == " 1" && \
243+ ( " $UNSHIM_FAST " ! = " 1" || " $UNSHIM_PARALLEL_WORLD_ONLY " ! = " 1" ) ]]; then
244+ echo >&2 " --unshim-reuse-built-jars requires --unshim-fast --parallel-world-only"
245+ exit 1
246+ fi
247+
248+ if [[ " $UNSHIM_ALLOWLIST_ONLY " == " 1" ]] && \
249+ git -C " $SOURCE_DIR " rev-parse --is-inside-work-tree > /dev/null 2>&1 ; then
250+ ALLOWLIST_ONLY_DIRTY=$(
251+ {
252+ git -C " $SOURCE_DIR " diff --name-only -- \
253+ . \
254+ ' :(exclude)dist/unshimmed-common-from-single-shim.txt' \
255+ ' :(exclude)dist/unshimmed-from-each-spark3xx.txt' \
256+ ' :(exclude)dist/keep-in-spark-shared.txt' \
257+ ' :(exclude)dist/keep-in-spark-shim-dirs.txt'
258+ git -C " $SOURCE_DIR " diff --cached --name-only -- \
259+ . \
260+ ' :(exclude)dist/unshimmed-common-from-single-shim.txt' \
261+ ' :(exclude)dist/unshimmed-from-each-spark3xx.txt' \
262+ ' :(exclude)dist/keep-in-spark-shared.txt' \
263+ ' :(exclude)dist/keep-in-spark-shim-dirs.txt'
264+ git -C " $SOURCE_DIR " ls-files --others --exclude-standard -- \
265+ . \
266+ ' :(exclude)dist/unshimmed-common-from-single-shim.txt' \
267+ ' :(exclude)dist/unshimmed-from-each-spark3xx.txt' \
268+ ' :(exclude)dist/keep-in-spark-shared.txt' \
269+ ' :(exclude)dist/keep-in-spark-shim-dirs.txt'
270+ } | sort -u
271+ )
272+ if [[ -n " $ALLOWLIST_ONLY_DIRTY " ]]; then
273+ echo >&2 " --unshim-allowlist-only can only reuse jars when changes are limited to dist/unshimmed*.txt or dist/keep-in-spark-*.txt"
274+ echo >&2 " $ALLOWLIST_ONLY_DIRTY "
275+ exit 1
276+ fi
277+ fi
180278
181279if [[ " $SCALA213 " == " 1" ]]; then
182280 POM_FILE=" scala2.13/pom.xml"
183281 export MVN=" $MVN -f scala2.13/"
184- $( dirname $0 ) /make-scala-version-build-files.sh 2.13
282+ if [[ " $UNSHIM_FAST " == " 1" && -f " $POM_FILE " ]]; then
283+ echo " Unshim fast: reusing existing Scala 2.13 POMs"
284+ else
285+ " $SCRIPT_DIR " /make-scala-version-build-files.sh 2.13
286+ fi
185287else
186288 POM_FILE=" pom.xml"
187289fi
@@ -216,7 +318,26 @@ case $DIST_PROFILE in
216318esac
217319
218320echo " Spark versions involved: ${SPARK_SHIM_VERSIONS[@]} ..."
219- export MVN_BASE_DIR=$( $MVN help:evaluate -Dexpression=project.basedir -q -DforceStdout)
321+ if [[ " $UNSHIM_FAST " == " 1" ]]; then
322+ if [[ " $SCALA213 " == " 1" ]]; then
323+ export MVN_BASE_DIR=" $SOURCE_DIR /scala2.13"
324+ else
325+ export MVN_BASE_DIR=" $SOURCE_DIR "
326+ fi
327+ export RAPIDS_PROJECT_VERSION=$( first_pom_value version " $POM_FILE " )
328+ export RAPIDS_SCALA_BINARY_VERSION=$( last_pom_value scala.binary.version " $POM_FILE " )
329+ else
330+ export MVN_BASE_DIR=$( $MVN help:evaluate -Dexpression=project.basedir -q -DforceStdout)
331+ fi
332+
333+ if [[ " $UNSHIM_PARALLEL_WORLD_ONLY " == " 1" ]]; then
334+ echo " Unshim parallel-world-only: preparing analyzer-only output and skipping JNI unpack, shimplify, and reduced POM generation"
335+ MVN_FAST_SKIP_OPTS=" $MVN_FAST_SKIP_OPTS -Drapids.jni.unpack.skip=true -Drapids.shimplify.skip=true -Drapids.parallel.world.skip.reduced.pom=true -Drapids.aggregator.downstream.refresh.skip=true"
336+ elif [[ " $UNSHIM_FAST " == " 1" && -d " $MVN_BASE_DIR /dist/target/jni-deps" ]]; then
337+ echo " Unshim fast: reusing existing JNI deps from $MVN_BASE_DIR /dist/target/jni-deps"
338+ MVN_FAST_SKIP_OPTS=" $MVN_FAST_SKIP_OPTS -Drapids.jni.unpack.skip=true"
339+ fi
340+ export MVN_FAST_SKIP_OPTS
220341
221342if [[ " $GEN_BLOOP " == " true" ]]; then
222343 bloopInstall
237358
238359echo " Building a combined dist jar with Shims for ${SPARK_SHIM_VERSIONS[@]} ..."
239360
361+ function refresh_fast_aggregator_jar() {
362+ [[ " $UNSHIM_FAST " == " 1" ]] || return 0
363+ local BUILD_VER=$1
364+ local agg_dir=" $MVN_BASE_DIR /aggregator/target/spark$BUILD_VER "
365+ local agg_base=" rapids-4-spark-aggregator_${RAPIDS_SCALA_BINARY_VERSION} -${RAPIDS_PROJECT_VERSION} "
366+ local shaded_jar=" $agg_dir /${agg_base} -shaded.jar"
367+ local downstream_jar=" $agg_dir /${agg_base} -spark$BUILD_VER .jar"
368+ if [[ ! -f " $shaded_jar " ]]; then
369+ echo >&2 " Expected shaded aggregator jar missing: $shaded_jar "
370+ exit 255
371+ fi
372+ if [[ -f " $downstream_jar " ]] && cmp -s " $shaded_jar " " $downstream_jar " ; then
373+ return 0
374+ fi
375+ cp -p " $shaded_jar " " $downstream_jar "
376+ }
377+ export -f refresh_fast_aggregator_jar
378+
379+ function verify_reusable_unshim_artifacts() {
380+ local BUILD_VER=$1
381+ local classifier=" spark$BUILD_VER "
382+ local api_base=" rapids-4-spark-sql-plugin-api_${RAPIDS_SCALA_BINARY_VERSION} -${RAPIDS_PROJECT_VERSION} "
383+ local agg_base=" rapids-4-spark-aggregator_${RAPIDS_SCALA_BINARY_VERSION} -${RAPIDS_PROJECT_VERSION} "
384+ local api_jar=" $MVN_BASE_DIR /sql-plugin-api/target/$classifier /${api_base} -$classifier .jar"
385+ local agg_shaded_jar=" $MVN_BASE_DIR /aggregator/target/$classifier /${agg_base} -shaded.jar"
386+ local jar_path
387+ for jar_path in " $api_jar " " $agg_shaded_jar " ; do
388+ if [[ ! -f " $jar_path " ]]; then
389+ echo >&2 " Expected reusable unshim artifact missing: $jar_path "
390+ echo >&2 " Re-run without --unshim-reuse-built-jars after source or dependency changes."
391+ exit 255
392+ fi
393+ done
394+ }
395+ export -f verify_reusable_unshim_artifacts
396+
240397function build_single_shim() {
241398 [[ " $BUILD_ALL_DEBUG " == " 1" ]] && set -x
242- BUILD_VER=$1
399+ local BUILD_VER=$1
243400 mkdir -p " $MVN_BASE_DIR /target"
244401 if (( BUILD_PARALLEL == 1 || NUM_SHIMS == 1 )) ; then
245402 # Single-shim/serial build: stream Maven output live rather than to a log
@@ -255,8 +412,8 @@ function build_single_shim() {
255412 LOG_FILE=" $MVN_BASE_DIR /target/mvn-build-$BUILD_VER .log"
256413 fi
257414
258- if [[ " $BUILD_VER " == " $BASE_VER " ]] ; then
259- SKIP_CHECKS= " false "
415+ if [[ " $BUILD_VER " == " $BASE_VER " && \
416+ ( " $UNSHIM_FAST " ! = " 1 " || " $UNSHIM_PARALLEL_WORLD_ONLY " ! = " 1 " ) ]] ; then
260417 # WORKAROUND:
261418 # maven build on L193 currently relies on aggregator dependency which
262419 # will removed by
@@ -267,24 +424,36 @@ function build_single_shim() {
267424 #
268425 MVN_PHASE=" install"
269426 else
270- SKIP_CHECKS=" true"
271427 MVN_PHASE=" package"
272428 fi
273429
430+ if [[ " $UNSHIM_FAST " == " 1" || " $BUILD_VER " != " $BASE_VER " ]]; then
431+ SKIP_CHECKS=" true"
432+ else
433+ SKIP_CHECKS=" false"
434+ fi
435+
436+ local BUILD_PROJECTS=" tools"
437+ if [[ " $UNSHIM_FAST " == " 1" ]]; then
438+ BUILD_PROJECTS=" aggregator"
439+ fi
440+
274441 echo " #### REDIRECTING mvn output to ${LOG_FILE:- stdout} ####"
275442 (
276443 if [[ " $LOG_FILE " == " " ]]; then
277444 exec 2>&1 || exit $?
278445 else
279446 exec > " $LOG_FILE " 2>&1 || exit $?
280447 fi
281- $MVN -U " $MVN_PHASE " \
448+ $MVN $MAVEN_REFRESH_OPT " $MVN_PHASE " \
282449 -DskipTests \
283450 -Dbuildver=" $BUILD_VER " \
284451 -Drat.skip=" $SKIP_CHECKS " \
285- -Dmaven.scaladoc.skip \
452+ -Dmaven.scaladoc.skip=true \
453+ -Dmaven.javadoc.skip=true \
286454 -Dmaven.scalastyle.skip=" $SKIP_CHECKS " \
287- -pl tools -am
455+ $MVN_FAST_SKIP_OPTS \
456+ -pl " $BUILD_PROJECTS " -am
288457 ) || {
289458 # Only tail when output went to a real log file; for a live stream
290459 # (/dev/tty or existing stdout) the failure output is already on screen.
@@ -294,6 +463,7 @@ function build_single_shim() {
294463 esac
295464 exit 255
296465 }
466+ refresh_fast_aggregator_jar " $BUILD_VER "
297467}
298468export -f build_single_shim
299469
@@ -310,25 +480,62 @@ export -f build_single_shim
310480time (
311481 # printf a single buildver array element per line
312482 if [[ " $SKIP_DIST_DEPS " != " 1" ]]; then
483+ if [[ " $UNSHIM_REUSE_BUILT_JARS " == " 1" ]]; then
484+ echo " Unshim fast: reusing existing per-shim jars and skipping Maven shim builds"
485+ for bv in " ${SPARK_SHIM_VERSIONS[@]} " ; do
486+ verify_reusable_unshim_artifacts " $bv "
487+ refresh_fast_aggregator_jar " $bv "
488+ done
489+ else
313490 # Execute initialize to download a massive jar for spark-rapids-jni in a single thread to
314- # avoid repeating this work in parallel
315- # Initialize sql-plugin-api only to avoid dealing with missing submodule dependencies
316- #
317- $MVN initialize -pl sql-plugin-api -am
491+ # avoid repeating this work in parallel. This is unnecessary in unshim-fast modes that skip
492+ # JNI unpacking.
493+ if [[ " $UNSHIM_FAST " == " 1" && " $MVN_FAST_SKIP_OPTS " == * " -Drapids.jni.unpack.skip=true" * ]]; then
494+ echo " Unshim fast: skipping serial Maven initialize preflight"
495+ else
496+ # Initialize sql-plugin-api only to avoid dealing with missing submodule dependencies.
497+ $MVN initialize -pl sql-plugin-api -am
498+ fi
318499
319500 printf " %s\n" " ${SPARK_SHIM_VERSIONS[@]} " | \
320501 xargs -t -I% -P " $BUILD_PARALLEL " -n 1 \
321502 bash -c ' build_single_shim "$@"' _ %
503+ fi
322504 fi
323- # This used to resume from dist. However, without including aggregator in the build
324- # the build does not properly initialize spark.version property via buildver profiles
325- # in the root pom, and we get a missing spark330 dependency even for --profile=330,331
326- # where the build does not require it. Moving it to aggregator resolves this issue with
327- # a negligible increase of the build time by ~2 seconds.
505+ if [[ " $UNSHIM_FAST " == " 1" && " $UNSHIM_REUSE_BUILT_JARS " != " 1" ]]; then
506+ for bv in " ${SPARK_SHIM_VERSIONS[@]} " ; do
507+ refresh_fast_aggregator_jar " $bv "
508+ done
509+ fi
510+ # Non-fast builds resume from aggregator so Maven initializes the buildver-derived
511+ # spark.version.classifier before dist resolves its aggregator dependency. The unshim-fast
512+ # dist path can skip that extra aggregator pass because the per-shim builds above already
513+ # installed the base aggregator jar and refreshed all target aggregator jars.
328514 joinShimBuildFrom=" aggregator"
329515 INCLUDED_BUILDVERS_OPT=-Dincluded_buildvers=$( join_by , " ${SPARK_SHIM_VERSIONS[@]} " )
330- echo " Resuming from $joinShimBuildFrom build only using $BASE_VER "
331- $MVN $FINAL_OP -rf $joinShimBuildFrom $MODULE_OPT $MVN_PROFILE_OPT $INCLUDED_BUILDVERS_OPT \
516+ if [[ " $UNSHIM_FAST " == " 1" && " $MODULE " == " dist" ]]; then
517+ if [[ " $UNSHIM_PARALLEL_WORLD_ONLY " == " 1" ]]; then
518+ echo " Unshim fast: assembling parallel-world directly without final Maven dist invocation"
519+ python3 " $SOURCE_DIR /dist/scripts/build-unshim-parallel-world.py" \
520+ --mvn-base-dir " $MVN_BASE_DIR " \
521+ --source-dir " $SOURCE_DIR " \
522+ --project-version " $RAPIDS_PROJECT_VERSION " \
523+ --scala-binary-version " $RAPIDS_SCALA_BINARY_VERSION " \
524+ --buildvers " $( join_by , " ${SPARK_SHIM_VERSIONS[@]} " ) " \
525+ --ignore-shim-revisions-check
526+ exit 0
527+ else
528+ echo " Resuming at dist only using $BASE_VER "
529+ FINAL_RESUME_OPT=" "
530+ FINAL_MODULE_OPT=" --projects dist"
531+ fi
532+ else
533+ echo " Resuming from $joinShimBuildFrom build only using $BASE_VER "
534+ FINAL_RESUME_OPT=" -rf $joinShimBuildFrom "
535+ FINAL_MODULE_OPT=" $MODULE_OPT "
536+ fi
537+ $MVN $FINAL_OP $FINAL_RESUME_OPT $FINAL_MODULE_OPT $MVN_PROFILE_OPT $INCLUDED_BUILDVERS_OPT \
332538 -Dbuildver=" $BASE_VER " \
333- -DskipTests -Dmaven.scaladoc.skip
539+ -DskipTests -Dmaven.scaladoc.skip=true -Dmaven.javadoc.skip=true \
540+ $MVN_FAST_SKIP_OPTS
334541)
0 commit comments