diff --git a/.cirrus.yml b/.cirrus.yml index eb3271ada..b2aab9f2f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,6 @@ freebsd_task: freebsd_instance: image_family: freebsd-13-2 - gmake_script: pkg install -y gmake matrix: - name: freebsd_clang env: @@ -10,7 +9,7 @@ freebsd_task: gcc_script: pkg install -y gcc env: CXX: g++ - test_script: gmake -j4 test + test_script: make CXX=$CXX -j$(sysctl -n hw.ncpu) test env: LC_ALL: en_US.UTF-8 @@ -28,7 +27,9 @@ linux_task: - name: linux_gcc container: image: gcc:10 - test_script: make -j4 test + env: + CXX: g++ + test_script: make CXX=$CXX -j$(nproc) test env: LC_ALL: en_US.UTF-8 @@ -47,4 +48,4 @@ macos_task: - arch -x86_64 /usr/local/bin/brew install gcc@10 env: CXX: g++-10 - test_script: make -j4 test + test_script: make CXX=$CXX -j$(sysctl -n hw.ncpu) test diff --git a/.github/workflows/build-releases-linux.yaml b/.github/workflows/build-releases-linux.yaml index 9271133a9..7f9ab34d9 100644 --- a/.github/workflows/build-releases-linux.yaml +++ b/.github/workflows/build-releases-linux.yaml @@ -19,9 +19,7 @@ jobs: - name: Build run: | mkdir -p kakoune-${{ github.event.release.tag_name }}-linux/ - make -C src all static=yes - make -C src install PREFIX=$(pwd)/kakoune-${{ github.event.release.tag_name }}-linux/ - strip -s kakoune-${{ github.event.release.tag_name }}-linux/bin/kak + make -j$(nproc) PREFIX=$(pwd)/kakoune-${{ github.event.release.tag_name }}-linux static=yes install strip tar cvjf kakoune-${{ github.event.release.tag_name }}-linux.tar.bz2 kakoune-${{ github.event.release.tag_name }}-linux/ - name: Upload uses: softprops/action-gh-release@v1 diff --git a/.gitignore b/.gitignore index 0c890a3af..26769f06a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ *.o -.*.d +*.d *.pyc *.1-r .*.kak.* +*.tar* src/kak src/kak.debug src/kak.debug.san_* diff --git a/Makefile b/Makefile index 3c4388bd1..37501679c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,216 @@ -all: - $(MAKE) -C src $@ +.POSIX: +.SUFFIXES: +.SUFFIXES: .o .cc -%: FORCE - $(MAKE) -C src $@ +CXX = c++ -.PHONY: all FORCE +debug = no +static = no +gzip_man = yes +# to get format compatible with GitHub archive use "gzip -S .gz" here +compress_bin = bzip + +compress-suffix-bzip = bz2 +compress-suffix-zstd = zst + +CPPFLAGS-debug-yes = -DKAK_DEBUG +CXXFLAGS-debug-yes = -O0 -g +suffix-debug-yes = .debug + +CXXFLAGS-debug-no = -O3 +suffix-debug-no = .opt + +CXXFLAGS-sanitize-address = -fsanitize=address +LDFLAGS-sanitize-address = -lasan +suffix-sanitize-address = .san_a + +CXXFLAGS-sanitize-undefined = -fsanitize=undefined + +LDFLAGS-sanitize-undefined = -lubsan +suffix-sanitize-undefined = .san_u + +LDFLAGS-static-yes = -static -pthread + +version != cat .version 2>/dev/null || git describe --tags HEAD 2>/dev/null || echo unknown + +sources != find src -type f -name '*.cc' | sed -e '/\.version\.cc/d' +deps != find src -type f -name '*.d' +objects = $(sources:.cc=.o) + +PREFIX = /usr/local +DESTDIR = # root dir + +bindir = $(DESTDIR)$(PREFIX)/bin +libexecdir = $(DESTDIR)$(PREFIX)/libexec/kak +sharedir = $(DESTDIR)$(PREFIX)/share/kak +docdir = $(DESTDIR)$(PREFIX)/share/doc/kak +mandir = $(DESTDIR)$(PREFIX)/share/man/man1 + +# Both Cygwin and MSYS2 have "_NT" in their uname. +os != uname | sed 's/.*_NT.*/Windows/' + +CPPFLAGS-os-Darwin = -I/opt/local/include +LDFLAGS-os-Darwin = -L/opt/local/lib + +CPPFLAGS-os-FreeBSD = -I/usr/local/include +LDFLAGS-os-FreeBSD = -L/usr/local/lib + +LIBS-os-Haiku = -lnetwork -lbe + +CPPFLAGS-os-OpenBSD = -DKAK_BIN_PATH="$(bindir)/kak" -I/usr/local/include +LDFLAGS-os-OpenBSD = -L/usr/local/lib +mandir-os-OpenBSD = $(DESTDIR)$(PREFIX)/man/man1 + +LDFLAGS-os-SunOS = -lsocket -rdynamic + +CPPFLAGS-os-Windows = -D_XOPEN_SOURCE=700 +LIBS-os-Windows = -ldbghelp + +CXXFLAGS-default = -std=c++2a -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-sign-compare + +compiler != $(CXX) --version | grep -E -o 'clang|g\+\+' | head -1 +#CXXFLAGS-compiler-clang = -frelaxed-template-template-args -Wno-ambiguous-reversed-operator +#CXXFLAGS-compiler-g++ = -Wno-init-list-lifetime +CXXFLAGS-compiler-clang = +CXXFLAGS-compiler-g++ = -Wno-init-list-lifetime -Wno-stringop-overflow + +KAK_CPPFLAGS = \ + $(CPPFLAGS-default) \ + $(CPPFLAGS-debug-$(debug)) \ + $(CPPFLAGS-os-$(os)) \ + $(CPPFLAGS) + +KAK_CXXFLAGS = \ + $(CXXFLAGS-default) \ + $(CXXFLAGS-debug-$(debug)) \ + $(CXXFLAGS-sanitize-$(sanitize)) \ + $(CXXFLAGS-compiler-$(compiler)) \ + $(CXXFLAGS) + +KAK_LDFLAGS = \ + $(LDFLAGS-default) \ + $(LDFLAGS-sanitize-$(sanitize)) \ + $(LDFLAGS-static-$(static)) \ + $(LDFLAGS-os-$(os)) \ + $(LDFLAGS) + +KAK_LIBS = \ + $(LIBS-os-$(os)) \ + $(LIBS) + +suffix = $(suffix-debug-$(debug))$(suffix-sanitize-$(sanitize)) + +all: src/kak + +src/kak: src/kak$(suffix) + ln -sf kak$(suffix) $@ + +src/kak$(suffix): src/.version.o $(objects) + $(CXX) $(KAK_LDFLAGS) $(KAK_CXXFLAGS) $(KAK_LIBS) $(objects) src/.version.o -o $@ + +include $(deps) + +.cc.o: + $(CXX) $(KAK_CPPFLAGS) $(KAK_CXXFLAGS) -MD -MP -MF $*.d -c -o $@ $< + +src/.version.cc: + echo 'namespace Kakoune { const char *version = "$(version)"; }' > $@ + +src/.version.o: src/.version.cc + $(CXX) $(KAK_CPPFLAGS) $(KAK_CXXFLAGS) -c -o $@ $< + +# Generate the man page +man: gzip-man-$(gzip_man) + +gzip-man-yes: doc/kak.1.gz +gzip-man-no: doc/kak.1 + +doc/kak.1.gz: doc/kak.1 + gzip -n -9 -f < $< > $@ + +check: test +test: src/kak + cd test && ./run + +TAGS: tags +tags: + ctags -R + +clean: + rm -f $(objects) $(deps) src/.version* + +dist: kakoune-$(version).tar.zst + +kakoune-$(version).tar.$(compress-suffix-$(compress_bin)): kakoune-$(version).tar + $(compress_bin) -f $< -o $@ + +kakoune-$(version).tar: + @if ! [ -d .git ]; then echo "make dist can only run from a git repo"; false; fi + @if git status -s | grep -qEv '^\?\?'; then echo "working tree is not clean"; false; fi + git archive --format=tar --prefix=$(@:.tar=)/ HEAD -o $@ + echo "$(version)" > src/.version + tar --transform "s,^,$(@:.tar=)/," -rf $@ src/.version + rm -f src/.version + +distclean: clean + rm -f src/kak src/kak$(suffix) + find doc -type f -name '*.gz' -exec rm -f '{}' + + +installdirs: installdirs-debug-$(debug) + +installdirs-debug-no: + mkdir -p \ + $(bindir) \ + $(libexecdir) \ + $(sharedir)/rc \ + $(sharedir)/colors \ + $(sharedir)/doc \ + $(docdir) \ + $(mandir) + +installdirs-debug-yes: installdirs-debug-no + mkdir -p $(sharedir)/gdb + +install: src/kak installdirs install-debug-$(debug) install-gzip-man-$(gzip_man) + cp src/kak$(suffix) $(bindir) + chmod 0755 $(bindir)/kak + + ln -sf ../../bin/kak $(libexecdir)/kak + + cp src/kak/kakrc $(sharedir) + chmod 0644 $(sharedir)/kakrc + + cp -r rc/* $(sharedir)/rc + find $(sharedir)/rc -type f -exec chmod 0644 {} + + [ -e $(sharedir)/autoload ] || ln -s rc $(sharedir)/autoload + + cp colors/* $(sharedir)/colors + chmod 0644 $(sharedir)/colors/* + + cp doc/pages/*.asciidoc README.asciidoc $(docdir) + chmod 0644 $(docdir)/*.asciidoc + +install-gzip-man-yes: gzip-man-yes + cp -f doc/kak.1.gz $(mandir) + chmod 0644 $(mandir)/kak.1.gz + +install-gzip-man-no: gzip-man-no + cp -f doc/kak.1 $(mandir) + chmod 0644 $(mandir)/kak.1 + +install-debug-yes: installdirs-debug-yes + cp -f gdb/kakoune.py $(sharedir)/gdb + chmod 0644 $(sharedir)/gdb/kakoune.py + +install-debug-no: installdirs-debug-no + +install-strip: install + strip -s $(bindir)/kak + +uninstall: + rm -rf \ + $(bindir)/kak \ + $(libexecdir) \ + $(sharedir) \ + $(docdir) \ + $(mandir)/kak.* diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index bb0f32e6e..000000000 --- a/src/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -debug ?= no -static ?= no -gzip_man ?= yes -# to get format compatible with GitHub archive use "gzip -S .gz" here -compress_bin ?= bzip2 - -ifneq ($(gzip_man),yes) - ifneq ($(gzip_man),no) - $(error gzip_man should be either yes or no) - endif -endif - -ifeq ($(debug),yes) - CPPFLAGS += -DKAK_DEBUG - CXXFLAGS += -O0 - suffix := .debug -else - ifeq ($(debug),no) - CXXFLAGS += -O3 - suffix := .opt - else - $(error debug should be either yes or no) - endif -endif - -ifneq (,$(findstring address,$(sanitize))) - CXXFLAGS += -fsanitize=address - LDFLAGS += -lasan - sanitize_suffix := $(sanitize_suffix)a -endif -ifneq (,$(findstring undefined,$(sanitize))) - CXXFLAGS += -fsanitize=undefined - LDFLAGS += -lubsan - sanitize_suffix := $(sanitize_suffix)u -endif - -ifneq (,$(sanitize_suffix)) - suffix := $(suffix).san_$(sanitize_suffix) -endif - -version ?= $(shell if [ -f .version ]; then cat .version; elif [ -d ../.git ]; then git describe --tags HEAD; else echo "unknown"; fi) - -sources := $(sort $(wildcard *.cc)) -objects := $(addprefix ., $(sources:.cc=$(suffix).o)) -deps := $(addprefix ., $(sources:.cc=$(suffix).d)) - -ifeq ($(static),yes) - LDFLAGS += -static -pthread -endif - -PREFIX ?= /usr/local -DESTDIR ?= # root dir - -bindir := $(DESTDIR)$(PREFIX)/bin -libexecdir := $(DESTDIR)$(PREFIX)/libexec/kak -sharedir := $(DESTDIR)$(PREFIX)/share/kak -docdir := $(DESTDIR)$(PREFIX)/share/doc/kak -mandir := $(DESTDIR)$(PREFIX)/share/man/man1 - -os := $(shell uname) - -ifeq ($(os),Darwin) - CPPFLAGS += -I/opt/local/include - LDFLAGS += -L/opt/local/lib -else ifeq ($(os),FreeBSD) - CPPFLAGS += -I/usr/local/include - LDFLAGS += -L/usr/local/lib -else ifeq ($(os),Haiku) - LIBS += -lnetwork -lbe -else ifeq ($(os),OpenBSD) - CPPFLAGS += -D'KAK_BIN_PATH="$(bindir)/kak"' -I/usr/local/include - LDFLAGS += -L/usr/local/lib - mandir := $(DESTDIR)$(PREFIX)/man/man1 -else ifneq (,$(findstring _NT,$(os))) - # Both Cygwin and MSYS2 have "_NT" in their uname. - CPPFLAGS += -D_XOPEN_SOURCE=700 - LIBS += -ldbghelp -else ifeq ($(os),SunOS) - LDFLAGS += -lsocket -rdynamic -else - LDFLAGS += -rdynamic -endif - -CXXFLAGS += -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address - -compiler := $(shell $(CXX) --version) -ifneq (,$(findstring clang,$(compiler))) - CXXFLAGS += -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -else ifneq (,$(findstring g++,$(compiler))) - CXXFLAGS += -Wno-init-list-lifetime -Wno-stringop-overflow -endif - -all : kak - -kak : kak$(suffix) - ln -sf $< $@ - -kak$(suffix) : $(objects) .version.o - $(CXX) $(LDFLAGS) $(CXXFLAGS) $(objects) .version.o $(LIBS) -o $@ - --include $(deps) - -.%$(suffix).o: %.cc - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -MP -MF $(addprefix ., $(<:.cc=$(suffix).d)) -c -o $@ $< - -.version.o: .version.cc - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< - -.version.cc: FORCE - @printf "%s" 'namespace Kakoune { const char* version = "$(version)"; }' > .version.cc.tmp - @if cmp -s .version.cc.tmp .version.cc; then rm .version.cc.tmp; else mv .version.cc.tmp .version.cc; fi - -# Generate the man page -ifeq ($(gzip_man),yes) -../doc/kak.1.gz: ../doc/kak.1 - gzip -n -9 -f < $< > $@ -man: ../doc/kak.1.gz -else -man: ../doc/kak.1 -endif - -check: test -test: kak - cd ../test && ./run - -TAGS: tags -tags: - ctags -R - -clean: - rm -f $(objects) $(deps) .version.cc .version.o - -dist: - @if ! [ -d ../.git ]; then echo "make dist can only run from a git repo"; false; fi - @if git status -s | grep -qEv '^\?\?'; then echo "working tree is not clean"; false; fi - cd ../; \ - basename="kakoune-$$(echo "$(version)" | sed -e s/^v//)"; \ - git archive --format=tar --prefix=$${basename}/ HEAD -o $${basename}.tar; \ - echo "$(version)" > src/.version; \ - tar --transform "s,^,$${basename}/," -rf $${basename}.tar src/.version; \ - rm src/.version; \ - $(compress_bin) $${basename}.tar; - -distclean: clean - rm -f kak kak$(suffix) - find ../doc -type f \( -name \*\\.gz -o -name \*\\.1 \) -exec rm -f '{}' + - -installdirs: - install -d $(bindir) \ - $(libexecdir) \ - $(sharedir)/rc \ - $(sharedir)/colors \ - $(sharedir)/doc \ - $(docdir) \ - $(mandir) -ifeq ($(debug),yes) - install -d $(sharedir)/gdb -endif - -install: kak man installdirs - install -m 0755 kak $(bindir) - ln -sf ../../bin/kak $(libexecdir)/kak - install -m 0644 ../share/kak/kakrc $(sharedir) - install -m 0644 ../doc/pages/*.asciidoc $(sharedir)/doc - cp -r ../rc/* $(sharedir)/rc - find $(sharedir)/rc -type f -exec chmod 0644 {} + - [ -e $(sharedir)/autoload ] || ln -s rc $(sharedir)/autoload - install -m 0644 ../colors/* $(sharedir)/colors - install -m 0644 ../README.asciidoc $(docdir) -ifeq ($(gzip_man),yes) - install -m 0644 ../doc/kak.1.gz $(mandir) -else - install -m 0644 ../doc/kak.1 $(mandir) -endif -ifeq ($(debug),yes) - install -m 0644 ../gdb/kakoune.py $(sharedir)/gdb -endif - -install-strip: install - strip -s $(bindir)/kak - -uninstall: - rm -rf $(bindir)/kak \ - $(libexecdir) \ - $(sharedir) \ - $(docdir) \ - $(mandir)/kak.1.gz \ - $(mandir)/kak.1 - -.PHONY: check TAGS clean dist distclean installdirs install install-strip uninstall -.PHONY: tags test man kak FORCE