diff --git a/.gitignore b/.gitignore index ab7081c..30f17c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ sciotest/sciotest +*.inc diff --git a/Makefile b/Makefile index 6e6b30c..032d08b 100644 --- a/Makefile +++ b/Makefile @@ -1,54 +1,78 @@ include premake.make -LIBNAME := $(shell basename $$(pwd)) -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 := "static const char* commit = \"$(COMMIT-HASH)\";" +VERSION := "static 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 -DATADIR ?= $(PREFIX)/share -DOCDIR ?= $(DATADIR)/$(LIBNAME)/doc MANDIR ?= $(PREFIX)/man +DATADIR ?= $(PREFIX)/share/$(PROJ) +DOCDIR ?= $(DATADIR)/doc -ifeq ($(UNAME_S),Darwin) - LINKERNAME := $(LIBNAME).dylib - SONAME := $(LIBNAME).$(MAJOR).dylib +# setup naming and versioning for library product +ifeq ($(UNAME_S), Darwin) + LINKERNAME := $(PROJ).dylib + SONAME := $(PROJ).$(MAJOR).dylib REALNAME := $(LINKERNAME) -endif -ifeq ($(UNAME_S),OpenBSD) - REALNAME := $(LIBNAME).so.$(MAJOR).$(MINOR) -endif -ifeq ($(UNAME_S),Linux) - LINKERNAME := $(LIBNAME).so +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 := $(LIBNAME).a +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 +CXXFLAGS += -g3 -fPIC +ifeq ($(DEBUG), 1) + CXXFLAGS += -DDEBUG -O0 CONFIG := debug else - CXXFLAGS += -D NDEBUG -O3 + CXXFLAGS += -DNDEBUG -O3 CONFIG := release endif +# setup build locations OUTDIR := build/$(CONFIG) BUILDDIR := build/obj +BIN := $(OUTDIR)/$(PROJ) -SRCS := $(notdir $(wildcard src/*.cpp)) +# 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) +HDRS ?= $(filter-out src/precomp.hpp, $(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: ; @@ -61,9 +85,19 @@ $(MANDIR)/man3/%: man/man3/% $(MANDIR)/man5/%: man/man5/% install -m 0644 $< $@ -.PHONY: all test clean install +# =========================================================== pattern rules -all: $(BUILDDIR) $(OUTDIR) $(OUTDIR)/$(REALNAME) $(OUTDIR)/$(STATICLIB) +# targets ================================================================= + +.PHONY: all commit-hash version plugins test clean dist-clean install-plugins \ +install install-data uninstall-data 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 $@ @@ -71,30 +105,75 @@ $(BUILDDIR): $(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) -install_name $(LIBDIR)/$(REALNAME) \ -current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(OBJS) $(LDLIBS) -endif -ifeq ($(UNAME_S),OpenBSD) +else ifeq ($(UNAME_S),OpenBSD) $(CXX) -g -shared -Wl,-soname,$(REALNAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS) -endif -ifeq ($(UNAME_S),Linux) +else ifeq ($(UNAME_S),Linux) $(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(OUTDIR)/$(REALNAME) $(LDFLAGS) $(OBJS) $(LDLIBS) endif --include $(DEPS) - $(OUTDIR)/$(STATICLIB): $(OBJS) ar r $(OUTDIR)/$(STATICLIB) $(OBJS) ifeq ($(GENERATELIBHEADER),1) -$(OUTDIR)/$(LIBNAME).hpp: $(HDRS) - @echo updating $(OUTDIR)/$(LIBNAME).hpp - @cp /dev/null $(OUTDIR)/$(LIBNAME).hpp +$(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)/$(LIBNAME).hpp; \ + 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 endif @@ -102,8 +181,16 @@ test: $(MAKE) -C tests && tests/tests clean: - rm -rf build - $(MAKE) -C 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.gch $(MANDIR)/man1: install -m 0755 -d $@ @@ -114,34 +201,94 @@ $(MANDIR)/man3: $(MANDIR)/man5: install -m 0755 -d $@ +$(DATADIR): + install -m 0755 -d $@ + +# (un)install targets + +ifdef DATAFILES +install-data: $(DATADIR) + install -m 0644 $(DATAFILES) $(DATADIR) +else +install-data: +endif + +uninstall-data: + rm -rf $(DATADIR) + +install-plugins: +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug install ;\ + done +endif + +uninstall-plugins: +ifdef PLUGINS + @for plug in $(PLUGINS) ;\ + do \ + $(MAKE) -C $$plug uninstall ;\ + done +endif + +ifeq ($(PRODUCT), tool) # -------------------------------------------- tool + +$(BINDIR): + install -m 0755 -d $@ + +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(BINDIR) $(MANS) install-data install-plugins + install -m 0755 $(BIN) $(BINDIR) + +uninstall: uninstall-data uninstall-plugins + rm -f $(BINDIR)/$(PROJ) $(MANS) + +endif # -------------------------------------------------------------- tool + +ifeq ($(PRODUCT), lib) # ---------------------------------------------- lib + $(LIBDIR): install -m 0755 -d $@ $(INCLUDEDIR): install -m 0755 -d $@ -ifeq ($(GENERATELIBHEADER),1) -install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(OUTDIR)/$(LIBNAME).hpp - install -m 0644 $(OUTDIR)/$(LIBNAME).hpp $(INCLUDEDIR) +$(INCLUDEDIR)/$(PROJ): + install -m 0755 -d $@ + +ifeq ($(GENERATELIBHEADER), 1) +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(OUTDIR)/$(PROJ).hpp install-data install-plugins + install -m 0644 $(OUTDIR)/$(PROJ).hpp $(INCLUDEDIR) else -install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) - install -m 0644 $(HDRS) $(INCLUDEDIR)/$(LIBNAME) +install: $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man5 $(LIBDIR) $(INCLUDEDIR) $(MANS) $(INCLUDEDIR)/$(PROJ) install-data 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) +ifeq ($(UNAME_S), Darwin) cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME) -endif -ifeq ($(UNAME_S),Linux) +else ifeq ($(UNAME_S), Linux) ifeq ($(USER), root) ldconfig else cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME) endif cd $(LIBDIR) && ln -sf $(SONAME) $(LINKERNAME) -endif -ifeq ($(UNAME_S),OpenBSD) +else ifeq ($(UNAME_S), OpenBSD) ldconfig -R endif +uninstall: uninstall-data 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/man/man3/libscio.3 b/man/man3/libscio.3 new file mode 100644 index 0000000..ae16d8a --- /dev/null +++ b/man/man3/libscio.3 @@ -0,0 +1,30 @@ +.Dd $Mdocdate$ +.Dt libscio 3 +.Os +.Sh NAME +.Nm libscio +.Nd one line about what it does +.\" .Sh LIBRARY +.\" For sections 2, 3, and 9 only. +.\" Not used in OpenBSD. +.Sh DESCRIPTION +The +.Nm +library ... +.\" .Sh RETURN VALUES +.\" For sections 2, 3, and 9 function return values only. +.\" .Sh ENVIRONMENT +.\" .Sh FILES +.\" .Sh EXAMPLES +.\" .Sh ERRORS +.\" For sections 2, 3, 4, and 9 errno settings only. +.\" .Sh SEE ALSO +.\" .Xr foobar 1 +.\" .Sh STANDARDS +.\" .Sh HISTORY +.Sh AUTHORS +Bob Polis +.\" .Sh CAVEATS +.\" .Sh BUGS +.\" .Sh SECURITY CONSIDERATIONS +.\" Not used in OpenBSD. diff --git a/premake.make b/premake.make index ab0406b..f0b38bd 100644 --- a/premake.make +++ b/premake.make @@ -1,11 +1,41 @@ +# Define linker flags here, like: -lsqlite3 -lpthread LDLIBS := -lscerror +# Dir name becomes product name. +PROJ := $(shell basename $$(pwd)) + +# Find out what platform we're on, e.g. Darwin, Linux, OpenBSD. +UNAME_S := $(shell uname -s) + +# We will build a library, not a tool. +PRODUCT := lib + +# Single source of truth for version. MAJOR := 1 -MINOR := 1 +MINOR := 0 PATCH := 0 +# Specify desired C++ standard for this project. +CXXFLAGS += -std=c++20 + +# Set to 1 if you want a precompiled header for the C++ Standard Library. +PRECOMPILE := 0 + +# Set to 0 if you want to create a library header by hand. +# By default, it will concatenate all headers, leaving out +# lines containing: @exclude GENERATELIBHEADER := 1 +# List of extra files to be installed in DATADIR (/usr/local/share/$(PROJ) by default) +DATAFILES := + +# Define plugin sub-projects here. Assumption here is a directory "plugins" +# containing plugin sub-projects, each in its own directory. +# Rename and/or repeat accordingly. +PLUGINS := $(wildcard plugins/*) +MAKE += --no-print-directory + +# Define specific order of headers HDRS := \ src/fdiobuf.hpp \ src/fdistream.hpp \ @@ -19,3 +49,4 @@ src/byte_order_changer.hpp \ src/memstreambuf.hpp \ src/mapped_file.hpp \ src/imemfile.hpp \ +src/version.hpp diff --git a/src/precomp.hpp b/src/precomp.hpp new file mode 100644 index 0000000..182bcb4 --- /dev/null +++ b/src/precomp.hpp @@ -0,0 +1,127 @@ +// C++98 (first official C++ standard) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (__cplusplus >= 201103L) // C++11 +#include +#include +#include +#include +#include +#include // deprecated in C++17, removed in C++26 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // C++11 + +#if (__cplusplus >= 201402L) // C++14 +#include +#endif // C++14 + +#if (__cplusplus >= 201703L) // C++17 +#include +#include +#include +#include +#include +#include +#include +#include +#endif // C++17 + +#if (__cplusplus >= 202002L) // C++20 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include not yet supported by clang 16 +//#include not yet supported by clang 17 +#include +#endif // C++20 + +#if (__cplusplus >= 202302L) // C++23 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // C++23 + +#if (__cplusplus > 202302L) // C++26 +#include +#include +#include +#include +#include +#include +#endif // C++26 diff --git a/src/version.cpp b/src/version.cpp new file mode 100644 index 0000000..d753001 --- /dev/null +++ b/src/version.cpp @@ -0,0 +1,19 @@ +#include "version.hpp" +#include + +std::string libscio_version() { +#include "version.inc" +#include "commit.inc" + std::ostringstream oss; + oss << "libscio version " << version; +#ifdef DEBUG + oss << " DEBUG"; +#endif + oss << '\n'; + if (commit[0] != '\0') { + oss << "build " << commit << ", "; + } + oss << __DATE__ << ", " << __TIME__ << '\n'; + oss << "(c) Bob Polis, all rights reserved"; + return oss.str(); +} diff --git a/src/version.hpp b/src/version.hpp new file mode 100644 index 0000000..d5007dc --- /dev/null +++ b/src/version.hpp @@ -0,0 +1,8 @@ +#ifndef _LIBSCIO_VERSION_H_ +#define _LIBSCIO_VERSION_H_ + +#include + +std::string libscio_version(); + +#endif // _LIBSCIO_VERSION_H_ diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 7e524f5..0000000 --- a/tests/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -include ../premake.make -LDLIBS += -lboost_unit_test_framework - -BIN := $(shell basename $$(pwd)) - -SRCS := $(notdir $(wildcard src/*.cpp)) -SRCS += $(notdir $(filter-out ../src/main.cpp,$(wildcard ../src/*.cpp))) -OBJS := $(SRCS:.cpp=.o) -DEPS := $(SRCS:.cpp=.d) - -BUILDDIR := build/intermediates/ - -CXX ?= g++ -RM := /bin/rm -rf -INSTALL := /usr/bin/install -c - -CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -g -std=c++17 -I../src -ifeq ($(DEBUG),1) - CXXFLAGS += -D DEBUG -O0 - CONFIG := debug -else - CXXFLAGS += -D NDEBUG -O3 - CONFIG := release -endif -OUTDIR := build/$(CONFIG)/ - -vpath %.cpp src ../src -vpath %.d $(BUILDDIR) -vpath %.o $(BUILDDIR) - -.PHONY: all clean prebuild - -all: prebuild $(OUTDIR)$(BIN) - -prebuild: - @mkdir -p $(BUILDDIR) $(OUTDIR) - -$(OUTDIR)$(BIN): $(OBJS) $(DEPS) - $(CXX) $(addprefix $(BUILDDIR),$(OBJS)) $(LDFLAGS) $(LDLIBS) -o $(OUTDIR)$(BIN) - @ln -sf $(OUTDIR)$(BIN) $(BIN) - -%.o: %.cpp %.d - $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $< - @mv $@ $*.d $(BUILDDIR) - --include $(BUILDDIR)*.d - -%.d: ; - -clean: - $(RM) build $(BIN) diff --git a/tests/Makefile b/tests/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/tests/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/tests/postmake.make b/tests/postmake.make new file mode 100644 index 0000000..39e713a --- /dev/null +++ b/tests/postmake.make @@ -0,0 +1,6 @@ +$(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 diff --git a/tests/premake.make b/tests/premake.make new file mode 100644 index 0000000..d5cfa47 --- /dev/null +++ b/tests/premake.make @@ -0,0 +1,5 @@ +include ../premake.make +LDLIBS += -lboost_unit_test_framework +CXXFLAGS += -I../src +SRCS := $(notdir $(filter-out ../src/main.cpp,$(wildcard ../src/*.cpp))) +PRODUCT := tool diff --git a/tests/src/precomp.hpp b/tests/src/precomp.hpp new file mode 120000 index 0000000..821bca7 --- /dev/null +++ b/tests/src/precomp.hpp @@ -0,0 +1 @@ +../../src/precomp.hpp \ No newline at end of file