aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile49
-rw-r--r--charconv-mcb.c31
-rw-r--r--common.h4
-rw-r--r--config.mk3
5 files changed, 82 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index 9bdfa88..7af26d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,5 +12,8 @@
*.gcov
*.gcno
*.gcda
+*.bo
/convert-to-*
!/convert-to-*.c
+/charconv-mcb.h
+/charconv-mcb
diff --git a/Makefile b/Makefile
index e74a5d9..8b92b86 100644
--- a/Makefile
+++ b/Makefile
@@ -201,29 +201,47 @@ LIBOBJ =\
LOBJ = $(LIBOBJ:.o=.lo)
BINOBJ = $(BIN:=.o) common.o
+MCBOBJ = $(BIN:=.bo) common.o
-all: libcharconv.a libcharconv.$(LIBEXT) $(BIN)
+all: libcharconv.a libcharconv.$(LIBEXT) $(BIN) charconv-mcb
common.o: libcharconv.h common.h
+$(MCBOBJ): libcharconv.h common.h
$(BINOBJ): libcharconv.h common.h
$(LIBOBJ): libcharconv.h lib-common.h
$(LOBJ): libcharconv.h lib-common.h
$(BIN): common.o libcharconv.a
+charconv-mcb.o: libcharconv.h common.h charconv-mcb.h
libcharconv_rotated_90deg_ccw.o libcharconv_rotated_90deg_ccw.lo: libcharconv_rotated_90deg_cw.c
libcharconv_rotated_45deg_ccw.o libcharconv_rotated_45deg_ccw.lo: libcharconv_rotated_45deg_cw.c
+charconv-mcb.h: Makefile
+ printf '#define LIST_BINS(X)' > $@
+ set -e && \
+ for c in $(BIN); do \
+ printf '\\\n\tX("%s", main_%s)' \
+ $$c $$(printf '%s\n' $$c | cut -d - -f 3- | tr - _); \
+ done >> $@
+ printf '\n' >> $@
+
+charconv-mcb: charconv-mcb.o $(MCBOBJ) libcharconv.a
+ $(CC) -o $@ charconv-mcb.o $(MCBOBJ) libcharconv.a $(LDFLAGS)
+
.c.o:
$(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS)
+.c.bo:
+ $(CC) -c -o $@ $< -Dmain=main_$$(printf '%s\n' $* | cut -d - -f 3- | tr - _) $(CFLAGS) $(CPPFLAGS)
+
.c.lo:
$(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS)
.o:
- $(CC) -fPIC -o $@ $< common.o libcharconv.a $(LDFLAGS)
+ $(CC) -o $@ $< common.o libcharconv.a $(LDFLAGS)
.c:
- $(CC) -fPIC -o $@ $< common.o libcharconv.a $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
+ $(CC) -o $@ $< common.o libcharconv.a $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
libcharconv.a: $(LIBOBJ)
@rm -f -- $@
@@ -233,9 +251,24 @@ libcharconv.a: $(LIBOBJ)
libcharconv.$(LIBEXT): $(LOBJ)
$(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS)
-install: libcharconv.a libcharconv.$(LIBEXT) $(BIN)
- mkdir -p -- "$(DESTDIR)$(PREFIX)/lib"
+install: $(BIN)
+ +$(MAKE) install-common
+ mkdir -p -- "$(DESTDIR)$(PREFIX)/bin"
+ cp -- $(BIN) "$(DESTDIR)$(PREFIX)/bin/"
+
+install-mcb: charconv-mcb
+ +$(MAKE) install-common
mkdir -p -- "$(DESTDIR)$(PREFIX)/bin"
+ mkdir -p -- "$(DESTDIR)$(PREFIX)$(LIBEXEC)"
+ cp -- charconv-mcb "$(DESTDIR)$(PREFIX)$(LIBEXEC)/"
+ set -e && \
+ for f in $(BIN); do \
+ test ! -d "$(DESTDIR)$(PREFIX)/bin/$$f" && \
+ ln $(LNFLAGS) -- "..$(LIBEXEC)/charconv-mcb" "$(DESTDIR)$(PREFIX)/bin/$$f";\
+ done
+
+install-common: libcharconv.a libcharconv.$(LIBEXT)
+ mkdir -p -- "$(DESTDIR)$(PREFIX)/lib"
mkdir -p -- "$(DESTDIR)$(PREFIX)/include"
cp -- libcharconv.a "$(DESTDIR)$(PREFIX)/lib/"
cp -- libcharconv.$(LIBEXT) "$(DESTDIR)$(PREFIX)/lib/libcharconv.$(LIBMINOREXT)"
@@ -243,7 +276,6 @@ install: libcharconv.a libcharconv.$(LIBEXT) $(BIN)
ln -sf -- libcharconv.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/libcharconv.$(LIBMAJOREXT)"
ln -sf -- libcharconv.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/libcharconv.$(LIBEXT)"
cp -- libcharconv.h "$(DESTDIR)$(PREFIX)/include/"
- cp -- $(BIN) "$(DESTDIR)$(PREFIX)/bin/"
uninstall:
-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libcharconv.a"
@@ -256,8 +288,9 @@ uninstall:
clean:
-rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib
-rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT) $(BIN)
+ -rm -f -- charconv-mcb.h charconv-mcb *.bo
.SUFFIXES:
-.SUFFIXES: .lo .o .c
+.SUFFIXES: .lo .o .c .bo
-.PHONY: all install uninstall clean
+.PHONY: all install install-mcb install-common uninstall clean
diff --git a/charconv-mcb.c b/charconv-mcb.c
new file mode 100644
index 0000000..798ff3b
--- /dev/null
+++ b/charconv-mcb.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#include "charconv-mcb.h"
+
+
+#define X(NAME, MAIN)\
+ extern int MAIN(int argc, char *argv[]);
+LIST_BINS(X)
+#undef X
+
+
+char *argv0 = NULL;
+
+
+int
+main(int argc, char *argv[])
+{
+ char *command = argv[0];
+ char *p = strrchr(command, '/');
+
+ command = p ? &p[1] : command;
+
+#define X(NAME, MAIN)\
+ if (!strcmp(command, NAME))\
+ return MAIN(argc, argv);
+ LIST_BINS(X)
+#undef X
+
+ fprintf(stderr, "%s: invalid invocation of multicall binary\n", argv[0]);
+ return 125;
+}
diff --git a/common.h b/common.h
index 7e42a49..d33a924 100644
--- a/common.h
+++ b/common.h
@@ -5,6 +5,10 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
+#ifdef main
+# define LIBSIMPLY_CONFIG_MULTICALL_BINARY
+#endif
#include <libsimple-arg.h>
diff --git a/config.mk b/config.mk
index f4adf12..409eb9d 100644
--- a/config.mk
+++ b/config.mk
@@ -1,8 +1,11 @@
PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
+LIBEXEC = /libexec
CC = c99
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
CFLAGS =
LDFLAGS =
+
+LNFLAGS = -sf