author | Olivier Brunel
<jjk@jjacky.com> 2023-03-31 13:40:14 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-03-31 13:40:14 UTC |
parent | 0c59daae2b512782455e69cb5586d589eee1b03d |
common.mk | +74 | -49 |
configure | +278 | -163 |
getdeps | +3 | -3 |
init | +6 | -6 |
libcomain | +103 | -18 |
meta/deps.tpl/limb/configure | +1 | -0 |
meta/deps.tpl/limb/incdir | +1 | -0 |
meta/deps.tpl/{limb/static => skalibs/after/limb} | +0 | -0 |
meta/deps.tpl/skalibs/configure | +1 | -0 |
meta/options/debug/{disabled => after/optimize} | +0 | -0 |
meta/options/debug/default | +1 | -0 |
meta/options/optimize/cflags | +1 | -0 |
meta/options/optimize/default | +1 | -0 |
meta/options/optimize/desc | +1 | -0 |
meta/options/optimizeOff/cflags | +1 | -0 |
meta/options/optimizeOff/desc | +1 | -0 |
meta/options/optimizeOff/invisible | +0 | -0 |
meta/options/optimizeOff/isdefault | +5 | -0 |
meta/options/warnings/cflags | +1 | -0 |
meta/options/warnings/default | +1 | -0 |
meta/options/warnings/desc | +1 | -0 |
mkbuild | +11 | -0 |
mkdoc | +8 | -0 |
mkreadme | +1 | -1 |
mktarball | +4 | -4 |
project.mk.tpl | +2 | -2 |
diff --git a/common.mk b/common.mk index 45780a8..573683c 100644 --- a/common.mk +++ b/common.mk @@ -3,56 +3,73 @@ # init some variables DEBUG = +CPPFLAGS= CFLAGS = LDFLAGS = -# basic warnings, create .d dependency files -COMMON_CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -COMMON_CPPFLAGS += -iquote include -COMMON_CFLAGS = -pipe -Wall -O3 -COMMON_CFLAGS += -MMD -MP -COMMON_LDFLAGS = -Wl,--sort-section=alignment -Wl,--sort-common -CFLAGS_SHARED = -fPIC -LDFLAGS_SHARED = -shared -Wl,--hash-style=gnu - -SRCS = $(wildcard src/*.c src/*/*.c) -ASMS = $(wildcard src/*.S src/*/*.S) -OBJS = $(SRCS:src/%.c=obj/%.o) $(ASMS:src/%.S=obj/%.o) -OBJS += $(SRCS:src/%.c=obj/%.lo) -DEPS = $(OBJS:%=%.d) -BINS = -LIBS = -TOOLS = -SHARED_LIBS = $(patsubst %,lib%.so,$(LIBS)) -STATIC_LIBS = $(patsubst %,lib%.a,$(LIBS)) -SRCS_DOCS = $(wildcard doc/*.md) -DOCS = README COPYING $(SRCS_DOCS:doc/%=%) +# basic flags, create .d dependency files +COMMON_CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 +COMMON_CPPFLAGS += -iquote src/include +COMMON_CFLAGS = -pipe +COMMON_CFLAGS += -MMD -MP +COMMON_LDFLAGS = +COMMON_CPPFLAGS_SHARED = +COMMON_CFLAGS_SHARED = -shared +COMMON_LDFLAGS_SHARED = + +BLD_DOCS = +BLD_SHARED_LIBS = +BLD_STATIC_LIBS = +BLD_BINS = +# this isn't ideal, since it's limited to a depth of 2. However, that'll be +# enough (for now), as 1 is binary/library level, 2 is header within library, +# and we don't expect to go any deeper than that. +DEPS = $(wildcard build/*/*.d) $(wildcard build/*/*/*.d) +LIBS = +STATIC_LIBS = $(LIBS:%=lib%.a) +SHARED_LIBS = $(LIBS:%=lib%.so) +BINS = +PRIV_LIBS = +PRIV_STATIC_LIBS = $(PRIV_LIBS:%=lib%.a) +PRIV_SHARED_LIBS = $(PRIV_LIBS:%=lib%.so) +PRIV_BINS = +DOCS = README COPYING $(BLD_DOCS:build/doc/%=md/%) DATA = # to be removed upon `make clean` -CLEAN = $(BINS) $(TOOLS) $(STATIC_LIBS) $(SHARED_LIBS) $(OBJS) $(DEPS) +CLEAN = $(BLD_STATIC_LIBS) $(BLD_SHARED_LIBS) $(BLD_BINS) -obj: comain - $(_DIR) comain/mkdirobj +build: comain + $(_DIR) comain/mkbuild -obj/%.o: src/%.c Makefile common.mk config.mk project.mk | obj - $(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) $(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) -o $@ -c $< - @mv $(@:%.o=%.d) $(@:%.o=%.o.d) +build/doc/%.md: | build + $(_DOC) comain/mkdoc $< $@ -obj/%.o: src/%.S Makefile common.mk config.mk project.mk | obj - $(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) $(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) -o $@ -c $< - @mv $(@:%.o=%.d) $(@:%.o=%.o.d) +build/%.o: src/%.c Makefile common.mk config.mk project.mk | build + $(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) \ + $(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) \ + -o $@ -c $< + @test -e $(@:%.o=%.d) && mv $(@:%.o=%.d) $(@:%.o=%.o.d) -obj/%.lo: src/%.c Makefile common.mk config.mk project.mk | obj - $(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) $(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) $(CFLAGS_SHARED) -o $@ -c $< - @mv $(@:%.lo=%.d) $(@:%.lo=%.lo.d) +build/%.o: src/%.S Makefile common.mk config.mk project.mk | build + $(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) \ + $(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) \ + -o $@ -c $< + @test -e $(@:%.o=%.d) && mv $(@:%.o=%.d) $(@:%.o=%.o.d) + +build/%.lo: src/%.c Makefile common.mk config.mk project.mk | build + $(_CC) $(COMMON_CPPFLAGS) $(COMMON_CPPFLAGS_SHARED) $(CPPFLAGS) \ + $(COMMON_CFLAGS) $(COMMON_CFLAGS_SHARED) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) \ + -o $@ -c $< + @test -e $(@:%.lo=%.d) && mv $(@:%.lo=%.d) $(@:%.lo=%.lo.d) lib%.a: $(_AR) $(AR) rc $@ $^ $(_RANLIB) $(RANLIB) $@ lib%.so: - $(_CC) -o $@ $(COMMON_CFLAGS) $(CFLAGS) $(CFLAGS_SHARED) $(LDFLAGS_SHARED) \ + $(_CC) -o $@ $(COMMON_CFLAGS) $(COMMON_CFLAGS_SHARED) $(CFLAGS) \ + $(COMMON_LDFLAGS) $(COMMON_LDFLAGS_SHARED) $(LDFLAGS) \ -Wl,-soname,$@.0 $^ # dependencies to try and make automatically @@ -68,7 +85,7 @@ include project.mk -include $(DEPS) # binary-specific deps -DEPS += $(BINS:%=%.d) +DEPS += $(BLD_BINS:%=%.d) # install binaries $(DESTDIR)$(BINDIR)/%: % @@ -95,11 +112,11 @@ $(DESTDIR)$(SHAREDIR)/doc/$(PROJECT_NAME)/%: % $(_INST) install -D -m 644 $< $@ # install *.md documentation -$(DESTDIR)$(SHAREDIR)/doc/$(PROJECT_NAME)/%.md: doc/%.md | dummy% +$(DESTDIR)$(SHAREDIR)/doc/$(PROJECT_NAME)/md/%.md: build/doc/%.md | dummy% $(_INST) install -D -m 644 $< $@ # dummy rule, so "install doc" takes precedence over "install *.md doc" whenver -# there is an *.md file in the root. E.g. whenit has been /generated from/ the +# there is an *.md file in the root. E.g. when it has been /generated from/ the # doc/*.md source file dummy%: @: @@ -111,30 +128,34 @@ $(DESTDIR)$(SHAREDIR)/$(PROJECT_NAME)/%: % install-bins: $(BINS:%=$(DESTDIR)$(BINDIR)/%) -install-libs: $(SHARED_LIBS:%=$(DESTDIR)$(LIBDIR)/%) \ - $(STATIC_LIBS:%=$(DESTDIR)$(LIBDIR)/$(PROJECT_NAME)/%) +install-libs: $(STATIC_LIBS:%=$(DESTDIR)$(LIBDIR)/%) \ + $(SHARED_LIBS:%=$(DESTDIR)$(LIBDIR)/%) + +install-priv: $(PRIV_STATIC_LIBS:%=$(DESTDIR)$(LIBDIR)/$(PROJECT_NAME)/%) \ + $(PRIV_SHARED_LIBS:%=$(DESTDIR)$(LIBDIR)/$(PROJECT_NAME)/%) \ + $(PRIV_BINS:%=$(DESTDIR)$(LIBDIR)/$(PROJECT_NAME)/%) install-docs: $(DOCS:%=$(DESTDIR)$(SHAREDIR)/doc/$(PROJECT_NAME)/%) install-data: $(DATA:%=$(DESTDIR)$(SHAREDIR)/$(PROJECT_NAME)/%) -install: install-bins install-libs install-docs install-data +install: install-bins install-libs install-priv install-docs install-data clean: - $(_CLEAN) rm -f $(CLEAN) - @rm -rf obj + $(_CLEAN) rm -rf build ; rm -f $(CLEAN) cleandeps: $(_CLEAN) rm -f $(BUILD_DEPS) $(foreach file,$(BUILD_DEPS),@make -C $(subst .built,,$(file)) clean) distclean: clean cleandeps - $(_CLEAN) rm -f config.mk include/config.h + $(_CLEAN) rm -f config.mk src/include/config.h repoclean: distclean $(_CLEAN) rm -f configure common.mk _DIR = $(if $(V),,$(call say," DIR ")$@;) +_DOC = $(if $(V),,$(call say," DOC ")$@;) _CP = $(if $(V),,$(call say," CP ")$@;) _CC = $(if $(V),$(CC),$(call say," CC ")$@;$(CC)) _GEN = $(if $(V),,$(call say," GEN ")$@;) @@ -146,19 +167,23 @@ _INST = $(if $(V),,$(call say," INST ")$@;) $(BUILD_DEPS): Makefile common.mk - $(_MAKE) cd $(subst .built,,$@) && ln -sf ../comain \ - && test -e configure || ( make || true ) \ + $(_MAKE) cd $(subst .built,,$@) \ && ./configure --bindir=$(BINDIR) --libdir=$(LIBDIR) \ --incdir=$(INCDIR) --sharedir=$(SHAREDIR) \ + $$(cd .. && cat meta/deps/$(subst .built,,$@)/configure) \ && make @touch $@ -$(BINS) $(SHARED_LIBS) $(STATIC_LIBS) $(OBJS): | $(BUILD_DEPS) +$(BLD_STATIC_LIBS) $(BLD_SHARED_LIBS) $(BLD_BINS): | $(BUILD_DEPS) + +all: doc $(BLD_STATIC_LIBS) $(BLD_SHARED_LIBS) $(BLD_BINS) + +deps: $(BUILD_DEPS) -all: $(BINS) $(SHARED_LIBS) $(STATIC_LIBS) $(BUILD_DEPS) +doc: $(BLD_DOCS) -$(BINS) $(TOOLS): +$(BLD_BINS): $(_CC) -o $@ $(COMMON_CFLAGS) $(CFLAGS) $(COMMON_LDFLAGS) $(LDFLAGS) $^ -.PHONY: install-bins install-libs install-docs install-data install \ +.PHONY: install-bins install-libs install-priv install-docs install-data install \ clean cleandeps distclean repoclean diff --git a/configure b/configure index 701d65a..eebfe3e 100755 --- a/configure +++ b/configure @@ -4,20 +4,25 @@ usageoptions() { - local name=$1 + local name=$2 local desc local disabled - eval desc=\$optdesc$name - eval disabled=\$optdisabled$name - # FIXME space alignment isn't right here, unless $name resolves to 5 chars - echon " --with-$name Enable $desc" - if test $disabled -eq 0; then + local invisible + local i + eval desc="\$optdesc$name" + eval disabled="\$optdisabled$name" + eval invisible="\$optinvisible$name" + if test $invisible -ne 0; then return; fi + i=$((23 - ${#name})) + printf " --with-$name%${i}sEnable $desc" + if test "$disabled" -eq 0; then echo " [default]" else echo "" fi - echon " --without-$name Disable $desc" - if test $disabled -eq 1; then + i=$(($i - 3)) + printf " --without-$name%${i}sDisable $desc" + if test "$disabled" -eq 1; then echo " [default]" else echo "" @@ -43,10 +48,15 @@ usage: $0 [OPTION..] --incdir=DIR Set include directory to DIR [PREFIX/include] --sharedir=DIR Set share directory to DIR [PREFIX/share] $s + + --no-shared Don't build shared libraries + --no-static Don't build static librairies + --prefer-shared Prefer to link shared libraires [default] --prefer-static Prefer to link static libraires --set-shared=DEP Use shared linking for dependency DEP --set-static=DEP Use static linking for dependency DEP + EOF foreach optname $nb_options usageoptions cat <<EOF @@ -72,6 +82,8 @@ has_skalibs=0 if test -d meta/deps/skalibs; then has_skalibs=1; fi sysdeps= prefer=shared +noshared=0 +nostatic=0 CVARS= CPPFLAGS= @@ -80,6 +92,9 @@ LDFLAGS= COMMON_CPPFLAGS= COMMON_CFLAGS= COMMON_LDFLAGS= +COMMON_CPPFLAGS_SHARED= +COMMON_CFLAGS_SHARED= +COMMON_LDFLAGS_SHARED= VPATHS="# this will handle prefer or set shared/static" BUILD_DEPS= @@ -105,7 +120,9 @@ for arg ; do --sysdeps=*) if test $has_skalibs -eq 1; then sysdeps=${arg#*=}; else error 1 "invalid option '$arg'"; fi;; - --prefer-shared) ;; + --no-shared) noshared=1 ;; + --no-static) nostatic=1 ;; + --prefer-shared) prefer=shared ;; --prefer-static) prefer=static ;; --set-shared=*) eval "link${arg#*=}=1" ;; --set-static=*) eval "link${arg#*=}=2" ;; @@ -133,7 +150,10 @@ incdir="$(echo $incdir | sed 's/\/\+/\//g')" sharedir="$(echo $sharedir | sed 's/\/\+/\//g')" sysdeps="$(echo $sysdeps | sed 's/\/\+/\//g')" +# pass 2, to be able to use state of other options as selection +setoptionsdefault +cprefix=$(sanitize "$name") procneeddep() { @@ -146,9 +166,10 @@ procneeddep() procdep() { - local dep="$1" + local idx=$1 + local dep="$2" local depname="${dep##*/}" - local cpnt="$2" + local cpnt="$3" local link=0 local needver="$(cat $dep/version 2>/dev/null)" local include="$depname" @@ -169,16 +190,16 @@ procdep() if procneeddep "$depname"; then echo " -> $type $depname not needed; SKipping" - nbdeps=$(($nbdeps+1)) - eval dep$nbdeps=$depname - eval lib$depname= + eval idx$depname=$1 + eval after$depname=0 return fi if test -d "./$depname"; then found=1 internal=1 - if test -e "$dep/static"; then link=2; fi + # internal deps defaults to static linking + link=2 path="include" if test -e "$dep/incdir"; then path="$(cat $dep/incdir)"; fi path="$depname/$path" @@ -249,8 +270,9 @@ procdep() fi if test $cpnt -ne 1; then - nbdeps=$(($nbdeps+1)) - eval dep$nbdeps=$depname + eval idx$depname=$1 + eval after$depname=0 + eval "library$depname=$library" case $link in 0) @@ -271,7 +293,6 @@ vpath lib$library.so $vpathso" vpath lib$library.a $vpatha" ;; esac - eval lib$depname=-l$library if test $internal -ne 1; then path="$incdir/$include" @@ -299,38 +320,29 @@ Configuring $name $version : => Checking requirements... EOF -setoptionsflags() -{ - local name=$1 - local cvar - local disabled - eval cvar=\$optcvar$name - eval disabled=\$optdisabled$name - if test $disabled -eq 1; then - CVARS="$CVARS -#undef $cvar" - return - fi - local cppflags - local cflags - local ldflags - eval cppflags=\"\$optcppflags$name\" - eval cflags=\"\$optcflags$name\" - eval ldflags=\"\$optldflags$name\" - CVARS="$CVARS -#define $cvar 1" - if test -n "$cppflags"; then COMMON_CPPFLAGS="$COMMON_CPPFLAGS $cppflags"; fi - if test -n "$cflags"; then COMMON_CFLAGS="$COMMON_CFLAGS $cflags"; fi - if test -n "$ldflags"; then COMMON_LDFLAGS="$COMMON_LDFLAGS $ldflags"; fi -} - loaddeps -foreach optname $nb_options setoptionsflags - -nbdeps=0 foreach "cpnt" $nb_cpnt procdep 1 foreach "deps" $nb_deps procdep 0 +setdepsafters() +{ + local dep + for dep in meta/deps/*/after; do + if test "$dep" = "meta/deps/*/after"; then break; fi + local depname="$(expr substr "$dep" 11 $((${#dep} - 16)))" + local depidx=$(($(eval echo \$idx$depname) + 0)) + local after=$(($(eval echo \$after$depname) + 0)) + local name + for name in meta/deps/$depname/after/*; do + name=${name##*/} + local idx=$(eval echo \$idx$name) + after=$(($after | (1 << ($idx - 1)))) + done + eval "after$depname=$after" + done +} +setdepsafters + if test -n "$fail"; then error 2 "Cannot continue: $fail" fi @@ -363,12 +375,26 @@ tryflag() fi } +tryldflag() +{ + echon " -> Checking whether linker accepts $2.." + echo "typedef int x;" > "tmp.c" + if $CC $CPPFLAGS $CFLAGS $LDFLAGS -nostdlib "$2" -o "tmp.o" "tmp.c" > /dev/null 2>&1; then + echo ".. yes" + eval "$1=\"\${$1} \$2\"" + eval "$1=\${$1# }" + return 0 + else + echo ".. no" + return 1 + fi +} + trap 'rm -f tmp.c tmp.o config.mk.tmp config.h.tmp' EXIT ABRT INT QUIT TERM HUP echo " => Checking compiler..." echon " -> Looking for a C compiler.." -trycmd CC "$CC" trycmd CC "gcc" trycmd CC "clang" trycmd CC "cc" @@ -378,9 +404,7 @@ if test -z "$CC"; then else echo ".. $CC" fi -trycmd AR "$AR" trycmd AR "ar" -trycmd RANLIB "$RANLIB" trycmd RANLIB "ranlib" ENDIAN=0 @@ -414,17 +438,25 @@ if test $has_skalibs -eq 1; then fi echo " => Testing C compiler..." -tryflag CFLAGS -std=c99 -tryflag CFLAGS -fomit-frame-pointer -tryflag CFLAGS -fno-exceptions -tryflag CFLAGS -fno-unwind-tables -tryflag CFLAGS -fno-asynchronous-unwind-tables -tryflag CPPFLAGS -Werror=implicit-function-declaration -tryflag CPPFLAGS -Werror=implicit-int -tryflag CPPFLAGS -Werror=pointer-sign -tryflag CPPFLAGS -Werror=pointer-arith -tryflag CFLAGS -ffunction-sections -tryflag CFLAGS -fdata-sections +tryflag COMMON_CFLAGS -std=c99 +tryflag COMMON_CFLAGS -fomit-frame-pointer +tryflag COMMON_CFLAGS -fno-exceptions +tryflag COMMON_CFLAGS -fno-unwind-tables +tryflag COMMON_CFLAGS -fno-asynchronous-unwind-tables +tryflag COMMON_CPPFLAGS -Werror=implicit-function-declaration +tryflag COMMON_CPPFLAGS -Werror=implicit-int +tryflag COMMON_CPPFLAGS -Werror=pointer-sign +tryflag COMMON_CPPFLAGS -Werror=pointer-arith +tryflag COMMON_CPPFLAGS -Wno-unused-value +tryflag COMMON_CFLAGS -ffunction-sections +tryflag COMMON_CFLAGS -fdata-sections +tryldflag COMMON_LDFLAGS -Wl,--as-needed +tryldflag COMMON_LDFLAGS -Wl,--sort-section=alignment +tryldflag COMMON_LDFLAGS -Wl,--sort-common +tryflag COMMON_CPPFLAGS_SHARED -fPIC +tryldflag COMMON_LDFLAGS_SHARED -Wl,--hash-style=gnu +tryldflag COMMON_LDFLAGS_SHARED -nostartfiles + echo " => Paths :" cat <<EOF @@ -434,26 +466,102 @@ cat <<EOF -> sharedir : $sharedir EOF +excl= options= +optleft=0 + showoption() { - local name=$1 + local idx=$1 + local name=$2 local disabled + local invisible + local cvar eval disabled=\$optdisabled$name - if test $disabled -eq 0; then + eval invisible=\$optinvisible$name + eval cvar=\$optcvar$name + if test $disabled -eq 1; then + CVARS="$CVARS +#undef ${cprefix}_$cvar" + if test -e meta/options/$name/objs; then + while IFS= read -r line; do + line="$(printf $line | sed -e 's/\//\\\//g')" + excl="-e s/build\\/$line//g $excl" + if test "$(expr substr "$line" $((${#line}-1)) 2)" = ".o"; then + line="$(expr substr "$line" 1 $((${#line}-2))).lo" + excl="-e s/build\\/$line//g $excl" + fi + done < meta/options/$name/objs + fi + else + CVARS="$CVARS +#define ${cprefix}_$cvar 1" + optleft=$(($optleft | (1 << ($idx - 1)))) local desc eval desc=\$optdesc$name - options="$options + if test -n "$desc"; then + options="$options -> $name : $desc" + fi fi } + if test $nb_options -gt 0; then - foreach optname $nb_options showoption + foreach "optname" $nb_options showoption if test -n "$options"; then echo " => Options :$options" fi fi +setoptionflags() +{ + local name=$1 + local cppflags + local cflags + local ldflags + eval cppflags=\"\$optcppflags$name\" + eval cflags=\"\$optcflags$name\" + eval ldflags=\"\$optldflags$name\" + if test -n "$cppflags"; then COMMON_CPPFLAGS="$COMMON_CPPFLAGS $cppflags"; fi + if test -n "$cflags"; then COMMON_CFLAGS="$COMMON_CFLAGS $cflags"; fi + if test -n "$ldflags"; then COMMON_LDFLAGS="$COMMON_LDFLAGS $ldflags"; fi +} + +setoptionsflags() +{ + local i=1 + while test $optleft -gt 0; do + local n=$((1 << ($i - 1))) + if test $(($optleft & $n)) -gt 0; then + local name="$(eval echo \$optname$i)" + local after=$((($(eval echo \$optafter$name) + 0) & $optleft)) + eval "optafter$name=$after" + if test $after -eq 0; then + setoptionflags "$name" + optleft=$(($optleft & ~$n)) + fi + fi + if test $i -eq $nb_options; then + i=1 + else + i=$(($i + 1)) + fi + done +} + +setoptionsflags + + +if test $(($noshared + $nostatic)) -gt 0; then + echo " => Librairies" + if test $noshared -eq 1; then + echo " -> Don't build shared librairies" + fi + if test $nostatic -eq 1; then + echo " -> Don't build static librairies" + fi +fi + echo " => Generating files..." echo " -> Generating config.mk..." @@ -483,103 +591,110 @@ else fi echo $VPATHS -setdep() -{ - local depname="$1" - if test "$line" != "$depname"; then return; fi - line="$(eval "echo \$lib$depname")" -} - echo "# dependencies" echo ".SECONDEXPANSION:" -if test -d meta/libs; then - for file in meta/libs/*; do - exec 4<"$file" - depsA= - depsSO= - while IFS= read -r line <&4; do - # ignore comment - if test "$(expr substr "$line" 1 1)" = "#"; then continue; fi - # +name=obj means only add obj is option name is set - if test "$(expr substr "$line" 1 1)" = "+"; then - opt="$(echo $line | cut -d= -f1)" - opt="$(expr substr "$opt" 2 ${#opt})" - eval disabled=\$optdisabled$opt - # empty $disabled means an option that doesn't exist! - if test -z "$disabled"; then error 2 "Unknown option '$opt' in $line"; fi - if test $disabled -eq 1; then continue; fi - line="$(echo $line | cut -d= -f2)" +BLD_STATIC_LIBS= +BLD_SHARED_LIBS= +BLD_BINS= +BLD_DOCS= +setupobjs() +{ + local docs_objs + local d + # FIXME find's -printf isn't POSIX + for d in src/*; do + local name="$(expr substr "$d" 5 ${#d})" + if test "$name" = "*" || test "$name" = "include"; then continue; fi + local objs + if test "$name" = "doc"; then + objs="$(find "$d" -type f -name '*.md')" + docs_objs="$(echo "$objs" \ + | sed -e 's/^src\/doc\(.*\/\)\(.\+\.md\)$/build\/doc\/\2: src\/doc\1\2/g')" + + objs="$(echo "$objs" \ + | sed -e 's/^.\+\(\/.\+\.md\)$/build\/doc\1/g' \ + | tr '\n' ' ')" + BLD_DOCS="$objs $BLD_DOCS" + continue + fi + objs="$(find "$d" -type f -name '*.[cS]' | sed -e s/^src/build/g \ + -e s/\\.c$/.o/g -e s/\\.S/.o/g $excl | tr '\n' ' ')" + objs="$objs $(find "$d" -type l -printf "build/%l ")" + + local libs= + local deps=0 + local depname + local tmp=configure-$PPID-$$ + mkfifo $tmp + find "$d" -type f -name '+*' > $tmp & + while IFS= read -r depname; do + depname=${depname##*/+} + local idx=$(($(eval echo \$idx$depname) + 0)) + deps=$(($deps | (1 << ($idx - 1)))) + done < $tmp + rm -r $tmp + local i=1 + while test $deps -gt 0; do + local n=$((1 << ($i - 1))) + if test $(($deps & $n)) -gt 0; then + depname=$(eval echo \$deps$i) + depname=${depname##*/} + local after=$((($(eval echo \$after$depname) + 0) & $deps)) + if test $after -eq 0; then + local library="$(eval echo \$library$depname)" + libs="$libs -l$library" + deps=$(($deps & ~$n)) + fi fi - # replace depname by -llibdeb (e.g. skalibs by -lskarnet) - foreach "dep" $nbdeps setdep - - offset=$((${#line}-1)) - # if a variable - e.g. $$(FOO) - then use $$(FOO_so) for shared lib - if test "$(expr substr "$line" ${#line} 1)" = ")"; then - lineso="$(expr substr "$line" 1 $offset)_so)" - # if a .o then use .lo for shared lib - elif test "$(expr substr "$line" $offset 2)" = ".o"; then - lineso="$(expr substr "$line" 1 $(($offset-1))).lo" + if test $i -eq $nb_deps; then + i=1 else - lineso= + i=$(($i + 1)) fi - # if .O then use .o always (shared lib also) - if test "$(expr substr "$line" $offset 2)" = ".O"; then - line="$(expr substr "$line" 1 $(($offset-1))).o" - fi - # not special for shared lib, so use the same - if test -z "$lineso"; then - lineso="$line" - fi - depsA="$depsA $line" - depsSO="$depsSO $lineso" done - exec 4<&- - echo lib${file##*/}.a: $depsA - echo lib${file##*/}.so: $depsSO - done -fi -if test -d meta/bins; then - for file in meta/bins/*; do - exec 4<"$file" - deps= - while IFS= read -r line <&4; do - # ignore comment - if test "$(expr substr "$line" 1 1)" = "#"; then continue; fi - # +name=obj means only add obj is option name is set - if test "$(expr substr "$line" 1 1)" = "+"; then - opt="$(echo $line | cut -d= -f1)" - opt="$(expr substr "$opt" 2 ${#opt})" - eval disabled=\$optdisabled$opt - # empty $disabled means an option that doesn't exist! - if test -z "$disabled"; then error 2 "Unknown option '$opt' in $line"; fi - if test $disabled -eq 1; then continue; fi - line="$(echo $line | cut -d= -f2)" + if test "$(expr substr "$name" 1 3)" = "lib"; then + local l="$(expr substr "$name" 4 ${#name})" + COMMON_CPPFLAGS="-isystem src/$name/include $COMMON_CPPFLAGS" + if test $nostatic -eq 0; then + echo "$name.a: $objs" + BLD_STATIC_LIBS="$name.a $BLD_STATIC_LIBS" fi - # replace depname by -llibdeb (e.g. skalibs by -lskarnet) - foreach "dep" $nbdeps setdep - - offset=$((${#line}-1)) - # if .O then use .o always - if test "$(expr substr "$line" $offset 2)" = ".O"; then - line="$(expr substr "$line" 1 $(($offset-1))).o" + if test $noshared -eq 0; then + objs="$(find "$d" -type f -name '*.[cS]' | sed -e s/^src/build/g \ + -e s/\\.c$/.lo/g -e s/\\.S/.o/g $excl | tr '\n' ' ')" + objs="$objs $(find "$d" -type l -printf "build/%l " | sed -e s/\\.o/.lo/g)" + echo "$name.so: $objs $libs" + BLD_SHARED_LIBS="$name.so $BLD_SHARED_LIBS" fi - deps="$deps $line" - done - exec 4<&- - echo ${file##*/}: $deps + else + BLD_BINS="$name $BLD_BINS" + echo "$name: $objs $libs" + fi done -fi + echo "# docs" + echo "$docs_objs" +} +setupobjs cat <<EOF + +# build targets +BLD_DOCS = $BLD_DOCS +BLD_STATIC_LIBS = $BLD_STATIC_LIBS +BLD_SHARED_LIBS = $BLD_SHARED_LIBS +BLD_BINS = $BLD_BINS + # some flags COMMON_CPPFLAGS += $COMMON_CPPFLAGS -COMMON_CFLAGS += $COMMON_CFLAGS -COMMON_LDFLAGS += $COMMON_LDFLAGS -CPPFLAGS = $CPPFLAGS -CFLAGS = $CFLAGS -LDFLAGS = $LDFLAGS +COMMON_CFLAGS += $COMMON_CFLAGS +COMMON_LDFLAGS += $COMMON_LDFLAGS +COMMON_CPPFLAGS_SHARED += $COMMON_CPPFLAGS_SHARED +COMMON_CFLAGS_SHARED += $COMMON_CFLAGS_SHARED +COMMON_LDFLAGS_SHARED += $COMMON_LDFLAGS_SHARED +CPPFLAGS += $CPPFLAGS +CFLAGS += $CFLAGS +LDFLAGS += $LDFLAGS # special dependencies we try to make automatically BUILD_DEPS = $BUILD_DEPS @@ -600,7 +715,6 @@ mv -f config.mk.tmp config.mk echo " -> Generating config.h..." -prefix=$(sanitize "$name") url="$(cat meta/site 2>/dev/null)" if test -z "$url"; then url="https://lila.oss"; fi @@ -611,27 +725,28 @@ cat <<EOF * $0 $@ * Any changes you make in here will be lost on the next ./configure */ -#ifndef ${prefix}_CONFIG_H -#define ${prefix}_CONFIG_H - -#define ${prefix}_CURYEAR "$(date +%Y)" -#define ${prefix}_AUTHOR "Olivier Brunel" -#define ${prefix}_VERSION "$version" -#define ${prefix}_URL "$url" -#define ${prefix}_LIBDIR "$libdir/$name" -#define ${prefix}_SHAREDIR "$sharedir/$name" +#ifndef ${cprefix}_CONFIG_H +#define ${cprefix}_CONFIG_H + +#define ${cprefix}_CURYEAR "$(date +%Y)" +#define ${cprefix}_AUTHOR "Olivier Brunel" +#define ${cprefix}_VERSION "$version" +#define ${cprefix}_URL "$url" +#define ${cprefix}_LIBDIR "$libdir/$name" +#define ${cprefix}_SHAREDIR "$sharedir/$name" $CVARS -#define ${prefix}_LITTLE 1234 -#define ${prefix}_BIG 4321 -#define ${prefix}_PDP 3412 -#define ${prefix}_ENDIAN ${prefix}_$ENDIAN +#define ${cprefix}_LITTLE 1234 +#define ${cprefix}_BIG 4321 +#define ${cprefix}_PDP 3412 +#define ${cprefix}_ENDIAN ${cprefix}_$ENDIAN -#endif /* ${prefix}_CONFIG_H */ +#endif /* ${cprefix}_CONFIG_H */ EOF exec 1>&5 5>&- -mv -f config.h.tmp include/config.h +if ! test -d src/include; then mkdir src/include; fi +mv -f config.h.tmp src/include/config.h echo "done." diff --git a/getdeps b/getdeps index 11c33ea..1b2ecfd 100755 --- a/getdeps +++ b/getdeps @@ -26,7 +26,7 @@ EOF showdep() { - local dep=$1 + local dep=$2 local depname="${dep##*/}" local needed eval needed=\"\$need$depname\" @@ -51,9 +51,9 @@ list() getdep() { - local dep=$1 + local dep=$2 local depname="${dep##*/}" - local intonly=$2 + local intonly=$3 if test $intonly -eq 1 && test ! -e "$dep/files"; then return; fi if test -e "$depname"; then warn "cannot clone $depname: file already exists" diff --git a/init b/init index 32958f5..6c7f0c4 100755 --- a/init +++ b/init @@ -18,7 +18,7 @@ fi run cp -n comain/Makefile Makefile run cp -n comain/project.mk.tpl project.mk -run mkdir include src +run mkdir src run cp -n comain/meta/README.git meta run echo https://lila.oss/$name > meta/site run echo git://lila.oss/$name.git > meta/git @@ -33,7 +33,9 @@ run touch meta/deps/comain/cpnt run cp -n comain/meta/version meta/deps/comain/version run cp -n comain/meta/git meta/deps/comain/git run mkdir meta/options -run ln -sf ../../comain/meta/options/debug meta/options +for opt in comain/meta/options/*; do + run ln -s ../../$opt meta/options +done run ln -sf meta/README.git README run ln -sf meta/AUTHORS run ln -sf meta/COPYING @@ -44,10 +46,8 @@ run cat > .gitignore <<EOF /configure /common.mk /config.mk -/include/config.h -*.o -*.lo -*.d +/src/include/config.h +/build EOF if test -e .git; then error 2 "Already a git repo (.git exist)"; fi git init . diff --git a/libcomain b/libcomain index b5d50c4..1c461c5 100644 --- a/libcomain +++ b/libcomain @@ -28,7 +28,7 @@ error() warn() { - echo "$0: $@" >&2 + echo "$0: warning: $@" >&2 } upper() @@ -72,11 +72,12 @@ foreach() local nb="$2" local fn="$3" shift 3 + local i=1 nb=$(($nb+0)) - while test $nb -gt 0; do - "$fn" "$(eval "echo \$$name$nb")" "$@" - nb=$(($nb-1)) + while test $i -le $nb; do + "$fn" $i "$(eval "echo \$$name$i")" "$@" + i=$(($i+1)) done } @@ -140,38 +141,122 @@ loadoptions() local cflags= local ldflags= local disabled= + local invisible= for name in meta/options/*; do name=${name##*/} + if test "$name" != "$(echo $name | tr -cd '[[:alnum:]]')"; then + warn "invalid option name: $name" + continue + fi + if test ! -r meta/options/$name/desc; then + warn "decription missing for option $name" + continue + fi desc="$(cat meta/options/$name/desc 2>/dev/null)" - if test -z "$desc"; then return 0; fi + if test -z "$desc" || test -e meta/options/$name/invisible; then + invisible=1 + else + invisible=0 + fi cvar="$(cat meta/options/$name/cvar 2>/dev/null)" if test -z "$cvar"; then cvar="WITH_$(sanitize $name)"; fi cflags="$(cat meta/options/$name/cflags 2>/dev/null)" ldflags="$(cat meta/options/$name/ldflags 2>/dev/null)" - disabled=0 - if test -e meta/options/$name/disabled; then disabled=1; fi + disabled=-1 + if test -e meta/options/$name/default; then + local s="$(cat meta/options/$name/default)" + if test "$s" = "0"; then + disabled=1 + elif test "$s" = "1"; then + disabled=0 + else + warn "invalid default value for option $name ($s)" + fi + fi dep="$(cat meta/options/$name/dep 2>/dev/null)" nb_options=$(($nb_options+1)) - eval optname$nb_options=$name - eval optdesc$name=\"$desc\" - eval optcvar$name=\"$cvar\" - eval optcflags$name=\"$cflags\" - eval optldflags$name=\"$ldflags\" - eval optdisabled$name=$disabled + eval "optname$nb_options"="$name" + eval "optdesc$name"=\"$desc\" + eval "optcvar$name"=\"$cvar\" + eval "optcflags$name"=\"$cflags\" + eval "optldflags$name"=\"$ldflags\" + eval "optdisabled$name"=$disabled + eval "optinvisible$name"=$invisible + eval "optafter$name"=0 local tmp eval tmp=\"\$need$dep\" if test -z "$tmp"; then - eval need$dep=$name + eval need$dep="$name" elif test "$tmp" = "1"; then - eval need$dep=$name + eval need$dep="$name" else eval need$dep=\"$\need$dep $name\" fi done + local opt= + for opt in meta/options/*/after; do + if test "$opt" = "meta/options/*/after"; then break; fi + opt=$(expr substr "$opt" 14 $((${#opt} - 19))) + if test "$opt" != "$(echo $opt | tr -cd '[[:alnum:]]')"; then + continue + fi + local after=0 + for name in meta/options/$opt/after/*; do + if test "$name" = "meta/options/$opt/after/*"; then break; fi + name=${name##*/} + local idx=0 + local n=$nb_options + while test $n -gt 0; do + if test "$(eval echo \$optname$n)" = "$name"; then + idx=$n + n=0 + fi + n=$((n - 1)) + done + if test $idx -eq 0; then continue; fi + n=$((1 << $idx - 1)) + after=$(($after | $n)) + done + eval "optafter$opt"=$after + done return 1 } +setoptenv() +{ + local name=$2 + local disabled + eval disabled=\$optdisabled$name + if test $disabled -eq 1; then + vars="WITH_OPT_$name=0 $vars" + elif test $disabled -eq 0; then + vars="WITH_OPT_$name=1 $vars" + fi +} + +setoptdef() +{ + local name=$2 + local disabled + eval disabled=\$optdisabled$name + if test $disabled -eq -1; then + local vars= + foreach "optname" $nb_options setoptenv + if env $vars meta/options/$name/isdefault 2>/dev/null; then + disabled=0 + else + disabled=1 + fi + eval "optdisabled$name"=$disabled + fi +} + +setoptionsdefault() +{ + foreach "optname" $nb_options setoptdef +} + optexist() { if test -e meta/options/"$1"; then echo 1; else echo 0; fi @@ -179,9 +264,9 @@ optexist() setneeddep() { - local dep=$1 + local dep=$2 local depname="${dep##*/}" - local optname=$2 + local optname=$3 local tmp eval tmp=\"\$need$depname\" tmp="$(echo $tmp | sed s/$optname//)" @@ -190,7 +275,7 @@ setneeddep() setoptionsdep() { - local name=$1 + local name=$2 local disabled eval disabled=\$optdisabled$name if test $disabled -eq 1; then diff --git a/meta/deps.tpl/limb/configure b/meta/deps.tpl/limb/configure index e69de29..4928a4a 100644 --- a/meta/deps.tpl/limb/configure +++ b/meta/deps.tpl/limb/configure @@ -0,0 +1 @@ +--no-shared diff --git a/meta/deps.tpl/limb/incdir b/meta/deps.tpl/limb/incdir new file mode 100644 index 0000000..30b990f --- /dev/null +++ b/meta/deps.tpl/limb/incdir @@ -0,0 +1 @@ +src/liblimb/include diff --git a/meta/deps.tpl/limb/static b/meta/deps.tpl/skalibs/after/limb similarity index 100% rename from meta/deps.tpl/limb/static rename to meta/deps.tpl/skalibs/after/limb diff --git a/meta/deps.tpl/skalibs/configure b/meta/deps.tpl/skalibs/configure new file mode 100644 index 0000000..5d55893 --- /dev/null +++ b/meta/deps.tpl/skalibs/configure @@ -0,0 +1 @@ +--disable-shared diff --git a/meta/options/debug/disabled b/meta/options/debug/after/optimize similarity index 100% rename from meta/options/debug/disabled rename to meta/options/debug/after/optimize diff --git a/meta/options/debug/default b/meta/options/debug/default new file mode 100644 index 0000000..573541a --- /dev/null +++ b/meta/options/debug/default @@ -0,0 +1 @@ +0 diff --git a/meta/options/optimize/cflags b/meta/options/optimize/cflags new file mode 100644 index 0000000..d15a710 --- /dev/null +++ b/meta/options/optimize/cflags @@ -0,0 +1 @@ +-O3 diff --git a/meta/options/optimize/default b/meta/options/optimize/default new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/meta/options/optimize/default @@ -0,0 +1 @@ +1 diff --git a/meta/options/optimize/desc b/meta/options/optimize/desc new file mode 100644 index 0000000..cade659 --- /dev/null +++ b/meta/options/optimize/desc @@ -0,0 +1 @@ +compilation optimizations diff --git a/meta/options/optimizeOff/cflags b/meta/options/optimizeOff/cflags new file mode 100644 index 0000000..e2571f8 --- /dev/null +++ b/meta/options/optimizeOff/cflags @@ -0,0 +1 @@ +-O0 diff --git a/meta/options/optimizeOff/desc b/meta/options/optimizeOff/desc new file mode 100644 index 0000000..44bdaae --- /dev/null +++ b/meta/options/optimizeOff/desc @@ -0,0 +1 @@ +disable compilation optimizations diff --git a/meta/options/optimizeOff/invisible b/meta/options/optimizeOff/invisible new file mode 100644 index 0000000..e69de29 diff --git a/meta/options/optimizeOff/isdefault b/meta/options/optimizeOff/isdefault new file mode 100755 index 0000000..3570b06 --- /dev/null +++ b/meta/options/optimizeOff/isdefault @@ -0,0 +1,5 @@ +#!/bin/sh +if test -n "$WITH_OPT_optimize" && test "$WITH_OPT_optimize" -eq 1; then + exit 1 +fi +exit 0 diff --git a/meta/options/warnings/cflags b/meta/options/warnings/cflags new file mode 100644 index 0000000..6492588 --- /dev/null +++ b/meta/options/warnings/cflags @@ -0,0 +1 @@ +-Wall -Wextra diff --git a/meta/options/warnings/default b/meta/options/warnings/default new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/meta/options/warnings/default @@ -0,0 +1 @@ +1 diff --git a/meta/options/warnings/desc b/meta/options/warnings/desc new file mode 100644 index 0000000..7357b48 --- /dev/null +++ b/meta/options/warnings/desc @@ -0,0 +1 @@ +compilation warnings diff --git a/mkbuild b/mkbuild new file mode 100755 index 0000000..c0373c6 --- /dev/null +++ b/mkbuild @@ -0,0 +1,11 @@ +#!/bin/sh + +if test ! -e build; then mkdir build; fi + +for dir in src/*; do + if test "$dir" = "src/*" || test "$dir" = "src/include"; then continue; fi + find "$dir" -name "include" -prune -o -type d | while read -r d; do + d="build/$(expr substr "$d" 5 ${#d})" + if test ! -d "$d"; then mkdir "$d"; fi + done +done diff --git a/mkdoc b/mkdoc new file mode 100755 index 0000000..15d8d2d --- /dev/null +++ b/mkdoc @@ -0,0 +1,8 @@ +#!/bin/sh + +src="$1" +dst="$2" + +awk 'BEGIN { FS="[ >]" } +{ if ($0 ~ /^<inc (.+)>$/) { system("cat src/doc/include/"$2) } + else { print } } ' "$src" > "$dst" diff --git a/mkreadme b/mkreadme index ade7be5..63d686e 100755 --- a/mkreadme +++ b/mkreadme @@ -99,7 +99,7 @@ fi LINKS= echodep() { - local dep="$1" + local dep="$2" local depname="${dep##*/}" local name="$depname" local needed diff --git a/mktarball b/mktarball index c576b8a..f1dae03 100755 --- a/mktarball +++ b/mktarball @@ -13,9 +13,9 @@ run git worktree add $tb -b tarball master adddep() { - local dep=$1 + local dep=$2 local depname="${dep##*/}" - local intonly=$2 + local intonly=$3 if test $intonly -eq 1 && test ! -e "$dep/files"; then return; fi local ref="$(cat $dep/ref 2>/dev/null)" @@ -45,9 +45,9 @@ run tar -cJp --owner=0 --group=0 --numeric-owner --exclude=".git"* -f $tb.tar.xz echo " => Clean up..." deldep() { - local dep=$1 + local dep=$2 local depname="${dep##*/}" - local intonly=$2 + local intonly=$3 if test $intonly -eq 1 && test ! -e "$dep/files"; then return; fi local ref="$(cat $dep/ref 2>/dev/null)" diff --git a/project.mk.tpl b/project.mk.tpl index cd9bd93..0d8c07b 100644 --- a/project.mk.tpl +++ b/project.mk.tpl @@ -1,7 +1,7 @@ $(error You need to edit project.mk) -# binaries: -- don't forget to set meta/bins/{bin1,bin2,...} with all deps & .o files +# binaries BINS = -# librairies -- don't forget to set meta/libs{lib1,lib2,...} with all deps & .o files +# librairies LIBS =