2009-07-28 15:26:36 -04:00
|
|
|
TOPDIR=$(shell pwd)
|
2009-02-09 14:51:52 -05:00
|
|
|
|
2009-07-28 15:26:36 -04:00
|
|
|
include $(TOPDIR)/common.mk
|
2009-03-15 18:15:16 -04:00
|
|
|
|
|
|
|
# Depend on the object files of all source-files in src/*.c and on all header files
|
2012-01-27 17:11:03 -05:00
|
|
|
AUTOGENERATED:=src/cfgparse.tab.c src/cfgparse.yy.c
|
2011-07-11 13:30:26 -04:00
|
|
|
FILES:=$(filter-out $(AUTOGENERATED),$(wildcard src/*.c))
|
2009-09-13 08:16:39 -04:00
|
|
|
FILES:=$(FILES:.c=.o)
|
2009-12-19 16:33:50 -05:00
|
|
|
HEADERS:=$(filter-out include/loglevels.h,$(wildcard include/*.h))
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 14:53:29 -05:00
|
|
|
CMDPARSE_HEADERS:=include/GENERATED_call.h include/GENERATED_enums.h include/GENERATED_tokens.h
|
2009-02-08 05:25:32 -05:00
|
|
|
|
2009-12-22 06:14:09 -05:00
|
|
|
# Recursively generate loglevels.h by explicitly calling make
|
|
|
|
# We need this step because we need to ensure that loglevels.h will be
|
|
|
|
# updated if necessary, but we also want to save rebuilds of the object
|
|
|
|
# files, so we cannot let the object files depend on loglevels.h.
|
|
|
|
ifeq ($(MAKECMDGOALS),loglevels.h)
|
2010-03-27 10:25:51 -04:00
|
|
|
#UNUSED:=$(warning Generating loglevels.h)
|
2009-12-22 06:14:09 -05:00
|
|
|
else
|
|
|
|
UNUSED:=$(shell $(MAKE) loglevels.h)
|
|
|
|
endif
|
|
|
|
|
2011-12-10 06:27:40 -05:00
|
|
|
SUBDIRS:=i3-msg i3-input i3-nagbar i3-config-wizard i3bar i3-dump-log
|
2011-07-24 18:31:35 -04:00
|
|
|
|
2009-03-15 18:15:16 -04:00
|
|
|
# Depend on the specific file (.c for each .o) and on all headers
|
2009-12-22 06:14:09 -05:00
|
|
|
src/%.o: src/%.c ${HEADERS}
|
2011-10-02 11:04:18 -04:00
|
|
|
echo "[i3] CC $<"
|
2011-07-13 07:22:15 -04:00
|
|
|
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -c -o $@ $<
|
2009-02-08 05:25:32 -05:00
|
|
|
|
2011-07-24 18:31:35 -04:00
|
|
|
all: i3 subdirs
|
|
|
|
|
2012-01-27 17:11:03 -05:00
|
|
|
i3: libi3/libi3.a src/cfgparse.y.o src/cfgparse.yy.o ${FILES}
|
2011-10-02 11:11:30 -04:00
|
|
|
echo "[i3] LINK i3"
|
|
|
|
$(CC) $(LDFLAGS) -o $@ $(filter-out libi3/libi3.a,$^) $(LIBS)
|
|
|
|
|
2011-10-23 08:16:39 -04:00
|
|
|
libi3/%.a: libi3/*.c
|
2011-10-02 11:11:30 -04:00
|
|
|
$(MAKE) -C libi3
|
2011-07-24 18:31:35 -04:00
|
|
|
|
|
|
|
subdirs:
|
|
|
|
for dir in $(SUBDIRS); do \
|
|
|
|
echo ""; \
|
|
|
|
echo "MAKE $$dir"; \
|
|
|
|
$(MAKE) -C $$dir; \
|
|
|
|
done
|
2009-02-08 05:25:32 -05:00
|
|
|
|
2009-12-22 06:14:09 -05:00
|
|
|
loglevels.h:
|
2011-10-02 11:04:18 -04:00
|
|
|
echo "[i3] LOGLEVELS"
|
2009-12-19 16:33:50 -05:00
|
|
|
for file in $$(ls src/*.c src/*.y src/*.l | grep -v 'cfgparse.\(tab\|yy\).c'); \
|
|
|
|
do \
|
|
|
|
echo $$(basename $$file .c); \
|
|
|
|
done > loglevels.tmp
|
|
|
|
(echo "char *loglevels[] = {"; for file in $$(cat loglevels.tmp); \
|
|
|
|
do \
|
2009-12-20 17:43:49 -05:00
|
|
|
echo "\"$$file\", "; \
|
2009-12-19 16:33:50 -05:00
|
|
|
done; \
|
2009-12-22 06:14:09 -05:00
|
|
|
echo "};") > include/loglevels.h;
|
2009-12-19 16:33:50 -05:00
|
|
|
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 14:53:29 -05:00
|
|
|
# The GENERATED_* files are actually all created from a single pass, so all
|
|
|
|
# files just depend on the first one.
|
|
|
|
include/GENERATED_call.h: generate-command-parser.pl parser-specs/commands.spec
|
|
|
|
echo "[i3] Generating command parser"
|
|
|
|
(cd include; ../generate-command-parser.pl)
|
|
|
|
include/GENERATED_enums.h: include/GENERATED_call.h
|
|
|
|
include/GENERATED_tokens.h: include/GENERATED_call.h
|
|
|
|
|
|
|
|
# This target compiles the command parser twice:
|
|
|
|
# Once with -DTEST_PARSER, creating a stand-alone executable used for tests,
|
|
|
|
# and once as an object file for i3.
|
|
|
|
src/commands_parser.o: src/commands_parser.c ${HEADERS} ${CMDPARSE_HEADERS}
|
|
|
|
echo "[i3] CC $<"
|
|
|
|
$(CC) $(CPPFLAGS) $(CFLAGS) -DTEST_PARSER -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -o test.commands_parser $<
|
|
|
|
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="((uint64_t)1 << $(shell awk '/$(shell basename $< .c)/ { print NR; exit 0; }' loglevels.tmp))" -c -o $@ $<
|
|
|
|
|
2010-03-02 06:56:45 -05:00
|
|
|
src/cfgparse.yy.o: src/cfgparse.l src/cfgparse.y.o ${HEADERS}
|
2011-10-02 11:04:18 -04:00
|
|
|
echo "[i3] LEX $<"
|
2011-11-21 19:01:01 -05:00
|
|
|
$(FLEX) -i -o$(@:.o=.c) $<
|
2011-07-13 07:22:15 -04:00
|
|
|
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="(1 << $(shell awk '/cfgparse.l/ { print NR }' loglevels.tmp))" -c -o $@ $(@:.o=.c)
|
2009-09-13 08:16:39 -04:00
|
|
|
|
2010-04-14 14:26:56 -04:00
|
|
|
|
2010-02-13 13:27:28 -05:00
|
|
|
src/cfgparse.y.o: src/cfgparse.y ${HEADERS}
|
2011-10-02 11:04:18 -04:00
|
|
|
echo "[i3] YACC $<"
|
2011-11-21 19:01:01 -05:00
|
|
|
$(BISON) --debug --verbose -b $(basename $< .y) -d $<
|
2011-07-13 07:22:15 -04:00
|
|
|
$(CC) $(CPPFLAGS) $(CFLAGS) -DLOGLEVEL="(1 << $(shell awk '/cfgparse.y/ { print NR }' loglevels.tmp))" -c -o $@ $(<:.y=.tab.c)
|
2009-09-13 08:16:39 -04:00
|
|
|
|
2010-04-14 14:26:56 -04:00
|
|
|
|
2009-02-22 11:41:30 -05:00
|
|
|
install: all
|
2011-10-02 11:04:18 -04:00
|
|
|
echo "[i3] INSTALL"
|
2010-03-15 19:08:54 -04:00
|
|
|
$(INSTALL) -d -m 0755 $(DESTDIR)$(PREFIX)/bin
|
|
|
|
$(INSTALL) -d -m 0755 $(DESTDIR)$(SYSCONFDIR)/i3
|
|
|
|
$(INSTALL) -d -m 0755 $(DESTDIR)$(PREFIX)/include/i3
|
|
|
|
$(INSTALL) -d -m 0755 $(DESTDIR)$(PREFIX)/share/xsessions
|
2012-01-26 05:26:17 -05:00
|
|
|
$(INSTALL) -d -m 0755 $(DESTDIR)$(PREFIX)/share/applications
|
2010-03-15 19:08:54 -04:00
|
|
|
$(INSTALL) -m 0755 i3 $(DESTDIR)$(PREFIX)/bin/
|
2011-07-31 17:11:05 -04:00
|
|
|
$(INSTALL) -m 0755 i3-migrate-config-to-v4 $(DESTDIR)$(PREFIX)/bin/
|
2011-09-25 13:45:51 -04:00
|
|
|
$(INSTALL) -m 0755 i3-sensible-editor $(DESTDIR)$(PREFIX)/bin/
|
|
|
|
$(INSTALL) -m 0755 i3-sensible-pager $(DESTDIR)$(PREFIX)/bin/
|
|
|
|
$(INSTALL) -m 0755 i3-sensible-terminal $(DESTDIR)$(PREFIX)/bin/
|
2010-03-15 19:08:54 -04:00
|
|
|
test -e $(DESTDIR)$(SYSCONFDIR)/i3/config || $(INSTALL) -m 0644 i3.config $(DESTDIR)$(SYSCONFDIR)/i3/config
|
2011-07-11 13:24:04 -04:00
|
|
|
test -e $(DESTDIR)$(SYSCONFDIR)/i3/config.keycodes || $(INSTALL) -m 0644 i3.config.keycodes $(DESTDIR)$(SYSCONFDIR)/i3/config.keycodes
|
2010-03-15 19:08:54 -04:00
|
|
|
$(INSTALL) -m 0644 i3.welcome $(DESTDIR)$(SYSCONFDIR)/i3/welcome
|
2012-01-26 05:26:17 -05:00
|
|
|
$(INSTALL) -m 0644 i3.xsession.desktop $(DESTDIR)$(PREFIX)/share/xsessions/i3.desktop
|
|
|
|
$(INSTALL) -m 0644 i3.applications.desktop $(DESTDIR)$(PREFIX)/share/applications/i3.desktop
|
2010-03-15 19:08:54 -04:00
|
|
|
$(INSTALL) -m 0644 include/i3/ipc.h $(DESTDIR)$(PREFIX)/include/i3/
|
2011-07-24 18:31:35 -04:00
|
|
|
for dir in $(SUBDIRS); do \
|
|
|
|
$(MAKE) -C $$dir install; \
|
|
|
|
done
|
2009-02-22 11:41:30 -05:00
|
|
|
|
2009-08-19 08:37:46 -04:00
|
|
|
dist: distclean
|
2009-05-03 11:16:12 -04:00
|
|
|
[ ! -d i3-${VERSION} ] || rm -rf i3-${VERSION}
|
2009-03-15 18:15:16 -04:00
|
|
|
[ ! -e i3-${VERSION}.tar.bz2 ] || rm i3-${VERSION}.tar.bz2
|
|
|
|
mkdir i3-${VERSION}
|
2012-01-26 05:26:17 -05:00
|
|
|
cp i3-migrate-config-to-v4 generate-command-parser.pl i3-sensible-* i3.config.keycodes DEPENDS GOALS LICENSE PACKAGE-MAINTAINER RELEASE-NOTES-${VERSION} i3.config i3.xsession.desktop i3.applications.desktop i3.welcome pseudo-doc.doxygen i3-wsbar Makefile i3-${VERSION}
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 14:53:29 -05:00
|
|
|
cp -r src libi3 i3-msg i3-nagbar i3-config-wizard i3bar i3-dump-log yajl-fallback include man parser-specs i3-${VERSION}
|
2009-05-03 11:16:12 -04:00
|
|
|
# Only copy toplevel documentation (important stuff)
|
|
|
|
mkdir i3-${VERSION}/docs
|
2010-03-30 07:20:04 -04:00
|
|
|
# Pre-generate documentation
|
2011-10-09 18:30:08 -04:00
|
|
|
$(MAKE) -C docs
|
|
|
|
$(MAKE) -C i3bar/doc
|
2011-07-31 16:18:48 -04:00
|
|
|
# Cleanup τεχ output files
|
|
|
|
find docs -regex ".*\.\(aux\|out\|log\|toc\|bm\|dvi\|log\)" -exec rm '{}' \;
|
2010-03-30 07:25:25 -04:00
|
|
|
find docs -maxdepth 1 -type f ! \( -name "*.xcf" -or -name "*.svg" \) -exec cp '{}' i3-${VERSION}/docs \;
|
2009-11-09 15:28:29 -05:00
|
|
|
# Only copy source code from i3-input
|
|
|
|
mkdir i3-${VERSION}/i3-input
|
|
|
|
find i3-input -maxdepth 1 -type f \( -name "*.c" -or -name "*.h" -or -name "Makefile" \) -exec cp '{}' i3-${VERSION}/i3-input \;
|
2011-10-23 06:31:55 -04:00
|
|
|
sed -e 's/^GIT_VERSION:=\(.*\)/GIT_VERSION:=$(shell /bin/echo '${GIT_VERSION}' | sed 's/\\/\\\\/g')/g;s/^VERSION:=\(.*\)/VERSION:=${VERSION}/g' common.mk > i3-${VERSION}/common.mk
|
2009-08-19 08:37:46 -04:00
|
|
|
# Pre-generate a manpage to allow distributors to skip this step and save some dependencies
|
2011-07-13 07:29:39 -04:00
|
|
|
$(MAKE) -C man
|
2009-11-09 15:28:29 -05:00
|
|
|
cp man/*.1 i3-${VERSION}/man/
|
2011-08-01 17:27:50 -04:00
|
|
|
cp i3bar/doc/*.1 i3-${VERSION}/i3bar/doc/
|
2009-11-09 15:28:29 -05:00
|
|
|
tar cfj i3-${VERSION}.tar.bz2 i3-${VERSION}
|
2009-03-15 18:15:16 -04:00
|
|
|
rm -rf i3-${VERSION}
|
|
|
|
|
2009-02-08 05:25:32 -05:00
|
|
|
clean:
|
2012-01-27 17:11:03 -05:00
|
|
|
rm -f src/*.o src/*.gcno src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} loglevels.tmp include/loglevels.h include/GENERATED_*
|
2011-08-01 11:12:04 -04:00
|
|
|
(which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true
|
2011-10-02 11:11:30 -04:00
|
|
|
$(MAKE) -C libi3 clean
|
2009-03-15 18:15:16 -04:00
|
|
|
$(MAKE) -C docs clean
|
|
|
|
$(MAKE) -C man clean
|
2011-07-31 17:01:16 -04:00
|
|
|
for dir in $(SUBDIRS); do \
|
|
|
|
echo ""; \
|
|
|
|
echo "CLEAN $$dir"; \
|
|
|
|
$(MAKE) TOPDIR=$(TOPDIR) -C $$dir distclean; \
|
|
|
|
done
|
2009-02-13 13:09:25 -05:00
|
|
|
|
|
|
|
distclean: clean
|
|
|
|
rm -f i3
|
2011-07-31 17:01:16 -04:00
|
|
|
for dir in $(SUBDIRS); do \
|
|
|
|
echo ""; \
|
|
|
|
echo "DISTCLEAN $$dir"; \
|
|
|
|
$(MAKE) TOPDIR=$(TOPDIR) -C $$dir distclean; \
|
|
|
|
done
|
2011-05-08 14:08:46 -04:00
|
|
|
|
|
|
|
coverage:
|
|
|
|
rm -f /tmp/i3-coverage.info
|
|
|
|
rm -rf /tmp/i3-coverage
|
|
|
|
lcov -d . -b . --capture -o /tmp/i3-coverage.info
|
|
|
|
genhtml -o /tmp/i3-coverage/ /tmp/i3-coverage.info
|