Skip to content

jhx1008/kudu

Repository files navigation

Copyright (c) 2014, Cloudera, inc.
Confidential Cloudera Information: Covered by NDA.

System Requirements
------------------------------------------------------------
The following dependencies are necessary to build kudu:

- autoconf
- automake
- boost >= 1.41, on CentOS boost-devel and boost-static,
  including the following components:
  - boost::thread
  - boost::system (thread depends on it)
- cmake 2.8.7
- curl
- gcc and g++ 4.4 or higher
- libcurl
- liboauth-dev
- libssl-dev (Ubuntu) or openssl-devel (CentOS)
- libsasl2-dev (Ubuntu) or cyrus-sasl-devel (CentOS)
- libtool
- python 2.6 or later
- ntp
- unzip

Earlier versions of each of these may work, but have not recently
been tested.

Download and build thirdparty dependencies
------------------------------------------------------------
$ thirdparty/build-if-necessary.sh

This downloads and builds the thirdparty dependencies and installs them into
thirdparty/installed/. The script is also invoked by cmake, so new thirdparty
dependencies added by other developers will be downloaded and built
automatically in subsequent builds. To disable the automatic invocation of
build-if-necessary.sh, set the NO_REBUILD_THIRDPARTY environment variable:

$ NO_REBUILD_THIRDPARTY=1 cmake .

If you are looking to manually run the protobuf compiler, the pprof tool,
etc, you can find these in thirdparty/installed/bin/

Notes on building thirdparty with gcc 4.4 (eg on RHEL6)
-----------------------------------------------------------------------------
The LLVM thirdparty dependency will not build properly with gcc 4.4, which is
the version of gcc shipped with RHEL6. On machines with the Cloudera
toolchain, you can use LLVM 3.3 from the toolchain to bootstrap the thirdparty
LLVM:

$ export CC=/REPLACE/WITH/YOUR/PATH/llvm-3.3/bin/clang
$ export CXX=/REPLACE/WITH/YOUR/PATH/llvm-3.3/bin/clang++
$ thirdparty/build-if-necessary.sh

If you don't have access to a newer compiler, you can build LLVM twice, once
without the gcc 4.4 incompatible code, and once with. Add the flag
-DLLVM_EXTERNAL_COMPILER_RT_BUILD=OFF to the cmake invocation for LLVM in
thirdparty/build-thirdparty.sh. When built, that will yield an incomplete but
otherwise working LLVM 3.4. Then, using the CC/CXX environment variables as
above, remove the aforementioned flag and rebuild LLVM using itself.

Building kudu and running tests
------------------------------------------------------------

# Add <root of kudu tree>/thirdparty/installed/bin to your $PATH
# before other parts of $PATH that may contain cmake, such as /usr/bin
# e.g. "export PATH=$HOME/git/kudu/thirdparty/installed/bin:$PATH"
# if using bash
$ cmake .
$ make -j4
$ make test  # or, to run tests in parallel, ctest -j8 (for 8-way parallelism)

The build artifacts, including the test binaries, will be stored in
'build/latest/', which itself is a symlink to either build/debug or
build/release.

Individual tests can be run by directly invoking the test binaries in
'build/latest'. Since Kudu uses the Google C++ Test Framework (gtest),
specific test cases can be run with gtest flags:

# List all the tests within a test binary, then run a single test
$ ./build/latest/test-tablet --gtest_list_tests
$ ./build/latest/test-tablet --gtest_filter=TestTablet/9.TestFlush

gtest also allows more complex filtering patterns. See the upstream
documentation for more details.

Running tests with the clang AddressSanitizer enabled
------------------------------------------------------------

AddressSanitizer is a nice clang feature which can detect many types of memory
errors. The Jenkins setup for kudu runs these tests automatically on a regular
basis, but if you make large changes it can be a good idea to run it locally
before pushing. To do so, you'll need a local install of clang.

$ rm -Rf CMakeCache.txt CMakeFiles/
$ CC=clang CXX=clang++ cmake -DKUDU_USE_ASAN=1 .   # or whatever your path to clang++
$ make -j
$ make test

The tests will run significantly slower than without ASAN enabled, and if any
memory error occurs, the test that triggered it will fail. You can then use a
command like:

$ build/latest/failing-test 2>&1 | asan_symbolize.py | c++filt | less

to get a proper symbolized stack trace. The asan_symbolize program can be found
in the llvm source distribution:
https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py

For more information on AddressSanitizer, please see:
  http://clang.llvm.org/docs/AddressSanitizer.html


Running tests with the clang Undefined Behavior Sanitizer (UBSAN) enabled
------------------------------------------------------------

Similar to the above, you can use a special set of clang flags to enable the Undefined
Behavior Sanitizer. This will generate errors on certain pieces of code which may
not themselves crash but rely on behavior which isn't defined by the C++ standard
(and thus are likely bugs).

You'll need at least clang 3.3 to use this feature.

$ rm -Rf CMakeCache.txt CMakeFiles/
$ CC=clang CXX=clang++ cmake -DKUDU_USE_UBSAN=1 .   # or whatever your path to clang++
$ make -j
$ make test

In order to get a stack trace from UBSan, you can use gdb on the failing test, and
set a breakpoint as follows:

(gdb) b __ubsan::Diag::~Diag

Then, when the breakpoint fires, gather a backtrace as usual using 'bt'.


Running tests with the tcmalloc memory leak checker enabled
------------------------------------------------------------

You can also run the tests with a tcmalloc feature that prints an error message
and aborts if it detects memory leaks in your program.

$ rm -Rf CMakeCache.txt CMakeFiles/
$ cmake .
$ make -j
$ # Note: LP_BIND_NOW=1 required below, see: https://code.google.com/p/gperftools/issues/detail?id=497
$ PPROF_PATH=thirdparty/installed/bin/pprof HEAPCHECK=normal LD_BIND_NOW=1 ctest -j8

For more information on the heap checker, please see:
  http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html

NOTE: The AddressSanitizer doesn't play nice with tcmalloc, so sadly the
HEAPCHECK environment has no effect if you have enabled ASAN.


Running tests with ThreadSanitizer enabled
------------------------------------------------------------
NOTE: this requires a relatively recent version of clang++, and may also require
a relatively recent version of libstdc++ on your system. It seems to work reasonably
well on Ubuntu 13.10, but YMMV.

$ rm -Rf CMakeCache.txt CMakeFiles/
$ CC=clang CXX=clang++ cmake . -DKUDU_USE_TSAN=1
$ make -j
$ ctest -j8

Note that we rely on a list of runtime suppressions in build-support/tsan-suppressions.txt.
If you simply run a unit test like build/latest/foo-test, you won't get these suppressions.
Instead, use a command like:

$ ctest -R foo-test

and then view the logs in build/test-logs/

In order for all of the suppressions to work, you need libraries with debug
symbols installed, particularly for libstdc++. On Ubuntu 13.10, the package
libstdc++6-4.8-dbg is needed for tsan builds to pass. It's not a bad idea to
install debug symbol packages for libboost, libc, and cyrus-sasl as well.

TSAN may truncate a few lines of the stack trace when reporting where the error
is. This can be bewildering. It's documented for TSANv1 here:
http://code.google.com/p/data-race-test/wiki/ThreadSanitizerAlgorithm
It is not mentioned in the documentation for TSANv2, but has been observed.
In order to find out what is _really_ happening, set a breakpoint on the TSAN
report in GDB using the following incantation:

gdb -ex 'set disable-randomization off' -ex 'b __tsan::PrintReport' ./some-test


Generating code coverage reports
------------------------------------------------------------

In order to generate a code coverage report, you must build with gcc (not clang)
and use the following flags:

$ cmake -DKUDU_GENERATE_COVERAGE=1 .
$ make clean
$ make -j4
$ ctest -j4

This will generate the code coverage files with extensions .gcno and .gcda. You can then
use a tool like lcov or gcovr to visualize the results. For example, using gcovr:

$ mkdir cov_html
$ ./thirdparty/gcovr-3.0/scripts/gcovr -r src/

Or using lcov (which seems to produce better HTML output):

$ lcov  --capture --directory src --output-file coverage.info
$ genhtml coverage.info --output-directory out


Running lint checks
------------------------------------------------------------

Kudu uses cpplint.py from Google to enforce coding style guidelines. You can run the
lint checks via cmake using the 'lint' target:

$ make lint

This may take quite some time, as it scans every file in the source tree. For local
development, it's often more convenient to only check the files which you've modified.
For this you can use the 'ilint' target:

$ make ilint

This will scan any file which is dirty in your working tree, or changed since the last
gerrit-integrated upstream change in your git log.


Improving build times
------------------------------------------------------------

The kudu build is compatible with ccache. Simply install your distro's ccache package,
prepend /usr/lib/ccache to your PATH, and watch your object files get cached. Link
times won't be affected, but you will see a noticeable improvement in compilation
times. You may also want to increase the size of your cache using "ccache -M new_size".


One of the major time sinks in the Kudu build is linking. GNU ld is historically
quite slow at linking large C++ applications. The alternative linker 'gold' is much
better at it. It's part of the binutils package in modern distros (try binutils-gold
in older ones). To enable it, simply repoint the /usr/bin/ld symlink from ld.bfd to
ld.gold.

Note that gold doesn't handle weak symbol overrides properly (see
https://sourceware.org/bugzilla/show_bug.cgi?id=16979 for details). As such, it cannot
be used with shared objects (see below) because it'll cause tcmalloc's alternative
malloc implementation to be ignored.


Kudu can be built into shared objects, which, when used with ccache, can result in a
dramatic build time improvement in the steady state (i.e. when the build tree is clean
but all object files will be served from ccache). By default, debug and fastdebug will
use dynamic linking, while other build types will use static linking. To enable
dynamic linking explicitly, run:

$ cmake -DKUDU_LINK=dynamic .

Subsequent builds will create shared objects instead of archives and use them when
linking the kudu binaries and unit tests. The full range of options for KUDU_LINK are
"static", "dynamic", and "auto". The default is "auto" and only the first letter
matters for the purpose of matching.

Note that dynamic linking is incompatible with ASAN and static linking is incompatible
with TSAN.


Developing Kudu in Eclipse
------------------------------------------------------------

Eclipse can be used as an IDE for Kudu. To generate Eclipse project files, run:

$ rm -rf CMakeCache.txt CMakeFiles/
$ cmake -G "Eclipse CDT4 - Unix Makefiles" .

It's critical that CMakeCache.txt be removed prior to running the generator,
otherwise the extra Eclipse generator logic (the CMakeFindEclipseCDT4.make module)
won't run and standard system includes will be missing from the generated project.
At the time of writing, the CMake version in the thirdparty tree (2.8.10.2) is too old
to be used to generate Eclipse projects when the default compiler is clang. This was
filed as a cmake bug (http://public.kitware.com/Bug/view.php?id=13823) and is fixed in
version 2.8.11. That said, it's fine to generate the project files with gcc and go on
to build Kudu with clang.

By default, the Eclipse CDT indexer will index everything under the kudu/ source tree.
It tends to choke on certain complicated source files within the thirdparty/llvm.
In some versions of CDT, the indexer will generate an error and stop indexing. In
others, it'll spin forever.

Either way, thirdparty/llvm must be excluded from indexing. An easy way to do this is
to exclude all the unnecessary source trees from within thirdparty/ (all we need are
the installed headers). To do this, right click on the project in the Project Explorer
and select Properties. In the dialog box, select "C/C++ Project Paths", select the
Source tab, highlight "Exclusion filter: (None)", and click "Edit...". In the new
dialog box, click "Add Multiple...". In the file chooser, select everything under
thirdparty except for gmock and installed. Click OK all the way out and rebuild the
project index by right clicking the project in the Project Explorer and selecting
Index --> Rebuild.

With these exclusions, the only false positives (i.e. red squigglies) that CDT
presents appear to be in atomicops functions (e.g. NoBarrier_CompareAndSwap).

Another Eclipse annoyance stems from the "[Targets]" linked resource that Eclipse
generates for each unit test. These are probably used for building within Eclipse,
but one side effect is that nearly every source file appears in the indexer twice:
once via a target and once via the raw source file. To fix this, simply delete the
[Targets] linked resource via the Project Explorer. Doing this should have no effect
on writing code, though it may affect your ability to build from within Eclipse.


Building on OSX
------------------------------------------------------------

It's currently only possible to run "cmake ." on OSX, which will build all the third
party libraries. Building Kudu itself isn't supported.

Requirements:

 - OSX 10.9 and above.
 - Xcode's command line tools (xcode-select --install)
 - Homebrew packages:
   - autoconf
   - automake
   - libtool
   - coreutils

About

Mirror of Apache Kudu

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 79.8%
  • Java 10.9%
  • C 3.3%
  • Python 2.2%
  • CMake 1.3%
  • Protocol Buffer 1.2%
  • Other 1.3%