在 Linux 上将 LevelDB 编译为 LLVM 二进制

前些时候我写了一篇关于如何在 Linux 上编译和安装 LevelDB的指南。

最近我在拼命学习 LLVM,关于如何在 C/C++ 中使用 LLVM 的教程系列即将推出。

由于我在许多项目中使用 LevelDB,我想要一种生成 LevelDB C++ 源代码的 LLVM IR(中间表示)的方法 - 我可以将 LLVM 程序链接到原生二进制,但为了从 LLVM 功能中受益,我认为对尽可能多的依赖使用 IR 是正确的方法。

通常有两种方法:

  1. 使用 g++ LLVM 后端
  2. 使用 clang++

我通常倾向于在 LLVM 任务中使用 clang++,因为即使有 colorgccgcc 错误消息生成的一些最近改进,我仍然更喜欢 clang++ 的错误消息,即使我对 gcc 错误消息有更多经验。此外,带 LLVM 后端的 g++ 似乎有一些 bug,包括将 -emit-llvm 解释为 -e -m -i …,加上最近的发行版版本与 LLVM gold 插件不太兼容,而且很难可靠地告诉 GCC 它应使用 llvm-ld 作为链接器。

编辑: 似乎 llvm-gcc 自 LLVM 3.0 起已弃用

一旦你有了创建库或程序的 g++ 命令,如果你满足于只在 all make 目标中列出所有 clang++/LLVM 调用,将 Makefile 转换为 clang++ 就相当容易。

这是带 Snappy 的 LevelDB for Linux 的 llvm.mk 文件(使用 make -f llvm.mk 编译):

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

注意 llvm-link 的调用以合并 IR 文件(.bc 扩展名)。llvm-ld 是将可执行文件与库链接的链接器,而 llvm-link 合并 IR 文件 - 它们不是同一个。

结果是 libleveldb.bc,一个 576 kiB 的 IR 文件,相比之下 688 kiB 的 libleveldb.a(git 修订版 514c943,2013 年 2 月 6 日)。然而 libleveldb.so.1.9 只有 392 kiB 大。


Check out similar posts by category: C/C++, Databases, LLVM