Commit af4254d1 authored by Marek Vavruša's avatar Marek Vavruša

build: amalgamated build support with AMALG=1

amalgamated build concatenates all files into a single .c file to
allow compiler see all symbols and produce possibly smaller code.
for binary distributions this is what you want, as it's faster but
may consume more memory during compilation.
it however cannot do incremental builds.
parent 3e99e9e1
......@@ -51,3 +51,5 @@ tmp*
/tests/test_set
/tests/test_utils
/tests/test_zonecut
kresd.amalg.c
libkres.amalg.c
......@@ -30,7 +30,7 @@ env:
before_script:
- ./scripts/bootstrap-depends.sh ${HOME}/.local
script:
- make -j2 install COVERAGE=1 PREFIX=${HOME}/.local
- make -j2 install AMALG=yes COVERAGE=1 PREFIX=${HOME}/.local
- ./daemon/kresd -h
- make -j2 check COVERAGE=1 PREFIX=${HOME}/.local
- make -j2 check-integration COVERAGE=1 PREFIX=${HOME}/.local
......
......@@ -2,7 +2,7 @@ include config.mk
include platform.mk
# Targets
all: info lib modules daemon
all: info lib daemon modules
install: lib-install modules-install daemon-install
check: all tests
clean: lib-clean modules-clean daemon-clean tests-clean doc-clean
......@@ -43,6 +43,7 @@ endif
endif
BUILD_CFLAGS += $(libknot_CFLAGS) $(libuv_CFLAGS) $(cmocka_CFLAGS) $(lua_CFLAGS) $(libdnssec_CFLAGS)
BUILD_CFLAGS += $(addprefix -I,$(wildcard contrib/ccan/*) contrib/murmurhash3)
# Overview
info:
......
......@@ -87,13 +87,7 @@
#ifdef __GNUC__
#define NONRET __attribute__((noreturn)) /** Function does not return **/
#define UNUSED __attribute__((unused)) /** Variable/parameter is knowingly unused **/
#define CONSTRUCTOR __attribute__((constructor)) /** Call function upon start of program **/
#define CONSTRUCTOR_WITH_PRIORITY(p) __attribute__((constructor(p))) /** Define constructor with a given priority **/
#define PACKED __attribute__((packed)) /** Structure should be packed **/
#define CONST __attribute__((const)) /** Function depends only on arguments **/
#define PURE __attribute__((pure)) /** Function depends only on arguments and global vars **/
#include "ccan/compiler/compiler.h"
#define FORMAT_CHECK(x,y,z) __attribute__((format(x,y,z))) /** Checking of printf-like format strings **/
#define likely(x) __builtin_expect((x),1) /** Use `if (likely(@x))` if @x is almost always true **/
#define unlikely(x) __builtin_expect((x),0) /** Use `if (unlikely(@x))` to hint that @x is almost always false **/
......
kresd_EMBED := \
contrib/ccan/json/json.c \
contrib/ccan/asprintf/asprintf.c
kresd_SOURCES := \
$(kresd_EMBED) \
......@@ -19,10 +18,15 @@ daemon/engine.o: daemon/lua/sandbox.inc daemon/lua/config.inc
bindings-install: daemon/lua/kres.lua daemon/lua/trust_anchors.lua
$(INSTALL) -m 0644 $^ $(PREFIX)/$(MODULEDIR)
# Dependencies
kresd_DEPEND := $(libkres)
kresd_LIBS := $(libkres_TARGET) $(libknot_LIBS) $(libdnssec_LIBS) $(libuv_LIBS) $(lua_LIBS)
# Amalgamated build for smaller code
ifeq ($(AMALG), yes)
kresd_CFLAGS := -fwhole-program
kresd.amalg.c: daemon/lua/sandbox.inc daemon/lua/config.inc
endif
# Make binary
ifeq ($(HAS_lua)|$(HAS_libuv), yes|yes)
$(eval $(call make_bin,kresd,daemon))
......
......@@ -204,7 +204,7 @@ int main(int argc, char **argv)
array_init(addr_set);
char *keyfile = NULL;
const char *config = NULL;
static char keyfile_buf[PATH_MAX + 1];
char *keyfile_buf = NULL;
/* Long options. */
int c = 0, li = 0, ret = 0;
......@@ -242,7 +242,12 @@ int main(int argc, char **argv)
#endif
break;
case 'k':
keyfile_buf = malloc(PATH_MAX + 1);
assert(keyfile_buf);
keyfile = realpath(optarg, keyfile_buf);
if (keyfile)
keyfile = strdup(keyfile);
free(keyfile_buf);
if (!keyfile || access(optarg, R_OK|W_OK) != 0) {
log_error("[system] keyfile '%s': not readable/writeable\n", optarg);
return EXIT_FAILURE;
......
......@@ -376,3 +376,6 @@ void kr_dnssec_key_free(struct dseckey **key)
dnssec_key_free((dnssec_key_t *) *key);
*key = NULL;
}
#undef DEBUG_MSG
......@@ -568,3 +568,5 @@ const knot_layer_api_t *iterate_layer(struct kr_module *module)
}
KR_MODULE_EXPORT(iterate)
#undef DEBUG_MSG
......@@ -84,7 +84,7 @@ static int loot_cache_pkt(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_
}
/** @internal Try to find a shortcut directly to searched packet. */
static int loot_cache(struct kr_cache_txn *txn, knot_pkt_t *pkt, struct kr_query *qry)
static int loot_pktcache(struct kr_cache_txn *txn, knot_pkt_t *pkt, struct kr_query *qry)
{
uint32_t timestamp = qry->timestamp.tv_sec;
const knot_dname_t *qname = qry->sname;
......@@ -93,7 +93,7 @@ static int loot_cache(struct kr_cache_txn *txn, knot_pkt_t *pkt, struct kr_query
return loot_cache_pkt(txn, pkt, qname, rrtype, want_secure, timestamp);
}
static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
static int pktcache_peek(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
struct kr_query *qry = req->current_query;
......@@ -115,7 +115,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
}
/* Fetch either answer to original or minimized query */
int ret = loot_cache(&txn, pkt, qry);
int ret = loot_pktcache(&txn, pkt, qry);
kr_cache_txn_abort(&txn);
if (ret == 0) {
DEBUG_MSG(qry, "=> satisfied from cache\n");
......@@ -158,7 +158,7 @@ static uint32_t packet_ttl(knot_pkt_t *pkt)
return limit_ttl(ttl);
}
static int stash(knot_layer_t *ctx, knot_pkt_t *pkt)
static int pktcache_stash(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
struct kr_query *qry = req->current_query;
......@@ -230,11 +230,13 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt)
const knot_layer_api_t *pktcache_layer(struct kr_module *module)
{
static const knot_layer_api_t _layer = {
.produce = &peek,
.consume = &stash
.produce = &pktcache_peek,
.consume = &pktcache_stash
};
return &_layer;
}
KR_MODULE_EXPORT(pktcache)
\ No newline at end of file
KR_MODULE_EXPORT(pktcache)
#undef DEBUG_MSG
......@@ -77,7 +77,7 @@ static int loot_rr(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_dname_t
}
/** @internal Try to find a shortcut directly to searched record. */
static int loot_cache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query *qry, uint16_t rrtype, bool dobit)
static int loot_rrcache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query *qry, uint16_t rrtype, bool dobit)
{
struct kr_cache_txn txn;
int ret = kr_cache_txn_begin(cache, &txn, NAMEDB_RDONLY);
......@@ -102,7 +102,7 @@ static int loot_cache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query *
return ret;
}
static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
static int rrcache_peek(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
struct kr_query *qry = req->current_query;
......@@ -120,13 +120,13 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
struct kr_cache *cache = &req->ctx->cache;
int ret = -1;
if (qry->stype != KNOT_RRTYPE_ANY) {
ret = loot_cache(cache, pkt, qry, qry->stype, (qry->flags & QUERY_DNSSEC_WANT));
ret = loot_rrcache(cache, pkt, qry, qry->stype, (qry->flags & QUERY_DNSSEC_WANT));
} else {
/* ANY query are used by either qmail or certain versions of Firefox.
* Probe cache for a few interesting records. */
static uint16_t any_types[] = { KNOT_RRTYPE_A, KNOT_RRTYPE_AAAA, KNOT_RRTYPE_MX };
for (size_t i = 0; i < sizeof(any_types)/sizeof(any_types[0]); ++i) {
if (loot_cache(cache, pkt, qry, any_types[i], (qry->flags & QUERY_DNSSEC_WANT)) == 0) {
if (loot_rrcache(cache, pkt, qry, any_types[i], (qry->flags & QUERY_DNSSEC_WANT)) == 0) {
ret = 0; /* At least single record matches */
}
}
......@@ -143,7 +143,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
}
/** @internal Baton for stash_commit */
struct stash_baton
struct rrcache_baton
{
struct kr_request *req;
struct kr_query *qry;
......@@ -152,7 +152,7 @@ struct stash_baton
uint32_t min_ttl;
};
static int commit_rrsig(struct stash_baton *baton, uint16_t rank, knot_rrset_t *rr)
static int commit_rrsig(struct rrcache_baton *baton, uint16_t rank, knot_rrset_t *rr)
{
/* If not doing secure resolution, ignore (unvalidated) RRSIGs. */
if (!(baton->qry->flags & QUERY_DNSSEC_WANT)) {
......@@ -165,7 +165,7 @@ static int commit_rrsig(struct stash_baton *baton, uint16_t rank, knot_rrset_t *
static int commit_rr(const char *key, void *val, void *data)
{
knot_rrset_t *rr = val;
struct stash_baton *baton = data;
struct rrcache_baton *baton = data;
/* Ensure minimum TTL */
knot_rdata_t *rd = rr->rrs.data;
for (uint16_t i = 0; i < rr->rrs.rr_count; ++i) {
......@@ -199,7 +199,7 @@ static int commit_rr(const char *key, void *val, void *data)
static int stash_commit(map_t *stash, struct kr_query *qry, struct kr_cache_txn *txn, struct kr_request *req)
{
struct stash_baton baton = {
struct rrcache_baton baton = {
.req = req,
.qry = qry,
.txn = txn,
......@@ -284,7 +284,7 @@ static int stash_answer(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, mm_
return kr_ok();
}
static int stash(knot_layer_t *ctx, knot_pkt_t *pkt)
static int rrcache_stash(knot_layer_t *ctx, knot_pkt_t *pkt)
{
struct kr_request *req = ctx->data;
struct kr_query *qry = req->current_query;
......@@ -352,11 +352,13 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt)
const knot_layer_api_t *rrcache_layer(struct kr_module *module)
{
static const knot_layer_api_t _layer = {
.produce = &peek,
.consume = &stash
.produce = &rrcache_peek,
.consume = &rrcache_stash
};
return &_layer;
}
KR_MODULE_EXPORT(rrcache)
#undef DEBUG_MSG
......@@ -38,7 +38,7 @@
#define DEBUG_MSG(qry, fmt...) QRDEBUG(qry, "vldr", fmt)
/** @internal Baton for validate_section */
struct stash_baton {
struct validate_baton {
const knot_pkt_t *pkt;
knot_section_t section_id;
const knot_rrset_t *keys;
......@@ -51,7 +51,7 @@ struct stash_baton {
static int validate_rrset(const char *key, void *val, void *data)
{
knot_rrset_t *rr = val;
struct stash_baton *baton = data;
struct validate_baton *baton = data;
if (baton->result != 0) {
return baton->result;
......@@ -97,7 +97,7 @@ static int validate_section(struct kr_query *qry, knot_pkt_t *answer,
}
}
struct stash_baton baton = {
struct validate_baton baton = {
.pkt = answer,
.section_id = section_id,
.keys = qry->zone_cut.key,
......@@ -202,7 +202,7 @@ static knot_rrset_t *update_ds(struct kr_zonecut *cut, const knot_pktsection_t *
return new_ds;
}
static int update_parent(struct kr_query *qry, uint16_t answer_type)
static int update_parent_keys(struct kr_query *qry, uint16_t answer_type)
{
struct kr_query *parent = qry->parent;
assert(parent);
......@@ -416,7 +416,7 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
}
/* Update parent query zone cut */
if (qry->parent) {
if (update_parent(qry, qtype) != 0) {
if (update_parent_keys(qry, qtype) != 0) {
return KNOT_STATE_FAIL;
}
}
......@@ -439,3 +439,5 @@ int validate_init(struct kr_module *module)
}
KR_MODULE_EXPORT(validate)
#undef DEBUG_MSG
......@@ -749,3 +749,6 @@ mm_ctx_t *kr_resolve_pool(struct kr_request *request)
}
return NULL;
}
#undef DEBUG_MSG
......@@ -169,4 +169,6 @@ struct kr_query *kr_rplan_next(struct kr_query *qry)
return NULL;
}
return (struct kr_query *)qry->node.prev; /* The lists are used as stack, TOP is the TAIL. */
}
\ No newline at end of file
}
#undef DEBUG_MSG
hints_SOURCES := modules/hints/hints.c contrib/ccan/json/json.c
hints_SOURCES := modules/hints/hints.c
hints_DEPEND := $(libkres)
hints_LIBS := $(libkres_TARGET) $(libkres_LIBS)
$(call make_c_module,hints)
\ No newline at end of file
stats_SOURCES := modules/stats/stats.c contrib/ccan/json/json.c
stats_SOURCES := modules/stats/stats.c
stats_DEPEND := $(libkres)
stats_LIBS := $(libkres_TARGET) $(libkres_LIBS)
$(call make_c_module,stats)
......@@ -2,6 +2,7 @@
CCLD := $(CC)
CGO := go tool cgo
GO := go
CAT := cat
LIBEXT := .so
MODEXT := $(LIBEXT)
AREXT := .a
......@@ -46,21 +47,32 @@ endif
define make_objs
$(1)_OBJ := $$($(1)_SOURCES:.c=.o)
$(1)_DEP := $$($(1)_SOURCES:.c=.d)
-include $$($(1)_DEP)
endef
# Make target (name,path,ext,ldflags,dst)
# Make target (name,path,ext,ldflags,dst,amalgable)
define make_target
ifeq ($(AMALG)|$(6), yes|yes)
$(1).amalg.c: $$($(1)_SOURCES)
$(call quiet,CAT,$$@) $$($(1)_SOURCES) > $$@
# AR requires .o compiled
$(1)_OBJ := $(1).amalg.c
ifeq ($(4),-$(ARTYPE))
$(1)_OBJ := $(1).amalg.o
endif
else
$$(eval $$(call make_objs,$(1)))
endif
$(1) := $(2)/$(1)$(3)
$(2)/$(1)$(3): $$($(1)_OBJ) $$($(1)_DEPEND)
ifeq ($(4),-$(ARTYPE))
$(call quiet,AR,$$@) rcs $$@ $$($(1)_OBJ)
else
$(call quiet,CCLD,$$@) $(BUILD_CFLAGS) $$($(1)_OBJ) -o $$@ $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS)
$(call quiet,CCLD,$$@) $(BUILD_CFLAGS) $$($(1)_CFLAGS) $$($(1)_OBJ) -o $$@ $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS)
endif
$(1)-clean:
$(RM) $$($(1)_OBJ) $$($(1)_DEP) $(2)/$(1)$(3)
$(RM) $$($(1)_OBJ) $$($(1)_DEP) $(2)/$(1)$(3) $(1).amalg.c $(1).amalg.o
$(1)-install: $(2)/$(1)$(3)
$(INSTALL) -d $(PREFIX)/$(5)
$(INSTALL) $$^ $(PREFIX)/$(5)
......@@ -72,11 +84,11 @@ endif
endef
# Make targets (name,path)
make_bin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(BINDIR))
make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR))
make_module = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(MODULEDIR))
make_shared = $(call make_target,$(1),$(2),$(MODEXT),-$(MODTYPE),$(LIBDIR))
make_static = $(call make_target,$(1),$(2),$(AREXT),-$(ARTYPE),$(LIBDIR))
make_bin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(BINDIR),yes)
make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR),yes)
make_module = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(MODULEDIR),no)
make_shared = $(call make_target,$(1),$(2),$(MODEXT),-$(MODTYPE),$(LIBDIR),yes)
make_static = $(call make_target,$(1),$(2),$(AREXT),-$(ARTYPE),$(LIBDIR),yes)
# Evaluate library
define have_lib
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment