Module Mkmf2
In: mkmf2.rb

Mkmf2: a drop-in replacement for mkmf

Mkmf2 aims at replacing the functionnality of the old mkmf, with a better and cleaner code. It hopefully will keep all the previous mkmf files working, while providing

  • better control over the Makefiles produced;
  • installation to $HOME;
  • uninstallation;
  • more flexibility.


Mkmf2 was written to supplement a missing feature on the old +mkmf.rb+: it is not possible to install include files along with the library, and not easy to make several libraries, that link each other, and install them… So here comes mkmf2.rb !


There are probably a huge number of bugs, or missing features, or misleading features. In case you find one, please file a request in the mkmf2 project on rubyforge, at the address

But before, please, check out the latest cvs version at and make sure the bug is still there…

Unimplemented features

  • It is currently impossible to remove directories with make uninstall. This is due to the fact that +rbconfig.rb+ doesn’t provide an entry for removing directories.

Note to anyone who wishes to contribute

Please, document any code you add, and keep the changelog up to date…


This module is copyright 2006 by Vincent Fourmond. You can use and redistribute it under the terms of the General Public License version 2. As a special exception, you can distribute any verbatim copy along with a program, provided that this program depends on mkmf2 to install.


Included Modules


Classes and Modules

Module Mkmf2::Logging
Class Mkmf2::MfBinaryLibEntity
Class Mkmf2::MfComment
Class Mkmf2::MfEntity
Class Mkmf2::MfRule


VERSION = "0.2"   The module version — will definitely come in useful !
CONFIG_DEFAULTS = { # first, a short for the rest... "RB_FILE_UTILS" => "$(RUBY_INSTALL_NAME) -r fileutils", "INSTALL" => "$(RB_FILE_UTILS) -e 'FileUtils.install(ARGV[0],ARGV[1],:mode => 0755)'", "INSTALL_DATA" => "$(RB_FILE_UTILS) -e 'FileUtils.install(ARGV[0],ARGV[1],:mode => 0644)'", "INSTALL_PROGRAM" => "$(INSTALL) ", "INSTALL_SCRIPT" => "$(INSTALL) ", "MAKEDIRS" => "$(RB_FILE_UTILS) -e 'FileUtils.makedirs(ARGV)'", "RM" => "$(RB_FILE_UTILS) -e 'FileUtils.rm(ARGV)'", "RM_PATH" => # a trick to remove a path "$(RB_FILE_UTILS) -e 'd = ARGV[0]; begin ;while FileUtils.rmdir d, :verbose=>true; d = File.dirname(d);end; rescue ; end;'", "DEFINES" => "", "LIBARG" => "-l%s", "LIBS_SUP" => "", }   This hash contains replacements for basic filesystem functions based on ruby and FileUtils. They are used only if the corresponding element is missing in CONFIG. They also contains some other default values for possibly missing CONFIG keys.
MAKEFILE_LINE_SIZE = 40   A recommandation for line size in the Makefile
CONFTEST_C = "conftest.c"   Also from old mkmf.rb

Public Class methods

Return extensions for C files.

This function returns the common build rules for C and C++ files.

Takes a list of CONFIG variables and returns them joined by spaces.

Returns the given config key, that will be used to write a rule in the Makefile. For better output, the function does store a list of all the config variables which are in use, and simply outputs +$(VARIABLE)+.

Return the extensions for C++ files.

A small helper function to extract the install directory name for one file. file is the file, install_dir where we want to install it. This should take care of messy dots.

A helper function for MfEntity instances that will have to install files into directories.

rule:the rule to use, see Mkmf2::rule
install_path:the installation path
files:a hash containing original -> destination pairs.

The companion of install_files, returning a list of strings rather than MfRules. Bascially behaves the same way. It is probably a better thing to use this function now.

Returns the installation path for a given thing (what). This function basically returns a simple MAKEFILE_CONFIG variable, which has otherwise been setup by setup_model. What is available for now:

lib:where to install .rb library
bin_lib:where to install binary libs
include:include files

Returns the way to represent the dependencies of a rule in the Makefile.

A small helper function to write quickly rules, based on a configuration item.

Returns the way to represent the current target in the Makefile.

Returns a string containing all the configuration variables. We use the MAKEFILE_CONFIG for more flexibility in the Makefile: the variables can then be redefined on the make command-line.

Returns a string where all the elements are joined together. The lines will break if they exceed line_size, but the elements themselves will not be broken. They will be indented

Register a directory that we might need to create. Make sure that the rules don’t appear twice.

Register a new name, making sure the name returned is unique.

Returns the string corresponding to a rule, given by the string rule, which can take the following values:

install_data:returns the rule for installing a data file to a given place
install_script:the rule for installing code at a given place
remove:to remove files
directory:to create a directory
build_library:to build a library; in that case, the first argument is the name of the target, and the ones after the objects.

the optional arguments are the arguments to the rule, if they exist. Else, they default to $(@D) $@ (or something like that).

Sets the model for directory installation. There are for now three values:

local:for a standard installation (like the default in mkmf.rb)
dist:to use in a packageing system
home:to install to a home directory (basically, prefix= $HOME)

Please do not modify @@model directly.

Returns a list of the potential source files extensions.

Public Instance methods

Adds one or more paths to the current include path.

Adds one or more paths to the current library path.

This functions checks for missing features in the CONFIG hash and supplements them using the FILE_UTILS_COMMAND hash if necessary.

The compatibility function with the mkmf.rb !

Also from old mkmf.rb

This function declares a shared binary library that will be built and installed using the appropriate functions.

libname is what is usually passed as an argument to the create_makefile function of the old

sources is the source files. They are processed using Dir.glob, so they can contain wildcards.

This function contends itselfs to declare the library, it does not build it, as this will be done by make.

Declares a documentation that doesn’t need to be built. For the arguments, see declare_library.

The main place for declaring files to be installed.

target_dir:the target directory relative to the install path if it is nil or empty, then just install in the base directory.
files:the source files
kind:the kind of target (see again and again install_path)
basename:wether or not to strip the leading directories ?
skip:a regular expression (or whatever object that has a === method that matches strings) saying wich files should be excluded. Defaults to /~$/.

Declares a set of include files to be installed. Defaults to all the files in the include subdirectory.

This function declares a Ruby library, namely files that want to be installed directly in the rubylibdir (or equivalent, depending on the user settings).

target_dir:the target directory, relative to the installation directory;
files:the files to install. Defaults to "lib/**.rb"

For instance,

 declare_library("Biniou", "toto.rb")

will install the file "Biniou/toto.rb" in the common library directory. Only basenames are kept for the target, so that

 declare_library("Biniou", "truc/muche/toto.rb")

does also end up in "Biniou/toto.rb". Beware ! If you think that this is obnoxious, tell me !

Return the rules to create the necessary directories

A small wrapper around Config::expand which diminishes the size of the code and makes sure the MAKEFILE_CONFIG hash is updated.

This is a compatibility function with the previous mkmf.rb. It does check for the presence of a header in the current include directories. If found, it returns true and sets the define HAVE_…

Also from old mkmf.rb

Parses command-line arguments, wiping the ones that we understood.

The same as have_header, but fails if the header is not found…

also taken straight from mkmf.rb

A function to ease the task of producing several libraries from the same source tree. It sets up a library context for one directory, adding it to the include path, and taking care of the files in:

+lib/+:the ruby library files;
+include/+:the include files

dir is the directory in the source, target_dir the base directory for target files. It is pretty rudimentary, but should do the job for many cases (and especially Tioga ;-) !). name is the name of the binary library. If nil, doesn’t try to build a binary library. include_dir is the target name for includes. If nil, doesn’t try to install them.

You can use either the return value or a block to change somehow the behavior of the different objects produced (like adding a binary library for instance).

Sets up a whole bunch of variables necessary for installation, depending on the current value of the @@model parameter. This is the place where we setup the variables used by the installation process, namely:

RUBYLIB_INSTALL_DIR:the directory where the text libraries are to be installed;
RUBYARCHLIB_INSTALL_DIR:the directory where architecture dependent libraries are installed;
INCLUDE_INSTALL_DIR:the directory where include files should go if necessary;

And for now, that is all.

Sets up the various variables pertaining to include and library paths.

Also from old mkmf.rb

Small helper function for write_makefile. target is a hash containing a "deps" array and a "rules" array which are created in case of need.

I know this is bad design, but that’s the best I think of for now. This function better be called before using MAKEFILE_CONFIG directly.

Writes the Makefile using @@entities — and others…