diff --git a/Makefile b/Makefile index ecdae2b..e6d6a04 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,3 @@ -# Taken from: https://stackoverflow.com/questions/2214575/passing-arguments-to-make-run -# If the first argument is "new"... -ifeq (new,$(firstword $(MAKECMDGOALS))) - # use the rest as arguments for "new" - NEW_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) - # ...and turn them into do-nothing targets - $(eval $(NEW_ARGS):;@:) -endif - BIN := $(shell basename $$(pwd)) PLUGINS := $(wildcard modules/*) @@ -65,9 +56,6 @@ $(BIN): $(OBJS) -include $(DEPS) -new: - @./newmodule $(NEW_ARGS) - modules: $(PLUGINS) mkdir -p plugins @for plug in $(PLUGINS) ;\ diff --git a/Makefile.unified b/Makefile.unified new file mode 100644 index 0000000..3927ffe --- /dev/null +++ b/Makefile.unified @@ -0,0 +1,287 @@ +include premake.make + +# dir name becomes product name +PROJ := $(shell basename $$(pwd)) + +# find out what platform we're on +UNAME_S := $(shell uname -s) + +# git commit hash and version for this build +COMMIT-HASH != git log 2>/dev/null | sed -e '1s/^commit //;q' +COMMIT := "const char* commit = \"$(COMMIT-HASH)\";" +VERSION := "const char* version = \"$(MAJOR).$(MINOR).$(PATCH)\";" + +# some important install locations +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +CONFIGDIR ?= $(PREFIX)/etc +INCLUDEDIR ?= $(PREFIX)/include +LIBDIR ?= $(PREFIX)/lib +MANDIR ?= $(PREFIX)/man +DATADIR ?= $(PREFIX)/share +DOCDIR ?= $(DATADIR)/$(PROJ)/doc + +# setup naming and versioning for library product +ifeq ($(UNAME_S), Darwin) + LINKERNAME := $(PROJ).dylib + SONAME := $(PROJ).$(MAJOR).dylib + REALNAME := $(LINKERNAME) +else ifeq ($(UNAME_S), OpenBSD) + REALNAME := $(PROJ).so.$(MAJOR).$(MINOR) +else ifeq ($(UNAME_S), Linux) + LINKERNAME := $(PROJ).so + SONAME := $(LINKERNAME).$(MAJOR) + REALNAME := $(SONAME).$(MINOR).$(PATCH) +endif +STATICLIB := $(PROJ).a + +# select default compiler +CXX ?= g++ + +# setup compiler flags and build config +CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -Wno-unused-parameter +CXXFLAGS += -g3 -std=c++20 -fPIC +ifeq ($(DEBUG), 1) + CXXFLAGS += -D DEBUG -O0 + CONFIG := debug +else + CXXFLAGS += -D NDEBUG -O3 + CONFIG := release +endif + +# setup build locations +OUTDIR := build/$(CONFIG) +BUILDDIR := build/obj +BIN := $(OUTDIR)/$(PROJ) + +# define sources and derived files +# allow for extra sources defined in premake.make +SRCS += $(notdir $(wildcard src/*.cpp)) +OBJS := $(addprefix $(BUILDDIR)/, $(SRCS:.cpp=.o)) +DEPS := $(addprefix $(BUILDDIR)/, $(SRCS:.cpp=.dep)) +HDRS ?= $(wildcard src/*.hpp) +MANS := $(addprefix $(PREFIX)/, $(wildcard man/man*/*)) + +# if project supports plugins, link to libdl where needed +ifdef PLUGINS +ifeq ($(UNAME_S),Darwin) + LDLIBS += -ldl +else ifeq ($(UNAME_S),Linux) + LDLIBS += -ldl +endif +endif + +# pattern rules =========================================================== + +$(BUILDDIR)/%.o: src/%.cpp +ifeq ($(PRECOMPILE), 1) + $(CXX) $(CXXFLAGS) -o $@ -include precomp.hpp -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $< +else + $(CXX) $(CXXFLAGS) -o $@ -MMD -MP -MT $@ -MF $(BUILDDIR)/$*.dep -c $< +endif + +%.dep: ; + +$(MANDIR)/man1/%: man/man1/% + install -m 0644 $< $@ + +$(MANDIR)/man3/%: man/man3/% + install -m 0644 $< $@ + +$(MANDIR)/man5/%: man/man5/% + install -m 0644 $< $@ + +# =========================================================== pattern rules + +# targets ================================================================= + +.PHONY: all commit-hash version plugins test clean dist-clean install-plugins install uninstall-plugins uninstall + +# main target +ifeq ($(PRODUCT), tool) +all: $(BUILDDIR) $(OUTDIR) commit-hash version plugins $(BIN) +else ifeq ($(PRODUCT), lib) +all: $(BUILDDIR) $(OUTDIR) commit-hash version plugins $(OUTDIR)/$(REALNAME) $(OUTDIR)/$(STATICLIB) +endif + +$(BUILDDIR): + mkdir -p $@ + +$(OUTDIR): + mkdir -p $@ + +# product build rules +ifeq ($(PRODUCT), tool) # -------------------------------------------- tool + +ifeq ($(PRECOMPILE), 1) +$(BIN): precomp.hpp.gch $(OBJS) +else +$(BIN): $(OBJS) +endif + $(CXX) -o $(BIN) $(LDFLAGS) $(OBJS) $(LDLIBS) + @ln -sf $(BIN) $(PROJ) + +endif # -------------------------------------------------------------- tool + +ifeq ($(PRODUCT), lib) # ---------------------------------------------- lib + +ifeq ($(PRECOMPILE), 1) +$(OUTDIR)/$(REALNAME): precomp.hpp.gch $(OBJS) +else +$(OUTDIR)/$(REALNAME): $(OBJS) +endif +ifeq ($(UNAME_S),Darwin) + $(CXX) -dynamiclib -o $(OUTDIR)/$(REALNAME) -current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(OBJS) $(LDLIBS) +else ifeq ($(UNAME_S),OpenBSD) + $(CXX) -g -shared -Wl,-soname,$(REALNAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS) +else ifeq ($(UNAME_S),Linux) + $(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS) +endif + +$(OUTDIR)/$(STATICLIB): $(OBJS) + ar r $(OUTDIR)/$(STATICLIB) $(OBJS) + +ifeq ($(GENERATELIBHEADER),1) +$(OUTDIR)/$(PROJ).hpp: $(HDRS) + @echo updating $(OUTDIR)/$(PROJ).hpp + @cp /dev/null $(OUTDIR)/$(PROJ).hpp + @for h in $(HDRS); \ + do \ + sed '/@exclude/d' $$h >> $(OUTDIR)/$(PROJ).hpp; \ + done +endif + +endif # --------------------------------------------------------------- lib + +# get generated dependencies, if any +-include $(DEPS) + +commit-hash: + @if ! echo $(COMMIT) | diff -q src/commit.inc - >/dev/null 2>&1 ;\ + then \ + echo $(COMMIT) > src/commit.inc ;\ + fi + +version: + @if ! echo $(VERSION) | diff -q src/version.inc - >/dev/null 2>&1 ;\ + then \ + echo $(VERSION) > src/version.inc ;\ + fi + +$(BUILDDIR)/version.o: src/version.inc src/commit.inc + +precomp.hpp.gch: src/precomp.hpp + $(CXX) $< $(CXXFLAGS) -o $@ + +plugins: +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug ;\ + done +else + ; +endif + +test: + $(MAKE) -C tests && tests/tests + +clean: + rm -rf $(BUILDDIR) tests/build tests/tests tests/src/commit.inc tests/src/version.inc +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug clean ;\ + done +endif + +dist-clean: clean + rm -rf build $(PROJ) src/commit.inc src/version.inc precomp.hpp.pch + +$(MANDIR)/man1: + install -m 0755 -d $@ + +$(MANDIR)/man3: + install -m 0755 -d $@ + +$(MANDIR)/man5: + install -m 0755 -d $@ + +# (un)install targets + +install-plugins: +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug install ;\ + done +else + ; +endif + +uninstall-plugins: +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug uninstall ;\ + done +else + ; +endif + +ifeq ($(PRODUCT), tool) # -------------------------------------------- tool + +$(BINDIR): + install -m 0755 -d $@ + +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(BINDIR) $(MANS) install-plugins + install -m 0755 $(BIN) $(BINDIR) + +uninstall: uninstall-plugins + rm -f $(BINDIR)/$(PROJ) $(MANS) + +endif # -------------------------------------------------------------- tool + +ifeq ($(PRODUCT), lib) # ---------------------------------------------- lib + +$(LIBDIR): + install -m 0755 -d $@ + +$(INCLUDEDIR): + install -m 0755 -d $@ + +$(INCLUDEDIR)/$(PROJ): + install -m 0755 -d $@ + +ifeq ($(GENERATELIBHEADER), 1) +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(OUTDIR)/$(PROJ).hpp install-plugins + install -m 0644 $(OUTDIR)/$(PROJ).hpp $(INCLUDEDIR) +else +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(INCLUDEDIR)/$(PROJ) install-plugins + install -m 0644 $(HDRS) $(INCLUDEDIR)/$(PROJ) +endif + install -m 0644 $(OUTDIR)/$(REALNAME) $(LIBDIR) + install -m 0644 $(OUTDIR)/$(STATICLIB) $(LIBDIR) +ifeq ($(UNAME_S), Darwin) + cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME) +else ifeq ($(UNAME_S), Linux) + ldconfig + cd $(LIBDIR) && ln -sf $(SONAME) $(LINKERNAME) +else ifeq ($(UNAME_S), OpenBSD) + ldconfig -R +endif + +uninstall: uninstall-plugins + rm -rf $(INCLUDEDIR)/$(PROJ).hpp $(INCLUDEDIR)/$(PROJ) $(MANS) $(LIBDIR)/$(STATICLIB) $(LIBDIR)/$(REALNAME) $(LIBDIR)/$(SONAME) $(LIBDIR)/$(LINKERNAME) +ifeq ($(UNAME_S), Linux) + ldconfig +else ifeq ($(UNAME_S), OpenBSD) + ldconfig -R +endif + +endif # --------------------------------------------------------------- lib + +# ================================================================= targets + +# project-specific targets go in here +-include postmake.make diff --git a/newmodule b/newmodule index f33e228..dfbc7a0 100755 --- a/newmodule +++ b/newmodule @@ -1,5 +1,5 @@ #!/bin/sh mkdir modules/$1 -cp skeleton/Makefile modules/$1/ +cp skeleton/Makefile skeleton/premake.make modules/$1/ sed -e "s/{MODULE}/$1/" skeleton/MODULE.hpp > modules/$1/$1.hpp sed -e "s/{MODULE}/$1/" skeleton/MODULE.cpp > modules/$1/$1.cpp diff --git a/postmake.make b/postmake.make new file mode 100644 index 0000000..cd6a0f1 --- /dev/null +++ b/postmake.make @@ -0,0 +1,11 @@ +# Taken from: https://stackoverflow.com/questions/2214575/passing-arguments-to-make-run +# If the first argument is "new"... +ifeq (new,$(firstword $(MAKECMDGOALS))) + # use the rest as arguments for "new" + NEW_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) + # ...and turn them into do-nothing targets + $(eval $(NEW_ARGS):;@:) +endif + +new: + @./newmodule $(NEW_ARGS) diff --git a/premake.make b/premake.make new file mode 100644 index 0000000..2c6938c --- /dev/null +++ b/premake.make @@ -0,0 +1,15 @@ +LDLIBS := -lm -lscgui -lcairo -lscerror -lscstring -lscscreensaver -lscnumerics + +LDLIBS += $(shell pkg-config sdl2 --libs) +CXXFLAGS += $(shell pkg-config sdl2 --cflags) + +PRODUCT := tool + +MAJOR := 1 +MINOR := 0 +PATCH := 0 + +PRECOMPILE := 0 + +MAKE += --no-print-directory +PLUGINS := $(wildcard modules/*) diff --git a/skeleton/Makefile b/skeleton/Makefile index cd973c8..c22234e 100644 --- a/skeleton/Makefile +++ b/skeleton/Makefile @@ -1,62 +1,53 @@ -LIBNAME := $(shell basename $$(pwd)) -MAJOR := 1 -MINOR := 0.0 +include premake.make -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) - LINKERNAME := $(LIBNAME).dylib - SONAME := $(LIBNAME).$(MAJOR).dylib - REALNAME := $(LINKERNAME) -else - LINKERNAME := $(LIBNAME).so - SONAME := $(LINKERNAME).$(MAJOR) - REALNAME := $(SONAME).$(MINOR) -endif - -PREFIX ?= ../.. -LIBDIR ?= $(PREFIX)/plugins +# some important install locations +PREFIX ?= /usr/local +DATADIR ?= $(PREFIX)/share +INSTALLDIR ?= $(DATADIR)/$(INSTALLDIRNAME) SRCS := $(wildcard *.cpp) -OBJS := $(subst .cpp,.o,$(SRCS)) -DEPS := $(subst .cpp,.d,$(SRCS)) -HDRS := $(filter-out $(LIBNAME).hpp,$(wildcard *.hpp)) +OBJS := $(SRCS:.cpp=.o) +DEPS := $(SRCS:.cpp=.dep) CXX ?= g++ -CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -g -std=c++17 -fPIC +CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -Wno-unused-parameter +CXXFLAGS += -g3 -std=c++20 -fPIC ifeq ($(DEBUG),1) CXXFLAGS += -D DEBUG -O0 else CXXFLAGS += -D NDEBUG -O3 endif -LDLIBS := -lcairo -lscscreensaver +%.o: %.cpp + $(CXX) $(CXXFLAGS) -o $@ -MMD -MP -MT $@ -MF $*.dep -c $< -RM := /bin/rm -f -INSTALL := /usr/bin/install -c +%.dep: ; -.PHONY: all clean install +.PHONY: all clean install uninstall -all: $(REALNAME) +all: $(PLUGIN) -$(REALNAME): $(OBJS) $(DEPS) +$(PLUGIN): $(OBJS) ifeq ($(UNAME_S),Darwin) - $(CXX) -dynamiclib -o $(REALNAME) -current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(LDLIBS) $(OBJS) + $(CXX) -g3 -dynamiclib -o $(PLUGIN) $(LDFLAGS) $(OBJS) $(LDLIBS) else - $(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(REALNAME) $(LDFLAGS) $(LDLIBS) $(OBJS) + $(CXX) -g3 -shared -o $(PLUGIN) $(LDFLAGS) $(OBJS) $(LDLIBS) endif -%.o: %.cpp %.d Makefile - $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $< - --include *.d - -%.d: ; +-include $(DEPS) clean: - $(RM) $(OBJS) $(DEPS) $(REALNAME) + rm -f $(OBJS) $(DEPS) $(PLUGIN) -install: $(REALNAME) - $(INSTALL) -d $(LIBDIR) - $(INSTALL) -m 644 $(REALNAME) $(LIBDIR)/$(LIBNAME).saver +$(INSTALLDIR): + install -m 0755 -d $@ + +install: $(INSTALLDIR) + install -m 0644 $(PLUGIN) $(INSTALLDIR) +ifdef EXTRAFILES + install -m 0644 $(EXTRAFILES) $(INSTALLDIR) +endif + +uninstall: + rm -f $(INSTALLDIR)/$(PLUGIN) $(addprefix $(INSTALLDIR)/, $(EXTRAFILES)) diff --git a/skeleton/premake.make b/skeleton/premake.make new file mode 100644 index 0000000..ec5846f --- /dev/null +++ b/skeleton/premake.make @@ -0,0 +1,6 @@ +LDLIBS := -lcairo -lscscreensaver +UNAME_S := $(shell uname -s) +PROJ := $(shell basename $$(pwd)) +PLUGIN := $(PROJ).saver +INSTALLDIRNAME := screensaver/plugins +EXTRAFILES :=