initial commit
This commit is contained in:
commit
89d561e5b7
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.build.mak
|
||||
build
|
79
Makefile
Normal file
79
Makefile
Normal file
@ -0,0 +1,79 @@
|
||||
######################################################################
|
||||
# Makefile
|
||||
#
|
||||
# This makefile is the one called by user, but it's only a trampoline
|
||||
# to create the build directory and call the real Makefile.build
|
||||
#
|
||||
# make can be invoqued with 'make build=<your_build_directory> ...'
|
||||
# all other options and target are passed to the real makefile.
|
||||
#
|
||||
# As an exception to the rule of not modifying source directory, a
|
||||
# .build.mak file is created to cache the configured build directory.
|
||||
# Subsequent invocations of make could be done without passing
|
||||
# 'build=...' parameter.
|
||||
#
|
||||
# distclean target is catched to destroy both the .build.mak and
|
||||
# the whole build directory.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# build directory is cached in BUILD_MAK file between make invocations
|
||||
BUILD_MAK = .build.mak
|
||||
ifneq ($(wildcard $(BUILD_MAK)),)
|
||||
include $(BUILD_MAK)
|
||||
endif
|
||||
|
||||
# default build directory 'build'
|
||||
build ?= build
|
||||
|
||||
# ($call quiet-command,CMD,MSG)
|
||||
# execute CMD and display MSG
|
||||
# if verbose mode is enabled (with 'make V=1`) print full CMD instead of MSG
|
||||
quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
|
||||
|
||||
# if the target is distclean, skip allmost rules
|
||||
# to doing anything which will be immediately
|
||||
# deleted after
|
||||
ifeq ($(filter distclean,$(MAKECMDGOALS)),)
|
||||
|
||||
# default target (when one invokes 'make' without target)
|
||||
# so we have a non-empty target which could be catched by
|
||||
# the catch-all target below.
|
||||
default-all:
|
||||
|
||||
# The catch-all target, which pass build to the main
|
||||
# makefile in the build directory.
|
||||
# strip-out 'default-all' for targets' list
|
||||
%: | $(build)
|
||||
$(call quiet-command, \
|
||||
$(MAKE) -C $(build) $(filter-out default-all,$@) \
|
||||
, "MAKE $(filter-out default-all,$@)")
|
||||
|
||||
# Creates the buld directory
|
||||
# and populates it with a link to the build makefile
|
||||
$(build): | $(BUILD_MAK)
|
||||
$(call quiet-command,\
|
||||
mkdir -p $@; \
|
||||
ln -sf $(CURDIR)/Makefile.build $@/Makefile \
|
||||
, "MKBUILD $@")
|
||||
|
||||
# always create BUILD_MAK to cache build configuration
|
||||
# but don't update it if not changed
|
||||
$(BUILD_MAK): FORCE
|
||||
@echo build=$(build) > $@.tmp
|
||||
@cmp -s $@.tmp $@ || (mv $@.tmp $@ && echo "GEN $@")
|
||||
@rm -f $@.tmp
|
||||
|
||||
else # if distclean
|
||||
|
||||
distclean:
|
||||
$(call quiet-command, rm -rf $(build) $(BUILD_MAK), "DISTCLEAN $(build)")
|
||||
|
||||
endif # distclean
|
||||
|
||||
|
||||
.PHONY: distclean FORCE
|
||||
|
||||
#ifndef V
|
||||
#.SILENT:
|
||||
#endif
|
213
Makefile.build
Normal file
213
Makefile.build
Normal file
@ -0,0 +1,213 @@
|
||||
######################################################################
|
||||
# Some helper functions
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# $(call inspect,LIST)
|
||||
# dump list of variables printing their values and their attributes
|
||||
inspect = $(foreach v,$(1),$(info $(v) [$(origin $(v)),$(flavor $(v))] = $($(v))))
|
||||
|
||||
# $(call undefine_default,LIST)
|
||||
# undefine default variables given in LIST)
|
||||
undefine_default = $(foreach v,$(1),$(if $(filter default,$(origin $(v))),$(eval undefine $(v)),))
|
||||
|
||||
# $(call setdef_ifdef,VAR,DEFVAR)
|
||||
# if DEFVAR exists, set default value of VAR to $(DEFVAR)
|
||||
setdefault_ifdef = $(if $(filter undefined,$(origin $(2))),,$(eval $(1) ?= $($(2))))
|
||||
|
||||
# $(call clean_bool_true,VALUE)
|
||||
# $(call clean_bool_false,VALUE)
|
||||
# $(call clean_bool,VALUE)
|
||||
# clean_bool,clean_bool_true:
|
||||
# if VALUE is identified as true (true, on, yes, enable, 1, ...) returns 1
|
||||
# clean_bool,clean_bool_false:
|
||||
# if VALUE is identified as false (false, off, no, disable, 0, ...) returns an empty string
|
||||
clean_bool_true = $(if $(filter true TRUE on ON yes YES enable ENABLE,$(1)),1,$(1))
|
||||
clean_bool_false = $(if $(filter false FALSE off OFF no NO disable DISABLE 0,$(1)),,$(1))
|
||||
clean_bool = $(call clean_bool_false,$(call clean_bool_true,$(1)))
|
||||
|
||||
# $(call quote_spaces,STR)
|
||||
# return STR, surrounded by double quotes if it contains spaces
|
||||
quote_spaces = $(if $(filter 0 1,$(words $1)),$1,"$1")
|
||||
|
||||
# $(call pathsearch,EXEC)
|
||||
# returns the full path of EXEC if it exists somewhere in $PATH
|
||||
# if not found, returns the unmodified EXEC
|
||||
pathsearch = $(if $(filter 1,$(words $(1))),$(firstword $(wildcard $(1) $(addsuffix /$(1),$(subst :, ,$(PATH)))) $(1)),$(1))
|
||||
|
||||
# $(call prepend_ccache,PREFIX,EXEC)
|
||||
# return 'ccache EXEC' if ccache is not already detected in EXEC
|
||||
prepend_ccache = $(if $(filter ccache,$(subst /, ,$(1))),$(1),ccache $(1))
|
||||
|
||||
# $(call clean_path,PATH)
|
||||
# return a sanitized path: remove //, trailing /
|
||||
clean_path = $(subst //,/,$(patsubst %/,%,$1))
|
||||
|
||||
# ($call quiet-command,CMD,MSG)
|
||||
# execute CMD and display MSG
|
||||
# if verbose mode is enabled (with 'make V=1`) print full CMD instead of MSG
|
||||
quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
|
||||
|
||||
|
||||
######################################################################
|
||||
# Cached configuration support
|
||||
#
|
||||
# variables listed in CONFIG_VARS are stored in CONFIG_MAK file
|
||||
# containing lines `cache_VAR=value`
|
||||
# This file is read on subsequent invocation and set default values
|
||||
# of these variables.
|
||||
#
|
||||
# The file is automatically generated but can be hand-edited.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
CONFIG_MAK = config.mak
|
||||
CONFIG_VARS = max
|
||||
|
||||
CONFIG_STRING = $(foreach var,$(CONFIG_VARS),$(var)=$(call quote_spaces,$($(var))))
|
||||
|
||||
# undefine variables which have a default value set by make itself
|
||||
# (mainly CC and CXX)
|
||||
$(call undefine_default,$(CONFIG_VARS))
|
||||
|
||||
# read the cached variables
|
||||
-include $(CONFIG_MAK)
|
||||
|
||||
# for all undefined variables set their default values from ones
|
||||
# stored in included CONFIG_MAK.
|
||||
$(foreach var,$(CONFIG_VARS),$(call setdefault_ifdef,$(var),cache_$(var)))
|
||||
|
||||
#default (non false) values
|
||||
# max ?= 10
|
||||
|
||||
# cleanup "False" boolean values, set them to empty value
|
||||
$(foreach var,$(CONFIG_VARS),$(eval override $(var):=$(call clean_bool_false,$($(var)))))
|
||||
|
||||
# print out user configuration
|
||||
# (only once in case the makefile has been reloaded)
|
||||
ifndef MAKE_RESTARTS
|
||||
$(info CONF $(CONFIG_STRING))
|
||||
endif
|
||||
|
||||
|
||||
######################################################################
|
||||
# Flags generation
|
||||
#
|
||||
######################################################################
|
||||
|
||||
CFLAGS =
|
||||
|
||||
ifdef max
|
||||
CFLAGS += -DFIBO_MAX=$(max)
|
||||
endif
|
||||
|
||||
|
||||
######################################################################
|
||||
# Source and objects collection
|
||||
#
|
||||
######################################################################
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
ifdef srcdir
|
||||
srcdir := $(patsubst %/,%,$(srcdir))
|
||||
else
|
||||
srcdir := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
|
||||
endif
|
||||
|
||||
INCLUDES := src \
|
||||
src/version \
|
||||
src/fibo
|
||||
|
||||
SRCS := src/main.c \
|
||||
src/version/version_tools.c \
|
||||
src/fibo/fibo.c
|
||||
|
||||
OBJS += src/version/version.o
|
||||
OBJS += $(SRCS:%.c=%.o)
|
||||
|
||||
|
||||
VPATH += $(srcdir)
|
||||
VPATH += .
|
||||
|
||||
CFLAGS += $(addprefix -I$(srcdir)/,$(INCLUDES))
|
||||
|
||||
GENERATED += $(OBJS)
|
||||
GENERATED += $(DEPDIR)
|
||||
GENERATED += src/version/version.c
|
||||
GENERATED += fibo
|
||||
|
||||
######################################################################
|
||||
# Dependencies tracking
|
||||
#
|
||||
######################################################################
|
||||
|
||||
DEPDIR := .deps
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td #generate dependency file in a temporary file
|
||||
|
||||
#Rename the generated temporary dependency file to the real dependency file.
|
||||
#We do this in a separate step so that failures during the compilation wont leave a corrupted dependency file
|
||||
#in some rare cases dep file can end up beeing newer than object, final touch ensures that object will always
|
||||
#be newer.
|
||||
POSTCOMPILE = @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@
|
||||
|
||||
CFLAGS += $(DEPFLAGS)
|
||||
|
||||
|
||||
######################################################################
|
||||
# Targets
|
||||
#
|
||||
######################################################################
|
||||
.SECONDEXPANSION:
|
||||
|
||||
all: fibo
|
||||
|
||||
fibo: $(OBJS)
|
||||
$(call quiet-command, $(CC) $^ -o $@, "LINK $@")
|
||||
|
||||
%.c: %.c.in FORCE
|
||||
@mkdir -p $(@D)
|
||||
@sed -e 's#@@GIT_SHA1@@#$(shell git describe --all --long --dirty)#' $< > $@.tmp
|
||||
@cmp -s $@.tmp $@ || (echo "GEN $@"; mv $@.tmp $@)
|
||||
@rm -f $@.tmp
|
||||
|
||||
.PRECIOUS: src/version/version.c
|
||||
|
||||
%.o: %.c | $(DEPDIR)/$$(@D)/
|
||||
$(call quiet-command, $(CC) $(CFLAGS) $(IFLAGS) -o $@ -c $<, "CC $@")
|
||||
$(POSTCOMPILE)
|
||||
|
||||
|
||||
%/:
|
||||
@mkdir -p $@
|
||||
|
||||
# Generate the cached configuration make script
|
||||
# - always generated
|
||||
# - file is written out only if modified
|
||||
$(CONFIG_MAK): FORCE
|
||||
@echo "# automatically generated" > $@.tmp
|
||||
@$(foreach var,$(CONFIG_VARS),echo cache_$(var)=$($(var)) >> $@.tmp;)
|
||||
@cmp -s $@.tmp $@ || (echo "GEN $@"; mv $@.tmp $@)
|
||||
@rm -f $@.tmp
|
||||
|
||||
$(OBJS): $(MAKEFILE_LIST)
|
||||
|
||||
inspect:
|
||||
$(call inspect,srcdir)
|
||||
$(call inspect,SRCS)
|
||||
$(call inspect,OBJS)
|
||||
$(call inspect,SHELL)
|
||||
|
||||
clean:
|
||||
$(call quiet-command, rm -rf $(GENERATED), "CLEAN")
|
||||
|
||||
distclean:
|
||||
$(call quiet-command, rm -rf $(GENERATED) $(CONFIG_MAK) Makefile, "DISTCLEAN")
|
||||
|
||||
.PHONY: FORCE clean inspect
|
||||
|
||||
# include all potential dependencies files
|
||||
-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
|
||||
|
||||
|
37
src/fibo/fibo.c
Normal file
37
src/fibo/fibo.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "fibo.h"
|
||||
|
||||
|
||||
static int *fibo;
|
||||
static u_int64_t fibo_size;
|
||||
|
||||
|
||||
void fibo_init(int size)
|
||||
{
|
||||
fibo = calloc(size, sizeof(u_int64_t));
|
||||
if (fibo == NULL) {
|
||||
fprintf(stderr, "ERROR: cannot allocate memory\n");
|
||||
exit(1);
|
||||
}
|
||||
fibo_size = size;
|
||||
}
|
||||
|
||||
|
||||
void fibo_compute(void)
|
||||
{
|
||||
fibo[0] = 1;
|
||||
fibo[1] = 1;
|
||||
for (int i = 2; i < fibo_size; i++)
|
||||
fibo[i] = fibo[i-2] + fibo[i-1];
|
||||
}
|
||||
|
||||
|
||||
void fibo_print()
|
||||
{
|
||||
printf("fibo:");
|
||||
for (int i=0; i<fibo_size; i++)
|
||||
printf(" %lu", fibo[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
5
src/fibo/fibo.h
Normal file
5
src/fibo/fibo.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
void fibo_init(int size);
|
||||
void fibo_compute(void);
|
||||
void fibo_print(void);
|
||||
|
21
src/main.c
Normal file
21
src/main.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "version_tools.h"
|
||||
#include "fibo.h"
|
||||
|
||||
|
||||
#ifdef FIBO_MAX
|
||||
#define MAIN_FIBO_MAX FIBO_MAX
|
||||
#else
|
||||
#define MAIN_FIBO_MAX 10
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
print_version();
|
||||
|
||||
fibo_init(MAIN_FIBO_MAX);
|
||||
fibo_compute();
|
||||
fibo_print();
|
||||
|
||||
return 0;
|
||||
}
|
3
src/version/version.c.in
Normal file
3
src/version/version.c.in
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
const char* git_sha1 = "@@GIT_SHA1@@";
|
||||
|
4
src/version/version.h
Normal file
4
src/version/version.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
|
||||
extern const char *git_sha1;
|
||||
|
8
src/version/version_tools.c
Normal file
8
src/version/version_tools.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include "version.h"
|
||||
|
||||
|
||||
void print_version(void)
|
||||
{
|
||||
printf("version: %s\n", git_sha1);
|
||||
}
|
3
src/version/version_tools.h
Normal file
3
src/version/version_tools.h
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
void print_version(void);
|
||||
|
Loading…
Reference in New Issue
Block a user