The residualvm-tools repository was born on April, 7th this year. From the very first moment I felt its build system was broken, mainly for these three reasons:
- to build a specific tool you must run “make tools/foo”. The repo is called residualvm-tools, there should be no need to specify “tools” in the make call too;
- there isn’t a single line of Makefile code shared between the different tool targets;
- each submodule of tools/, like tools/lua/module.mk, needs to be added in Makefile.common. I’d like a way to set it up into tools/module.mk, with a parent-child relationship.
So some days ago I decided to try to improve it a bit, even though I never wrote a single line of a Makefile.
My first try was to work on rules.mk: I modified a bit the code that created a target from the value of TOOL_EXECUTABLE and of some other variables. After some trial and error I came up with a piece of code that allowed me to put in tools/module.mk, for each tool, something like this:
TOOL_EXECUTABLE := unlab MODULE_OBJS := unlab.o include $(srcdir)/rules.mk TOOL_EXECUTABLE := vima MODULE_OBJS := vima.o include $(srcdir)/rules.mk ....
Quite ugly, but still better than before.
Then I started working on 3. Long story short, I couldn’t come up with an acceptable solution.
Then an heretic thought passed through my mind: CMake!
I really like the add_executable and add_subdirectory functions of CMake, but I know that porting to CMake would require a big effort, since it doesn’t work out of the box on all the platforms configure currently supports.
So I started thinking: configure works perfectly, I just need a way to confortably generate a bit of Makefile code. configure is an sh script, why not just use sh?
So I wrote a script, makegen, with the functions add_executable and add_subdirectory.
add_subdirectory() {
MODULE="$MODULE/$1"
. $srcdir/$MODULE/module.mg
MODULE="${MODULE%/$1}"
}
add_executable() {
echo -n "$1_SOURCES := " >> $builddir/Makefile.modules
for f in $2; do
echo -n "$MODULE/$f " >> $builddir/Makefile.modules
done
echo >> $builddir/Makefile.modules
echo -e \
"build: $1
$1_DIRS := \$(sort \$(dir \$($1_SOURCES)))
$1_dirs:
\$(QUIET)\$(MKDIR) \$($1_DIRS)
$1: $1_dirs \$($1_SOURCES)
\$(QUIET)\$(MKDIR) \$(DEPDIR)
\$(QUIET_CXX)\$(CXX) \$(LDFLAGS) $3 \$(DEFINES) -I. -I\$(srcdir) \
\$(filter %.cpp %.o, $+) -o \$@\$(EXEEXT)
EXECUTABLES += $1\$(EXEEXT)
clean: clean/$1
clean/$1:
\$(QUIET)\$(RM) \$($1_SOURCES) $1
\$(RMDIR) \$($1_DIRS) \n" >> $builddir/Makefile.modules
}
This script is called from configure and it simply generates a file Makefile.modules with the targets for the tools.
Now, adding a new tool is simply a matter of adding in tools/module.mg
add_executable toolname "toolname.o foo.o bar.o"
You’ll then be able to call make toolname.
This is not finished and still experimental, and I can’t know if it will ever be actually used, but I would like to hear some thoughts.