# Copyright 2007-2022 Mitchell. See LICENSE. # Base compilers, flags, options, etc. CFLAGS := -Os CXXFLAGS := -Os -std=c++17 lua_flags := -Ilua/src ifeq (win, $(findstring win, $(MAKECMDGOALS))) # Cross-compile for Win32. CROSS := i686-w64-mingw32- CC := $(CROSS)gcc CXX := $(CROSS)g++ CFLAGS += -mms-bitfields CXXFLAGS += -mms-bitfields lua_flags += -DLUA_BUILD_AS_DLL -DLUA_LIB LDFLAGS := -static-libgcc -static-libstdc++ -Wl,--retain-symbols-file -Wl,$(shell pwd)/lua.sym WINDRES := windres gtk_flags := $(shell PKG_CONFIG_PATH=`pwd`/win32gtk/lib/pkgconfig \ pkg-config --define-variable=prefix=win32gtk --cflags gtk+-2.0) gtk_libs += $(shell PKG_CONFIG_PATH=`pwd`/win32gtk/lib/pkgconfig \ pkg-config --define-variable=prefix=win32gtk --libs gtk+-2.0 gmodule-2.0) glib_flags := $(shell PKG_CONFIG_PATH=`pwd`/win32gtk/lib/pkgconfig \ pkg-config --define-variable=prefix=win32gtk --cflags glib-2.0) curses_flags := -DLIBICONV_STATIC -Iwin32curses/include else ifeq (osx, $(findstring osx, $(MAKECMDGOALS))) # Cross-compile for macOS. CROSS := x86_64-apple-darwin17- CC := $(CROSS)cc CXX := $(CROSS)c++ CFLAGS += -mdynamic-no-pic CXXFLAGS += -mdynamic-no-pic -stdlib=libc++ -Wno-register LDLIBS := -liconv lua_flags += -DLUA_USE_MACOSX gtk_flags := $(shell PKG_CONFIG_PATH=`pwd`/gtkosx/lib/pkgconfig \ pkg-config --define-variable=prefix=gtkosx --cflags gtk+-2.0) gtk_libs := $(shell PKG_CONFIG_PATH=`pwd`/gtkosx/lib/pkgconfig \ pkg-config --define-variable=prefix=gtkosx --libs gtk+-2.0 gmodule-2.0 gtk-mac-integration) \ -framework Cocoa glib_flags := $(shell PKG_CONFIG_PATH=`pwd`/gtkosx/lib/pkgconfig \ pkg-config --define-variable=prefix=gtkosx --cflags glib-2.0) else # Build for Linux/BSD. lua_flags += -DLUA_USE_LINUX ifeq (Linux, $(shell uname -s)) CC := gcc CXX := g++ LDLIBS := -ldl MAKE := make else CC := cc CXX := c++ LDLIBS := -liconv MAKE := gmake endif LDFLAGS := -rdynamic -Wl,--retain-symbols-file -Wl,$(shell pwd)/lua.sym PREFIX ?= /usr/local bin_dir := $(PREFIX)/bin data_dir := $(PREFIX)/share/textadept XDG_DATA_DIR ?= $(PREFIX)/share/applications PIXMAPS_DIR ?= /usr/share/pixmaps desktop_files := $(wildcard *.desktop) ifndef GTK3 gtk_flags := $(shell pkg-config --cflags gtk+-2.0 gmodule-2.0) gtk_libs += $(shell pkg-config --libs gtk+-2.0 gmodule-2.0) else gtk_flags := $(shell pkg-config --cflags gtk+-3.0 gmodule-2.0) -Wno-deprecated-declarations gtk_libs += $(shell pkg-config --libs gtk+-3.0 gmodule-2.0) endif glib_flags := $(shell pkg-config --cflags glib-2.0) curses_flags := $(shell pkg-config --silence-errors --cflags ncursesw || \ pkg-config --silence-errors --cflags ncurses || pkg-config --silence-errors --cflags curses) curses_libs := $(shell pkg-config --silence-errors --libs ncursesw || \ pkg-config --silence-errors --libs ncurses || pkg-config --silence-errors --libs curses || \ echo -lncursesw) -lpthread ifeq (, $(findstring curses, $(MAKECMDGOALS))) install_targets := ../textadept else install_targets := ../textadept-curses endif endif version := $(shell grep -m 1 _RELEASE ../core/init.lua | cut -d ' ' -f4- | tr ' ' '_' | tr -d "'") WGET := wget -O $@ get-objs = $(addsuffix .o, $(basename $(notdir $(wildcard $(1))))) # Executables. exes := textadept textadept-curses textadept.exe textadept-curses.exe textadept-osx \ textadept-osx-curses .PHONY: all curses win32 osx $(exes) all: textadept textadept-curses curses: textadept-curses win32: textadept.exe textadept-curses.exe osx: textadept-osx textadept-osx-curses # Scintilla. sci_flags := -pedantic -DSCI_LEXER -DNDEBUG -Iscintilla/include -Iscintilla/src -Ilexilla/include \ -Ilexilla/lexlib -Wall sci_objs := $(call get-objs, scintilla/src/*.cxx) sci_lex_objs := $(call get-objs, lexilla/lexlib/*.cxx) sci_lexer_gtk_objs := LexLPeg.o sci_lexer_curses_objs := LexLPeg-curses.o sci_lexer_objs := $(sci_lexer_gtk_objs) $(sci_lexer_curses_objs) sci_gtk_objs := $(call get-objs, scintilla/gtk/*.cxx) sci_gtk_c_objs := $(call get-objs, scintilla/gtk/*.c) sci_curses_objs := $(call get-objs, scintilla/curses/*.cxx) # Textadept. ta_flags := -std=c99 -pedantic -Iscintilla/include -Igtdialog -Wall textadept_gtk_objs := textadept.o textadept_curses_objs := textadept-curses.o textadept_objs := $(textadept_gtk_objs) $(textadept_curses_objs) textadept_rc_objs := textadept_rc.o lua_objs := $(filter-out lua.o luac.o loslib.o, $(call get-objs, lua/src/*.c)) lua_oslib_gtk_objs := loslib.o lua_oslib_curses_objs := loslib.o-curses.o lua_oslib_objs := $(lua_oslib_gtk_objs) $(lua_oslib_curses_objs) lua_lib_objs := $(call get-objs, lua/src/lib/*.c) gtdialog_gtk_objs := gtdialog.o gtdialog_curses_objs := gtdialog-curses.o gtdialog_objs := $(gtdialog_gtk_objs) $(gtdialog_curses_objs) termkey_objs := termkey.o termkey_unix_objs := driver-ti.o driver-csi.o termkey_win_objs := driver-win32-pdcurses.o termkey_all_objs := $(termkey_objs) $(termkey_unix_objs) $(termkey_win_objs) cdk_objs := $(addprefix cdk-, $(addsuffix .o, binding buttonbox cdk cdk_display cdk_objs cdkscreen \ draw entry fselect itemlist label mentry popup_label scroll scroller select_file selection \ slider traverse version)) # Add debugging symbols and disable optimizations when DEBUG=1. # Notes: # In order to profile with gprof (-pg), do not retain symbols in LDFLAGS. # In order to report code coverage with gcov (-fprofile-arcs -ftest-coverage): # Run test suite with textadept, run gcov-9 textadept.c, then examine # textadept.c.gcov # Run test suite with textadept-curses, run gcov-9 textadept-curses.c, then # examine textadept.c.gcov. ifdef DEBUG CFLAGS += -g -O0 CXXFLAGS += -g -O0 lua_flags += -DLUA_USE_APICHECK sci_flags += -UNDEBUG -DDEBUG endif # Target-specific compiler and linker flags. $(sci_objs): CXXFLAGS += $(sci_flags) $(sci_lex_objs): CXXFLAGS += $(sci_flags) $(sci_lexer_objs): CXXFLAGS += $(sci_flags) $(lua_flags) -DNO_SCITE -DNO_DLL $(sci_lexer_gtk_objs): CXXFLAGS += -DGTK $(sci_lexer_curses_objs): CXXFLAGS += -DCURSES $(curses_flags) $(sci_gtk_objs): CXXFLAGS += $(sci_flags) -DGTK $(gtk_flags) $(sci_gtk_c_objs): CFLAGS += $(gtk_flags) $(sci_curses_objs): CXXFLAGS += $(sci_flags) -DCURSES $(curses_flags) $(textadept_objs): CFLAGS += $(lua_flags) $(ta_flags) $(textadept_gtk_objs): CFLAGS += -DGTK $(gtk_flags) $(textadept_curses_objs): CFLAGS += -DCURSES -Iscintilla/curses -Itermkey -Icdk $(curses_flags) $(lua_objs): CFLAGS += $(lua_flags) -ULUA_LIB $(lua_oslib_objs): CFLAGS += -std=c99 -pedantic $(lua_flags) -ULUA_LIB $(lua_oslib_gtk_objs): CFLAGS += -DGTK $(glib_flags) $(lua_lib_objs): CFLAGS += $(lua_flags) $(gtdialog_objs): CFLAGS += -std=c99 -pedantic -DNOHELP -DLIBRARY $(gtdialog_gtk_objs): CFLAGS += -DGTK $(gtk_flags) $(gtdialog_curses_objs): CFLAGS += -DCURSES -I. -Icdk $(curses_flags) $(cdk_objs): CFLAGS += -D_GNU_SOURCE -Itermkey -Icdk $(curses_flags) $(termkey_all_objs): CFLAGS += -std=c99 $(curses_flags) textadept textadept.exe textadept-osx: LDFLAGS += $(gtk_libs) textadept.exe: CXXFLAGS += -mwindows textadept.exe: LDLIBS = -liconv textadept-curses: LDFLAGS += $(curses_libs) textadept-curses.exe: LDLIBS = win32curses/lib/pdcurses.a win32curses/lib/libiconv.a textadept-osx-curses: LDLIBS += -lncurses # Build. define build-cxx = $(CXX) $(CXXFLAGS) -c $< -o $@ endef define build-cc = $(CC) $(CFLAGS) -c $< -o $@ endef define build-exe = $(CXX) $(CXXFLAGS) -o ../$@ $^ $(LDFLAGS) $(LDLIBS) endef $(sci_objs): %.o: scintilla/src/%.cxx ; $(build-cxx) $(sci_lex_objs): %.o: lexilla/lexlib/%.cxx ; $(build-cxx) $(sci_lexer_objs): LexLPeg.cxx ; $(build-cxx) $(sci_gtk_objs): %.o: scintilla/gtk/%.cxx ; $(build-cxx) $(sci_gtk_c_objs): %.o: scintilla/gtk/%.c ; $(build-cc) $(sci_curses_objs): %.o: scintilla/curses/%.cxx ; $(build-cxx) $(textadept_objs): textadept.c ; $(build-cc) $(lua_objs): %.o: lua/src/%.c ; $(build-cc) $(lua_oslib_objs): lua/src/loslib.c ; $(build-cc) $(lua_lib_objs): %.o: lua/src/lib/%.c ; $(build-cc) $(gtdialog_objs): gtdialog/gtdialog.c ; $(build-cc) $(cdk_objs): cdk-%.o: cdk/%.c ; $(build-cc) $(termkey_all_objs): %.o: termkey/%.c ; $(build-cc) $(textadept_rc_objs): textadept.rc ; $(CROSS)$(WINDRES) $< $@ common_objs := $(sci_objs) $(sci_lex_objs) $(lua_objs) $(lua_lib_objs) gui_objs := $(sci_lexer_gtk_objs) $(sci_gtk_objs) $(sci_gtk_c_objs) $(textadept_gtk_objs) \ $(lua_oslib_gtk_objs) $(gtdialog_gtk_objs) curses_objs := $(sci_lexer_curses_objs) $(sci_curses_objs) $(textadept_curses_objs) \ $(lua_oslib_curses_objs) $(gtdialog_curses_objs) $(termkey_objs) $(cdk_objs) $(exes): $(common_objs) ; $(build-exe) textadept textadept.exe textadept-osx: $(gui_objs) textadept.exe: $(textadept_rc_objs) textadept-curses textadept-curses.exe textadept-osx-curses: $(curses_objs) textadept-curses textadept-osx-curses: $(termkey_unix_objs) textadept-curses.exe: $(termkey_win_objs) $(textadept_rc_objs) # Install/uninstall. .PHONY: install uninstall install: $(install_targets) | ../core ../docs ../init.lua ../lexers ../LICENSE ../modules ../themes install -d $(DESTDIR)$(bin_dir) $(DESTDIR)$(data_dir) install $^ $(DESTDIR)$(data_dir) cp -rL $| $(DESTDIR)$(data_dir) ln -s $(subst .., $(data_dir), $^) $(DESTDIR)$(bin_dir) if [ -d "$(XDG_DATA_DIR)" ]; then \ install -d $(DESTDIR)$(XDG_DATA_DIR); \ install $(desktop_files) $(DESTDIR)$(XDG_DATA_DIR); \ fi if [ -d "$(PIXMAPS_DIR)" ]; then \ install -d $(DESTDIR)$(PIXMAPS_DIR); \ ln -s $(data_dir)/core/images/textadept.svg $(DESTDIR)$(PIXMAPS_DIR); \ ln -s $(data_dir)/core/images/ta_48x48.png $(DESTDIR)$(PIXMAPS_DIR)/textadept.png; \ fi uninstall: rm -r $(DESTDIR)$(bin_dir)/textadept* $(DESTDIR)$(data_dir) if [ -d "$(XDG_DATA_DIR)" ]; then rm $(DESTDIR)$(XDG_DATA_DIR)/textadept*.desktop; fi if [ -d "$(PIXMAPS_DIR)" ]; then rm $(DESTDIR)$(PIXMAPS_DIR)/textadept*; fi # Clean. .PHONY: clean clean: ; rm -f *.o ../textadept* # Documentation. ifndef ALL_MODULES modules := $(addprefix ../modules/, ansi_c lua textadept) else modules := ../modules endif ta_home := $(shell dirname `pwd`) .PHONY: docs manual luadoc docs: luadoc manual manual: ../docs/api.md $(wildcard ../docs/*.md) | ../docs/_layouts/default.html for file in $(basename $^); do cat $| | ../scripts/fill_layout.lua $$file.md > $$file.html; done sed -i "s/\(\# Textadept\).\+\?\(Manual\|API\)/\1 $(subst _, ,$(version)) \2/;" ../docs/*.md luadoc: ../core $(modules) ../lexers/lexer.lua | ../modules/lua/lua.luadoc cd ../scripts && luadoc --doclet markdowndoc $^ > ../docs/api.md cd ../modules && luadoc -d lua --doclet lua/tadoc $^ --ta-home=$(ta_home) cd ../modules/lua && mv tags ta_tags && mv api ta_api cd ../modules && luadoc -d lua --doclet lua/tadoc $| --ta-home=$(ta_home) # Releases. ifndef NIGHTLY basedir := textadept_$(version) else basedir := textadept_nightly_$(shell date +"%F") endif osxapp := Textadept.app osxapp_bin := $(osxapp)/Contents/MacOS osxapp_res := $(osxapp)/Contents/Resources osxapp_libs := libatk-1.0.0.dylib libcairo.2.dylib libexpat.1.dylib libffi.6.dylib \ libfontconfig.1.dylib libfreetype.6.dylib libgdk_pixbuf-2.0.0.dylib libgdk-quartz-2.0.0.dylib \ libgio-2.0.0.dylib libglib-2.0.0.dylib libgmodule-2.0.0.dylib libgobject-2.0.0.dylib \ libgthread-2.0.0.dylib libgtkmacintegration.2.dylib libgtk-quartz-2.0.0.dylib \ libharfbuzz.0.dylib libintl.8.dylib libpango-1.0.0.dylib libpangocairo-1.0.0.dylib \ libpangoft2-1.0.0.dylib libpixman-1.0.dylib libpng16.16.dylib charset.alias gdk-pixbuf-2.0 gtk-2.0 .PHONY: release-all release win32-release osx-release modules-release release-all: release win32-release osx-release #modules-release ifneq (, $(shell hg summary 2>/dev/null)) archive = hg archive -X ".hg*" $(1) else archive = cd ../ && git archive HEAD --prefix src/$(1)/ | tar -xf - endif modules := css ctags debugger export file_diff html lsp lua_repl open_file_mode python rest ruby \ spellcheck yaml $(basedir).linux: ; $(call archive,$@) release: $(basedir).linux $(MAKE) deps clean docs $(MAKE) -j4 CXXFLAGS="$(CXXFLAGS) -static-libstdc++" cp -rL ../docs ../lexers ../textadept ../textadept-curses $< tar czf $<.tgz $< && rm -rf $< $(basedir).win32: ; $(call archive,$@) win32-release: $(basedir).win32 $(MAKE) -j4 clean win32-deps cp win32gtk/bin/*.dll $< && cp -r win32gtk/etc win32gtk/lib win32gtk/share $< rm -r $ $@/slider.h $@/gen-scale.sh SLIDER Slider Int int $@/gen-slider.c > $@/slider.c patch -d $@ -N -p1 < $< $(termkey_tgz): ; $(WGET) http://www.leonerd.org.uk/code/libtermkey/$@ termkey: termkey.patch | $(termkey_tgz) if [ -d $@ ]; then rm -r $@; fi mkdir $@ && tar xzf $| -C $@ && mv $@/*/* $@ && chmod +w $@/termkey.h patch -d $@ -N -p1 < $< $(win32gtk_zip): ; $(WGET) $(root_url)/textadept-build/raw/default/$@ win32gtk: | $(win32gtk_zip) ; unzip $| $(win32curses_zip): ; $(WGET) $(root_url)/textadept-build/raw/default/$@ $(pdcurses_zip): ; $(WGET) http://prdownloads.sourceforge.net/pdcurses/$@ win32curses: pdcurses.patch | $(win32curses_zip) $(pdcurses_zip) unzip $(win32curses_zip) mkdir $@/src && unzip -d $@/src $(pdcurses_zip) && mv $@/src/*/* $@/src cp $@/src/curses.h $@/include patch -d $@/src -N -p1 < $< cd $@/src/wincon && $(MAKE) CC="$(CC) $(CFLAGS)" LIBEXE=$(CROSS)ar \ LINK="$(CC) $(CFLAGS)" WIDE=Y UTF8=Y libs cp $@/src/wincon/pdcurses.a $@/lib/ $(gtkosx_tgz): ; $(WGET) $(root_url)/textadept-build/raw/default/$@ gtkosx: | $(gtkosx_tgz) ; mkdir $@ && tar xzf $| -C $@ && mv $@/*/* $@ $(cloc_zip): ; $(WGET) https://github.com/AlDanial/cloc/archive/refs/tags/$@ cloc: | $(cloc_zip) ; unzip -j $| "*/$@" -x "*/Unix/$@" .PHONY: clean-deps clean-deps: rm -rf scintilla ../lexers lexilla $(LexLPeg) lua gtdialog cdk termkey win32gtk win32curses \ gtkosx $(scinterm_zip) $(scintillua_zip) $(gtdialog_zip) # Count lines of code. .PHONY: count plots sources := ../core ../modules/ansi_c ../modules/lua ../modules/textadept textadept.c Makefile \ ../init.lua count: cloc ; perl $< $(sources) --not-match-f=tadoc.lua --exclude-lang=SVG plots: ; ../scripts/gen_plots.sh