Compiling LevelDB as LLVM binary on Linux
Some time ago I wrote a guide on how to compile and install LevelDB on Linux.
Recently I’m desperately trying to get into LLVM and a tutorial series on how to use LLVM with C/C++ is coming shortly.
As I’m using LevelDB in many of my projects I’d like a way of generating a LLVM IR (intermediate representation) of the LevelDB C++ source - I could link a LLVM program to the native binary, but in order to profit from LLVMs features I suppose using IRs for as many dependencies as possible is the way to go.
Generally there are two ways to go:
- Use the g++ LLVM backend
- Use clang++
I usually tend to use clang++ for LLVM tasks because even with colorgcc and some recent improvements in gcc error message generation I prefer the clang++ error messages, even if I have way more experience with gcc error messages. Additionally the g++ with LLVM backend does seem to have some bugs, including interpreting -emit-llvm
as -e -m -i …, plus recent distribution versions don’t work too well with the LLVM gold plugin and it has proved difficult to tell GCC reliably that it shall use llvm-ld
as linker.
Edit: It seems like llvm-gcc
is deprecated since LLVM 3.0
Once you have the g++ commands to create a library or program, it’s pretty easy to convert the Makefile to clang++
, if you are satisfied with just listing all clang++/LLVM invocations in the all make target.
Here is the llvm.mk
file for LevelDB for Linux with Snappy (compile using make -f llvm.mk
):
all:
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/builder.cc -o db/builder.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/c.cc -o db/c.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/dbformat.cc -o db/dbformat.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/db_impl.cc -o db/db_impl.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/db_iter.cc -o db/db_iter.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/filename.cc -o db/filename.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/log_reader.cc -o db/log_reader.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/log_writer.cc -o db/log_writer.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/memtable.cc -o db/memtable.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/repair.cc -o db/repair.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/table_cache.cc -o db/table_cache.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/version_edit.cc -o db/version_edit.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/version_set.cc -o db/version_set.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c db/write_batch.cc -o db/write_batch.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/block_builder.cc -o table/block_builder.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/block.cc -o table/block.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/filter_block.cc -o table/filter_block.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/format.cc -o table/format.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/iterator.cc -o table/iterator.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/merger.cc -o table/merger.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/table_builder.cc -o table/table_builder.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/table.cc -o table/table.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c table/two_level_iterator.cc -o table/two_level_iterator.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/arena.cc -o util/arena.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/bloom.cc -o util/bloom.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/cache.cc -o util/cache.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/coding.cc -o util/coding.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/comparator.cc -o util/comparator.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/crc32c.cc -o util/crc32c.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/env.cc -o util/env.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/env_posix.cc -o util/env_posix.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/filter_policy.cc -o util/filter_policy.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/hash.cc -o util/hash.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/histogram.cc -o util/histogram.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/logging.cc -o util/logging.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/options.cc -o util/options.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c util/status.cc -o util/status.bc
clang++ -emit-llvm -I. -I./include -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -DSNAPPY -O2 -DNDEBUG -c port/port_posix.cc -o port/port_posix.bc
llvm-link -o libleveldb.bc db/builder.bc db/c.bc db/dbformat.bc db/db_impl.bc db/db_iter.bc db/filename.bc db/log_reader.bc db/log_writer.bc db/memtable.bc db/repair.bc db/table_cache.bc db/version_edit.bc db/version_set.bc db/write_batch.bc table/block_builder.bc table/block.bc table/filter_block.bc table/format.bc table/iterator.bc table/merger.bc table/table_builder.bc table/table.bc table/two_level_iterator.bc util/arena.bc util/bloom.bc util/cache.bc util/coding.bc util/comparator.bc util/crc32c.bc util/env.bc util/env_posix.bc util/filter_policy.bc util/hash.bc util/histogram.bc util/logging.bc util/options.bc util/status.bc port/port_posix.bc
Note the invocation of llvm-link
in order to merge the IR files (.bc
extension). llvm-ld
is a linker that links executables with libraries whereas llvm-link
merges IR files - they are not the same.
The result is libleveldb.bc
, a 576 kiB IR file, compared to the 688 kiB libleveldb.a
(git revision *514c943),*Feb 6 2013). libleveldb.so.1.9
however is only 392 kiB large.