# # Makefile for Mini-XML, a small XML-like file parsing library. # # https://www.msweet.org/mxml # # Copyright © 2003-2024 by Michael R Sweet. # # Licensed under Apache License v2.0. See the file "LICENSE" for more # information. # # # This is a POSIX makefile # .POSIX: # # Mini-XML version... # MXML_VERSION = @MXML_VERSION@ # # Programs... # AR = @AR@ CC = @CC@ DSO = @DSO@ INSTALL = @INSTALL@ LN = @LN@ -sf MKDIR = @MKDIR@ -p RANLIB = @RANLIB@ RM = @RM@ -f RMDIR = @RMDIR@ SHELL = /bin/sh # # Installation programs... # INSTALL_BIN = $(INSTALL) -c -m 755 INSTALL_DATA = $(INSTALL) -c -m 444 INSTALL_DIR = $(INSTALL) -d -m 755 INSTALL_LIB = $(INSTALL) -c -m 755 INSTALL_MAN = $(INSTALL) -c -m 444 # # Libraries... # LIBMXML = @LIBMXML@ LIBMXML_BASE = @LIBMXML_BASE@ LIBMXML_STATIC = @LIBMXML_STATIC@ MXML_MAN = @MXML_MAN@ MXML_PC = @MXML_PC@ # # Install static libraries? # INSTALL_STATIC = @INSTALL_STATIC@ # # Code signing... # CODE_SIGN = @CODE_SIGN@ CODESIGN_IDENTITY = - CSFLAGS = -s "$(CODESIGN_IDENTITY)" @CSFLAGS@ --timestamp # # Library archiver... # ARFLAGS = @ARFLAGS@ # # C compiler and preprocessor... # CFLAGS = @CFLAGS@ $(CPPFLAGS) $(OPTIM) $(WARNINGS) CPPFLAGS = @CPPFLAGS@ WARNINGS = @WARNINGS@ # # Linker options... # DSOFLAGS = @DSOFLAGS@ $(OPTIM) LDFLAGS = @LDFLAGS@ $(OPTIM) LIBS = @LIBS@ -lm # # Optimization and architecture options for both the compiler and linker. # OPTIM = @OPTIM@ # # Directories... # bindir = @bindir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ exec_prefix = @exec_prefix@ includedir = @includedir@ infodir = @infodir@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ top_srcdir = @top_srcdir@ BUILDROOT = $(DSTROOT)$(DESTDIR) # # Rules... # .SILENT: .SUFFIXES: .c .man .o .c.o: echo Compiling $< $(CC) $(CFLAGS) -c -o $@ $< # # Targets... # DOCFILES = doc/mxml.epub doc/mxml.html doc/mxml-cover.png \ CHANGES.md LICENSE NOTICE README.md PUBLIBOBJS = mxml-attr.o mxml-file.o mxml-get.o mxml-index.o \ mxml-node.o mxml-options.o mxml-search.o mxml-set.o LIBOBJS = $(PUBLIBOBJS) mxml-private.o OBJS = testmxml.o $(LIBOBJS) ALLTARGETS = $(LIBMXML) testmxml CROSSTARGETS = $(LIBMXML) TARGETS = $(@TARGETS@) # # Make everything... # all: $(TARGETS) # # Clean everything... # clean: echo Cleaning build files... $(RM) $(OBJS) $(ALLTARGETS) $(RM) mxml4.dll $(RM) mxml4.lib $(RM) libmxml4.a $(RM) libmxml4.so $(RM) libmxml4.so.1 $(RM) libmxml4.1.dylib $(RM) libmxml4.dylib # # Really clean everything... # distclean: clean echo Cleaning distribution files... $(RM) config.cache config.log config.status $(RM) Makefile config.h mxml.pc $(RM) test.xmlfd $(RM) temp1.xml temp1.xmlfd temp1s.xml $(RM) temp2.xml temp2s.xml $(RM) -r autom4te*.cache $(RM) *.bck *.bak $(RM) -r clang # # Install everything... # .NOTPARALLEL: install install-$(LIBMXML) $(INSTALL_STATIC) install: $(TARGETS) install-$(LIBMXML) $(INSTALL_STATIC) echo Installing documentation in $(BUILDROOT)$(docdir)... $(INSTALL_DIR) $(BUILDROOT)$(docdir) for file in $(DOCFILES); do \ $(INSTALL_MAN) $$file $(BUILDROOT)$(docdir)/`basename $$file .md`; \ done echo Installing header files in $(BUILDROOT)$(includedir)... $(INSTALL_DIR) $(BUILDROOT)$(includedir) $(INSTALL_DATA) mxml.h $(BUILDROOT)$(includedir) echo Installing pkgconfig files in $(BUILDROOT)$(libdir)/pkgconfig... $(INSTALL_DIR) $(BUILDROOT)$(libdir)/pkgconfig $(INSTALL_DATA) mxml4.pc $(BUILDROOT)$(libdir)/pkgconfig/$(MXML_PC) echo Installing man pages in $(BUILDROOT)$(mandir)... $(INSTALL_DIR) $(BUILDROOT)$(mandir)/man3 $(INSTALL_MAN) doc/mxml.3 $(BUILDROOT)$(mandir)/man3/$(MXML_MAN) install-libmxml.a: libmxml.a echo Installing libmxml.a to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir) $(RANLIB) $(BUILDROOT)$(libdir)/libmxml.a install-libmxml.so.2: libmxml.so.2 echo Installing libmxml.so to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.so.2 $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.so $(LN) libmxml.so.2 $(BUILDROOT)$(libdir)/libmxml.so $(LDCONFIG) install-libmxml.2.dylib: libmxml.2.dylib echo Installing libmxml.dylib to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.2.dylib $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.dylib $(LN) libmxml.2.dylib $(BUILDROOT)$(libdir)/libmxml.dylib install-libmxml4.a: libmxml4.a echo Installing libmxml4.a to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml4.a $(BUILDROOT)$(libdir) $(RANLIB) $(BUILDROOT)$(libdir)/libmxml4.a install-libmxml4.so.2: libmxml4.so.2 echo Installing libmxml4.so to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml4.so.2 $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml4.so $(LN) libmxml4.so.2 $(BUILDROOT)$(libdir)/libmxml4.so $(LDCONFIG) install-libmxml4.2.dylib: libmxml4.2.dylib echo Installing libmxml4.dylib to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml4.2.dylib $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml4.dylib $(LN) libmxml4.2.dylib $(BUILDROOT)$(libdir)/libmxml4.dylib # # Uninstall everything... # uninstall: uninstall-$(LIBMXML) @UNINSTALL_STATIC@ echo Uninstalling documentation from $(BUILDROOT)$(docdir)... $(RM) -r $(BUILDROOT)$(docdir) echo Uninstalling headers from $(BUILDROOT)$(includedir)... $(RM) $(BUILDROOT)$(includedir)/mxml.h echo Uninstalling pkgconfig files from $(BUILDROOT)$(libdir)/pkgconfig... $(RM) $(BUILDROOT)$(libdir)/pkgconfig/$(MXML_PC) echo Uninstalling man pages from $(BUILDROOT)$(mandir)... $(RM) $(BUILDROOT)$(mandir)/man3/$(MXML_MAN) uninstall-libmxml.a: echo Uninstalling libmxml.a from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.a uninstall-libmxml.so.2: echo Uninstalling libmxml.so from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.so $(RM) $(BUILDROOT)$(libdir)/libmxml.so.2 $(LDCONFIG) uninstall-libmxml.2.dylib: echo Uninstalling libmxml.dylib from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.dylib $(RM) $(BUILDROOT)$(libdir)/libmxml.2.dylib uninstall-libmxml4.a: echo Uninstalling libmxml4.a from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml4.a uninstall-libmxml4.so.2: echo Uninstalling libmxml4.so from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml4.so $(RM) $(BUILDROOT)$(libdir)/libmxml4.so.2 $(LDCONFIG) uninstall-libmxml4.2.dylib: echo Uninstalling libmxml4.dylib from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml4.dylib $(RM) $(BUILDROOT)$(libdir)/libmxml4.2.dylib # # Test everything... # test: testmxml @echo Testing library... ./testmxml test.xml temp1s.xml >temp1.xml ./testmxml temp1.xml temp2s.xml >temp2.xml @if cmp temp1.xml temp2.xml; then \ echo Stdio file test passed!; \ $(RM) temp2.xml temp2s.xml; \ else \ echo Stdio file test failed!; \ exit 1; \ fi @if cmp temp1.xml temp1s.xml; then \ echo String test passed!; \ $(RM) temp1.xml temp1s.xml; \ else \ echo String test failed!; \ exit 1; \ fi @if cmp test.xml test.xmlfd; then \ echo File descriptor test passed!; \ $(RM) test.xmlfd temp1.xmlfd; \ else \ echo File descriptor test failed!; \ exit 1; \ fi # # Figure out lines-of-code... # .PHONY: sloc sloc: echo "libmxml: \c" sloccount $(LIBOBJS:.o=.c) mxml-private.c mxml.h 2>/dev/null | \ grep "Total Physical" | awk '{print $$9}' # # libmxml.a # libmxml.a libmxml4.a: $(LIBOBJS) echo Creating $@... $(RM) $@ $(AR) $(ARFLAGS) $@ $(LIBOBJS) $(RANLIB) $@ $(LIBOBJS): mxml.h mxml-private.h # # libmxml2.dll # libmxml.dll libmxml4.dll: $(LIBOBJS) echo Creating $@... $(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) # # libmxml.so.2 # libmxml.so.2 libmxml4.so.2: $(LIBOBJS) echo Creating $@... $(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) $(RM) `basename $@ .2` $(LN) $@ `basename $@ .2` # # libmxml.2.dylib # libmxml.2.dylib libmxml4.2.dylib: $(LIBOBJS) echo Creating $@... $(DSO) $(DSOFLAGS) -o $@ \ -install_name $(libdir)/`basename $@ .2.dylib`.dylib \ -current_version 2.0.0 \ -compatibility_version 2.0.0 \ $(LIBOBJS) $(LIBS) $(RM) `basename $@ .2.dylib`.dylib $(LN) $@ `basename $@ .2.dylib`.dylib # # testmxml # testmxml: $(LIBMXML_STATIC) testmxml.o echo Linking $@... $(CC) $(LDFLAGS) -o $@ testmxml.o $(LIBMXML_STATIC) $(LIBS) testmxml-vg: $(LIBOBJS) testmxml.o echo Linking $@... $(CC) $(LDFLAGS) -o $@ testmxml.o $(LIBOBJS) $(LIBS) testmxml.o: mxml.h # Fuzz-test the library <> .PHONY: afl afl: $(MAKE) -$(MAKEFLAGS) CC="afl-clang-fast" COMMONFLAGS="-g" clean all test afl-output || rm -rf afl-output afl-fuzz -x xml.dict -i afl-input -o afl-output -V 600 -e xml -t 5000 ./testmxml @@ temps.xml # # Analyze code with the Clang static analyzer # .PHONY: clang clang: clang $(CPPFLAGS) --analyze $(OBJS:.o=.c) 2>clang.log rm -rf $(OBJS:.o=.plist) test -s clang.log && (echo "$(GHA_ERROR)Clang detected issues."; echo ""; cat clang.log; exit 1) || exit 0 # # Analyze code using Cppcheck # .PHONY: cppcheck cppcheck: cppcheck $(CPPFLAGS) --template=gcc --addon=cert.py --suppressions-list=.cppcheck $(OBJS:.o=.c) 2>cppcheck.log test -s cppcheck.log && (echo "$(GHA_ERROR)Cppcheck detected issues."; echo ""; cat cppcheck.log; exit 1) || exit 0 # # Documentation (depends on separate codedoc utility) # .PHONY: doc doc: mxml.h $(PUBLIBOBJS:.o=.c) \ doc/body.md doc/body.man doc/footer.man \ doc/mxml-cover.png echo Generating API documentation... $(RM) mxml.xml codedoc --body doc/body.md \ --coverimage doc/mxml-cover.png \ mxml.xml mxml.h $(PUBLIBOBJS:.o=.c) >doc/mxml.html codedoc --body doc/body.md \ --coverimage doc/mxml-cover.png \ --epub doc/mxml.epub mxml.xml codedoc --man mxml --title "Mini-XML API" \ --body doc/body.man --footer doc/footer.man \ mxml.xml >doc/mxml.3 $(RM) mxml.xml # # All object files depend on the makefile and config header... # $(OBJS): Makefile config.h