Introduce libi3, an *internal* library to eliminate code duplication

This commit is contained in:
Michael Stapelberg 2011-10-02 16:11:30 +01:00
parent 4f6e58e250
commit 094c26556e
5 changed files with 109 additions and 3 deletions

View File

@ -27,9 +27,12 @@ src/%.o: src/%.c ${HEADERS}
all: i3 subdirs all: i3 subdirs
i3: src/cfgparse.y.o src/cfgparse.yy.o src/cmdparse.y.o src/cmdparse.yy.o ${FILES} i3: libi3/libi3.a src/cfgparse.y.o src/cfgparse.yy.o src/cmdparse.y.o src/cmdparse.yy.o ${FILES}
echo "LINK i3" echo "[i3] LINK i3"
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(CC) $(LDFLAGS) -o $@ $(filter-out libi3/libi3.a,$^) $(LIBS)
libi3/%.a:
$(MAKE) -C libi3
subdirs: subdirs:
for dir in $(SUBDIRS); do \ for dir in $(SUBDIRS); do \
@ -120,6 +123,7 @@ dist: distclean
clean: clean:
rm -f src/*.o src/*.gcno src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} src/cmdparse.tab.{c,h} src/cmdparse.yy.c src/cmdparse.{output,dot} loglevels.tmp include/loglevels.h rm -f src/*.o src/*.gcno src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} src/cmdparse.tab.{c,h} src/cmdparse.yy.c src/cmdparse.{output,dot} loglevels.tmp include/loglevels.h
(which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true (which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true
$(MAKE) -C libi3 clean
$(MAKE) -C docs clean $(MAKE) -C docs clean
$(MAKE) -C man clean $(MAKE) -C man clean
for dir in $(SUBDIRS); do \ for dir in $(SUBDIRS); do \

View File

@ -58,6 +58,7 @@ CPPFLAGS += -DPCRE_HAS_UCP=1
endif endif
LIBS += -lm LIBS += -lm
LIBS += -L $(TOPDIR)/libi3 -li3
LIBS += $(call ldflags_for_lib, xcb-event, xcb-event) LIBS += $(call ldflags_for_lib, xcb-event, xcb-event)
LIBS += $(call ldflags_for_lib, xcb-keysyms, xcb-keysyms) LIBS += $(call ldflags_for_lib, xcb-keysyms, xcb-keysyms)
ifeq ($(shell pkg-config --exists xcb-util || echo 1),1) ifeq ($(shell pkg-config --exists xcb-util || echo 1),1)

26
libi3/Makefile Normal file
View File

@ -0,0 +1,26 @@
# Default value so one can compile i3-msg standalone
TOPDIR=..
include $(TOPDIR)/common.mk
CFLAGS += -I$(TOPDIR)/include
# Depend on the object files of all source-files in src/*.c and on all header files
FILES=$(patsubst %.c,%.o,$(wildcard *.c))
HEADERS=$(wildcard *.h)
# Depend on the specific file (.c for each .o) and on all headers
%.o: %.c ${HEADERS}
echo "[libi3] CC $<"
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
all: libi3.a
libi3.a: ${FILES}
echo "[libi3] AR libi3.a"
ar rcs libi3.a ${FILES}
clean:
rm -f *.o libi3.a
distclean: clean

16
libi3/README Normal file
View File

@ -0,0 +1,16 @@
Introduction
============
libi3 is an *INTERNAL* library which contains functions that i3 and related
tools (i3-msg, i3-input, i3-nagbar, i3-config-wizard, i3bar) use.
It is NOT to be used by other programs.
Structure
=========
Every function gets its own .c file, which in turn gets compiled into an .o
object file. Afterwards, all .o files are archived into one static library
(libi3.a). This library will be linked into all i3 binaries. The linker is able
to eliminate unused .o files when linking, so only the functions which you
actually use will be included in the corresponding binary.

59
libi3/get_socket_path.c Normal file
View File

@ -0,0 +1,59 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
*
* © 2009-2011 Michael Stapelberg and contributors
*
* See file LICENSE for license information.
*
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <limits.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
/*
* Try to get the socket path from X11 and return NULL if it doesnt work.
*
* The memory for the socket path is dynamically allocated and has to be
* free()d by the caller.
*
*/
char *socket_path_from_x11() {
xcb_connection_t *conn;
xcb_intern_atom_cookie_t atom_cookie;
xcb_intern_atom_reply_t *atom_reply;
int screen;
char *socket_path;
if ((conn = xcb_connect(NULL, &screen)) == NULL ||
xcb_connection_has_error(conn))
return NULL;
atom_cookie = xcb_intern_atom(conn, 0, strlen("I3_SOCKET_PATH"), "I3_SOCKET_PATH");
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
xcb_window_t root = root_screen->root;
atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
if (atom_reply == NULL)
return NULL;
xcb_get_property_cookie_t prop_cookie;
xcb_get_property_reply_t *prop_reply;
prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
XCB_GET_PROPERTY_TYPE_ANY, 0, PATH_MAX);
prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
if (prop_reply == NULL || xcb_get_property_value_length(prop_reply) == 0)
return NULL;
if (asprintf(&socket_path, "%.*s", xcb_get_property_value_length(prop_reply),
(char*)xcb_get_property_value(prop_reply)) == -1)
return NULL;
xcb_disconnect(conn);
return socket_path;
}