TRYDIR=1_try
# compiler and flags
-CC=gcc
+C=gcc
CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
#CFLAGS=-std=gnu11 -fPIC -I. -Werror
LINKFLAGS=-L1_lib -lda
+CC=
+
LIBFILE=libda.a
INCFILE=da.h
MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tools/lib/makefile_cc
#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile_cc
+
# compiler and flags
-CC=gcc
+C=gcc
CFLAGS=-std=gnu11 -fPIC -I. -I../1_include -ggdb -Werror -DDEBUG -DDEBUGDB
#CFLAGS=-std=gnu11 -fPIC -I. -I../1_include -Werror
LINKFLAGS=-L. -L../1_lib -ltests -lda
MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tools/lib/makefile_cc
#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile_cc
-
+++ /dev/null
-/*
-Tests for da.
-
-*/
-
-#include "da.h"
-#include "test_da.lib.h"
-#include <stdbool.h>
-
-int test_da_0(){
- da da0;
- da_alloc(&da0, sizeof(int)); // leaves room for 4 ints
- int i = 0;
- int *pt = da0->base;
- // will double, 4 -> 8, then double 8 -> 16
- while( i < 10 ){
- if(da_boundq(&da0, pt)){
- char *old_base = da_expand(&da);
- da_rebase(&da, old_base, pt);
- }
- *pt = i;
- i++;
- pt++;
- }
-
- bool f0 = da.size == sizof(int) * 16;
- bool f1 = 10 == (da.end - da.base) / sizeof(int);
- bool f2 = true;
- pt = da0->base;
- while( i < 10 ){
- f2 = f2 && *pt == i && !da_endq(&da, pt);
- i++;
- pt++;
- }
- bool f3 = da_endq(&da, pt);
-
- return f0 && f1 && f2 && f3;
-}
-
-
--- /dev/null
+# src-da/0_makefile
+
+SHELL=/bin/bash
+
+-include 0_makefile-flags
+
+all: version deps lib execs
+
+lib:
+ $(MAKE) $@
+ cp da.lib.h 1_include/da.h
+
+%::
+ $(MAKE) $@
+
+
+
+
--- /dev/null
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# directories used by this makefile, these could all be set to dot for
+# the simplest source directory structure
+
+#LIDBIR, EXECSDIR, HDIR hold the make results that might later be staged
+#$(PWD) is the directory that make was called from, this is already build in
+#set to dot to use the same directory as the source code
+#leave blank to ommit
+DEPRDIR=1_deprecated
+DOCDIR=1_doc
+EXECSDIR=1_execs
+INCDIR=1_include
+LIBDIR=1_lib
+TESTDIR=1_tests
+TMPDIR=1_tmp
+TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools)
+TRYDIR=1_try
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
+#CFLAGS=-std=gnu11 -fPIC -I. -Werror
+
+LINKFLAGS=-L1_lib -lda
+
+LIBFILE=libdispatch.a
+INCFILE=dispatch.h
+
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tools/lib/makefile_cc
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile_cc
+
+++ /dev/null
-/*
- Runs a command or function as its own process.
-
- For the return status from command or function must be greater than ERR_DISPATCH.
- In the case of dispatch_exec, we only have a promise from the user to not dispatch
- non compliant commands.
-
- Interesting it isn't possible to have a kernel dispatch that calls fork, and then
- others that call this kernel. The reason being is because of collision in return
- status values between the function in the kernel, and with each wrapper. The
- TTCA with the passed in error processing functions would not have this problem.
-
-*/
-#define _GNU_SOURCE
-
-#include "dispatch.lib.h"
-
-// we need the declaration for uid_t etc.
-// without this #define execvpe is undefined
-#define _GNU_SOURCE
-
-#include <wait.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#if INTERFACE
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-//--------------------------------------------------------------------------------
-// dispatch returns an instance of this class.
-//
-#if INTERFACE
-// currently both dispatcher and dispatchee strings are statically allocated
-struct dispatch_ctx{
- char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
- char *dispatchee; // name of the function being dispatched
- int err; // error code as listed below, or status returned from dispatchee
-};
-#define ERR_DISPATCH -1024
-#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
-#define ERR_DISPATCH_F_FORK -1025
-#define ERR_DISPATCH_F_SETEUID -1026
-#define ERR_DISPATCH_F_SETEGID -1027
-#define ERR_DISPATCH_NULL_EXECUTABLE -1028
-#define ERR_DISPATCH_EXEC -1029
-#endif
-void dispatch_f_mess(char *fname, int err, char *dispatchee){
- if(err == 0) return;
- fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
- if(err > ERR_DISPATCH){
- fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
- return;
- }
- switch(err){
- case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
- fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
- break;
- case ERR_DISPATCH_F_FORK:
- case ERR_DISPATCH_F_SETEUID:
- case ERR_DISPATCH_F_SETEGID:
- fputc(' ', stderr);
- perror(dispatchee);
- break;
- case ERR_DISPATCH_NULL_EXECUTABLE:
- fprintf(stderr, " executable was not specified");
- break;
- case ERR_DISPATCH_EXEC:
- // exec is running in another process when it fails, so we can't see the errno value it set
- fprintf(stderr, " exec of \"%s\" failed", dispatchee);
- break;
- default:
- fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
- }
- fputc('\n', stderr);
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
- #ifdef DEBUG
- dbprintf("%s %s\n", "dispatch_f", fname);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- int status = (*f)(f_arg); // we require that f return a zero or positive value
- if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function with a given euid/egid
-// of course this will only work if our euid is root in the first place
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
- #ifdef DEBUG
- dbprintf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK;
- if( pid == 0 ){ // we are the child
- int status;
- if( seteuid(euid) == -1 )
- status = ERR_DISPATCH_F_SETEUID;
- else if( setegid(egid) == -1 )
- status = ERR_DISPATCH_F_SETEGID;
- else{
- status = (*f)(f_arg);
- if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }
- }else{ // we are the parent
- uint err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a executable
-int dispatch_exec(char **argv, char **envp){
- char *command;
- {
- if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
- #ifdef DEBUG
- dbprintf("dispatch_exec:");
- char **apt = argv;
- while( *apt ){
- dbprintf(" %s",*apt);
- apt++;
- }
- dbprintf("\n");
- #endif
- command = argv[0];
- }
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- execvpe(command, argv, envp); // exec will only return if it has an error
- #ifdef DEBUG
- dbprintf("dispatch_exec: exec returned, perror message:");
- perror("dispatch_exec"); // our only chance to print this message, as this is the child process
- #endif
- fflush(stdout);
- exit(ERR_DISPATCH_EXEC);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-
--- /dev/null
+#tranche dispatch.lib.cc
+
+#tranche dispatch.lib.h
+/*
+ Runs a command or function as its own process.
+
+ The return status integer from command or function must be greater than ERR_DISPATCH.
+ In the case of dispatch_exec, we only have a promise from the user to not dispatch
+ non compliant commands.
+
+*/
+#ifndef DISPATCH_LIB_H
+#define DISPATCH_LIB_H
+#include <sys/types.h>
+#include <unistd.h>
+
+#define ERR_DISPATCH -1024
+#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+#define ERR_DISPATCH_F_FORK -1025
+#define ERR_DISPATCH_F_SETEUID -1026
+#define ERR_DISPATCH_F_SETEGID -1027
+#define ERR_DISPATCH_NULL_EXECUTABLE -1028
+#define ERR_DISPATCH_EXEC -1029
+
+// currently both dispatcher and dispatchee strings are statically allocated
+struct dispatch_ctx{
+ char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+ char *dispatchee; // name of the function being dispatched
+ int err; // error code as listed below, or status returned from dispatchee
+};
+#tranche-end
+
+#include "dispatch.lib.h"
+
+// we need the declaration for uid_t etc.
+// without this #define execvpe is undefined
+#define _GNU_SOURCE
+
+#include <wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#tranche dispatch.lib.h
+void dispatch_f_mess(char *fname, int err, char *dispatchee);
+#tranche-end
+void dispatch_f_mess(char *fname, int err, char *dispatchee){
+ if(err == 0) return;
+ fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
+ if(err > ERR_DISPATCH){
+ fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
+ return;
+ }
+ switch(err){
+ case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
+ fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
+ break;
+ case ERR_DISPATCH_F_FORK:
+ case ERR_DISPATCH_F_SETEUID:
+ case ERR_DISPATCH_F_SETEGID:
+ fputc(' ', stderr);
+ perror(dispatchee);
+ break;
+ case ERR_DISPATCH_NULL_EXECUTABLE:
+ fprintf(stderr, " executable was not specified");
+ break;
+ case ERR_DISPATCH_EXEC:
+ // exec is running in another process when it fails, so we can't see the errno value it set
+ fprintf(stderr, " exec of \"%s\" failed", dispatchee);
+ break;
+ default:
+ fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
+ }
+ fputc('\n', stderr);
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function
+#tranche dispatch.lib.h
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
+#tranche-end
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
+ #ifdef DEBUG
+ dbprintf("%s %s\n", "dispatch_f", fname);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ int status = (*f)(f_arg); // we require that f return a zero or positive value
+ if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function with a given euid/egid
+// of course this will only work if our euid is root in the first place
+#tranche dispatch.lib.h
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
+#tranche-end
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
+ #ifdef DEBUG
+ dbprintf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK;
+ if( pid == 0 ){ // we are the child
+ int status;
+ if( seteuid(euid) == -1 )
+ status = ERR_DISPATCH_F_SETEUID;
+ else if( setegid(egid) == -1 )
+ status = ERR_DISPATCH_F_SETEGID;
+ else{
+ status = (*f)(f_arg);
+ if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }
+ }else{ // we are the parent
+ uint err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a executable
+#tranche dispatch.lib.h
+int dispatch_exec(char **argv, char **envp);
+#tranche-end
+int dispatch_exec(char **argv, char **envp){
+ char *command;
+ {
+ if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
+ #ifdef DEBUG
+ dbprintf("dispatch_exec:");
+ char **apt = argv;
+ while( *apt ){
+ dbprintf(" %s",*apt);
+ apt++;
+ }
+ dbprintf("\n");
+ #endif
+ command = argv[0];
+ }
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ execvpe(command, argv, envp); // exec will only return if it has an error
+ #ifdef DEBUG
+ dbprintf("dispatch_exec: exec returned, perror message:");
+ perror("dispatch_exec"); // our only chance to print this message, as this is the child process
+ #endif
+ fflush(stdout);
+ exit(ERR_DISPATCH_EXEC);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+#tranche-end
INCFILE=tranche.h
MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tools/lib/makefile_cc
+
+# files used by the compiler
+SOURCES_LIB= $(wildcard *.lib.c)
+SOURCES_CLI= $(wildcard *.cli.c)
+SOURCES= $(SOURCES_LIB) $(SOURCES_CLI)
+
+HFILES = $(wildcard *.lib.h) $(wildcard *.cli.h)
+
+OBJECTS_LIB= $(patsubst %.c, %.o, $(SOURCES_LIB))
+OBJECTS_CLI= $(patsubst %.c, %.o, $(SOURCES_CLI))
+OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI)
+
+EXECS= $(sort $(patsubst %.cli.c, %, $(wildcard *.cli.c)))
SHELL=/bin/bash
+# files used by the compiler
+C_SOURCES_LIB= $(wildcard *.lib.c)
+C_SOURCES_CLI= $(wildcard *.cli.c)
+C_SOURCES= $(C_SOURCES_LIB) $(C_SOURCES_CLI)
+
+CC_SOURCES_LIB= $(wildcard *.lib.cc)
+CC_SOURCES_CLI= $(wildcard *.cli.cc)
+CC_SOURCES= $(CC_SOURCES_LIB) $(CC_SOURCES_CLI)
+
+OBJECTS_LIB=$(sort\
+ $(patsubst %.c, %.o, $(C_SOURCES_LIB))\
+ $(patsubst %.cc, %.o, $(CC_SOURCES_LIB))\
+ )
+OBJECTS_CLI=$(sort\
+ $(patsubst %.c, %.o, $(C_SOURCES_CLI))\
+ $(patsubst %.cc, %.o, $(CC_SOURCES_CLI))\
+ )
+OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI)
+
+EXECS= $(sort \
+ $(patsubst %.cli.c, %, $(wildcard *.cli.c))\
+ $(patsubst %.cli.cc, %, $(wildcard *.cli.cc))\
+ )
+
+#otherwise make provides default values for these
+C=
+CC=
+
-include 0_makefile-flags
DEPSFILE=$(TMPDIR)/makefile_deps
blank :=
space :=$(blank) $(blank)
-# files used by the compiler
-SOURCES_LIB= $(wildcard *.lib.c)
-SOURCES_CLI= $(wildcard *.cli.c)
-SOURCES= $(SOURCES_LIB) $(SOURCES_CLI)
-
-HFILES = $(wildcard *.lib.h) $(wildcard *.cli.h)
-
-OBJECTS_LIB= $(patsubst %.c, %.o, $(SOURCES_LIB))
-OBJECTS_CLI= $(patsubst %.c, %.o, $(SOURCES_CLI))
-OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI)
-
-EXECS= $(sort $(patsubst %.cli.c, %, $(wildcard *.cli.c)))
all: version deps lib execs
@echo makefile version 3.0
@echo "PWD: " $(PWD)
@echo "MAKEFILE_LIST: " $(MAKEFILE_LIST)
- @echo "CC: " $(CC)
+ @echo "C: " $(C)
@echo "CFLAGS: " $(CFLAGS)
+ @echo "CC: " $(CC)
+ @echo "CCFLAGS: " $(CCFLAGS)
@echo "LINKFLAGS: " $(LINKFLAGS)
info:
@echo "TRYDIR: " $(TRYDIR)
@echo "DEPSFILE: " $(DEPSFILE)
@echo "LIBFILE: " $(LIBFILE)
- @echo "SOURCES_LIB: " $(SOURCES_LIB)
- @echo "SOURCES_CLI: " $(SOURCES_CLI)
- @echo "SOURCES: " $(SOURCES)
- @echo "HFILES: " $(HFILES)
+ @echo "C_SOURCES_LIB: " $(C_SOURCES_LIB)
+ @echo "C_SOURCES_CLI: " $(C_SOURCES_CLI)
+ @echo "C_SOURCES: " $(C_SOURCES)
+ @echo "CC_SOURCES_LIB: " $(CC_SOURCES_LIB)
+ @echo "CC_SOURCES_CLI: " $(CC_SOURCES_CLI)
+ @echo "CC_SOURCES: " $(CC_SOURCES)
@echo "OBJECTS_LIB: " $(OBJECTS_LIB)
@echo "OBJECTS_CLI: " $(OBJECTS_CLI)
@echo "OBJECTS: " $(OBJECTS)
if [ ! -e $(TRYDIR) ]; then mkdir $(TRYDIR); fi
deps:
- $(CC) $(CFLAGS) -MM $(SOURCES) 1> $(DEPSFILE)
- for i in $(EXECS) ; do\
- $(ECHO) >> $(DEPSFILE);\
- $(ECHO) "$(EXECSDIR)/$$i : $$i.cli.o $(LIBDIR)/$(LIBFILE)" >> $(DEPSFILE);\
- $(ECHO) " $(CC) -o $(EXECSDIR)/$$i $$i.cli.o $(LINKFLAGS)" >> $(DEPSFILE);\
- done
+ @if [ -z "$(CC)" ]; then\
+ if [ -z "$C()" ]; then\
+ echo "No compiler specified";\
+ exit 1;\
+ else\
+ echo "C compiler only deps" ;\
+ $(C) $(CFLAGS) -MM $(C_SOURCES) 1> $(DEPSFILE);\
+ echo "deps for C linking";\
+ for i in $(EXECS) ; do\
+ $(ECHO) >> $(DEPSFILE);\
+ $(ECHO) "$(EXECSDIR)/$$i : $$i.cli.o $(LIBDIR)/$(LIBFILE)" >> $(DEPSFILE);\
+ $(ECHO) " $(C) -o $(EXECSDIR)/$$i $$i.cli.o $(LINKFLAGS)" >> $(DEPSFILE);\
+ done;\
+ fi;\
+ else\
+ $(CC) $(CCFLAGS) -MM $(CC_SOURCES) 1> $(DEPSFILE);\
+ if [ -z "$C()" ]; then\
+ echo "CC compiler only deps" ;\
+ else\
+ echo "CC and C mixed compile deps" ;\
+ $(C) $(CFLAGS) -MM $(C_SOURCES) 1>> $(DEPSFILE);\
+ fi;\
+ echo "deps for CC linking";\
+ for i in $(EXECS) ; do\
+ $(ECHO) >> $(DEPSFILE);\
+ $(ECHO) "$(EXECSDIR)/$$i : $$i.cli.o $(LIBDIR)/$(LIBFILE)" >> $(DEPSFILE);\
+ $(ECHO) " $(CC) -o $(EXECSDIR)/$$i $$i.cli.o $(LINKFLAGS)" >> $(DEPSFILE);\
+ done;\
+ fi
lib:
- if [ ! -e $(DEPSFILE) ]; then make deps; fi
- make sub_lib
-
-sub_lib: $(LIBDIR)/$(LIBFILE)
+ make $(LIBDIR)/$(LIBFILE)
+$(LIBDIR)/$(LIBFILE) : $(OBJECTS_LIB)
+ if [ ! -e $(DEPSFILE) ]; then make deps; fi
+ ar rcs $(LIBDIR)/$(LIBFILE) $(OBJECTS_LIB)
execs: $(LIBDIR)/$(LIBFILE)
- if [ ! -e $(DEPSFILE) ]; then make deps; fi
make sub_execs
sub_execs: $(patsubst %, $(EXECSDIR)/%, $(EXECS))
stage:
if [ -f $(LIBDIR)/$(LIBFILE) ]; then cp $(LIBDIR)/$(LIBFILE) $(PROJECT_SUBU)/stage/lib; fi
if [ -f $(INCDIR)/$(INCFILE) ]; then cp $(INCDIR)/$(INCFILE) $(PROJECT_SUBU)/stage/include; fi
- cp $(EXECSDIR)/* $(PROJECT_SUBU)/stage/bin
+ -cp $(EXECSDIR)/* $(PROJECT_SUBU)/stage/bin
clean:
for i in $(wildcard *~); do mv $$i $(TMPDIR); done
if [ -f $(LIBDIR)/$(LIBFILE) ]; then rm $(LIBDIR)/$(LIBFILE); fi
if [ -f $(DEPSFILE) ]; then rm $(DEPSFILE); fi
-#
-$(LIBDIR)/$(LIBFILE) : $(OBJECTS_LIB)
- ar rcs $(LIBDIR)/$(LIBFILE) $(OBJECTS_LIB)
-
-include $(DEPSFILE)
# recipe for making object files:
#
%.o : %.c
- $(CC) $(CFLAGS) -c $<
+ $(C) $(CFLAGS) -c $<
+
+%.o : %.cc
+ $(CC) $(CCFLAGS) -c $<
--- /dev/null
+
+SHELL=/bin/bash
+
+-include 0_makefile-flags
+
+DEPSFILE=$(TMPDIR)/makefile_deps
+
+# a single space literal, for example if you wanted to subsitute commas to
+# spaces: $(subst $(space),;,$(string)) we ran into this out of a need to send
+# multiple separate command arguments to a shell script from one variable value
+blank :=
+space :=$(blank) $(blank)
+
+# files used by the compiler
+SOURCES_LIB= $(wildcard *.lib.c)
+SOURCES_CLI= $(wildcard *.cli.c)
+SOURCES= $(SOURCES_LIB) $(SOURCES_CLI)
+
+HFILES = $(wildcard *.lib.h) $(wildcard *.cli.h)
+
+OBJECTS_LIB= $(patsubst %.c, %.o, $(SOURCES_LIB))
+OBJECTS_CLI= $(patsubst %.c, %.o, $(SOURCES_CLI))
+OBJECTS= $(OBJECTS_LIB) $(OBJECTS_CLI)
+
+EXECS= $(sort $(patsubst %.cli.c, %, $(wildcard *.cli.c)))
+
+all: version deps lib execs
+
+version:
+ @echo makefile version 3.0
+ @echo "PWD: " $(PWD)
+ @echo "MAKEFILE_LIST: " $(MAKEFILE_LIST)
+ @echo "CC: " $(CC)
+ @echo "CFLAGS: " $(CFLAGS)
+ @echo "LINKFLAGS: " $(LINKFLAGS)
+
+info:
+ @echo "DEPDIR: " $(DEPDIR)
+ @echo "DOCDIR: " $(DOCDIR)
+ @echo "EXECSDIR: " $(EXECSDIR)
+ @echo "INCDIR: " $(INCDIR)
+ @echo "LIBDIR: " $(LIBDIR)
+ @echo "TESTDIR: " $(TESTDIR)
+ @echo "TMPDIR: " $(TMPDIR)
+ @echo "TOOLSDIR: " $(TOOLSDIR)
+ @echo "TRYDIR: " $(TRYDIR)
+ @echo "DEPSFILE: " $(DEPSFILE)
+ @echo "LIBFILE: " $(LIBFILE)
+ @echo "SOURCES_LIB: " $(SOURCES_LIB)
+ @echo "SOURCES_CLI: " $(SOURCES_CLI)
+ @echo "SOURCES: " $(SOURCES)
+ @echo "HFILES: " $(HFILES)
+ @echo "OBJECTS_LIB: " $(OBJECTS_LIB)
+ @echo "OBJECTS_CLI: " $(OBJECTS_CLI)
+ @echo "OBJECTS: " $(OBJECTS)
+ @echo "EXECS: " $(EXECS)
+
+# should be safe to run this in an already setup or partially setup directory
+setup:
+ if [ ! -e $(DEPRDIR) ]; then mkdir $(DEPRDIR); fi
+ if [ ! -e $(DOCDIR) ]; then mkdir $(DOCDIR); fi
+ if [ ! -e $(EXECSDIR) ]; then mkdir $(EXECSDIR); fi
+ if [ ! -e $(INCDIR) ]; then mkdir $(INCDIR); fi
+ if [ ! -e $(LIBDIR) ]; then mkdir $(LIBDIR); fi
+ if [ ! -e $(TESTDIR) ]; then mkdir $(TESTDIR); fi
+ if [ ! -e $(TMPDIR) ]; then mkdir $(TMPDIR); fi
+ if [ ! -e $(TRYDIR) ]; then mkdir $(TRYDIR); fi
+
+deps:
+ $(CC) $(CFLAGS) -MM $(SOURCES) 1> $(DEPSFILE)
+ for i in $(EXECS) ; do\
+ $(ECHO) >> $(DEPSFILE);\
+ $(ECHO) "$(EXECSDIR)/$$i : $$i.cli.o $(LIBDIR)/$(LIBFILE)" >> $(DEPSFILE);\
+ $(ECHO) " $(CC) -o $(EXECSDIR)/$$i $$i.cli.o $(LINKFLAGS)" >> $(DEPSFILE);\
+ done
+
+lib:
+ if [ ! -e $(DEPSFILE) ]; then make deps; fi
+ make sub_lib
+
+sub_lib: $(LIBDIR)/$(LIBFILE)
+
+
+execs: $(LIBDIR)/$(LIBFILE)
+ if [ ! -e $(DEPSFILE) ]; then make deps; fi
+ make sub_execs
+
+sub_execs: $(patsubst %, $(EXECSDIR)/%, $(EXECS))
+
+stage:
+ if [ -f $(LIBDIR)/$(LIBFILE) ]; then cp $(LIBDIR)/$(LIBFILE) $(PROJECT_SUBU)/stage/lib; fi
+ if [ -f $(INCDIR)/$(INCFILE) ]; then cp $(INCDIR)/$(INCFILE) $(PROJECT_SUBU)/stage/include; fi
+ cp $(EXECSDIR)/* $(PROJECT_SUBU)/stage/bin
+
+clean:
+ for i in $(wildcard *~); do mv $$i $(TMPDIR); done
+ for i in $(wildcard *.lib.o) $(wildcard *.cli.o); do rm $$i; done
+ for i in $(EXECS); do if [ -e $(EXECSDIR)/$$i ]; then rm $(EXECSDIR)/$$i; fi; done
+ if [ -f $(LIBDIR)/$(LIBFILE) ]; then rm $(LIBDIR)/$(LIBFILE); fi
+ if [ -f $(DEPSFILE) ]; then rm $(DEPSFILE); fi
+
+#
+$(LIBDIR)/$(LIBFILE) : $(OBJECTS_LIB)
+ ar rcs $(LIBDIR)/$(LIBFILE) $(OBJECTS_LIB)
+
+-include $(DEPSFILE)
+
+# recipe for making object files:
+#
+%.o : %.c
+ $(CC) $(CFLAGS) -c $<
+
+