wiki:pm-source-make

Version 5 (modified by andreasw, 13 years ago) (diff)

added comment about proper dependencies for LIBADD inclusions

Makefile.am Files in Source Directories

The source code directories are usually the src directories in a project's subdirectory, or subdirectories under src.

The Makefiles in those directories take care of the fun stuff. They define what is to be built (libraries, executables), how it is built, and where (and if) the products are to be installed.


Beginning of the Makefile.am File

# Copyright (C) 2006 International Business Machines and others.
# All Rights Reserved.
# This file is distributed under the Common Public License.

## $Id: Makefile.am 789 2006-06-01 20:11:12Z andreasw $

# Author:  Andreas Waechter           IBM    2006-04-13

AUTOMAKE_OPTIONS = foreign
  • As usual, we start with a copyright note, author information, and the svn:keywords "$Id$". I'm not sure if the AUTOMAKE_OPTIONS variable has to be set here...

Building a Library

Name of the Library

# Name of the library compiled in this directory.  We want it to be installed
# in the 'lib' directory
lib_LTLIBRARIES = libClp.la
  • First we tell Automake the name of the library that we want to create. The extension ".la" is used, since we are using the Libtool utility to handle libraries, which allows us to build both static and shared libraries on almost all platforms. The final name of the library(ies) depends on the platform.
  • In the above example, we use the Automake prefix lib_ to tell Automake, that we want this library to be installed in the lib installation directory. As Automake primary we use LTLIBRARIES (as opposed to LIBRARIES) to tell Autoconf, that we want to use Libtool.
  • If we want to build a library that is not going to be installed, we use the noinst_ prefix. For example, we might have the source code for the final library distributed into different directories, but in the end we only want to install one library that containts everything. In this case, we need to create auxilliary libraries in each source code directory (except for one), that are later collected into a single library. The auxilliary libraries should not be installed.

The corresponding line in the Makefile.am file for an auxilliary library then looks like:

# Name of the library compiled in this directory.  We don't want it to be
# installed since it will be collected into the libCgl library
noinst_LTLIBRARIES = libCglTwomir.la

Source Files for the Library

# List all source files for this library, including headers
libClp_la_SOURCES = \
        ClpConfig.h \
        ClpCholeskyBase.cpp ClpCholeskyBase.hpp \
        ClpCholeskyDense.cpp ClpCholeskyDense.hpp \
        ClpCholeskyUfl.cpp ClpCholeskyUfl.hpp \
        Clp_C_Interface.cpp Clp_C_Interface.h \
        ClpParameters.hpp \
.
.
.
  • To tell Automake which source files should be compiled in order to build the library, we use the library name as prefix (with "." and "-" replaced by "_"), and the SOURCES primary. In this list, one also includes all corresponding header files, so that they would be installed in a tarball generated by make dist.

Based on the extension of the source files, automake will figure out how they are to be compiled. In COIN, we use ".c" for C code, ".cpp" for C++ code, and ".f" for Fortran code.

Additional Link Command for the Library

This subsection is likely to change

# This is for libtool
libClp_la_LDFLAGS = $(LT_LDFLAGS)

For now, just use the above line for your library, no matter if it is installed or not.

Collecting Objects from Other Libraries

# We want to have also the objects from the DylpStdLib in this library
libDylp_la_LIBADD = ../DylpStdLib/libDylpStdLib.la

# Since automake is not doing this on its own, we need to declare the
# dependencies to the subdirectory libraries here
libDylp_la_DEPENDENCIES = $(libDylp_la_LIBADD)
  • If you distribute the source code for a library into several directories, you will have to tell Automake, which libraries should be included in the final library that is going to be installed. In the above example, taken from the DyLP project, the final library to be installed is libDylp (with the approprate extension, such as ".a"). In the Makefile.am for this library you would find those lines. The LIBADD primary tells Autoconf, that the objects from the specified Libtool libraries should be included in the final library. Wee also need to tell automake explicitly, that the libDyLP.la library needs to be updated if any of the libraries change, that are included with LIBADD.

Building a Program

Name of the Program

# Name of the executable compiled in this directory.  We want it to be
# installed in the 'bin' directory
bin_PROGRAMS = clp
  • First we tell Automake the name of the executable that we want to create (skip the ".exe" extension even if you are working under Windows). Usually, we want programs to be installed in the bin installation directory, as indicated by the bin_ prefix. However, the unit test program is usually not installed, in which case one uses the noinst_ prefix.

Source Files for the Executable

# List all source files for this executable, including headers
clp_SOURCES = \
        ClpMain.cpp \
        CbcOrClpParam.cpp CbcOrClpParam.hpp \
        MyEventHandler.cpp MyEventHandler.hpp \
        MyMessageHandler.cpp MyMessageHandler.hpp \
        unitTest.cpp
  • Just as for libraries, one lists all source files, including headers, in a variable, which has the program name as prefix, and uses the SOURCES primary.

Specifying Linking Flags

This subsection is likely to change

# List all additionally required COIN libraries
clp_LDADD = libClp.la \
        $(COINUTILSOBJDIR)/src/libCoinUtils.la

# Here we add additional libraries
LIBS += $(ADDLIBS) `cat $(COINUTILSOBJDIR)/coinutils_addlibs.txt`

# Finally, the -rpath flag is used by libtool to make sure that the shared
# library is found (in the lib install directory) when we are using dynamic
# libraries.
clp_LDFLAGS = -rpath $(libdir)
  • For now, list all COIN library dependencies in _LDADD (using the libtool extension ".la"), additional library dependencies are added to LIBS, and the _LDFLAGS should just be set as shown (to ensure that the program is compiled to hardwire the library installation directory into the executable, if shared libraries are used).
  • Note:
    • The ADDLIBS Autoconf output variable is set to the list of additional library dependencies for third party packages.
    • For COIN projects, the AC_COIN_HAS_PROJECT Autoconf macro generates output variables PRJSRCDIR and PRJOBJDIR, which are set to the project's main source and object subdirectory (which are different for a VPATH compilation). Here, PRJ is the name of the project as provided to the macro, in all capital letters.

Additional Flags

Include Directories

########################################################################
#                            Additional flags                          #
########################################################################

# Here list all include flags, relative to this "srcdir" directory.  This
# "cygpath" stuff is necessary to compile with native compilers on Windows.
AM_CPPFLAGS = \
        -I`$(CYGPATH_W) $(COINUTILSSRCDIR)/src`
  • To specify the compiler flags for include directories for header files, one should use the AM_CPPFLAGS variable. The usage of the CYGPATH_W variable might seem a bit cumbersome (and it is), but this is necessary to ensure that the code can also be compiled with native Windows compilers under Cygwin. The CYGPATH_W variable is automatically set to "cygpath -w" on Cygwin, which translates the UNIX-style path to a proper Windows path. On other platforms, it is simply set to "echo".

Note that one can make use of the PRJSRCDIR variables for the COIN projects.

Additional Preprocessor Definitions

# List additional defines
AM_CPPFLAGS += -DCOIN_NO_CLP_MESSAGE -DUSE_CBCCONFIG
  • Additional "-D" preprocessor flags should also be added to the AM_CPPFLAGS variable.

Correction for Default Include Flags

# This line is necessary to allow VPATH compilation with MS compilers
# on Cygwin
DEFAULT_INCLUDES = -I. -I`$(CYGPATH_W) $(srcdir)` -I$(top_builddir)/inc
  • You should have the lines above somewhere in your Makefile.am file, to make sure that users can compile your code under Cygwin using the native Windows compilers in a VPATH configuration. The default setting for DEFAULT_INCLUDES does not use the CYGPATH_W variable.

Installation of Header Files

########################################################################
#                Headers that need to be installed                     #
########################################################################

# Here list all the header files that are required by a user of the library,
# and that therefore should be installed in 'install'
include_HEADERS = \
        ../inc/config_cbc.h \
        CbcBranchActual.hpp \
        CbcBranchBase.hpp \
        CbcBranchLotsize.hpp \
        CbcBranchCut.hpp \
        CbcCompareActual.hpp \
        CbcCompareBase.hpp \
        CbcCutGenerator.hpp \
        CbcEventHandler.hpp \
        CbcHeuristic.hpp \
        CbcHeuristicFPump.hpp \
        CbcHeuristicGreedy.hpp \
.
.
.
  • In order to use a COIN library (if it is written in C or C++), a user will need some of the header files in the source directories to compile her/his own code. For this reason, we specify the required header files (which mighy only be a subset of all header files in the source directory) in the include_HEADERS Automake variable. The prefix include_ tells automake that those files should be copied into the include installation directory. Note that you should make sure that also the configuration header file (usually in the inc directory) is installed.
#############################################################################
# Create the Config.h file that always defines HAVE_CONFIG_H and install it #
#############################################################################

# You only need to adapt the following line
ConfigHeader = ClpConfig.h

install-exec-local:
        echo "#ifndef HAVE_CONFIG_H" >bla
        echo "#define HAVE_CONFIG_H" >>bla
        echo "#endif" >> bla
        cat $(srcdir)/$(ConfigHeader) >> bla
        $(install_sh_DATA) bla $(DESTDIR)$(includedir)/$(ConfigHeader)
        rm -f bla

uninstall-local:
        rm -f $(DESTDIR)$(includedir)/$(ConfigHeader)
  • As discussed in the Autotools introduction page, in COIN we don't include the configuration header file (above config_clp.h) directly. Instead, this is done via the PkgConfig.h file, to make sure that the compilation can also be done smoothly with the Developer Studio. Therefore, the PkgConfig.h header file should also be installed, but it has to be modified slightly. This is done with the lines above; you should have those in one of your source code Makefile.am files, and adapt the ConfigHeader? variable for your project. The install-exec-local is run by the generated Makefile for a make install, and the commands for uninstall-local are executed for the make uninstall.