1# We assume X64 unless HH_POWER, HH_ARM, or HH_AARCH64 are defined.
2
3override CPPFLAGS += -I.
4override CXXFLAGS += -std=c++11 -Wall -fPIC -pthread
5override LDFLAGS += -pthread
6
7PREFIX ?= /usr/local
8INCDIR ?= $(PREFIX)/include
9LIBDIR ?= $(PREFIX)/lib
10
11SIP_OBJS := $(addprefix obj/, \
12	sip_hash.o \
13	sip_tree_hash.o \
14	scalar_sip_tree_hash.o \
15)
16
17DISPATCHER_OBJS := $(addprefix obj/, \
18	arch_specific.o \
19	instruction_sets.o \
20	nanobenchmark.o \
21	os_specific.o \
22)
23
24HIGHWAYHASH_OBJS := $(DISPATCHER_OBJS) obj/hh_portable.o
25HIGHWAYHASH_TEST_OBJS := $(DISPATCHER_OBJS) obj/highwayhash_test_portable.o
26VECTOR_TEST_OBJS := $(DISPATCHER_OBJS) obj/vector_test_portable.o
27
28# aarch64 and ARM use the same code, although ARM usually needs an extra flag for NEON.
29ifdef HH_ARM
30CXXFLAGS += -mfloat-abi=hard -march=armv7-a -mfpu=neon
31HH_AARCH64 = 1
32endif
33
34ifdef HH_AARCH64
35HH_X64 =
36HIGHWAYHASH_OBJS += obj/hh_neon.o
37HIGHWAYHASH_TEST_OBJS += obj/highwayhash_test_neon.o
38VECTOR_TEST_OBJS += obj/vector_test_neon.o
39else
40ifdef HH_POWER
41HH_X64 =
42HIGHWAYHASH_OBJS += obj/hh_vsx.o
43HIGHWAYHASH_TEST_OBJS += obj/highwayhash_test_vsx.o
44else
45HH_X64 = 1
46HIGHWAYHASH_OBJS += obj/hh_avx2.o obj/hh_sse41.o
47HIGHWAYHASH_TEST_OBJS += obj/highwayhash_test_avx2.o obj/highwayhash_test_sse41.o
48VECTOR_TEST_OBJS += obj/vector_test_avx2.o obj/vector_test_sse41.o
49endif
50endif
51
52# In case highwayhash_test defines PRINT_RESULTS.
53HIGHWAYHASH_TEST_OBJS += $(HIGHWAYHASH_OBJS)
54
55all: $(addprefix bin/, \
56	profiler_example nanobenchmark_example vector_test sip_hash_test \
57	highwayhash_test benchmark) lib/libhighwayhash.a
58
59obj/%.o: highwayhash/%.cc
60	@mkdir -p -- $(dir $@)
61	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@
62
63bin/%: obj/%.o
64	@mkdir -p -- $(dir $@)
65	$(CXX) $(LDFLAGS) $^ -o $@
66
67.DELETE_ON_ERROR:
68deps.mk: $(wildcard highwayhash/*.cc) $(wildcard highwayhash/*.h) Makefile
69	set -eu; for file in highwayhash/*.cc; do \
70		target=obj/$${file##*/}; target=$${target%.*}.o; \
71		[ "$$target" = "obj/highwayhash_target.o" ] || \
72		[ "$$target" = "obj/data_parallel_benchmark.o" ] || \
73		[ "$$target" = "obj/data_parallel_test.o" ] || \
74		$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -DHH_DISABLE_TARGET_SPECIFIC -MM -MT \
75		"$$target" "$$file"; \
76	done | sed -e ':b' -e 's-../[^./]*/--' -e 'tb' >$@
77-include deps.mk
78
79bin/profiler_example: $(DISPATCHER_OBJS)
80
81bin/nanobenchmark_example: $(DISPATCHER_OBJS) obj/nanobenchmark.o
82
83ifdef HH_X64
84# TODO: Portability: Have AVX2 be optional so benchmarking can be done on older machines.
85obj/sip_tree_hash.o: CXXFLAGS+=-mavx2
86# (Compiled from same source file with different compiler flags)
87obj/highwayhash_test_avx2.o: CXXFLAGS+=-mavx2
88obj/highwayhash_test_sse41.o: CXXFLAGS+=-msse4.1
89obj/hh_avx2.o: CXXFLAGS+=-mavx2
90obj/hh_sse41.o: CXXFLAGS+=-msse4.1
91obj/vector_test_avx2.o: CXXFLAGS+=-mavx2
92obj/vector_test_sse41.o: CXXFLAGS+=-msse4.1
93
94obj/benchmark.o: CXXFLAGS+=-mavx2
95endif
96
97ifdef HH_POWER
98obj/highwayhash_test_vsx.o: CXXFLAGS+=-mvsx
99obj/hh_vsx.o: CXXFLAGS+=-mvsx
100obj/benchmark.o: CXXFLAGS+=-mvsx
101# Skip file - vector library/test not supported on PPC
102obj/vector_test_target.o: CXXFLAGS+=-DHH_DISABLE_TARGET_SPECIFIC
103obj/vector_test.o: CXXFLAGS+=-DHH_DISABLE_TARGET_SPECIFIC
104endif
105
106lib/libhighwayhash.a: $(SIP_OBJS) $(HIGHWAYHASH_OBJS) obj/c_bindings.o
107	@mkdir -p -- $(dir $@)
108	$(AR) rcs $@ $^
109	# Disabled due to false positives; ideally the test instead ensures
110	# target-specific modules _only_ export symbols starting with a prefix.
111	# ./test_exports.sh $^
112
113lib/libhighwayhash.so: $(SIP_OBJS) $(HIGHWAYHASH_OBJS) obj/c_bindings.o
114	@mkdir -p -- $(dir $@)
115	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $^ -o $@.0 -Wl,-soname,libhighwayhash.so.0
116	@cd $(dir $@); ln -s libhighwayhash.so.0 libhighwayhash.so
117
118bin/highwayhash_test: $(HIGHWAYHASH_TEST_OBJS)
119
120bin/benchmark: obj/benchmark.o $(HIGHWAYHASH_TEST_OBJS)
121bin/benchmark: $(SIP_OBJS) $(HIGHWAYHASH_OBJS)
122bin/vector_test: $(VECTOR_TEST_OBJS)
123
124clean:
125	[ ! -d obj ] || $(RM) -r -- obj/
126
127distclean: clean
128	[ ! -d bin ] || $(RM) -r -- bin/
129	[ ! -d lib ] || $(RM) -r -- lib/
130
131# Mode bits are from issue #58, thanks to yurivict for suggesting.
132# Also added owner-write for stripping the .so in post-install.
133install: lib/libhighwayhash.a lib/libhighwayhash.so
134	mkdir -p $(DESTDIR)/$(LIBDIR)
135	mkdir -p $(DESTDIR)/$(INCDIR)/highwayhash
136	install -m0444 lib/libhighwayhash.a $(DESTDIR)/$(LIBDIR)
137	install -m0755 lib/libhighwayhash.so $(DESTDIR)/$(LIBDIR)
138	install -m0444 highwayhash/*.h $(DESTDIR)/$(INCDIR)/highwayhash/
139
140post-install:
141	${STRIP_CMD} $(DESTDIR)/$(LIBDIR)/libhighwayhash.so
142
143.PHONY: clean distclean all install post-install
144