My Wiki!

Maketools begin

maketools

Create directory structure:

  mkdir dailutil; cd daiutil; mkdir config; mkdir build; mkdir test; mkdir src; mkdir tools; mkdir m4
daiutil/
├── autogen.sh
├── m4
├── config
├── build
├── test
├── src
└── tools

Create autogen.sh

cat << 'EOF' > autogen.sh ; chmod +x autogen.sh
#!/bin/sh
autoreconf --force --install -I config -I m4
EOF

Create configure.ac

cat << 'EOF' > configure.ac

dnl Process this file with autoconf to produce a configure script.

# boiler plate
AC_PREREQ(2.59)
AC_INIT([ima_carpc], [0.10], [xuan-thuy.dang@dailabor.de])

AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR([m4])

# Check the availability of main.cpp. For library only check src dir: 
# AC_CONFIG_SRCDIR(src)
AC_CONFIG_SRCDIR(src/main.cpp)

AC_CANONICAL_SYSTEM

# automake initialization (mandatory) including a check for automake API version >= 1.9
#AM_INIT_AUTOMAKE([1.11])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AM_INIT_AUTOMAKE([subdir-objects])

# Option: This section should include macros which add command-line options to 'configure'.


# Check Programs needed for build process

#AM_PROG_AR
#AC_PROG_CC
AC_PROG_CXX # c++ support
AC_PROG_CXX([g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC QCC])
AC_PROG_CXXCPP

#AM_PROG_LEX
#AC_PROG_YACC
AC_PROG_LIBTOOL ## 2.2.6

# Libtools for making libraries
LT_PREREQ([2.2])
LT_INIT([dlopen])

# Debian resets this to no, but this break both Spot and the libtool
# test suite itself.  Instead of requiring developer to install a
# non-patched version of Libtool on any Debian they use, we just
# cancel the effect of Debian's patch here.
link_all_deplibs=yes
link_all_deplibs_CXX=yes

### Macros to check the availability of Libraries, headers, etc.
### http://www.openismus.com/documents/linux/using_libraries/using_libraries.shtml

# use the C++ compiler for the following checks
AC_LANG([C++])

## check if log4cxx installed and make the lib paths available: 
# LOG4CXX_CFLAGS LOG4CXX_LIBS. See m4/log4cxx.m4 script
#AC_CONFIG_LOG4CXX

## manually add dependency paths
# copy cross_lib_dep to .m4
#AC_CONFIG_LIB_DEP

### -Dxxx
### use AM_CONDITIONAL instead
#CPPFLAGS="$CPPFLAGS -DUCLIBC_OWRT -DGPS_DEBUG"

## Get LIBOONET library and include locations
AC_ARG_WITH([liboonet],
  [AS_HELP_STRING([--with-liboonet],
    [prefix location of the LIBOONET library, defaults to /usr])],
  [OONET_PREFIX="$withval"],
  [OONET_PREFIX='/usr'])

OONET_CPPFLAGS="-I$OONET_PREFIX/include"
OONET_LDFLAGS="-L$OONET_PREFIX/lib -loonet"
OONET_LIBS="-L$OONET_PREFIX/lib -loonet"
AC_SUBST([OONET_CPPFLAGS])
AC_SUBST([OONET_LDFLAGS])
AC_SUBST([OONET_LIBS])

## Get LIBDAIUTI library and include locations
AC_ARG_WITH([libdaiutil],
  [AS_HELP_STRING([--with-libdaiutil],
    [prefix location of the LIBDAIUTIL library, defaults to /usr])],
  [DAIUTIL_PREFIX="$withval"],
  [DAIUTIL_PREFIX='/usr'])

DAIUTIL_CPPFLAGS="-I$DAIUTIL_PREFIX/include"
DAIUTIL_LDFLAGS="-L$DAIUTIL_PREFIX/lib -ldaiutil"
DAIUTIL_LIBS="-L$DAIUTIL_PREFIX/lib -ldaiutil"
AC_SUBST([DAIUTIL_CPPFLAGS])
AC_SUBST([DAIUTIL_LDFLAGS])
AC_SUBST([DAIUTIL_LIBS])


## libgps: check and set GPSD_CFLAGS GPSD_LIBS.
#PKG_CHECK_MODULES(GPSD, libgps)

GPSD_LIBS="-lgps"
#AC_SUBST([GPSD_CPPFLAGS])
#AC_SUBST([GPSD_LDFLAGS])
AC_SUBST([GPSD_LIBS])

#CPPFLAGS="$CPPFLAGS -DUCLIBC_OWRT"
# Set -DUCLIBC_OWRT and put it in config.h.in
AM_CONDITIONAL([UCLIBC_OWRT], [test 1])
AC_DEFINE([UCLIBC_OWRT],[1],[Compile on openwrt_uclibc])

AM_CONDITIONAL([GPS_DEBUG], [test ])
AC_DEFINE([GPS_DEBUG],[0],[Test with gpsd ver. < 2.5])

## this extlib_dir is relative to abs_srcdir. Use $(top_srcdir) in Makefile.am to refer to other directories.
#AC_SUBST(EXTLIB_DIR, `pwd`/libext)
AC_SUBST(EXTLIB_DIR, `pwd`/libext)

# Hack source dir  <----- convenient variable.
AC_SUBST(TOPSRC_DIR, `pwd`/src)

# use the C++ compiler for the following checks
AC_LANG([C++])

# Macros to check the availability of Headers
AC_HEADER_STDC
#AC_CHECK_HEADERS([string])
#AC_CHECK_HEADERS([iostream])

## Macros to check the availability of Typedefs and structs
AC_TYPE_SIZE_T

# Check Functions

# distribute additional compiler and linker flags
# --> set these variables instead of CXXFLAGS or LDFLAGS
AC_SUBST([AM_CXXFLAGS], [-Wall])
AC_SUBST([AM_LDFLAGS])

# Output stuffs: create configure, Makefile, etc.,

AC_CONFIG_HEADERS([config.h])

## Top-levle Makefile.am specifies recursive Makefile in 2 subfolder 'src' and 'examples'. 
## Non-recursive Makefile.am in 'src' with subfolders.
#	examples/Makefile
AC_CONFIG_FILES([
	Makefile
	src/Makefile
	test/Makefile
	])
AC_OUTPUT
EOF

Create Makefile.am

Blueprint for the generation of Makefiles

Top-level Makefile.am

Recursive make: top level Makefile.am specifies sub-dirs where other Makefile.am reside. No binary or source code in top-level folder.

cat<<EOF >Makefile.am
ACLOCAL_AMFLAGS = -I m4

include $(top_srcdir)/Makecommon.am

srcdir = @srcdir@
VPATH = @srcdir@

SUBDIRS = src test
EXTRA_DIST = autogen.sh             # Include this file in the distribution package
dist_noinst_SCRIPTS = autogen.sh    # Don't install this file to '--prefix-dir'

EOF

src Makefile.am - Building binaries from src

We are building a library from source files. cd to src-dir.

cat<<EOF >Makefile.am

include $(top_srcdir)/Makecommon.am

srcdir = @srcdir@
VPATH = @srcdir@

## we are building PROGRAMS.
#bin_PROGRAMS = doit
#doit_SOURCES = doit.c main.c

## we are building STATIC lib
#lib_LIBRARIES = libzlib.a
#libzlib_a_SOURCES = headers*.h source*.cpp 

## Dynamic libs.
lib_LTLIBRARIES = libdaiutil.la
libdaiutil_la_SOURCES = 

EOF

Autogen and build

First time build

Work for me?

  ./autogen.sh
  make

Otherwise:

  • run 'aclocal' to generate the m4-files
  • run 'autoconf' to generate the configure script on the base of the configure.ac file
  • run 'automake -a -c' to generate all still missing files with generic content (INSTALL and COPYING) and to generate the Makefile.in files that are used by the configure script to generate the final Makefiles
  • run the generated local 'configure' script in order to create the final Makefiles (you can set the install directory via the –prefix=INSTALLPATH parameter of the script)
  • run 'make' to build your programs and 'make install' to install the program in the usual or via the –prefix parameter of the configure-script defined install path
    • with 'make dist' you can generate a packed source code distribution, which you can provide for download (e.g. with 'make dist-gzip' in .tar.gz format)

    Further build

    if configure.ac is changed (go to top dir): ./autogen.sh
    if Makefile.am is changed (go to top dir): automake
    then:
    cd build ./../configure make

More complicated scenario

A sample scenario is to separate headers*.h and put them in $src/include folder. A Makefile in src-dir must know about this.

1.) Define a variable to hold the location in configure.ac:

AC_SUBST(SRC_INCLUDE_DIR, `pwd`/include)

2.) In src-dir/Makefile.am, pass this location to compile flag of the specific binary:

  libdaiutil_la_CPPFLAGS = -I @SRC_INCLUDE_DIR@\util
  

OR set the global FLAGS for all Makefile.

  AM_CPPFLAGS = -I@SRC_INCLUDE_DIR@
  

Global FLAGS

One solution is to include a common makefile fragment on all your Makefile.ams:

include $(top_srcdir)/makecommon.am
...
bin_PROGRAMS = foo
foo_SOURCES = ...

In makecommon.mk:

AM_CXXFLAGS = -fpic -Wall -Wextra

Cross compiling

 ./configure --help
 ./configure CC=/home/t/s/arm-mv5sft-linux-gnueabi/SW3.2p1/bin/arm-mv5sft-linux-gnueabi-gcc CXX=/home/t/s/arm-mv5sft-linux-gnueabi/SW3.2p1/bin/arm-mv5sft-linux-gnueabi-g++  CFLAGS="-m32" LDFLAGS="-m32"--host=arm-mv5sft-linux-gnueabi --with-sysroot=/home/t/s/arm-mv5sft-linux-gnueabi/SW3.2p1/arm-mv5sft-linux-gnueabi/
 
 

Cross compiling script for android

source: https://gist.github.com/nddrylliog/4688209

#!/bin/sh
 
# I put all my dev stuff in here
export DEV_PREFIX=$HOME/Dev/
 
# Don't forget to adjust this to your NDK path
export ANDROID_NDK=${DEV_PREFIX}/android-ndk-r8d/
 
export CROSS_COMPILE=arm-linux-androideabi
 
# I chose the gcc-4.7 toolchain - works fine for me!
export ANDROID_PREFIX=${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.7/prebuilt/darwin-x86
 
# Apparently android-8 works fine, there are other versions, look them up
export SYSROOT=${ANDROID_NDK}/platforms/android-8/arch-arm
 
export CROSS_PATH=${ANDROID_PREFIX}/bin/${CROSS_COMPILE}
 
# Non-exhaustive lists of compiler + binutils
# Depending on what you compile, you might need more binutils than that
export CPP=${CROSS_PATH}-cpp
export AR=${CROSS_PATH}-ar
export AS=${CROSS_PATH}-as
export NM=${CROSS_PATH}-nm
export CC=${CROSS_PATH}-gcc
export CXX=${CROSS_PATH}-g++
export LD=${CROSS_PATH}-ld
export RANLIB=${CROSS_PATH}-ranlib
 
# This is just an empty directory where I want the built objects to be installed
export PREFIX=${DEV_PREFIX}/android/prefix
 
# Don't mix up .pc files from your host and build target
export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig
 
# You can clone the full Android sources to get bionic if you want.. I didn't
# want to so I just got linker.h from here: http://gitorious.org/0xdroid/bionic
# Note that this was only required to build boehm-gc with dynamic linking support.
export CFLAGS="${CFLAGS} --sysroot=${SYSROOT} -I${SYSROOT}/usr/include -I${ANDROID_PREFIX}/include -I${DEV_PREFIX}/android/bionic"
export CPPFLAGS="${CFLAGS}"
export LDFLAGS="${LDFLAGS} -L${SYSROOT}/usr/lib -L${ANDROID_PREFIX}/lib"
 
./configure --host=${CROSS_COMPILE} --with-sysroot=${SYSROOT} --prefix=${PREFIX} "$@"

Including third-party Makefile

Structuring project

  • we want to support sub-projects so:
    • The top-level Makefile.am will include subdirs.
    • Each sub-srcdir will have its own Makefile.am Sources.am and other project specific includes

Put generated binaries in a specific folder

bin_PROGRAMS = $(top_builddir)/bin/foo
__top_builddir__bin_foo_SOURCES = ...
__top_builddir__bin_foo_CPPFLAGS = ...
__top_builddir__bin_foo_LDFLAGS = ...

Unsolved: Make libs available after build

I want libs go to lib-dir and headers go to include-dir

Solved: Files not found when build in separate build-dir

Solution: use $(topsrcdir). It always points to original top src-dir. ACSUBST(VAR, pwd) variables in configure.ac are resovled relative to build dirs. As a result, something will not be found in build-dir.

-- 1/

I discovered that, if we build the source in a separate directory, we
need to fix some minor things:

in Makefile.am I used to write:

LIBTRAINING_DIR=../lib
AM_CPPFLAGS = -I$(LIBTRAINING_DIR)
[...]
training_LDADD = ../lib/libtraining.la

Now, thanks to the tries with 'make distcheck', I must be more strict:

LIBTRAINING_SRCDIR=$(top_srcdir)/src/lib
LIBTRAINING_BUILDDIR=$(top_builddir)/src/lib

AM_CPPFLAGS = -I$(LIBTRAINING_SRCDIR)

bin_PROGRAMS = training
training_SOURCES = training.c internal_version.c
training_LDADD = $(LIBTRAINING_BUILDDIR)/libtraining.la

Variables used to build

configure option --with-libname

This is convenient for crosscompiling and quick fix when user know where the libs were installed.

## Get LIBOONET library and include locations
# Provide --with-option with default sysroot (/usr)
AC_ARG_WITH([liboonet],
  [AS_HELP_STRING([--with-liboonet],
    [prefix location of the LIBOONET library, defaults to /usr])],
  [OONET_PREFIX="$withval"],
  [OONET_PREFIX='/usr'])

# Collect FLAGS 
OONET_CPPFLAGS="-I$OONET_PREFIX/include"
OONET_LDFLAGS="-L$OONET_PREFIX/lib -loonet"
OONET_LIBS="-L$OONET_PREFIX/lib -loonet"
# Make FLAGS available in Makefile.am
AC_SUBST([OONET_CPPFLAGS])
AC_SUBST([OONET_LDFLAGS])
AC_SUBST([OONET_LIBS])

Using the AC_SUBST variables

Define Variables

 53 # FLAGS
 54 # Make AM_CXXFLAGS global or define in Makefile.am
 55 # Makefile.am: AM_CXXFLAGS= -std=c++0x
 56 AC_SUBST([AM_CXXFLAGS], [-Wall -std=c++0x])

Using them

include $(top_srcdir)/Makecommon.am
include $(top_srcdir)/Sources.am

srcdir = @srcdir@
VPATH = @srcdir@ 
## global variable. Modified inside  Makemodule.am by (+=)
bin_PROGRAMS = carpcd
man_MANS = 

## openwrt cross
##AM_CPPFLAGS= $(GPSD_CFLAGS) 

## host build
AM_CPPFLAGS= -I@TOPSRC_DIR@

if GPS_DEBUG
AM_CPPFLAGS += -DGPS_DEBUG
endif

if UCLIBC_OWRT
AM_CPPFLAGS += -DUCLIBC_OWRT @OONET_CPPFLAGS@ @DAIUTIL_CPPFLAGS@ @YAJL_CPPFLAGS@ \
							 @LIBPHIDGET_CPPFLAGS@ \
							 $(GPSD_CPPFLAGS)
endif

carpcd_LDADD= @OONET_LIBS@ @DAIUTIL_LIBS@ @YAJL_LIBS@ \
							@LIBPHIDGET_LIBS@ \
							$(GPSD_LIBS)

#AM_CPPFLAGS= -I@EXTLIB_DIR@ -I@TOPSRC_DIR@ 
#AM_CPPFLAGS= $(GPSD_CFLAGS) -I$(liboonet_incdir) -I$(libdaiutil_incdir) -I$(libyajl_incdir)
#AM_LDFLAGS= $(GPSD_LIBS) @LOG4CXX_LIBS@
#carpcd_LDADD = $(liboonet_sla)/liboonet.la $(libdaiutil_la)/libdaiutil.la $(libyajl_la)/libyajl.la

## this .a works with static lib.. surprise!
#carpcd_LDADD = $(liboonet_sla)/liboonet.a $(libdaiutil_la)/libdaiutil.a $(libyajl_la)/libyajl.a
##carpcd_LDFLAGS = -Wl,-Bstatic,-L$(libdaiutil_la)/,-ldaiutil.a,-Bdynamic
carpcddir=$(bindir)
#datadir=$(bindir)
carpcd_SCRIPTS= carpcd.conf
#dist_pkgdata_DATA = carpcd.conf
carpcd_SOURCES = $(CARPCD_SRCS)

Other example

In configure.in…

PKGCHECKMODULES(LIBGLADE, libxml-2.0 >= 2.4.10

                          atk >= 1.0.0
                          gtk+-2.0 >= 2.0.0)

ACSUBST(LIBGLADELIBS) ACSUBST(LIBGLADECFLAGS)

and in Makefile.am.

INCLUDES = @LIBGLADECFLAGS@ libgladeLDADD = @LIBGLADE_LIBS@

Since autoconf defines Makefile variables for each substitution that it does, the last example could also be written as

INCLUDES = $(LIBGLADECFLAGS) libgladeLDADD = $(LIBGLADE_LIBS)

Srcs not copied to build_dir

see Autoconf Manual, chapter 4.7.3 Build Directories

Each Makefile.in should contain:

srcdir = @srcdir@
VPATH = @srcdir@

Due to VPATH limitations it might be necessary in certain cases to include the '$(srcdir)/' prefix in your Makefile.

AM_CPPFLAGS= -I@TOPSRC_DIR@ -I$(srcdir)/include

Conditional sources with AM_CONDITIONAL

When all else failed

rm -rf build/* autom4* aclocal.m4 configure
autoreconf --force --install -I config -I m4       <-----   ./autoreconf
          

These are generated again:

    [dang@localhost nfc_client_cpp]$ ./autogen.sh 
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, `config'.
libtoolize: copying file `config/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
configure.ac:13: installing 'config/config.guess'
configure.ac:13: installing 'config/config.sub'
configure.ac:16: installing 'config/install-sh'
configure.ac:16: installing 'config/missing'
src/Makefile.am: installing 'config/depcomp'

3rd package and maketools

CPPUNIT test

  rpm -ql cppunit-devel
  cp /usr/share/aclocal/cppunit.m4 m4/

configure.in

dnl Process this file with autoconf to produce a configure script. 
AC_INIT(Makefile.am) 
AM_INIT_AUTOMAKE(money,0.1) 
AM_PATH_CPPUNIT(1.9.6) 
AC_PROG_CXX 
AC_PROG_CC 
AC_PROG_INSTALL 
AC_OUTPUT(Makefile)

Makefile.am

# Rules for the test code (use `make check` to execute)
TESTS = MoneyApp
check_PROGRAMS = $(TESTS)
MoneyApp_SOURCES = Money.h MoneyTest.h MoneyTest.cpp MoneyApp.cpp
MoneyApp_CXXFLAGS = $(CPPUNIT_CFLAGS)
MoneyApp_LDFLAGS = $(CPPUNIT_LIBS)
MoneyApp_LDFLAGS = -ldl

Navigation