1# Variables:
2prefix = /usr/local
3exec_prefix = $(prefix)
4bindir = $(exec_prefix)/bin
5libdir = $(exec_prefix)/lib
6includedir = $(prefix)/include
7pkgconfigdir = $(libdir)/pkgconfig
8
9CFLAGS = -Wall -Wextra
10LDFLAGS_GCSECTIONS = -Wl,--gc-sections
11LDFLAGS = $(if $(gc_sections-pass),$(LDFLAGS_GCSECTIONS))
12
13GIT_ARCHIVE = git archive --prefix="$(PACKAGE)/" -9
14INSTALL = install
15INSTALL_DATA = $(INSTALL) -m 644
16INSTALL_PROGRAM = $(INSTALL) -m 755
17QMAKE = qmake
18MKDIR = mkdir -p
19RMDIR = rmdir
20SED = sed
21
22# Our sources
23TINYCBOR_HEADERS = \
24	src/cbor.h \
25 	src/cborjson.h \
26	src/cbor_enocoder_writer.h \
27	src/cbor_decoder_reader.h
28TINYCBOR_SOURCES = \
29	src/cborerrorstrings.c \
30	src/cborencoder.c \
31	src/cborencoder_close_container_checked.c \
32	src/cborparser.c \
33	src/cborparser_dup_string.c \
34	src/cborpretty.c \
35	src/cborpretty_stdio.c \
36	src/cbortojson.c \
37	src/cborvalidation.c \
38	src/cbor_buf_reader.c \
39	src/cbor_buf_writer.c
40#
41CBORDUMP_SOURCES = tools/cbordump/cbordump.c
42
43BUILD_SHARED = $(shell file -L /bin/sh 2>/dev/null | grep -q ELF && echo 1)
44BUILD_STATIC = 1
45
46ifneq ($(BUILD_STATIC),1)
47ifneq ($(BUILD_SHARED),1)
48  $(error error: BUILD_STATIC and BUILD_SHARED can not be both disabled)
49endif
50endif
51
52INSTALL_TARGETS += $(bindir)/cbordump
53ifeq ($(BUILD_SHARED),1)
54BINLIBRARY=lib/libtinycbor.so
55INSTALL_TARGETS += $(libdir)/libtinycbor.so
56INSTALL_TARGETS += $(libdir)/libtinycbor.so.0
57INSTALL_TARGETS += $(libdir)/libtinycbor.so.$(VERSION)
58endif
59ifeq ($(BUILD_STATIC),1)
60BINLIBRARY=lib/libtinycbor.a
61INSTALL_TARGETS += $(libdir)/libtinycbor.a
62endif
63INSTALL_TARGETS += $(pkgconfigdir)/tinycbor.pc
64INSTALL_TARGETS += $(TINYCBOR_HEADERS:src/%=$(includedir)/tinycbor/%)
65
66# setup VPATH
67MAKEFILE := $(lastword $(MAKEFILE_LIST))
68SRCDIR := $(dir $(MAKEFILE))
69VPATH = $(SRCDIR):$(SRCDIR)/src
70
71# Our version
72GIT_DIR := $(strip $(shell git -C $(SRCDIR). rev-parse --git-dir 2> /dev/null))
73ifeq ($(GIT_DIR),)
74  VERSION = $(shell cat $(SRCDIR)VERSION)
75  DIRTYSRC :=
76else
77  VERSION := $(shell git -C $(SRCDIR). describe --tags | cut -c2-)
78  DIRTYSRC := $(shell \
79	test -n "`git -C $(SRCDIR). diff --name-only HEAD`" && \
80	echo +)
81endif
82PACKAGE = tinycbor-$(VERSION)
83
84# Check that QMAKE is Qt 5
85ifeq ($(origin QMAKE),file)
86  check_qmake = $(strip $(shell $(1) -query QT_VERSION 2>/dev/null | cut -b1))
87  ifneq ($(call check_qmake,$(QMAKE)),5)
88    QMAKE := qmake -qt5
89    ifneq ($(call check_qmake,$(QMAKE)),5)
90      QMAKE := qmake-qt5
91      ifneq ($(call check_qmake,$(QMAKE)),5)
92        QMAKE := @echo >&2 $(MAKEFILE): Cannot find a Qt 5 qmake; false
93      endif
94    endif
95  endif
96endif
97
98-include .config
99
100# if open_memstream is unavailable on the system, try to implement our own
101# version using funopen or fopencookie
102ifeq ($(open_memstream-pass),)
103  ifeq ($(funopen-pass)$(fopencookie-pass),)
104    CFLAGS += -DCBOR_WITHOUT_OPEN_MEMSTREAM
105    $(warning warning: funopen and fopencookie unavailable, open_memstream can not be implemented and conversion to JSON will not work properly!)
106  else
107    TINYCBOR_SOURCES += src/open_memstream.c
108  endif
109endif
110
111# json2cbor depends on an external library (cjson)
112ifneq ($(cjson-pass)$(system-cjson-pass),)
113  JSON2CBOR_SOURCES = tools/json2cbor/json2cbor.c
114  INSTALL_TARGETS += $(bindir)/json2cbor
115  ifeq ($(system-cjson-pass),1)
116    LDFLAGS_CJSON = -lcjson
117  else
118    JSON2CBOR_SOURCES += src/cjson/cJSON.c
119    json2cbor_CCFLAGS = -I$(SRCDIR)src/cjson
120  endif
121endif
122
123# Rules
124all: .config \
125	$(if $(subst 0,,$(BUILD_STATIC)),lib/libtinycbor.a) \
126	$(if $(subst 0,,$(BUILD_SHARED)),lib/libtinycbor.so) \
127	bin/cbordump tinycbor.pc
128all: $(if $(JSON2CBOR_SOURCES),bin/json2cbor)
129check: tests/Makefile | $(BINLIBRARY)
130	$(MAKE) -C tests check
131silentcheck: | $(BINLIBRARY)
132	TESTARGS=-silent $(MAKE) -f $(MAKEFILE) -s check
133configure: .config
134.config: Makefile.configure
135	$(MAKE) -f $(SRCDIR)Makefile.configure OUT='>&9' configure 9> $@
136
137lib/libtinycbor.a: $(TINYCBOR_SOURCES:.c=.o)
138	@$(MKDIR) -p lib
139	$(AR) cqs $@ $^
140
141lib/libtinycbor.so: $(TINYCBOR_SOURCES:.c=.pic.o)
142	@$(MKDIR) -p lib
143	$(CC) -shared -Wl,-soname,libtinycbor.so.0 -o lib/libtinycbor.so.$(VERSION) $(LDFLAGS) $^
144	cd lib ; ln -sf libtinycbor.so.$(VERSION) libtinycbor.so ; ln -sf libtinycbor.so.$(VERSION) libtinycbor.so.0
145
146bin/cbordump: $(CBORDUMP_SOURCES:.c=.o) $(BINLIBRARY)
147	@$(MKDIR) -p bin
148	$(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS) -lm
149
150bin/json2cbor: $(JSON2CBOR_SOURCES:.c=.o) $(BINLIBRARY)
151	@$(MKDIR) -p bin
152	$(CC) -o $@ $(LDFLAGS) $^ $(LDFLAGS_CJSON) $(LDLIBS) -lm
153
154tinycbor.pc: tinycbor.pc.in
155	$(SED) > $@ < $< \
156		-e 's,@prefix@,$(prefix),' \
157		-e 's,@exec_prefix@,$(exec_prefix),' \
158		-e 's,@libdir@,$(libdir),' \
159		-e 's,@includedir@,$(includedir),' \
160		-e 's,@version@,$(VERSION),'
161
162tests/Makefile: tests/tests.pro
163	$(QMAKE) $(QMAKEFLAGS) -o $@ $<
164
165$(PACKAGE).tar.gz: | .git
166	GIT_DIR=$(SRCDIR).git $(GIT_ARCHIVE) --format=tar.gz -o "$(PACKAGE).tar.gz" HEAD
167$(PACKAGE).zip: | .git
168	GIT_DIR=$(SRCDIR).git $(GIT_ARCHIVE) --format=zip -o "$(PACKAGE).zip" HEAD
169
170$(DESTDIR)$(libdir)/%: lib/%
171	$(INSTALL) -d $(@D)
172	$(INSTALL_DATA) $< $@
173$(DESTDIR)$(bindir)/%: bin/%
174	$(INSTALL) -d $(@D)
175	$(INSTALL_PROGRAM) $< $@
176$(DESTDIR)$(pkgconfigdir)/%: %
177	$(INSTALL) -d $(@D)
178	$(INSTALL_DATA) $< $@
179$(DESTDIR)$(includedir)/tinycbor/%: src/%
180	$(INSTALL) -d $(@D)
181	$(INSTALL_DATA) $< $@
182
183install-strip:
184	$(MAKE) -f $(MAKEFILE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
185
186install: $(INSTALL_TARGETS:%=$(DESTDIR)%)
187uninstall:
188	$(RM) $(INSTALL_TARGETS:%=$(DESTDIR)%)
189
190mostlyclean:
191	$(RM) $(TINYCBOR_SOURCES:.c=.o)
192	$(RM) $(TINYCBOR_SOURCES:.c=.pic.o)
193	$(RM) $(CBORDUMP_SOURCES:.c=.o)
194
195clean: mostlyclean
196	$(RM) bin/cbordump
197	$(RM) bin/json2cbor
198	$(RM) lib/libtinycbor.a
199	$(RM) tinycbor.pc
200	$(RM) lib/libtinycbor.so*
201	test -e tests/Makefile && $(MAKE) -C tests clean || :
202
203distclean: clean
204	test -e tests/Makefile && $(MAKE) -C tests distclean || :
205
206docs:
207	cd $(SRCDIR)src && VERSION=$(VERSION) doxygen $(SRCDIR)/../Doxyfile
208
209dist: $(PACKAGE).tar.gz $(PACKAGE).zip
210distcheck: .git
211	-$(RM) -r $${TMPDIR-/tmp}/tinycbor-distcheck
212	GIT_DIR=$(SRCDIR).git git archive --prefix=tinycbor-distcheck/ --format=tar HEAD | tar -xf - -C $${TMPDIR-/tmp}
213	cd $${TMPDIR-/tmp}/tinycbor-distcheck && $(MAKE) silentcheck
214	$(RM) -r $${TMPDIR-/tmp}/tinycbor-distcheck
215
216tag: distcheck
217	@cd $(SRCDIR). && perl maketag.pl
218
219.PHONY: all check silentcheck configure install uninstall
220.PHONY: mostlyclean clean distclean
221.PHONY: docs dist distcheck release
222.SECONDARY:
223
224cflags := $(CPPFLAGS) -I$(SRCDIR)src
225cflags += -DTINYCBOR_VERSION_SUFFIX=\"$(DIRTYSRC)\"
226cflags += -std=c99 $(CFLAGS)
227%.o: %.c
228	@test -d $(@D) || $(MKDIR) $(@D)
229	$(CC) $(cflags) $($(basename $(notdir $@))_CCFLAGS) -c -o $@ $<
230%.pic.o: %.c
231	@test -d $(@D) || $(MKDIR) $(@D)
232	$(CC) $(cflags) -fPIC $($(basename $(notdir $@))_CCFLAGS) -c -o $@ $<
233
234-include src/*.d
235