How to add host specific configuration - bakkeby/dusk GitHub Wiki

When using dusk (or dwm for that matter) on more than one system it may be desirable to have some configuration settings that is specific to the one machine.

For example due to difference in screen size the default workspace layouts could be different when compiling the window manager for a laptop compared to when it is compiled for a desktop computer.

An obvious solution would be to just clone and maintain two different instances of the window manager, but this may lead to more work to keep some things like keybindings in sync across instances.

This guide documents one way to add host specific configuration.

General idea

The principle behind this is to use C preprocessor directives to choose one config or another depending on the hostname of the computer the binary is being compiled on.

Problem

The main complication with this idea is that C preprocessor directives cannot be used to compare strings of variable length, i.e. unfortunately we can't use an if statement on the form of:

#if HOST == "laptop"
// laptop specific configuration
#endif

Workaround

One viable workaround would be to use an integer hash of the hostname and use that for the C preprocessor if statements.

One program to compile such a hash is cksum which seems to be a fairly standard tool on most distributions.

$ hostname | cksum
3448345503 8

The first value is the generated hash while the second number represents the number of bytes / characters in the source string. You can simply use the first value, but it is almost easier to remove the space to use both.

$ hostname | cksum | tr -d ' '
34483455038

Passing the hash value

OK, so we have a way to get an integer hash of the machine's hostname, great. Now what?

We will want generate this value when running the make script and pass this on when compiling the software.

We want to pass -DHOST=34483455038 to the compiler, which will define a preprocessor variable as "HOST" that has the value of 34483455038.

Consider the following diff which makes changes to config.mk:

diff --git a/config.mk b/config.mk
index 518d841..0f9be5c 100644
--- a/config.mk
+++ b/config.mk
@@ -44,8 +44,11 @@ IMLIB2LIBS = -lImlib2
 INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC}
 LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}  ${XRENDER} ${XCBLIBS} ${KVMLIB} ${YAJLLIBS} ${IMLIB2LIBS}

+# Optional host flag for computer specific configuration
+HOSTFLAGS = -DHOST=$(shell command -v cksum > /dev/null && hostname | cksum | tr -d ' ')
+
 # flags
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${HOSTFLAGS}
 #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
 CFLAGS   = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
 LDFLAGS  = ${LIBS}

The command -v cksum > /dev/null && part of the command is merely to check if the cksum command exists, to avoid compilation failures in case it doesn't.

The $(shell ...) means to run the ... part in a shell. Note that the solution here is specific for GNU Make. If you know a better and more portable way to do this I would be interested to hear you out.

We store -DHOST=... in a variable HOSTFLAGS which we are merely passing as part of the CPPFLAGS options.

Now when compiling we *should* see a value being passed in the compilation output.

cc -c ... -DHOST=34483455038 dusk.c

Using the hash value

I have two machines, a laptop with hostname of "samsung" and a desktop with a hostname of "ryzen".

At the top of config.h define a preprocessor value for each of your hosts, e.g.

#define RYZEN 29292992336
#define SAMSUNG 34483455038

and now you can use these elsewhere in your configuration as you please.

Here is an example setting smartgaps_fact to 0 if I am using my laptop, but leave it as 6 for any other installation.

#if HOST == SAMSUNG
static const unsigned int smartgaps_fact = 0;   /* smartgaps factor when there is only one client; 0 = no gaps, 3 = 3x outer gaps */
#else
static const unsigned int smartgaps_fact = 6;   /* smartgaps factor when there is only one client; 0 = no gaps, 3 = 3x outer gaps */
#endif

Back to Guides.

⚠️ **GitHub.com Fallback** ⚠️