| VERSION=0.6.4 | |
| ######################################################################## | |
| # The following variables can be overwritten from the command line | |
| OS = linux | |
| CC = gcc | |
| CXX = g++ | |
| LD = $(CC) | |
| AR = ar | |
| CFLAGS ?= -O2 -g | |
| DESTDIR ?= | |
| PREFIX ?= $(HOME) | |
| BINDIR ?= $(PREFIX)/bin | |
| MANDIR ?= $(PREFIX)/share/man | |
| PKG_CONFIG ?= pkg-config | |
| CHECKER_FLAGS ?= -Wno-vla | |
| # Allow users to override build settings without dirtying their trees | |
| # For debugging, put this in local.mk: | |
| # | |
| # CFLAGS += -O0 -DDEBUG -g3 -gdwarf-2 | |
| # | |
| SPARSE_LOCAL_CONFIG ?= local.mk | |
| -include ${SPARSE_LOCAL_CONFIG} | |
| ######################################################################## | |
| LIB_OBJS := | |
| LIB_OBJS += allocate.o | |
| LIB_OBJS += builtin.o | |
| LIB_OBJS += char.o | |
| LIB_OBJS += compat-$(OS).o | |
| LIB_OBJS += cse.o | |
| LIB_OBJS += dissect.o | |
| LIB_OBJS += dominate.o | |
| LIB_OBJS += evaluate.o | |
| LIB_OBJS += expand.o | |
| LIB_OBJS += expression.o | |
| LIB_OBJS += flow.o | |
| LIB_OBJS += flowgraph.o | |
| LIB_OBJS += inline.o | |
| LIB_OBJS += ir.o | |
| LIB_OBJS += lib.o | |
| LIB_OBJS += linearize.o | |
| LIB_OBJS += liveness.o | |
| LIB_OBJS += memops.o | |
| LIB_OBJS += opcode.o | |
| LIB_OBJS += optimize.o | |
| LIB_OBJS += options.o | |
| LIB_OBJS += parse.o | |
| LIB_OBJS += predefine.o | |
| LIB_OBJS += pre-process.o | |
| LIB_OBJS += ptrlist.o | |
| LIB_OBJS += ptrmap.o | |
| LIB_OBJS += scope.o | |
| LIB_OBJS += show-parse.o | |
| LIB_OBJS += simplify.o | |
| LIB_OBJS += sort.o | |
| LIB_OBJS += ssa.o | |
| LIB_OBJS += stats.o | |
| LIB_OBJS += storage.o | |
| LIB_OBJS += symbol.o | |
| LIB_OBJS += target.o | |
| LIB_OBJS += target-alpha.o | |
| LIB_OBJS += target-arm.o | |
| LIB_OBJS += target-arm64.o | |
| LIB_OBJS += target-bfin.o | |
| LIB_OBJS += target-default.o | |
| LIB_OBJS += target-h8300.o | |
| LIB_OBJS += target-m68k.o | |
| LIB_OBJS += target-microblaze.o | |
| LIB_OBJS += target-mips.o | |
| LIB_OBJS += target-nds32.o | |
| LIB_OBJS += target-nios2.o | |
| LIB_OBJS += target-openrisc.o | |
| LIB_OBJS += target-ppc.o | |
| LIB_OBJS += target-riscv.o | |
| LIB_OBJS += target-s390.o | |
| LIB_OBJS += target-sh.o | |
| LIB_OBJS += target-sparc.o | |
| LIB_OBJS += target-x86.o | |
| LIB_OBJS += target-xtensa.o | |
| LIB_OBJS += tokenize.o | |
| LIB_OBJS += unssa.o | |
| LIB_OBJS += utils.o | |
| LIB_OBJS += version.o | |
| PROGRAMS := | |
| PROGRAMS += compile | |
| PROGRAMS += ctags | |
| PROGRAMS += example | |
| PROGRAMS += graph | |
| PROGRAMS += obfuscate | |
| PROGRAMS += sparse | |
| PROGRAMS += test-dissect | |
| PROGRAMS += test-lexing | |
| PROGRAMS += test-linearize | |
| PROGRAMS += test-parsing | |
| PROGRAMS += test-show-type | |
| PROGRAMS += test-unssa | |
| INST_PROGRAMS=sparse cgcc | |
| INST_MAN1=sparse.1 cgcc.1 | |
| all: | |
| ######################################################################## | |
| # common flags/options/... | |
| cflags = -fno-strict-aliasing | |
| cflags += -Wall -Wwrite-strings | |
| GCC_BASE := $(shell $(CC) --print-file-name=) | |
| cflags += -DGCC_BASE=\"$(GCC_BASE)\" | |
| MULTIARCH_TRIPLET := $(shell $(CC) -print-multiarch 2>/dev/null) | |
| cflags += -DMULTIARCH_TRIPLET=\"$(MULTIARCH_TRIPLET)\" | |
| bindir := $(DESTDIR)$(BINDIR) | |
| man1dir := $(DESTDIR)$(MANDIR)/man1 | |
| ######################################################################## | |
| # target specificities | |
| compile: compile-i386.o | |
| EXTRA_OBJS += compile-i386.o | |
| # Can we use GCC's generated dependencies? | |
| HAVE_GCC_DEP:=$(shell touch .gcc-test.c && \ | |
| $(CC) -c -Wp,-MP,-MMD,.gcc-test.d .gcc-test.c 2>/dev/null && \ | |
| echo 'yes'; rm -f .gcc-test.d .gcc-test.o .gcc-test.c) | |
| ifeq ($(HAVE_GCC_DEP),yes) | |
| cflags += -Wp,-MP,-MMD,$(@D)/.$(@F).d | |
| endif | |
| # Can we use libxml (needed for c2xml)? | |
| HAVE_LIBXML:=$(shell $(PKG_CONFIG) --exists libxml-2.0 2>/dev/null && echo 'yes') | |
| ifeq ($(HAVE_LIBXML),yes) | |
| PROGRAMS+=c2xml | |
| INST_PROGRAMS+=c2xml | |
| c2xml-ldlibs := $(shell $(PKG_CONFIG) --libs libxml-2.0) | |
| c2xml-cflags := $(shell $(PKG_CONFIG) --cflags libxml-2.0) | |
| else | |
| $(warning Your system does not have libxml, disabling c2xml) | |
| endif | |
| HAVE_SQLITE := $(shell $(PKG_CONFIG) --exists sqlite3 2>/dev/null && echo 'yes') | |
| ifeq ($(HAVE_SQLITE),yes) | |
| SQLITE_VERSION:=$(shell $(PKG_CONFIG) --modversion sqlite3) | |
| SQLITE_VNUMBER:=$(shell printf '%d%02d%02d' $(subst ., ,$(SQLITE_VERSION))) | |
| ifeq ($(shell expr "$(SQLITE_VNUMBER)" '>=' 32400),1) | |
| PROGRAMS += semind | |
| INST_PROGRAMS += semind | |
| INST_MAN1 += semind.1 | |
| semind-ldlibs := $(shell $(PKG_CONFIG) --libs sqlite3) | |
| semind-cflags := $(shell $(PKG_CONFIG) --cflags sqlite3) | |
| semind-cflags += -std=gnu99 | |
| else | |
| $(warning Your SQLite3 version ($(SQLITE_VERSION)) is too old, 3.24.0 or later is required.) | |
| endif | |
| else | |
| $(warning Your system does not have sqlite3, disabling semind) | |
| endif | |
| # Can we use gtk (needed for test-inspect) | |
| GTK_VERSION:=3.0 | |
| HAVE_GTK:=$(shell $(PKG_CONFIG) --exists gtk+-$(GTK_VERSION) 2>/dev/null && echo 'yes') | |
| ifneq ($(HAVE_GTK),yes) | |
| GTK_VERSION:=2.0 | |
| HAVE_GTK:=$(shell $(PKG_CONFIG) --exists gtk+-$(GTK_VERSION) 2>/dev/null && echo 'yes') | |
| endif | |
| ifeq ($(HAVE_GTK),yes) | |
| GTK_CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk+-$(GTK_VERSION)) | |
| ast-view-cflags := $(GTK_CFLAGS) | |
| ast-model-cflags := $(GTK_CFLAGS) | |
| ast-inspect-cflags := $(GTK_CFLAGS) | |
| test-inspect-cflags := $(GTK_CFLAGS) | |
| test-inspect-ldlibs := $(shell $(PKG_CONFIG) --libs gtk+-$(GTK_VERSION)) | |
| test-inspect: ast-model.o ast-view.o ast-inspect.o | |
| EXTRA_OBJS += ast-model.o ast-view.o ast-inspect.o | |
| PROGRAMS += test-inspect | |
| INST_PROGRAMS += test-inspect | |
| else | |
| $(warning Your system does not have gtk3/gtk2, disabling test-inspect) | |
| endif | |
| # Can we use LLVM (needed for ... sparse-llvm)? | |
| LLVM_CONFIG:=llvm-config | |
| HAVE_LLVM:=$(shell $(LLVM_CONFIG) --version >/dev/null 2>&1 && echo 'yes') | |
| ifeq ($(HAVE_LLVM),yes) | |
| arch := $(shell uname -m) | |
| ifeq (${MULTIARCH_TRIPLET},x86_64-linux-gnux32) | |
| arch := x32 | |
| endif | |
| ifneq ($(filter ${arch},i386 i486 i586 i686 x86_64 amd64 aarch64 arm64),) | |
| LLVM_VERSION:=$(shell $(LLVM_CONFIG) --version) | |
| LLVM_VERSION_MAJOR:=$(firstword $(subst ., ,$(LLVM_VERSION))) | |
| ifeq ($(shell expr "$(LLVM_VERSION_MAJOR)" '>=' 3),1) | |
| LLVM_PROGS := sparse-llvm | |
| $(LLVM_PROGS): LD := $(CXX) | |
| LLVM_LDFLAGS := $(shell $(LLVM_CONFIG) --ldflags) | |
| LLVM_CFLAGS := $(shell $(LLVM_CONFIG) --cppflags) | |
| LLVM_LIBS := $(shell $(LLVM_CONFIG) --libs) | |
| LLVM_LIBS += $(shell $(LLVM_CONFIG) --system-libs 2>/dev/null) | |
| LLVM_LIBS += $(shell $(LLVM_CONFIG) --cxxflags | grep -F -q -e '-stdlib=libc++' && echo -lc++) | |
| PROGRAMS += $(LLVM_PROGS) | |
| INST_PROGRAMS += sparse-llvm sparsec | |
| sparse-llvm-cflags := $(LLVM_CFLAGS) | |
| sparse-llvm-ldflags := $(LLVM_LDFLAGS) | |
| sparse-llvm-ldlibs := $(LLVM_LIBS) | |
| ifeq ($(LLVM_VERSION_MAJOR),14) | |
| sparse-llvm-cflags += -Wno-deprecated-declarations | |
| endif | |
| else | |
| $(warning LLVM 3.0 or later required. Your system has version $(LLVM_VERSION) installed.) | |
| endif | |
| else | |
| $(warning sparse-llvm disabled on ${arch}) | |
| endif | |
| else | |
| $(warning Your system does not have llvm, disabling sparse-llvm) | |
| endif | |
| ifeq ($(HAVE_BOOLECTOR),yes) | |
| PROGRAMS += scheck | |
| scheck-cflags := -I${BOOLECTORDIR}/include/boolector | |
| scheck-ldflags := -L${BOOLECTORDIR}/lib | |
| scheck-ldlibs := -lboolector -llgl -lbtor2parser | |
| endif | |
| ######################################################################## | |
| LIBS := libsparse.a | |
| OBJS := $(LIB_OBJS) $(EXTRA_OBJS) $(PROGRAMS:%=%.o) | |
| # Pretty print | |
| V := @ | |
| Q := $(V:1=) | |
| ######################################################################## | |
| all: $(PROGRAMS) | |
| ldflags += $($(@)-ldflags) $(LDFLAGS) | |
| ldlibs += $($(@)-ldlibs) $(LDLIBS) | |
| $(PROGRAMS): % : %.o $(LIBS) | |
| @echo " LD $@" | |
| $(Q)$(LD) $(ldflags) $^ $(ldlibs) -o $@ | |
| libsparse.a: $(LIB_OBJS) | |
| @echo " AR $@" | |
| $(Q)$(AR) rcs $@ $^ | |
| cflags += $($(*)-cflags) $(CPPFLAGS) $(CFLAGS) | |
| %.o: %.c | |
| @echo " CC $@" | |
| $(Q)$(CC) $(cflags) -c -o $@ $< | |
| %.sc: %.c sparse | |
| @echo " CHECK $<" | |
| $(Q)CHECK=./sparse ./cgcc -no-compile $(CHECKER_FLAGS) $(cflags) -c $< | |
| selfcheck: $(OBJS:.o=.sc) | |
| SPARSE_VERSION:=$(shell git describe --dirty 2>/dev/null || echo '$(VERSION)') | |
| version.o: version.h | |
| version.h: FORCE | |
| @echo '#define SPARSE_VERSION "$(SPARSE_VERSION)"' > version.h.tmp | |
| @if cmp -s version.h version.h.tmp; then \ | |
| rm version.h.tmp; \ | |
| else \ | |
| echo " GEN $@"; \ | |
| mv version.h.tmp version.h; \ | |
| fi | |
| check: all | |
| $(Q)cd validation && ./test-suite | |
| validation/%: $(PROGRAMS) FORCE | |
| $(Q)validation/test-suite $* | |
| clean: clean-check | |
| @rm -f *.[oa] .*.d $(PROGRAMS) version.h | |
| clean-check: | |
| @echo " CLEAN" | |
| @find validation/ \( -name "*.c.output.*" \ | |
| -o -name "*.c.error.*" \ | |
| -o -name "*.o" \ | |
| \) -exec rm {} \; | |
| install: install-bin install-man | |
| install-bin: $(INST_PROGRAMS:%=$(bindir)/%) | |
| install-man: $(INST_MAN1:%=$(man1dir)/%) | |
| $(bindir)/%: % | |
| @echo " INSTALL $@" | |
| $(Q)install -D $< $@ || exit 1; | |
| $(man1dir)/%: % | |
| @echo " INSTALL $@" | |
| $(Q)install -D -m 644 $< $@ || exit 1; | |
| .PHONY: FORCE | |
| # GCC's dependencies | |
| -include $(OBJS:%.o=.%.o.d) |