The short version:

I've replaced the Imake build system in ctwm with a CMake structure.
Comments on the concept in general or the implementation in specific
are solicited.  This is the first time I've tried seriously using
cmake, so I'm in no position to claim it's done in the best possible
way.  But it works for me, and looks OK in reading.

Branch has been pushed up to LP.  Branch at 'lp:~fullermd/ctwm/cmake',
URL <https://code.launchpad.net/~fullermd/ctwm/cmake>.  Tarball
<http://bazaar.launchpad.net/~fullermd/ctwm/cmake/tarball/343> if
that's your preferred (at least as of the current head rev; watch out
for it changing).

README describes more details of invoking it, but for most systems the
Makefile in the root should do it all behind your back just fine; just
run 'make'.  See how it does it and/or README for more details if you
need to (or want to) experiment with using it directly.

Builds should wind up largely with the defaults currently extant, with
the exception that USE_GNU_REGEX is enabled by default.  It doesn't
actually have anything to do with GNU; it just uses regex functions
from libc.  If we find that we're dealing with a ton of systems that
don't have a regexp implementation in libc, well, we'll worry about
that then.

Other than that, please test and comment!  If it does well, we wanna
land it, and if it doesn't, we'll need to come up with a backup plan.


                   ---------------------------------

The long version:


Why Imake

  ctwm uses imake because twm used imake.  And twm used imake because,
  well, everything X used imake.  And imake does a lot of things well
  in practice, and an even larger set in theory.  In particular, it
  knows (practically by definition) everything about how X is
  installed on the local system, and how to link in all the needed
  pieces.  It also knows, because it's build with that knowledge,
  where the compiler and linker are and how to invoke them.  And it
  knows, because the sysadmin sets local configuration, what other
  things are available and how to get at them.

Why not Imake

  The practice, mostly doesn't work that well.  It still knows X, but
  it may or may not know the local compiler with the rise of binary
  packages, and if sysadmins regularly made local configuration to it
  in the 1980's, they sure as heck don't know.  And it's not even
  necessarily that reliable on X anymore, since X itself no longer
  uses it.

What we need

  We don't per se _need_ a Makefile builder.  I know perfectly well
  how to write Makefiles, and so do plenty of other people around.
  But we do need something that sets things up cross-platform.  That
  knows how to interact with different make's[0] and different
  compilers and linkers.  That can handle a configuration role, of
  en/disabling capabilities, finding libraries and includes, etc.
  That can, well, not make us HAVE to deal with some of the messy bits
  of Makefile writing.  So we might as well go whole-hog.

What are our choices?

  I discarded right off the class of reimplemented build systems, like
  scons and rake and jam and such.  We want something that just builds
  a standard buildchain.

  There are 3 major options I'm aware of: GNU autotools, qmake, and
  cmake.  I'm passingly aware of some others (like gyp), but I didn't
  give them more than a passing glance.

  autotools
    I think this can best be summed up as "just, no".  It's the way
    the rest of X went when they discarded imake, but nothing I've
    ever seen from it as either a user or a dev makes me want to get
    any closer.  The few times I've had to deal with autotools
    intimately have ranked solidly among my least pleasant programming
    experiences.  The only significant plus is that, on the end-user
    system, they don't require anything but a Bourne shell.

  qmake
    I didn't investigate this too deeply.  It's built for Qt, but
    isn't strictly Qt specific; it can certainly be used for other
    things.  But it usually isn't, and even a lot of Qt stuff seems to
    have moved to CMake instead.

  CMake
    Well represented in the free software world now, it's got maturity
    and momentum.  In my readings of docs and existing files out
    there, it seems relatively unpainful to work with, so I chose to
    run with it.  My experience porting ctwm to it has been fairly
    pleasant; the docs aren't always great, but I could figure things
    out, and it seems fairly easy to reason about.


Cmake plus/minus/notes

  CMake is standalone, and doesn't require any dependencies beyond
  itself.  On the other hand, it is a large C++ program; some old
  systems might not have a compiler competent to handle it.  They do
  seem to cover the recent *nixen well, plus Mac and Win, and there is
  evidence of _some_ level of VMS support (though
  http://public.kitware.com/Bug/view.php?id=3974 suggests it's not
  complete).

  It does require that you have cmake around to build ctwm.  And if
  you have to build it to get it around, it takes a lot longer to
  build than ctwm does (but hey, we require X, which also takes a long
  time).

  We no longer have to copy/edit an Imakefile.local to en/disable
  things; it can all be done on the cmake command line like autoconf
  and friends do.  I haven't added specific hooks for setting odd
  library/include dirs, though you can via the generic cmake params
  like CMAKE_SYSTEM_INCLUDE_PATH etc.

  The build happens out of tree; all the intermediate and final
  generated files wind up under build/.  So rm -rf build/* cleans up
  everything.

  Actual command lines for things like the compiler runs can be made
  visible via 'make VERBOSE=1' 

  Full stack through install is easy to test with DESTDIR just like
  before.  e.g., "make DESTDIR=/tmp/ctwm allclean all install" will
  run you from pristine through installed in /tmp/ctwm/$PREFIX.

  CMake is common enough that various OS packaging systems probably
  already have recipes that make it easy to package for them.  Imake
  is getting toward unloved enough that things might be getting
  trickier.

  There's probably more or different things that can be done.  I have
  it erroring out if e.g. libjpeg is enabled, but not found.  It's
  possibly we'd want it more automated like "use if available,
  otherwise don't"; I chose to do it this way because I like more
  immediate feedback if things aren't as expected.  Similarly, a
  possible future step would be splitting things up the source tree a
  little more, rather than having everything (except the pile of XPM's
  anyway) in the root of the tree.  Such things are intentionally not
  yet investigated; one thing at a time.


Random cmake refs/tabs I've kept open through the process:

  (in no order, just a tabdump)
  <http://www.cmake.org/cmake/help/v2.8.12/cmake.html>
  <http://www.cmake.org/Wiki/CMake>
  <http://www.cmake.org/Wiki/CMake_FAQ>
  <http://rachid.koucha.free.fr/tech_corner/cmake_manual.html>



[0] Or other build systems completely.  It will build configs for
    various IDE's (on Mac frex may be interesting for us) and can do
    so for some other build systems too.  For instance, it can build
    ninja control files; tested lightly and works fine here, so you
    can go that way if all those dozens of microseconds make wastes
    ordering dependencies are messing with your build times.



-- 
Matthew Fuller     (MF4839)   |  [email protected]
Systems/Network Administrator |  http://www.over-yonder.net/~fullermd/
           On the Internet, nobody can hear you scream.

Reply via email to