Welcome to little lamb

Code » comain » commit 218e992

Change dependencies handling to add recursivity..

author Olivier Brunel
2023-05-23 13:25:14 UTC
committer Olivier Brunel
2023-06-20 07:07:15 UTC
parent a4dcc0a01a96c6e4741bf0bba64b0dbc797742e9

Change dependencies handling to add recursivity..

..to get libs, flags, etc

build/comain/comain/version +1 -0
common.mk +67 -14
configure +304 -76
initrepo +2 -0
libcomain +17 -0
mkcmn +24 -0
tpl/gitignore +0 -1

diff --git a/build/comain/comain/version b/build/comain/comain/version
new file mode 120000
index 0000000..19d2fe8
--- /dev/null
+++ b/build/comain/comain/version
@@ -0,0 +1 @@
+../../../meta/version
\ No newline at end of file
diff --git a/common.mk b/common.mk
index 2d8f138..37d8205 100644
--- a/common.mk
+++ b/common.mk
@@ -3,7 +3,7 @@
 
 # init some variables
 DEBUG =
-CPPFLAGS=
+CPPFLAGS =
 CFLAGS =
 LDFLAGS =
 
@@ -46,31 +46,73 @@ build/doc/%.md: | build
 	$(_DOC) comain/mkdoc $< $@
 
 build/%.o: src/%.c Makefile common.mk config.mk project.mk | build
-	$(_CC) $(COMMON_CPPFLAGS) $(CPPFLAGS) \
-		$(COMMON_CFLAGS) $(CFLAGS_$(<:src/%.c=%)) $(CFLAGS) \
-		-o $@ -c $<
+	$(_SAY) Building $@ :
+	$(_CC) \
+		$(COMMON_CPPFLAGS) \
+		$(CPPFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(CPPFLAGS) \
+		$(COMMON_CFLAGS) \
+		$(CFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(CFLAGS_$(<:src/%.c=%)) \
+		$(CFLAGS) \
+		-o $@ \
+		-c $<
 	@test -e $(@:%.o=%.d) && mv $(@:%.o=%.d) $(@:%.o=%.o.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 $<
+	$(_SAY) \n Building $@ :
+	$(_CC) \
+		$(COMMON_CPPFLAGS) \
+		$(CPPFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(CPPFLAGS) \
+		$(COMMON_CFLAGS) \
+		$(CFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(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 $<
+	$(_SAY) Building $@ :
+	$(_CC) \
+		$(COMMON_CPPFLAGS) \
+		$(COMMON_CPPFLAGS_SHARED) \
+		$(CPPFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(CPPFLAGS) \
+		$(COMMON_CFLAGS) \
+		$(COMMON_CFLAGS_SHARED) \
+		$(CFLAGS_$(word 2, $(subst /, ,$<))) \
+		$(CFLAGS_$(<:src/%.c=%)) \
+		$(CFLAGS) \
+		-o $@ \
+		-c $<
 	@test -e $(@:%.lo=%.d) && mv $(@:%.lo=%.d) $(@:%.lo=%.lo.d)
 
+build/comain/%: $(LIBS)
+	$(_SAY) Making comain confdir :
+	$(_CMN) comain/mkcmn $@
+
+
 lib%.a:
+	$(_SAY) Linking $@ :
 	$(_AR) $(AR) rc $@ $^
 	$(_RANLIB) $(RANLIB) $@
 
 lib%.so:
-	$(_CC) -o $@ $(COMMON_CFLAGS) $(COMMON_CFLAGS_SHARED) $(CFLAGS) \
-		$(COMMON_LDFLAGS) $(COMMON_LDFLAGS_SHARED) $(LDFLAGS) \
-		-Wl,-soname,$@.0 $^
+	$(_SAY) Linking $@ :
+	$(_CC) \
+		$(COMMON_CFLAGS) \
+		$(COMMON_CFLAGS_SHARED) \
+		$(CFLAGS_$(@:%.so=%)) \
+		$(CFLAGS) \
+		$(COMMON_LDFLAGS) \
+		$(COMMON_LDFLAGS_SHARED) \
+		$(LDFLAGS_$(@:%.so=%)) \
+		$(LDFLAGS) \
+		-Wl,-soname,$@.0 \
+		-o $@ \
+		$^
 
 # dependencies to try and make automatically
 BUILD_DEPS =
@@ -163,6 +205,7 @@ distclean: clean cleandeps
 repoclean: distclean
 	$(_CLEAN) rm -f configure common.mk
 
+_SAY = $(if $(V),@printf \\n;echo,@true)
 _DIR = $(if $(V),,$(call say," DIR  ")$@;)
 _DOC = $(if $(V),,$(call say," DOC  ")$@;)
 _CP = $(if $(V),,$(call say,"  CP  ")$@;)
@@ -173,6 +216,7 @@ _RANLIB = $(if $(V),,$(call say,"RANLIB")$@;)
 _CLEAN = $(if $(V),,$(call say,"CLEAN ");)
 _MAKE = $(if $(V),,$(call say," MAKE ")$@;)
 _INST = $(if $(V),,$(call say," INST ")$@;)
+_CMN = $(if $(V),,$(call say," CMN  ")$@;)
 
 
 $(BUILD_DEPS): Makefile common.mk
@@ -193,7 +237,16 @@ doc: $(BLD_MD0) $(BLD_MD1) $(BLD_MD2) $(BLD_MD3) $(BLD_MD4) $(BLD_MD5) \
 	$(BLD_MD6) $(BLD_MD7) $(BLD_MD8) $(BLD_MD9)
 
 $(BLD_BINS):
-	$(_CC) -o $@ $(COMMON_CFLAGS) $(CFLAGS) $(COMMON_LDFLAGS) $(LDFLAGS) $^
+	$(_SAY) Linking $@ :
+	$(_CC) \
+		$(COMMON_CFLAGS) \
+		$(CFLAGS_$(@)) \
+		$(CFLAGS) \
+		$(COMMON_LDFLAGS) \
+		$(LDFLAGS_$(@)) \
+		$(LDFLAGS) \
+		-o $@ \
+		$^
 
 .PHONY: install-bins install-libs install-priv install-docs install-data install \
 	clean cleandeps distclean repoclean
diff --git a/configure b/configure
index 5f9c4a0..67f22d6 100755
--- a/configure
+++ b/configure
@@ -158,6 +158,168 @@ setoptionsdefault
 
 cprefix=$(sanitize "$name")
 
+procdep_real()
+{
+    local depdir="$1"
+    local intdir="$2"
+    local libdir="$3"
+    local incdir="$4"
+
+    local depname="${depdir##*/}"
+    local libname="$(cat "$depdir/library" 2>/dev/null)"
+    if test -z "$libname"; then libname="$depname"; fi
+
+    # internal or not?
+    local isint=0
+    if test -d "$intdir/$depname"; then isint=1; fi
+
+    local d
+
+    # can we find it?
+    if test $isint -eq 1; then
+        d="$intdir/$depname"
+    else
+        d="$libdir"
+    fi
+
+    if ! test -e "$depdir/cpnt"; then
+        if ! test -e "$d/lib$libname.so" && ! test -e "$d/lib$libname.a"; then
+            echo $isint NOTFOUND
+            return
+        fi
+    fi
+
+    # is it lila?
+    local islila=0
+    if ! test -e "$depdir/get_version"; then islila=1; fi
+
+    # get version
+    local version
+    if test $islila -eq 1; then
+        if test $isint -eq 1; then
+            d="$intdir/$depname/build"
+        else
+            d="$libdir"
+        fi
+        d="$d/comain/$depname"
+        version="$(cat "$d/version" 2>/dev/null)"
+    else
+        version="$("$depdir/get_version" $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+    fi
+
+    if test -z "$version"; then
+        echo $isint NOVERSION
+        return
+    fi
+
+    # needed version
+    local needver="$(cat "$depdir/version" 2>/dev/null)"
+    if test -z "$needver"; then
+        echo $isint NONEEDVER
+        return
+    fi
+
+    local verok=$(vercmp "$version" "$needver")
+    if test $verok -lt 0; then
+        echo $isint BADVERSION $version $needver $verok
+        return
+    fi
+
+    # get data: libs, flags...
+    local libs
+    local cppflags
+    local clfags
+    local ldflags
+    if test $islila -eq 1; then
+        libs="$(cat "$d/libs" 2>/dev/null)"
+        libsA="$(cat "$d/libs.static" 2>/dev/null)"
+        ldflags="$(cat "$d/ldflags" 2>/dev/null)"
+        ldflagsA="$(cat "$d/ldflags.static" 2>/dev/null)"
+        cflags="$(cat "$d/cflags" 2>/dev/null)"
+        cflagsA="$(cat "$d/cflags.static" 2>/dev/null)"
+        if test $isint -eq 1; then
+            cppflags="src/lib$depname/include"
+        fi
+    else
+        libs="$("$depdir/get_libs" shared $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        libsA="$("$depdir/get_libs" static $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        ldflags="$("$depdir/get_ldflags" shared $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        ldflagsA="$("$depdir/get_ldflags" static $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        cflags="$("$depdir/get_cflags" shared $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        cflagsA="$("$depdir/get_cflags" static $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+        cppflags="$("$depdir/get_incdir" $isint "$intdir/$depname" "$libdir" "$incdir" 2>/dev/null)"
+    fi
+    if test $isint -eq 1; then
+        d="$intdir/$depname"
+        vpath="$d"
+    else
+        d="$incdir"
+        vpath="$libdir"
+    fi
+    if test -n "$cppflags"; then
+        cppflags="-isystem $d/$cppflags"
+    else
+        cppflags="-isystem $d"
+    fi
+
+    # lila: dependencies?
+    if test $islila -eq 1; then
+        if test $isint -eq 1; then
+            d="$intdir/$depname/build"
+        else
+            d="$libdir"
+        fi
+        d="$d/comain/$depname/deps"
+
+        if test -d "$d"; then
+            for d in "$d/"*; do
+                local tmp=configure-$PPID-$$
+                while test -e $tmp; do
+                    tmp=configure-$PPID-$$-"$(date +%s 2>/dev/null)"
+                done
+                local err
+                local i=0
+                mkfifo $tmp
+                procdep_real "$d" "$intdir" "$libdir" "$incdir" > "$tmp" &
+                while IFS= read -r arg; do
+                    if test $i -ne 1; then
+                        i=1
+                        err="$(expr substr "$arg" 3 ${#arg})"
+                    else
+                        case "$arg" in
+                            LIBS=*) libs="$libs $(expr substr "$arg" 6 ${#arg}) " ;;
+                            LIBSA=*) libsa="$libsa $(expr substr "$arg" 7 ${#arg}) " ;;
+                            LDFLAGS=*) ldflags="$ldflags $(expr substr "$arg" 9 ${#arg}) " ;;
+                            LDFLAGSA=*) ldflagsa="$ldflagsa $(expr substr "$arg" 10 ${#arg}) " ;;
+                            CFLAGS=*) cflags="$cflags $(expr substr "$arg" 8 ${#arg}) " ;;
+                            CFLAGSA=*) cflagsa="$cflags $(expr substr "$arg" 9 ${#arg}) " ;;
+                            CPPFLAGS=*) cppflags="$cppflags $(expr substr "$arg" 10 ${#arg}) " ;;
+                            VPATH=*) vpath="$vpath $(expr substr "$arg" 7 ${#arg}) " ;;
+                        esac
+                    fi
+                done < $tmp
+                rm -r $tmp
+                if ! test "$(expr substr "$err" 1 3)" = "OK "; then
+                    echo $isint ERRDEP ${d##*/} $err
+                    return
+                fi
+            done
+        fi
+    fi
+
+    cat <<EOF
+$isint OK $version $needver $verok
+LIBS=$(echo $libs | tr '\n' ' ')
+LIBSA=$(echo $libsa | tr '\n' ' ')
+LDFLAGS=$(echo $ldflags | tr '\n' ' ')
+LDFLAGSA=$(echo $ldflagsa | tr '\n' ' ')
+CFLAGS=$(echo $cflags | tr '\n' ' ')
+CFLAGSA=$(echo $cflagsa | tr '\n' ' ')
+CPPFLAGS=$(echo $cppflags | tr '\n' ' ')
+VPATH=$(echo $vpath | tr '\n' ' ')
+EOF
+}
+
 procneeddep()
 {
     local depname=$1
@@ -167,6 +329,19 @@ procneeddep()
     return 1
 }
 
+procdep_error()
+{
+    local s="$@"
+    case ${s%% *} in
+        BADVERSION) echo "version too old" ;;
+        NOTFOUND) echo "not found" ;;
+        NOVERSION) echo "version unknown";;
+        NONEEDVER) echo "needed version unknown" ;;
+        ERRDEP) echo "dependency error" ;;
+        *) echo "unexpected error" ;;
+    esac
+}
+
 procdep()
 {
     local idx=$1
@@ -175,10 +350,11 @@ procdep()
     local cpnt="$3"
     local link=0
     local needver="$(cat $dep/version 2>/dev/null)"
-    local include="$depname"
-    if test -e "$dep/include"; then include="$(cat $dep/include)"; fi
-    local path="$incdir/$include"
-    local depver=
+    # include dir: defaults to $incdir/NAME
+    local path="$depname"
+    # a different dirname (inside $incdir) might be specified
+    if test -e "$dep/include"; then path="$(cat $dep/include)"; fi
+    local path="$incdir/$path"
     local library="$depname"
     if test -e "$dep/library"; then library="$(cat $dep/library)"; fi
     local internal=0
@@ -200,71 +376,87 @@ procdep()
         eval after$depname=0
         return
     fi
+    local tmp=configure-$PPID-$$
+    while test -e $tmp; do
+        tmp=configure-$PPID-$$-"$(date +%s 2>/dev/null)"
+    done
+    local s
+    local i=0
+    mkfifo $tmp
+    procdep_real "$dep" "deps" "$libdir" "$incdir" > "$tmp" &
+    while IFS= read -r arg; do
+        if test $i -ne 1; then
+            i=1
+            s="$arg"
+        else
+            case "$arg" in
+                LIBS=*) deplibs="$(expr substr "$arg" 6 ${#arg}) " ;;
+                LIBSA=*) deplibsa="$(expr substr "$arg" 7 ${#arg}) " ;;
+                LDFLAGS=*) depldflags="$(expr substr "$arg" 9 ${#arg}) " ;;
+                LDFLAGSA=*) depldflagsa="$(expr substr "$arg" 10 ${#arg}) " ;;
+                CFLAGS=*) depcflags="$(expr substr "$arg" 8 ${#arg}) " ;;
+                CFLAGSA=*) depcflagsa="$(expr substr "$arg" 9 ${#arg}) " ;;
+                CPPFLAGS=*) depcppflags="$(expr substr "$arg" 10 ${#arg}) " ;;
+                VPATH=*) vpath="$(expr substr "$arg" 7 ${#arg}) " ;;
+            esac
+        fi
+    done < $tmp
+    rm -r $tmp
 
-    if test -d "$depdir"; then
-        found=1
-        internal=1
-        # internal deps defaults to static linking
-        link=2
-        path="include"
-        if test -e "$dep/incdir"; then path="$(cat $dep/incdir)"; fi
-        path="$depdir/$path"
-    fi
+    if test "$(expr substr "$s" 1 1)" = "1"; then internal=1; fi
+    s="$(expr substr "$s" 3 ${#s})"
 
     echon "  -> $type $depname "
-
-    local l="$(eval "echo \$link$depname")"
-    if test -n "$l" && test "$l" -ge 0; then link="$l"; fi
-
-    local vpathso="$depdir"
-    local vpatha="$depdir"
-    if test $cpnt -ne 1 && test $found -eq 0; then
-        local ln="lib$library"
-        local d="$(cat $dep/dynlibdir 2>/dev/null)"
-        vpathso="$libdir/$d"
-        d="$(cat $dep/libdir 2>/dev/null)"
-        vpatha="$libdir/$d"
-        if test -e "$vpathso/$ln.so" || test -e "$vpatha/$ln.a"; then
-            found=1
-        fi
+    if test $internal -ne 1; then
+        echon "(system) "
+    else
+        echon "(internal) "
+        # internal deps defaults to static linking
+        link=2
     fi
 
-    if test $found -ne 1; then
-        echo "MISSING"
-        test -z "$fail" && fail="$type $depname could not be found"
-        return
+    local err="$(procdep_error $s)"
+    local code="${s%% *}"
+    if test "$code" = "OK" || test "$code" = "BADVERSION"; then
+        local i=0
+        for s in $s; do
+            case $i in
+                1) depver=$s ;;
+                2) needver=$s ;;
+                3) cmp=$s ;;
+            esac
+            i=$(( $i + 1 ))
+        done
+        echon "version $depver ($needver needed)"
     fi
-    echon "found"
 
-    if test -e "$depdir/meta/version"; then
-        depver="$(cat $depdir/meta/version)"
-    fi
-    if test -z "$depver"; then
-        depver="$($dep/get_version "$path" 2>/dev/null)"
-    fi
-    if test -z "$depver"; then
+    if ! test "$code" = "OK"; then
         echo
-        test -z "$fail" && fail="Unable to get version for $depname"
+        local m=
+        if test "$code" = "ERRDEP"; then
+            m=${s#* }
+            m=" (${m%% *}: $(procdep_error ${m#* }))"
+        fi
+        test -z "$fail" && fail="$type $depname: $err$m"
         return
     fi
-    verok=$(vercmp "$depver" "$needver")
 
+    # linking type
+    local l="$(eval "echo \$link$depname")"
+    if test -n "$l" && test "$l" -ge 0; then link="$l"; fi
+
+    local vpathso
+    local vpatha
     if test $cpnt -ne 1; then
-        if test $internal -ne 1; then
-            echon " (system)"
+        if test $internal -eq 1; then
+            vpathso="$depdir"
+            vpatha="$depdir"
         else
-            echon " (internal)"
+            vpathso="$libdir"
+            vpatha="$libdir"
         fi
     fi
-    echon ", "
-    if test $verok -lt 0; then
-        echon "version $depver too old (need $needver)"
-        test -z "$fail" && fail="Dependency $depname must be at least v$needver"
-    elif test $verok -eq 0; then
-        echon "verion $depver"
-    else
-        echon "version $depver ($needver needed)"
-    fi
+
     if test $cpnt -ne 1 && test $link -gt 0; then
         if test $link -eq 1; then
             echo " (shared linking)"
@@ -278,20 +470,15 @@ procdep()
     if test $cpnt -ne 1; then
         eval idx$depname=$1
         eval after$depname=0
-        eval "library$depname=$library"
+        eval "cppflags$depname=\"$depcppflags\""
+        eval "cflags$depname=\"$depcflags\""
+        eval "cflagsA$depname=\"$depcflagsA\""
+        eval "ldflags$depname=\"$depldflags\""
+        eval "ldflagsA$depname=\"$depldflagsA\""
+        eval "libs$depname=\"$deplibs\""
+        eval "libsA$depname=\"$deplibsA\""
 
         case $link in
-            0)
-                if test $prefer = "shared"; then
-                    VPATHS="$VPATHS
-vpath lib$library.so $vpathso
-vpath lib$library.a $vpatha"
-                elif test $prefer = "static"; then
-                    VPATHS="$VPATHS
-vpath lib$library.a $vpatha
-vpath lib$library.so $vpathso"
-                fi
-                ;;
             1) VPATHS="$VPATHS
 vpath lib$library.so $vpathso"
                 ;;
@@ -299,14 +486,17 @@ vpath lib$library.so $vpathso"
 vpath lib$library.a $vpatha"
                 ;;
         esac
-
-        if test $internal -ne 1; then
-            path="$incdir/$include"
+        if test $prefer = "shared"; then
+            VPATHS="$VPATHS
+vpath lib%.so $vpath
+vpath lib%.a $vpath"
         else
-            path="include"
-            if test -e "$dep/incdir"; then path="$(cat $dep/incdir)"; fi
-            path="$depdir/$path"
+            VPATHS="$VPATHS
+vpath lib%.a $vpath
+vpath lib%.so $vpath"
+        fi
 
+        if test $internal -eq 1; then
             if test -e "$dep/configure"; then
                 local f=
                 local e=
@@ -329,7 +519,6 @@ vpath lib$library.a $vpatha"
                 sysdeps="$depdir/sysdeps.cfg"
             fi
         fi
-        COMMON_CPPFLAGS="$COMMON_CPPFLAGS -isystem $path"
     fi
 }
 
@@ -630,6 +819,7 @@ else
 fi
 echo $VPATHS
 
+PER_FLAGS=
 echo "# dependencies"
 echo ".SECONDEXPANSION:"
 BLD_STATIC_LIBS=
@@ -647,7 +837,7 @@ setupobjs()
         local objs
         if test "$name" = "doc"; then
             if test $nodoc -eq 1; then continue; fi
-            objs="$(find "$d" -type f -name '*.md')"
+            objs="$(find "$d" -name '*.md')"
             for i in {9..0}; do
                 local s="$(echo "$objs" \
                     | sed -e 's/^src\/doc\/\(.\+\).'$i'.md$/build\/doc\/\1.'$i'.md/g' \
@@ -667,10 +857,19 @@ setupobjs()
             -e s/\\.c$/.o/g -e s/\\.S/.o/g $excl | tr '\n' ' ')"
         objs="$objs $(find "$d" -type l -printf "build/%l ")"
 
+        local cppflags=
+        local cflags=
+        local cflagsA=
+        local ldflags=
+        local ldflagsA=
         local libs=
+        local libsA=
         local deps=0
         local depname
         local tmp=configure-$PPID-$$
+        while test -e $tmp; do
+            tmp=configure-$PPID-$$-"$(date +%s 2>/dev/null)"
+        done
         mkfifo $tmp
         find "$d" -type f -name '+*' > $tmp  &
         while IFS= read -r depname; do
@@ -689,8 +888,13 @@ setupobjs()
                 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"
+                    libs="$libs $(eval echo \$libs$depname)"
+                    libsA="$libsA $(eval echo \$libsA$depname)"
+                    cppflags="$cppflags $(eval echo \$cppflags$depname)"
+                    cflags="$cflags $(eval echo \$cflags$depname)"
+                    cflagsA="$cflagsA $(eval echo \$cflagsA$depname)"
+                    ldflags="$ldflags $(eval echo \$ldflags$depname)"
+                    ldflagsA="$ldflagsA $(eval echo \$ldflagsA$depname)"
                     deps=$(($deps & ~$n))
                 fi
             fi
@@ -719,6 +923,28 @@ setupobjs()
             BLD_BINS="$name $BLD_BINS"
             echo "$name: $objs $libs"
         fi
+
+        cppflags=$(trim "$cppflags")
+        if test -n "$cppflags"; then
+            append PER_FLAGS "CPPFLAGS_$name = $cppflags"
+        fi
+        cflags=$(trim "$cflags")
+        if test -n "$cflags"; then
+            append PER_FLAGS "CFLAGS_$name = $cflags"
+        fi
+        cflagsA=$(trim "$cflagsA")
+        if test -n "$cflagsA"; then
+            append PER_FLAGS "CFLAGS_STATIC_$name = $cflagsA"
+        fi
+        ldflags=$(trim "$ldflags")
+        if test -n "$ldflags"; then
+            append PER_FLAGS "LDFLAGS_$name = $ldflags"
+        fi
+        ldflagsA=$(trim "$ldflagsA")
+        if test -n "$ldflagsA"; then
+            append PER_FLAGS "LDFLAGS_STATIC_$name = $ldflagsA $libsA $libs"
+        fi
+
     done
     echo "# docs"
     echo "$docs_objs"
@@ -744,6 +970,8 @@ CPPFLAGS += $CPPFLAGS
 CFLAGS   += $CFLAGS
 LDFLAGS  += $LDFLAGS
 
+$PER_FLAGS
+
 # special dependencies we try to make automatically
 BUILD_DEPS = $BUILD_DEPS
 EOF
diff --git a/initrepo b/initrepo
index 817d795..6689b40 100755
--- a/initrepo
+++ b/initrepo
@@ -41,6 +41,8 @@ run ln -sf meta/README.git README
 run ln -sf meta/AUTHORS
 run ln -sf meta/COPYING
 run ln -sf meta/HISTORY
+run mkdir deps
+run ln -s ../comain deps/comain
 if test -e .gitignore; then error 2 "File '.gitignore' already exists"; fi
 run cat > .gitignore <<EOF
 /comain
diff --git a/libcomain b/libcomain
index 5268314..c5d2260 100644
--- a/libcomain
+++ b/libcomain
@@ -56,6 +56,23 @@ quote()
     printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ;
 }
 
+trim()
+{
+    echo $@
+}
+
+append()
+{
+    local name=$1
+    shift
+    local v="$(eval echo "\$$name")"
+    if test -z "$v"; then
+        eval "$name=$(printf \"%s\" \"\$@\")"
+    else
+        eval "$name=$(printf \"%s\\n%s\" \$$name \"\$@\")"
+    fi
+}
+
 fnmatch()
 {
     case "$2" in $1) return 0 ;; *) return 1 ;; esac ;
diff --git a/mkcmn b/mkcmn
new file mode 100755
index 0000000..b0bde99
--- /dev/null
+++ b/mkcmn
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+d=$1
+if ! test "$(expr substr "$d" 1 13)" = "build/comain/"; then
+    echo "invalid destination: $d" >&2
+    exit 1
+fi
+n="$(expr substr "$d" 14 ${#d})"
+
+test -e "$d" || mkdir -p "$d"
+cp meta/version "$d"
+echo -l$n > "$d/libs"
+if test -d meta/deps; then
+    mkdir "$d/deps"
+    for dep in meta/deps/*; do
+        test -e "$dep/cpnt" && continue
+        n="$(expr substr "$dep" 11 ${#dep})"
+        mkdir "$d/deps/$n"
+        for file in {version,library,get_version,get_libs,get_cflags,get_ldflags,get_incdir}
+        do
+            test -e "$dep/$file" && cp "$dep/$file" "$d/deps/$n"
+        done
+    done
+fi
diff --git a/tpl/gitignore b/tpl/gitignore
index 0ad2cb8..5d3fa2c 100644
--- a/tpl/gitignore
+++ b/tpl/gitignore
@@ -1,2 +1 @@
-/deps
 /$name