forked from yugabyte/yugabyte-db
-
Notifications
You must be signed in to change notification settings - Fork 0
/
yb_build.sh
executable file
·2084 lines (1871 loc) · 66.2 KB
/
yb_build.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
#
# Copyright (c) YugaByte, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations
# under the License.
#
set -euo pipefail
script_name=${0##*/}
script_name=${script_name%.*}
# shellcheck source=build-support/common-test-env.sh
. "${BASH_SOURCE%/*}"/build-support/common-test-env.sh
ensure_option_has_arg() {
if [[ $# -lt 2 ]]; then
echo "Command line option $1 expects an argument" >&2
exit 1
fi
}
show_help() {
cat >&2 <<-EOT
yb_build.sh (or "ybd") is the main build tool for Yugabyte Database.
Usage: ${0##*/} [<options>] [<build_type>] [<target_keywords>] [<yb_env_var_settings>]
Options:
--help, -h
Show help.
Build options:
--arch <architecture>
Build for the given architecture. Currently only relevant for Apple Silicon where we can build
for x86_64 and arm64 (no cross-compilation support yet).
--compiler-type
Specify compiler type, e.g. gcc, clang, or a specific version, e.g. gcc10 or clang12.
--gcc, --gcc<version>, --clang, --clang<version>
A shorter way to achieve the same thing as --compiler-type.
-j <parallelism>, -j<parallelism>
Build using the given number of concurrent jobs (defaults to the number of CPUs).
--clean
Remove the build directory for the appropriate build type before building.
--clean-venv
Remove and re-create the Python virtual environment before building.
--clean-all
Remove all build directories and the Python virtual environment before building.
--clean-force, --cf, -cf
A combination of --clean and --force.
--clean-thirdparty
Remove previously built third-party dependencies and rebuild them. Implies --clean.
--force, -f, -y
Run a clean build without asking for confirmation even if a clean build was recently done.
--skip-build, --sb
Skip all kinds of build (C++, Java)
--skip-java-build, --skip-java, --sjb, --sj, --no-java, --nj
Do not package and install java source code.
--skip-cxx-build, --scb
Skip C++ build. This is useful when repeatedly debugging tests using this tool and not making
any changes to the code.
--no-postgres, --skip-postgres, --np, --sp
Skip PostgreSQL build
--no-latest-symlink
Disable the creation/overwriting of the "latest" symlink in the build directory.
--no-tests, --skip-tests
Do not build tests
--no-tcmalloc
Do not use tcmalloc.
--use-google-tcmalloc, --google-tcmalloc
Use Google's implementation of tcmalloc from https://github.com/google/tcmalloc
--no-google-tcmalloc, --use-gperftools-tcmalloc, --gperftools-tcmalloc
Use the gperftools implementation of tcmalloc
--clean-postgres
Do a clean build of the PostgreSQL subtree.
--rebuild-postgres
Clean and rebuild PostgeSQL code
--java-only, --jo
Only build Java code
--resolve-java-dependencies
Force Maven to download all Java dependencies to the local repository
--build-yugabyted-ui
Build yugabyted-ui. If specified with --cmake-only, it won't be built.
--target, --targets
Pass the given target or set of targets to make or ninja.
--rebuild-file <source_file_to_rebuild>
The .o file corresponding to the given source file will be deleted from the build directory
before the build.
--rebuild-file <target_name>
Combines --target and --rebuild-file. Currently only works if target name matches the object
file name to be deleted.
--cmake-only
Only run CMake, don't run any other build steps.
--force-run-cmake, --frcm
Ensure that we explicitly invoke CMake from this script. CMake may still run as a result of
changes made to CMakeLists.txt files if we just invoke make on the CMake-generated Makefile.
--force-no-run-cmake, --fnrcm, --skip-cmake, --no-cmake
The opposite of --force-run-cmake. Makes sure we do not run CMake.
--cmake-args
Additional CMake arguments
--make
Use the Make backend (as opposed to Ninja).
--ninja
Use the Ninja backend instead of Make for CMake. This provides faster build speed in case
most part of the code is already built.
--make-ninja-extra-args <extra_args>
Extra arguments for the build tool such as Unix Make or Ninja.
--thirdparty-dir <thirdparty_dir>
Use a third-party directory other than <source_tree_root>/thirdparty. This is useful when using
multiple build directories with different versions of YB code so we can avoid building
third-party code multiple times.
--download-thirdparty, --dltp (This is the default.)
Use prebuilt third-party dependencies, downloadable e.g. from a GitHub release. Also records the
third-party URL in the build root so that further invocations of yb_build.sh don't reqiure
this option (this could be reset by --clean).
--no-download-thirdparty|--ndltp)
Disable downloading pre-built third-party dependencies.
--no-rebuild-thirdparty, --nbtp, --nb3p, --nrtp, --nr3p
Skip building third-party libraries, even if the thirdparty directory has changed in git.
--no-ccache
Do not use ccache. Useful when debugging build scripts or compiler/linker options.
--generate-build-debug-scripts, --gen-build-debug-scripts, --gbds
Specify this to generate one-off shell scripts that could be used to re-run and understand
failed compilation commands.
--write-build-descriptor <build_descriptor_path>
Write a "build descriptor" file. A "build descriptor" is a YAML file that provides information
about the build root, compiler used, etc.
--remote
Prefer a remote build on an auto-scaling cluster of build workers. The parallelism is picked
automatically based on the current number of build workers.
--build-root
The build root directory, e.g. build/debug-gcc-dynamic-enterprise. This is used in scripting
and is checked against other parameters.
--show-compiler-cmd-line, --sccl
Show compiler command line.
--export-compile-commands, --ccmds
Export the C/C++ compilation database. Equivalent to setting YB_EXPORT_COMPILE_COMMANDS to 1.
--export-compile-commands-cxx-only, --ccmdscxx
Only export the compilation commands for C++ code. Compilation database generation for Postgres
C code can be time-consuming and this
--linuxbrew or --no-linuxbrew
Specify in order to do a Linuxbrew based build, or specifically prohibit doing so. This
influences the choice of prebuilt third-party archive. This can also be specified using the
YB_USE_LINUXBREW environment variable.
--static-analyzer
Enable Clang static analyzer
--clangd-index
Build a static Clangd index using clangd-indexer.
--clangd-index-only, --cio
A combination of --clangd-index, --skip-initdb, and --skip-java
--clangd-index-format <format>
Clangd index format ("binary" or "yaml"). A YAML index can be moved to another directory.
--mvn-opts <maven_options>
Specify additional Maven options for Java build/tests.
--lto <lto_type>, --thin-lto, --full-lto, --no-lto
LTO (link time optimization) type, e.g. "thin" (faster to link) or "full" (faster code; see
https://llvm.org/docs/LinkTimeOptimization.html and https://clang.llvm.org/docs/ThinLTO.html).
Can also be specified by setting environment variable YB_LINKING_TYPE to thin-lto or full-lto.
Set YB_LINKING_TYPE to 'dynamic' to disable LTO.
--no-initdb, --skip-initdb
Skip the initdb step. The initdb build step is mostly single-threaded and can be executed on a
low-CPU build machine even if the majority of the build is being executed on a high-CPU host.
--skip-test-log-rewrite
Skip rewriting the test log.
--skip-final-lto-link
For LTO builds, skip the final linking step for server executables, which could take many
minutes.
--cxx-test-filter-re, --cxx-test-filter-regex
Regular expression for filtering C++ tests to build. This regular expression is not anchored
on either end, so e.g. you can specify a substring of the test name. Use ^ or $ as needed.
Linting options:
--shellcheck
Check various Bash scripts in the codebase.
--java-lint
Run a simple shell-based "linter" on our Java code that verifies that we are importing the right
methods for assertions and using the right test runners. We exit the script after this step.
Test options:
--ctest
Runs ctest in the build directory after the build. This is mutually exclusive with --cxx-test.
This will also skip building Java code, unless --run-java-tests is specified.
--ctest-args
Specifies additional arguments to ctest. Implies --ctest.
--cxx-test <cxx_test_program_name>
Build and run the given C++ test program. We run the test using ctest. Specific tests within the
test program can be chosen using --gtest_filter.
--gtest_filter
Use the given filter to select Google Test tests to run. Uses with --cxx-test.
--test-args
Extra arguments to pass to the test. Used with --cxx-test.
--sanitizer-extra-options, --extra-sanitizer-options
Extra options to pass to ASAN/LSAN/UBSAN/TSAN. See https://goo.gl/VbTjHH for possible values.
--sanitizers-enable-coredump
When running tests with LLVM sanitizers (ASAN/TSAN/etc.), enable core dump.
--sanitizer-verbosity
Use the given verbosity value for clang sanitizers. The default is 0.
--collect-java-tests
Collect the set of Java test methods into a file
--java-tests, --run-java-tests
Run the Java unit tests.
--java-test <java_test_name>
Build and run the given Java test. Test name format is e.g.
org.yb.loadtester.TestRF1Cluster[#testRF1toRF3].
--run-java-test-methods-separately, --rjtms
Run each Java test (test method or a parameterized instantiation of a test method) separately
as its own top-level Maven invocation, writing output to a separate file. This is the default
when --java-test specifies a particular test method using the [package.]ClassName#testMethod
syntax, and only makes a difference when running the entire test suite.
--java-test-args
Extra arguments to pass to Maven when running tests. Used with --java-test.
--python-tests
Run various Python tests (doctest, unit test) and exit.
--{no,skip}-{test-existence-check,check-test-existence}
Don't check that all test binaries referenced by CMakeLists.txt files exist.
--num-repetitions, --num-reps, -n
Repeat a C++/Java test this number of times. This delegates to the repeat_unit_test.sh script.
--test-parallelism, --tp N
When running tests repeatedly, run up to N instances of the test in parallel. Equivalent to the
--parallelism argument of repeat_unit_test.sh.
--host-for-tests
Use this host for running tests. Could also be set using the YB_HOST_FOR_RUNNING_TESTS env
variable.
--test-timeout-sec
Test timeout in seconds
--remove-successful-test-logs
Remove logs after a successful test run.
--stop-at-failure, --stop-on-failure
Stop running further iterations after the first failure happens when running a unit test
repeatedly.
--stack-trace-error-status, --stes
When running tests, print stack traces when error statuses are generated. Only works in
non-release mode.
--stack-trace-error-status-re, --stesr
When running tests, print stack traces when error statuses matching the given regex are
generated. Only works in non-release mode.
--cmake-unit-tests
Run our unit tests for CMake code. This should be much faster than running the build.
--
Pass all arguments after -- to repeat_unit_test.
--extra-daemon-flags, --extra-daemon-args <extra_daemon_flags>
Extra flags to pass to mini-cluster daemons (master/tserver). Note that bash-style quoting won't
work here -- they are naively split on spaces.
--(with|no)-fuzz-targets
Build|Do not build fuzz targets. By default - do not build.
--(with|no)-odyssey
Specify whether to build Odyssey (PostgreSQL connection pooler). Not building by default.
--enable-ysql-conn-mgr-test
Use YSQL Connection Manager as an endpoint when running unit tests. Could also be set using
the YB_ENABLE_YSQL_CONN_MGR_IN_TESTS env variable.
--validate-args-only
Only validate command-line arguments and exit immediately. Suppress all unnecessary output.
Debug options:
--verbose
Show debug output
--bash-debug
Show detailed debug information for each command executed by this script.
--super-bash-debug
Log the location of every command executed in this script
Build types:
${VALID_BUILD_TYPES[*]}
(default: debug)
Supported target keywords:
...-test - build and run a C++ test
[yb-]master - master executable
[yb-]tserver - tablet server executable
daemons - yb-master, yb-tserver, and the postgres server
packaged[-targets] - targets that are required for a release package
initdb - Initialize the initial system catalog snapshot for fast cluster startup
reinitdb - Reinitialize the initial system catalog snapshot for fast cluster startup
Setting YB_... environment variables on the command line:
YB_SOME_VARIABLE1=some_value1 YB_SOME_VARIABLE2=some_value2
The same also works for postgres_FLAGS_... variables.
---------------------------------------------------------------------------------------------------
EOT
}
set_cxx_test_name() {
expect_num_args 1 "$@"
if [[ $cxx_test_name == "$1" ]]; then
# Duplicate test name specified, ignore.
return
fi
if [[ -n $cxx_test_name ]]; then
fatal "Only one C++ test name can be specified (found '$cxx_test_name' and '$1')."
fi
if [[ $1 == TEST* ]]; then
local test_source_path
test_source_path=$(
( cd "$YB_SRC_ROOT/src" && git grep "$1" ) | cut -d: -f1 | sort | uniq
)
if [[ ! -f "$YB_SRC_ROOT/src/$test_source_path" ]]; then
fatal "Failed to identify test path based on code substring $cxx_test_name." \
"Grep result: $test_source_path"
fi
cxx_test_name=${test_source_path##*/}
cxx_test_name=${cxx_test_name%.cc}
# A convenience syntax for copying and pasting a line from a C++ test.
# E.g. --cxx-test='TEST(FormatTest, Time) {' or even
# --cxx-test='TEST_F_EX(ClientTest, CompactionStatusWaitingForHeartbeats, CompactionClientTest)'
local gtest_filter
local identifier='([a-zA-Z_][a-zA-Z_0-9]*)'
if [[ $1 =~ ^(TEST_F_EX)\($identifier,\ *$identifier,\ *$identifier\) ||
$1 =~ ^(TEST|TEST_F)\($identifier,\ *$identifier\) ]]; then
gtest_filter=${BASH_REMATCH[2]}.${BASH_REMATCH[3]}
elif [[ $1 =~ ^TEST_P\($identifier,\ *$identifier\) ]]; then
# Create a filter with wildcards that match all possiblilities. For example,
# - PackingVersion/PgPackedRowTest.AddDropColumn/kV1
# - PackingVersion/PgPackedRowTest.AddDropColumn/kV2
gtest_filter="*/${BASH_REMATCH[1]}.${BASH_REMATCH[2]}/*"
else
fatal "Could not determine gtest test filter from source substring $1"
fi
export YB_GTEST_FILTER=$gtest_filter
log "Determined C++ test based on source substring:" \
"--cxx-test=$cxx_test_name --gtest_filter=$gtest_filter"
else
cxx_test_name=$1
fi
running_any_tests=true
build_java=false
}
set_java_test_name() {
expect_num_args 1 "$@"
if [[ $java_test_name == "$1" ]]; then
# Duplicate test name specified, ignore.
return
fi
if [[ -n $java_test_name ]]; then
fatal "Only one Java test name can be specified (found '$java_test_name' and '$1')."
fi
running_any_tests=true
run_java_tests=true
build_java=true
java_test_name=$1
}
set_vars_for_cxx_test() {
if [[ -n $cxx_test_name ]]; then
make_targets+=( "$cxx_test_name" )
fi
# This is necessary to avoid failures if we are just building one test.
test_existence_check=false
}
# shellcheck disable=SC2317
print_report_line() {
local format_suffix=$1
shift
printf '%-32s : '"$format_suffix\n" "$@"
}
# Report the time taken for a particular operation, based on the start and end time variables.
# If these variables are not set, then no report line is printed.
# shellcheck disable=SC2317
report_time() {
expect_num_args 2 "$@"
local description=$1
local time_var_prefix=$2
local start_time_var_name="${time_var_prefix}_start_time_sec"
local end_time_var_name="${time_var_prefix}_end_time_sec"
local -i start_time=${!start_time_var_name:-0}
local -i end_time=${!end_time_var_name:-0}
if [[ $start_time -ne 0 && $end_time -ne 0 ]]; then
local caption="$description time"
print_report_line "%d seconds" "$caption" "$(( end_time - start_time ))"
fi
}
# shellcheck disable=SC2317
print_report() {
if [[ ${show_report} == "true" ]]; then
(
echo
thick_horizontal_line
echo "YUGABYTE BUILD SUMMARY"
thick_horizontal_line
print_report_line "%s" "Build type" "${build_type:-undefined}"
if [[ -n ${YB_COMPILER_TYPE:-} ]]; then
print_report_line "%s" "C/C++ compiler" "$YB_COMPILER_TYPE"
fi
print_report_line "%s" "Build architecture" "${YB_TARGET_ARCH}"
print_report_line "%s" "Build directory" "${BUILD_ROOT:-undefined}"
print_report_line "%s" "Third-party dir" "${YB_THIRDPARTY_DIR:-undefined}"
if using_linuxbrew; then
print_report_line "%s" "Linuxbrew dir" "${YB_LINUXBREW_DIR:-undefined}"
fi
set +u
local make_targets_str="${make_targets[*]}"
set -u
if [[ -n $make_targets_str ]]; then
print_report_line "%s" "Targets" "$make_targets_str"
fi
report_time "CMake" cmake
report_time "C++ compilation" make
report_time "Java compilation" java_build
report_time "C++ (one test program)" cxx_test
report_time "ctest (multiple C++ test programs)" ctest
report_time "Collecting Java tests" collect_java_tests
report_time "Java tests" java_tests
report_time "Remote tests" remote_tests
if [[ ${YB_SKIP_BUILD:-} == "1" ]]; then
echo
echo "NO COMPILATION WAS DONE AS PART OF THIS BUILD (--skip-build)"
echo
fi
if [[ -n ${YB_BUILD_EXIT_CODE:-} && $YB_BUILD_EXIT_CODE -ne 0 ]]; then
print_report_line "%s" "Exit code" "$YB_BUILD_EXIT_CODE"
fi
horizontal_line
) >&2
fi
}
set_flags_to_skip_build() {
build_cxx=false
build_java=false
}
create_build_descriptor_file() {
if [[ -n $build_descriptor_path ]]; then
# The format of this file is YAML.
cat >"$build_descriptor_path" <<-EOT
build_type: "$build_type"
build_arch: "$(uname -m)"
cmake_build_type: "${cmake_build_type:-undefined}"
build_root: "$BUILD_ROOT"
compiler_type: "$YB_COMPILER_TYPE"
thirdparty_dir: "${YB_THIRDPARTY_DIR:-$YB_SRC_ROOT/thirdparty}"
EOT
if using_linuxbrew; then
echo "linuxbrew_dir: \"${YB_LINUXBREW_DIR:-}\"" >>"$build_descriptor_path"
fi
log "Created a build descriptor file at '$build_descriptor_path'"
fi
}
create_build_root_file() {
if [[ -n ${BUILD_ROOT:-} ]]; then
local latest_build_root_path=$YB_SRC_ROOT/build/latest_build_root
echo "Saving BUILD_ROOT to $latest_build_root_path"
echo "$BUILD_ROOT" > "$latest_build_root_path"
fi
}
capture_sec_timestamp() {
expect_num_args 1 "$@"
local current_timestamp
current_timestamp=$(date +%s)
eval "${1}_time_sec=$current_timestamp"
}
run_yugabyted_ui_build() {
# This is a standalone build script. It honors BUILD_ROOT from the env
"${YB_SRC_ROOT}/yugabyted-ui/build.sh"
}
run_cxx_build() {
expect_vars_to_be_set make_file
# shellcheck disable=SC2154
if [[ (
${force_run_cmake} == "true" ||
${cmake_only} == "true" ||
! -f ${make_file}
) && ${force_no_run_cmake} == "false" ]]
then
local cmake_binary
if is_mac && [[ "${YB_TARGET_ARCH:-}" == "arm64" ]]; then
cmake_binary=/opt/homebrew/bin/cmake
else
if ! which cmake &> /dev/null; then
echo "Error: cmake not found in PATH" >&2
exit 1
fi
cmake_binary=$( which cmake )
fi
log "Using cmake binary: $cmake_binary"
find "${BUILD_ROOT}" -name "CMake*.log" -exec rm -f {} \;
log "Running cmake in $PWD"
capture_sec_timestamp "cmake_start"
local cmake_stdout_path=${BUILD_ROOT}/cmake_stdout.txt
local cmake_stderr_path=${BUILD_ROOT}/cmake_stderr.txt
set +e
(
# Always disable remote build (running the compiler on a remote worker node) when running the
# CMake step.
#
# We are modifying YB_REMOTE_COMPILATION inside a subshell on purpose.
# shellcheck disable=SC2030
export YB_REMOTE_COMPILATION=0
set -x
# We are not double-quoting $cmake_extra_args on purpose to allow multiple arguments.
# shellcheck disable=SC2086
"${cmake_binary}" "${cmake_opts[@]}" $cmake_extra_args "${YB_SRC_ROOT}" \
>"${cmake_stdout_path}" 2>"${cmake_stderr_path}"
)
local cmake_exit_code=$?
set -e
capture_sec_timestamp "cmake_end"
# Show the contents of special CMake output files before we show CMake output itself.
if [[ ${cmake_exit_code} != 0 ]]; then
log "CMake failed with exit code ${cmake_exit_code}."
(
find "${BUILD_ROOT}" -name "CMake*.log" | while read -r cmake_log_path; do
echo
echo "--------------------------------------------------------------------------------"
echo "Contents of ${cmake_log_path}:"
echo "--------------------------------------------------------------------------------"
echo
cat "${cmake_log_path}"
echo
echo "--------------------------------------------------------------------------------"
echo
done
) >&2
fi
if [[ -s ${cmake_stdout_path} ]]; then
if [[ ${cmake_exit_code} != 0 ]]; then
# Only mark CMake standard output as such in case of an error. Otherwise, just pass it
# through.
echo "CMake standard output (also saved to ${cmake_stdout_path}):"
echo
fi
cat "${cmake_stdout_path}"
if [[ ${cmake_exit_code} != 0 ]]; then
echo
fi
fi
if [[ -s ${cmake_stderr_path} ]]; then
echo "CMake standard error (also saved to ${cmake_stderr_path}):" >&2
echo >&2
cat "${cmake_stderr_path}" >&2
echo >&2
fi
if [[ ${cmake_exit_code} != 0 ]]; then
fatal "CMake failed with exit code ${cmake_exit_code}. See additional logging above."
fi
fi
if [[ ${cmake_only} == "true" ]]; then
log "CMake has been invoked, stopping here (--cmake-only specified)."
exit
fi
if [[ ${build_cxx} == "false" ]]; then
log "Skipping C++ build after invoking CMake."
return
fi
if [[ ${#object_files_to_delete[@]} -gt 0 ]]; then
log_empty_line
log "Deleting object files corresponding to: ${object_files_to_delete[*]}"
# TODO: can delete multiple files using the same find command.
for object_file_to_delete in "${object_files_to_delete[@]}"; do
( set -x; find "$BUILD_ROOT" -name "$object_file_to_delete" -exec rm -fv {} \; )
done
log_empty_line
fi
fix_gtest_cxx_test_name
set_vars_for_cxx_test
log "Running $make_program in $PWD"
capture_sec_timestamp "make_start"
set +u +e # "set -u" may cause failures on empty lists
# We are not double-quoting $make_ninja_extra_args on purpose, to allow multiple arguments.
# shellcheck disable=SC2206
make_program_args=(
"-j$YB_MAKE_PARALLELISM"
"${make_opts[@]}"
$make_ninja_extra_args
"${make_targets[@]}"
)
set -u
if [[ ${reduce_log_output} == "true" ]]; then
time (
set -x
"$make_program" "${make_program_args[@]}" | filter_boring_cpp_build_output
)
else
time (
set -x
"$make_program" "${make_program_args[@]}"
)
fi
local exit_code=$?
set -u -e
capture_sec_timestamp "make_end"
log "C++ build finished with exit code $exit_code" \
"(build type: $build_type, compiler: $YB_COMPILER_TYPE)." \
"Timing information is available above."
if [[ $exit_code -ne 0 ]]; then
exit "$exit_code"
fi
# Don't check for test binary existence in case targets are explicitly specified.
if [[ $test_existence_check == "true" && ${#make_targets[@]} -eq 0 ]]; then
(
cd "$BUILD_ROOT"
log "Checking if all test binaries referenced by CMakeLists.txt files exist."
if ! check_test_existence; then
log "Re-running test existence check again with more verbose output"
# We need to do this because sometimes we get an error with no useful output otherwise.
# We pass a pattern that includes all lines in the output.
check_test_existence '.*'
fatal "Some test binaries referenced in CMakeLists.txt files do not exist," \
"or failed to check. See detailed output above."
fi
)
fi
}
run_repeat_unit_test() {
export YB_COMPILER_TYPE
set +u
local repeat_unit_test_args=(
"${repeat_unit_test_inherited_args[@]}"
)
set -u
repeat_unit_test_args+=(
"$@"
--build-type "$build_type"
--num-iter "$num_test_repetitions"
)
if [[ -n ${YB_TEST_PARALLELISM:-} ]]; then
repeat_unit_test_args+=( --parallelism "$YB_TEST_PARALLELISM" )
fi
if [[ ${verbose} == "true" ]]; then
repeat_unit_test_args+=( --verbose )
fi
(
set -x
"$YB_SRC_ROOT"/bin/repeat_unit_test.sh "${repeat_unit_test_args[@]}"
)
}
run_ctest() {
# Not setting YB_CTEST_VERBOSE here because we don't want the output of a potentially large number
# of tests to go to stdout.
(
cd "$BUILD_ROOT"
set -x
# Not quoting $ctest_args on purpose.
# shellcheck disable=SC2086
ctest -j"$YB_NUM_CPUS" --verbose $ctest_args 2>&1 |
grep -Ev "^[0-9]+: Test timeout computed to be: "
)
}
run_tests_remotely() {
ran_tests_remotely=false
if [[ $running_any_tests == "false" ]]; then
# Nothing to run remotely.
return
fi
if [[ -n ${YB_HOST_FOR_RUNNING_TESTS:-} && \
$YB_HOST_FOR_RUNNING_TESTS != "127.0.0.1" && \
$YB_HOST_FOR_RUNNING_TESTS != "localhost" && \
$YB_HOST_FOR_RUNNING_TESTS != "$HOSTNAME" && \
$YB_HOST_FOR_RUNNING_TESTS != "$HOSTNAME."* ]] ; then
capture_sec_timestamp "remote_tests_start"
log "Running tests on host '$YB_HOST_FOR_RUNNING_TESTS' (current host is '$HOSTNAME')"
# Add extra arguments to the sub-invocation of yb_build.sh. We have to add them before the
# first "--".
set +u
sub_yb_build_args=()
extra_args=( --skip-build --host-for-tests "localhost" --no-report )
for arg in "${original_args[@]}"; do
case $arg in
--)
sub_yb_build_args+=( "${extra_args[@]}" "$arg" )
extra_args=()
;;
--clean|--clean-*)
# Do not pass these arguments to the child yb_build.sh.
;;
*)
sub_yb_build_args+=( "$arg" )
esac
done
sub_yb_build_args+=( "${extra_args[@]}" )
set -u
log "Running tests on server '$YB_HOST_FOR_RUNNING_TESTS': yb_build.sh ${sub_yb_build_args[*]}"
run_remote_cmd "$YB_HOST_FOR_RUNNING_TESTS" "$YB_SRC_ROOT/yb_build.sh" \
"${sub_yb_build_args[@]}"
capture_sec_timestamp "remote_tests_end"
ran_tests_remotely=true
fi
}
run_cxx_test() {
fix_cxx_test_name
if [[ $num_test_repetitions -eq 1 ]]; then
(
set_sanitizer_runtime_options
cd "$BUILD_ROOT"
# The following makes our test framework repeat the test log in stdout in addition writing the
# log file instead of simply redirecting it to the log file. Combined with the --verbose ctest
# option, this gives us nice real-time test output, while still taking advantage of correct
# test flags such (e.g. ASAN/TSAN options and suppression rules) that are set in run-test.sh.
export YB_CTEST_VERBOSE=1
# --verbose: enable verbose output from tests. Test output is normally suppressed and only
# summary information is displayed. This option will show all test output.
# --output-on-failure is unnecessary when --verbose is specified. In fact, adding
# --output-on-failure will result in duplicate output in case of a failure.
#
# In this verbose mode, ctest also adds some number (test number?) with a colon in the
# beginning of every line of the output. We filter that out.
set -x
ctest --verbose -R ^"$cxx_test_name"$ 2>&1 | sed 's/^[0-9][0-9]*: //g'
)
else
run_repeat_unit_test "$build_type" "$test_binary_name"
fi
}
register_file_to_rebuild() {
expect_num_args 1 "$@"
local file_name=${1%.o}
object_files_to_delete+=(
"$file_name.o"
"$file_name.c.o"
"$file_name.cc.o"
)
}
# This is used for "initdb" and "reinitdb" target keywords.
set_initdb_target() {
make_targets+=( "initial_sys_catalog_snapshot" )
build_java=false
}
disable_initdb() {
export YB_SKIP_INITIAL_SYS_CATALOG_SNAPSHOT=1
}
# shellcheck disable=SC2317
cleanup() {
local YB_BUILD_EXIT_CODE=$?
print_report
exit "$YB_BUILD_EXIT_CODE"
}
print_saved_log_path() {
heading "To view log:"$'\n\n'"less '$log_path'"$'\n\n'\
"Or using symlink:"$'\n\n'"less '$latest_log_symlink_path'"$'\n'
}
set_clean_build() {
# We use is_clean_build in common-build-env.sh.
# shellcheck disable=SC2034
is_clean_build=true
remove_build_root_before_build=true
}
enable_clangd_index_build() {
should_build_clangd_index=true
# Compilation database is required before we can build the Clangd index.
export YB_EXPORT_COMPILE_COMMANDS=1
}
set_cxx_test_filter_regex() {
expect_num_args 1 "$@"
force_run_cmake=true
cmake_opts+=( "-DYB_TEST_FILTER_RE=$1" )
}
# This function is used to propagate a boolean variable to a CMake variable. For example, if we have
# a variable named build_tests, we will propagate that variable to a CMake parameter named
# YB_BUILD_TESTS, and will replace true with ON and false with OFF. This is useful for variables
# that are used in both build scripts and CMake files.
propagate_bool_var_to_cmake() {
expect_num_args 1 "$@"
local var_name=$1
# var_name could be something build_tests. We will propagate that variable to a CMake parameter
# named e.g. YB_BUILD_TESTS, and will replace true with ON and false with OFF.
if [[ -n ${!var_name:-} ]]; then
local cmake_var_name
cmake_var_name=YB_$( tr '[:lower:]' '[:upper:]' <<<"${var_name}" )
local cmake_var_value
case "${!var_name}" in
true) cmake_var_value=ON ;;
false) cmake_var_value=OFF ;;
*) fatal "Invalid value of variable ${var_name}: ${!var_name}. Expected 'true' or 'false'."
esac
cmake_opts+=( "-D${cmake_var_name}=${cmake_var_value}" )
# CMakeCache.txt will contain something like
# YB_BUILD_ODYSSEY:UNINITIALIZED=ON
# Only re-run CMake if we want to put a different value of this variable there.
local cmake_cache_path="$BUILD_ROOT/CMakeCache.txt"
if [[ ${force_no_run_cmake} == "false" ]] && (
[[ ! -f $cmake_cache_path ]] ||
! grep -Eq "^${cmake_var_name}:[A-Z]*=${cmake_var_value}$" "$cmake_cache_path"
); then
force_run_cmake=true
fi
fi
}
use_packaged_targets() {
local packaged_targets=()
local optional_components_args=()
if [[ "${build_odyssey:-}" == "true" ]]; then
optional_components_args+=( "--with_odyssey" )
else
optional_components_args+=( "--no_odyssey" )
fi
if [[ "${build_yugabyted_ui:-}" == "true" ]]; then
optional_components_args+=( "--with_yugabyted_ui" )
else
optional_components_args+=( "--no_yugabyted_ui" )
fi
while IFS='' read -r line; do
packaged_targets+=( "$line" )
done < <(
activate_virtualenv &>/dev/null
set_pythonpath
"$YB_SCRIPT_PATH_LIST_PACKAGED_TARGETS" "${optional_components_args[@]}"
)
if [[ ${#packaged_targets[@]} -eq 0 ]]; then
fatal "Failed to identify the set of targets to build for the release package"
fi
make_targets+=(
"${packaged_targets[@]}"
initial_sys_catalog_snapshot
update_ysql_conn_mgr_template
update_ysql_migrations
)
}
# -------------------------------------------------------------------------------------------------
# Command line parsing
# -------------------------------------------------------------------------------------------------
build_type=""
verbose=false
force_run_cmake=false
force_no_run_cmake=false
remove_build_root_before_build=false
remove_entire_build_dir_before_build=false
clean_thirdparty=false
no_ccache=false
make_opts=()
force=false
build_cxx=true
build_java=true
# We will set this to true if we are running a single Java test or all tests.
run_java_tests=false
save_log=false
make_targets=()
no_tcmalloc=false
must_use_tcmalloc=false
cxx_test_name=""
test_existence_check=true
object_files_to_delete=()
should_run_ctest=false
ctest_args=""
num_test_repetitions=1
build_descriptor_path=""
export YB_GTEST_FILTER=""
repeat_unit_test_inherited_args=()
forward_args_to_repeat_unit_test=false
original_args=( "$@" )
user_mvn_opts=""
java_only=false
cmake_only=false
run_python_tests=false
cmake_extra_args=""
pgo_data_path=""
predefined_build_root=""
java_test_name=""
show_report=true
running_any_tests=false
clean_postgres=false
make_ninja_extra_args=""
java_lint=false
collect_java_tests=false
should_use_packaged_targets=false
# The default value of this parameter will be set based on whether we're running on Jenkins.
reduce_log_output=""
resolve_java_dependencies=false
run_cmake_unit_tests=false
run_shellcheck=false
should_build_clangd_index=false
clangd_index_format=binary
export YB_DOWNLOAD_THIRDPARTY=${YB_DOWNLOAD_THIRDPARTY:-1}
export YB_HOST_FOR_RUNNING_TESTS=${YB_HOST_FOR_RUNNING_TESTS:-}
export YB_EXTRA_GTEST_FLAGS=""
unset BUILD_ROOT
if [[ ${YB_RECREATE_INITIAL_SYS_CATALOG_SNAPSHOT:-} == "1" ]]; then
log "Warning: re-setting externally passed value of YB_RECREATE_INITIAL_SYS_CATALOG_SNAPSHOT" \
"back to 0 by default."
fi
export YB_RECREATE_INITIAL_SYS_CATALOG_SNAPSHOT=0
cxx_test_filter_regex=""
reset_cxx_test_filter=false
use_google_tcmalloc=""
# -------------------------------------------------------------------------------------------------
# Switches deciding what components or targets to build
# -------------------------------------------------------------------------------------------------
build_tests=""
build_fuzz_targets=""
# These will influence what targets to build if invoked with the packaged_targets meta-target.
build_odyssey=false
if is_linux; then
build_odyssey=true
fi
build_yugabyted_ui=false
# -------------------------------------------------------------------------------------------------
validate_args_only=false
# -------------------------------------------------------------------------------------------------
# Actually parsing command-line arguments
# -------------------------------------------------------------------------------------------------
yb_build_args=( "$@" )
while [[ $# -gt 0 ]]; do
if is_valid_build_type "$1"; then
build_type="$1"