# The following variables will likely need to be modified, depending on where # and how you built LLVM & Clang. They can be overridden in a command-line # invocation of make, like: # # make LLVM_SRC_PATH= LIBCXX_INSTALL_PATH= CLANG_PATH= \ # PNACL_BIN_PATH= ... # # LLVM_SRC_PATH is the path to the root of the checked out source code. This # directory should contain the configure script, the include/ and lib/ # directories of LLVM, Clang in tools/clang/, etc. # Alternatively, if you're building vs. a binary download of LLVM, then # LLVM_SRC_PATH can point to the main untarred directory. LLVM_SRC_PATH ?= ../llvm # The x86-32-specific sandboxed translator directory. # It holds sandboxed versions of libraries and binaries. SB_LLVM_PATH ?= $(shell readlink -e \ ../../out/sandboxed_translators_work/translator-i686/llvm-sb/Release) # NACL_ROOT is the root of the native client repository. NACL_ROOT ?= $(shell python -c "import sys; sys.path.insert(0, 'pydir'); \ import utils; print utils.FindBaseNaCl()") # TOOLCHAIN_ROOT is the location of NaCl/PNaCl toolchains and other # tools like qemu. TOOLCHAIN_ROOT ?= $(shell readlink -e $(NACL_ROOT)/toolchain/linux_x86) # PNACL_TOOLCHAIN_ROOT is the location of the PNaCl toolchain. # This is used as the default root for finding binutils, libcxx, etc. PNACL_TOOLCHAIN_ROOT ?= $(shell readlink -e $(TOOLCHAIN_ROOT)/pnacl_newlib_raw) # The location of PNaCl tools (e.g., binutils objdump, pnacl-clang++, etc.). PNACL_BIN_PATH ?= $(shell readlink -e $(PNACL_TOOLCHAIN_ROOT)/bin) # Hack to auto-detect autoconf versus cmake build of LLVM. If the LLVM tools # were dynamically linked with something like libLLVM-3.7svn.so, it is an # autoconf build, otherwise it is a cmake build. AUTOCONF is set to 0 for # cmake, nonzero for autoconf. AUTOCONF ?= $(shell ldd $(PNACL_BIN_PATH)/opt | grep -c libLLVM-) # CLANG_PATH is the location of the clang compiler to use for building # the host binaries. CLANG_PATH ?= $(shell readlink -e \ $(NACL_ROOT)/../third_party/llvm-build/Release+Asserts/bin) # LIBCXX_INSTALL_PATH is the directory where libc++ is located. It should # contain header files and corresponding libraries. This is used for # building the host binaries in conjuction with clang. LIBCXX_INSTALL_PATH ?= $(PNACL_TOOLCHAIN_ROOT) STDLIB_FLAGS := -stdlib=libc++ -I$(LIBCXX_INSTALL_PATH)/include/c++/v1 HOST_ARCH ?= x86_64 ifeq ($(HOST_ARCH),x86_64) HOST_FLAGS = -m64 else ifeq ($(HOST_ARCH),x86) HOST_FLAGS = -m32 endif endif ifdef DEBUG OBJDIR = build/Debug OPTLEVEL = -O0 LINKOPTLEVEL = -O0 else OBJDIR = build/Release OPTLEVEL = -O2 -ffunction-sections -fdata-sections LINKOPTLEVEL = -O2 endif # The list of CXX defines that are dependent on build parameters. BASE_CXX_DEFINES = CXX_EXTRA = LD_EXTRA = ifdef MINIMAL NOASSERT = 1 OBJDIR := $(OBJDIR)+Min BASE_CXX_DEFINES += -DALLOW_DUMP=0 -DALLOW_LLVM_CL=0 -DALLOW_LLVM_IR=0 \ -DALLOW_LLVM_IR_AS_INPUT=0 -DALLOW_DISABLE_IR_GEN=0 \ -DALLOW_MINIMAL_BUILD=1 else BASE_CXX_DEFINES += -DALLOW_DUMP=1 -DALLOW_LLVM_CL=1 -DALLOW_LLVM_IR=1 \ -DALLOW_LLVM_IR_AS_INPUT=1 -DALLOW_DISABLE_IR_GEN=1 \ -DALLOW_MINIMAL_BUILD=0 endif SB_CXX_DEFINES := $(BASE_CXX_DEFINES) -DPNACL_BROWSER_TRANSLATOR=1 CXX_DEFINES := $(BASE_CXX_DEFINES) -DPNACL_BROWSER_TRANSLATOR=0 ifdef NOASSERT ASSERTIONS = -DNDEBUG else ASSERTIONS = OBJDIR := $(OBJDIR)+Asserts endif ifdef UBSAN OBJDIR := $(OBJDIR)+UBSan CXX_EXTRA += -fsanitize=undefined -fno-sanitize=vptr -fno-sanitize=nonnull-attribute LD_EXTRA += -fsanitize=undefined endif ifdef UBSAN_TRAP OBJDIR := $(OBJDIR)+UBSan_Trap CXX_EXTRA += -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -fno-sanitize=vptr -fno-sanitize=nonnull-attribute LD_EXTRA += -fsanitize=undefined-trap endif ifdef TSAN OBJDIR := $(OBJDIR)+TSan CXX_EXTRA += -fsanitize=thread LD_EXTRA += -fsanitize=thread endif ifdef ASAN OBJDIR := $(OBJDIR)+ASan CXX_EXTRA += -fsanitize=address LD_EXTRA += -fsanitize=address endif ifdef MSAN # TODO(ascull): this has an as yet undiagnosed uninitialized memory access OBJDIR := $(OBJDIR)+MSan CXX_EXTRA += -fsanitize=memory LD_EXTRA += -fsanitize=memory endif SB_OBJDIR := $(OBJDIR)+Sandboxed $(info -----------------------------------------------) $(info Using LLVM_SRC_PATH = $(LLVM_SRC_PATH)) $(info Using SB_LLVM_PATH = $(SB_LLVM_PATH)) $(info Using NACL_ROOT = $(NACL_ROOT)) $(info Using TOOLCHAIN_ROOT = $(TOOLCHAIN_ROOT)) $(info Using PNACL_TOOLCHAIN_ROOT = $(PNACL_TOOLCHAIN_ROOT)) $(info Using PNACL_BIN_PATH = $(PNACL_BIN_PATH)) $(info Using CLANG_PATH = $(CLANG_PATH)) $(info Using LIBCXX_INSTALL_PATH = $(LIBCXX_INSTALL_PATH)) $(info Using HOST_ARCH = $(HOST_ARCH)) $(info -----------------------------------------------) LLVM_CXXFLAGS := `$(PNACL_BIN_PATH)/llvm-config --cxxflags` SB_LLVM_CXXFLAGS := $(LLVM_CXXFLAGS) # Listing specific libraries that are needed for pnacl-sz # and the unittests, since we build "tools-only" for the # sandboxed_translators (which doesn't include every library # listed by llvm-config). LLVM_LIBS_LIST := -lLLVMIRReader -lLLVMBitReader -lLLVMNaClBitTestUtils \ -lLLVMNaClBitReader -lLLVMNaClBitAnalysis -lLLVMNaClBitWriter \ -lLLVMAsmParser -lLLVMNaClAnalysis -lLLVMCore -lLLVMSupport ifeq ($(AUTOCONF), 0) # LLVM cmake build LLVM_LIBS := $(LLVM_LIBS_LIST) # For the cmake build, the gtest libs end up in the same place as the LLVM # libs, so no "-L..." arg is needed. GTEST_LIB_PATH ?= CLANG_FORMAT_PATH ?= $(PNACL_BIN_PATH) else # LLVM autoconf build LLVM_LIBS := -lLLVM-3.7svn GTEST_LIB_PATH ?= -L../../out/llvm_x86_64_linux_work/Release+Asserts/lib CLANG_FORMAT_PATH ?= ../../out/llvm_x86_64_linux_work/Release+Asserts/bin endif LLVM_LDFLAGS := $(LLVM_LIBS) \ `$(PNACL_BIN_PATH)/llvm-config --ldflags` \ `$(PNACL_BIN_PATH)/llvm-config --system-libs` SB_LLVM_LDFLAGS := $(LLVM_LIBS_LIST) \ -L$(SB_LLVM_PATH)/lib CCACHE := `command -v ccache` CXX := CCACHE_CPP2=yes $(CCACHE) $(CLANG_PATH)/clang++ SB_CXX := CCACHE_CPP2=yes $(CCACHE) $(PNACL_BIN_PATH)/pnacl-clang++ SB_TRANSLATE := $(PNACL_BIN_PATH)/pnacl-translate # Extra warnings that LLVM's build system adds in addition to -Wall. LLVM_EXTRA_WARNINGS := -Wcovered-switch-default BASE_CXXFLAGS := -std=gnu++11 -Wall -Wextra -Werror -fno-rtti \ -fno-exceptions $(OPTLEVEL) $(ASSERTIONS) -g -pedantic \ $(LLVM_EXTRA_WARNINGS) $(CXX_EXTRA) CXXFLAGS := $(LLVM_CXXFLAGS) $(BASE_CXXFLAGS) $(CXX_DEFINES) $(HOST_FLAGS) \ $(STDLIB_FLAGS) SB_CXXFLAGS := $(SB_LLVM_CXXFLAGS) $(BASE_CXXFLAGS) $(SB_CXX_DEFINES) LDFLAGS := $(HOST_FLAGS) -L$(LIBCXX_INSTALL_PATH)/lib -Wl,--gc-sections \ $(LD_EXTRA) $(STDLIB_FLAGS) # Not specifying -Wl,--gc-sections but instead doing bitcode linking GC w/ LTO. SB_LDFLAGS := $(LINKOPTLEVEL) $(LD_EXTRA) SRCS = \ IceAssembler.cpp \ IceAssemblerARM32.cpp \ IceBrowserCompileServer.cpp \ IceCfg.cpp \ IceCfgNode.cpp \ IceClFlags.cpp \ IceCompiler.cpp \ IceCompileServer.cpp \ IceELFObjectWriter.cpp \ IceELFSection.cpp \ IceFixups.cpp \ IceGlobalContext.cpp \ IceGlobalInits.cpp \ IceInst.cpp \ IceInstARM32.cpp \ IceInstMIPS32.cpp \ IceInstX8632.cpp \ IceInstX8664.cpp \ IceIntrinsics.cpp \ IceLiveness.cpp \ IceLoopAnalyzer.cpp \ IceOperand.cpp \ IceRegAlloc.cpp \ IceRNG.cpp \ IceSwitchLowering.cpp \ IceTargetLowering.cpp \ IceTargetLoweringARM32.cpp \ IceTargetLoweringMIPS32.cpp \ IceTargetLoweringX8632.cpp \ IceTargetLoweringX8664.cpp \ IceThreading.cpp \ IceTimerTree.cpp \ IceTranslator.cpp \ IceTypes.cpp \ main.cpp \ PNaClTranslator.cpp ifndef MINIMAL SRCS += IceConverter.cpp \ IceTypeConverter.cpp endif OBJS=$(patsubst %.cpp, $(OBJDIR)/%.o, $(SRCS)) SB_OBJS=$(patsubst %.cpp, $(SB_OBJDIR)/%.o, $(SRCS)) UNITTEST_SRCS = \ BitcodeMunge.cpp \ IceELFSectionTest.cpp \ IceParseInstsTest.cpp # The X86 assembler tests take too long to compile. Given how infrequently the # assembler will change, we disable them. ifdef CHECK_X86_ASM ifndef DEBUG $(error Run check-unit with DEBUG=1 lest your machine perish) endif UNITTEST_SRCS += AssemblerX8632/LowLevel.cpp \ AssemblerX8632/DataMov.cpp \ AssemblerX8632/Locked.cpp \ AssemblerX8632/GPRArith.cpp \ AssemblerX8632/XmmArith.cpp \ AssemblerX8632/ControlFlow.cpp \ AssemblerX8632/Other.cpp \ AssemblerX8632/X87.cpp \ AssemblerX8664/LowLevel.cpp \ AssemblerX8664/DataMov.cpp \ AssemblerX8664/Locked.cpp \ AssemblerX8664/GPRArith.cpp \ AssemblerX8664/XmmArith.cpp \ AssemblerX8664/ControlFlow.cpp \ AssemblerX8664/Other.cpp endif UNITTEST_OBJS = $(patsubst %.cpp, $(OBJDIR)/unittest/%.o, $(UNITTEST_SRCS)) UNITTEST_LIB_OBJS = $(filter-out $(OBJDIR)/main.o,$(OBJS)) # Keep all the first target so it's the default. all: $(OBJDIR)/pnacl-sz make_symlink runtime ifdef TSAN sb: @echo "Skipping pnacl-sz.*.nexe: TSAN isn't supported under NaCl." else sb: $(SB_OBJDIR)/pnacl-sz.x86-32.nexe endif # SHOW_BUILD_ATTS is an executable that is run to show what build # attributes were used to build pnacl-sz. SHOW_BUILD_ATTS = $(OBJDIR)/pnacl-sz --build-atts # Creates symbolic link so that testing is easier. Also runs # pnacl-sz to verify that the defines flags have valid values, # as well as describe the corresponding build attributes. make_symlink: $(OBJDIR)/pnacl-sz rm -rf pnacl-sz ln -s $(OBJDIR)/pnacl-sz @echo "Build Attributes:" @$(SHOW_BUILD_ATTS) .PHONY: all make_symlink runtime bloat sb docs $(OBJDIR)/pnacl-sz: $(OBJS) $(CXX) $(LDFLAGS) -o $@ $^ $(LLVM_LDFLAGS) \ -Wl,-rpath=$(abspath $(LIBCXX_INSTALL_PATH)/lib) $(SB_OBJDIR)/pnacl-sz.x86-32.nexe: $(SB_OBJS) $(eval PNACL_SZ_BASE := $(patsubst %.nexe, %, $@)) $(SB_CXX) $(SB_LDFLAGS) -o $(PNACL_SZ_BASE).nonfinal.pexe $^ \ $(SB_LLVM_LDFLAGS) $(SB_TRANSLATE) -arch x86-32 $(PNACL_SZ_BASE).nonfinal.pexe -o $@ \ --allow-llvm-bitcode-input # TODO(stichnot): Be more precise than "*.h" here and elsewhere. $(OBJS): $(OBJDIR)/%.o: src/%.cpp src/*.h src/*.def $(CXX) -c $(CXXFLAGS) $< -o $@ $(SB_OBJS): $(SB_OBJDIR)/%.o: src/%.cpp src/*.h src/*.def $(SB_CXX) -c $(SB_CXXFLAGS) $< -o $@ $(OBJDIR)/run_unittests: $(UNITTEST_OBJS) $(UNITTEST_LIB_OBJS) $(CXX) $(GTEST_LIB_PATH) $(LDFLAGS) -o $@ $^ $(LLVM_LDFLAGS) \ -lgtest -lgtest_main -ldl \ -Wl,-rpath=$(abspath $(LIBCXX_INSTALL_PATH)/lib) $(UNITTEST_OBJS): $(OBJDIR)/unittest/%.o: unittest/%.cpp \ unittest/*.h src/*.h src/*.def $(CXX) -c $(CXXFLAGS) \ -Isrc/ \ -Iunittest/ \ -I$(LLVM_SRC_PATH)/utils/unittest/googletest/include \ -I$(LLVM_SRC_PATH) \ -DGTEST_HAS_RTTI=0 -DGTEST_USE_OWN_TR1_TUPLE \ $< -o $@ $(OBJS): | $(OBJDIR) $(SB_OBJS): | $(SB_OBJDIR) $(UNITTEST_OBJS): | $(OBJDIR)/unittest $(OBJDIR)/unittest/AssemblerX8632 $(OBJDIR)/unittest/AssemblerX8664 $(OBJDIR): @mkdir -p $@ $(SB_OBJDIR): @mkdir -p $@ $(OBJDIR)/unittest: $(OBJDIR) @mkdir -p $@ $(OBJDIR)/unittest/AssemblerX8632: $(OBJDIR)/unittest @mkdir -p $@ $(OBJDIR)/unittest/AssemblerX8664: $(OBJDIR)/unittest @mkdir -p $@ RT_SRC := runtime/szrt.c runtime/szrt_ll.ll runtime/szrt_profiler.c RT_OBJ := build/runtime/szrt_native_x8632.o build/runtime/szrt_sb_x8632.o \ build/runtime/szrt_native_x8664.o build/runtime/szrt_sb_x8664.o \ build/runtime/szrt_native_arm32.o build/runtime/szrt_sb_arm32.o runtime: $(RT_OBJ) # Use runtime.is.built so that build-runtime.py is invoked only once # even in a parallel build. .INTERMEDIATE: runtime.is.built $(RT_OBJ): runtime.is.built runtime.is.built: $(RT_SRC) pydir/build-runtime.py @echo ================ Building Subzero runtime ================ ./pydir/build-runtime.py -v --pnacl-root $(PNACL_TOOLCHAIN_ROOT) check-lit: $(OBJDIR)/pnacl-sz make_symlink PNACL_BIN_PATH=$(PNACL_BIN_PATH) \ $(LLVM_SRC_PATH)/utils/lit/lit.py -sv tests_lit ifdef MINIMAL check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime @echo "Crosstests disabled, minimal build" else check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime # Do all native/sse2 tests, but only test_vector_ops for native/sse4.1. # For (slow) sandboxed tests, limit to Om1/sse4.1. # TODO(jpp): implement x8664 sandbox, then enable xtests. # TODO(jpp): reenable the x86-64 tests. ./pydir/crosstest_generator.py -v --lit \ --toolchain-root $(TOOLCHAIN_ROOT) \ -i x8632,native,sse2 \ -i x8632,native,sse4.1,test_vector_ops \ -i x8632,sandbox,sse4.1,Om1 \ -e x8664,native,sse2 \ -e x8664,native,sse4.1,test_vector_ops \ -e x8664,native,sse2,test_global \ -i arm32,native,neon \ -e arm32,native,neon,test_vector_ops \ -e arm32,native,neon,test_select PNACL_BIN_PATH=$(PNACL_BIN_PATH) \ $(LLVM_SRC_PATH)/utils/lit/lit.py -sv crosstest/Output endif check-unit: $(OBJDIR)/run_unittests $(OBJDIR)/run_unittests check: check-lit check-unit check-xtest FORMAT_BLACKLIST = # Add one of the following lines for each source file to ignore. FORMAT_BLACKLIST += ! -name IceParseInstsTest.cpp FORMAT_BLACKLIST += ! -name IceParseTypesTest.cpp FORMAT_BLACKLIST += ! -name assembler_arm.h FORMAT_BLACKLIST += ! -name assembler_arm.cc format: $(CLANG_FORMAT_PATH)/clang-format -style=LLVM -i \ `find . -regex '.*\.\(c\|h\|cpp\)' $(FORMAT_BLACKLIST)` format-diff: git diff -U0 `git merge-base HEAD master` | \ PATH=$(PNACL_BIN_PATH):$(PATH) \ $(LLVM_SRC_PATH)/../clang/tools/clang-format/clang-format-diff.py \ -p1 -style=LLVM -i bloat: make_symlink nm -C -S -l pnacl-sz | \ bloat/bloat.py --nm-output=/dev/stdin syms > build/pnacl-sz.bloat.json @echo See Subzero size breakdown in bloat/pnacl-sz.bloat.html docs: doxygen Doxyfile @echo See file://`pwd`/docs/html/index.html clean: rm -rf pnacl-sz *.o $(OBJDIR) $(SB_OBJDIR) build/pnacl-sz.bloat.json clean-all: clean rm -rf build/ docs/