3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 # Finds the optimal update_pch settings that results in,
11 # per module and library, the fastest build time and
12 # smallest intermediate files (.o/.obj) output.
14 # Usage: update_pch_autotune.sh [<module1> <module2>]
15 # Invoke: /opt/lo/bin/make cmd cmd="./bin/update_pch_autotune.sh [..]"
17 # The resulting values may be entered in update_pch
18 # to be use for generating PCH in the future.
19 # Run this script after major header changes.
22 root
=`cd $root/.. && pwd`
26 modules
=`ls ./*/inc/pch/precompiled_*.hxx | sed -e s%./%% -e s%/.*%% | uniq`
31 if [[ "$OSTYPE" == "cygwin" ]]; then
39 local START
=$
(date +%s.
%N
)
41 $MAKE -sr "$module" > /dev
/null
45 # Spurious failures happen.
46 $MAKE "$module.build" > /dev
/null
50 local END
=$
(date +%s.
%N1
)
51 build_time
=$
(printf %.1f $
(echo "$END - $START" |
bc))
57 # The total size of the object files.
58 size
="$(du -s workdir/CxxObject/$module/ | awk '{print $1}')"
59 # Add the pch file size.
60 filename_rel
="workdir/PrecompiledHeader/nodebug/$(basename $header)*"
61 filename_dbg
="workdir/PrecompiledHeader/debug/$(basename $header)*"
62 if [[ $filename_rel -nt $filename_dbg ]]; then
63 pch_size
="$(du -s $filename_rel | awk '{print $1}' | paste -sd+ | bc)"
65 pch_size
="$(du -s $filename_dbg | awk '{print $1}' | paste -sd+ | bc)"
67 size
="$(echo "$pch_size + $size" | bc)"
69 # Compute a score based on the build time and size.
70 # The shorter the build time, and smaller disk usage, the higher the score.
71 score
=$
(printf %.2f $
(echo "10000 / ($build_time * e($size/1048576))" |
bc -l))
77 local msg
="$module.$libname, ${@:3}, "
79 .
/bin
/update_pch
"$module" "$libname" "${@:3}" --silent
86 summary
="$build_time, $size, $score"
89 new_best_for_cuttof
=$
(echo "$score > $best_score_for_cuttof" |
bc -l)
90 if [ $new_best_for_cuttof -eq 1 ];
92 best_score_for_cuttof
=$score
95 new_best
=$
(echo "$score > $best_score" |
bc -l)
96 if [ $new_best -eq 1 ];
100 best_time
=$build_time
102 summary
="$build_time, $size, $score,*"
106 # Skip if pch is not updated.
113 function args_to_table
()
119 IFS
=' ' read -r -a aargs
<<< $best_args
120 for index
in "${!aargs[@]}"
122 if [ "${aargs[index]}" = "--include:system" ];
125 elif [ "${aargs[index]}" = "--exclude:system" ];
128 elif [ "${aargs[index]}" = "--include:module" ];
131 elif [ "${aargs[index]}" = "--exclude:module" ];
134 elif [ "${aargs[index]}" = "--include:local" ];
137 elif [ "${aargs[index]}" = "--exclude:local" ];
140 elif [[ "${aargs[index]}" == *"cutoff"* ]]
142 cutoff
=$
(echo "${aargs[index]}" |
grep -Po '\-\-cutoff\=\K\d+')
146 local key
=$
(printf "'%s.%s'" $module $libname)
147 echo "$(printf " %-36s: (%2d
, %s
, %s
, %s
), # %5.1f" $key $cutoff $sys $mod $loc $best_time)"
150 for module
in $modules; do
152 # Build without pch includes as sanity check.
153 #run "$root" "$module" --cutoff=999
155 # Build before updating pch.
156 $MAKE "$module.build" > /dev
/null
159 # Build with dependencies before updating pch.
160 echo "Failed to build $module, building known state with dependencies..."
161 .
/bin
/update_pch.sh
"$module" > /dev
/null
162 $MAKE "$module.clean" > /dev
/null
163 $MAKE "$module.all" > /dev
/null
167 echo "Failed to build $module with dependencies, building all..."
171 >&2 echo "Broken build. Please revert changes and try again."
177 # Find pch files in the module to update.
178 headers
=`find $root/$module/ -type f -iname "precompiled_*.hxx"`
180 # Each pch belongs to a library.
181 for header
in $headers; do
182 libname
=`echo $header | sed -e s/.*precompiled_// -e s/\.hxx//`
183 #TODO: Backup the header and restore when last tune fails.
185 # Force update on first try below.
186 echo "Autotuning $module.$libname..."
187 .
/bin
/update_pch
"$module" "$libname" --cutoff=999 --silent --force
195 best_score_for_cuttof
=0
196 #run "$root" "$module" "--cutoff=$i" --include:system --exclude:module --exclude:local
197 run
"$root" "$module" "--cutoff=$i" --exclude:system
--exclude:module
--exclude:local
198 #run "$root" "$module" "--cutoff=$i" --include:system --include:module --exclude:local
199 run
"$root" "$module" "--cutoff=$i" --exclude:system
--include:module
--exclude:local
200 #run "$root" "$module" "--cutoff=$i" --include:system --exclude:module --include:local
201 run
"$root" "$module" "--cutoff=$i" --exclude:system
--exclude:module
--include:local
202 #run "$root" "$module" "--cutoff=$i" --include:system --include:module --include:local
203 run
"$root" "$module" "--cutoff=$i" --exclude:system
--include:module
--include:local
205 if [ $i -gt $
((best_cutoff
+2)) ];
207 score_too_low
=$
(echo "$best_score_for_cuttof < $best_score / 1.10" |
bc -l)
208 if [ $score_too_low -eq 1 ];
210 echo "Score hit low of $best_score_for_cuttof, well below overall best of $best_score. Stopping."
216 .
/bin
/update_pch
"$module" "$libname" $best_args --force --silent
217 echo "> $module.$libname, $best_args, $best_time, $size, $score"
221 table
+="$(args_to_table)"
226 echo "Update the relevant lines in ./bin/update_pch script:"