====== Maketools begin ======
{{tag>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<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<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 ======
===== Setting compile and link FLAGS =====
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} "$@"
* http://stackoverflow.com/questions/14628253/how-to-force-compiler-in-autotools-with-eclipse
==== Including third-party Makefile ====
source: http://www.gnu.org/software/automake/manual/html_node/Third_002dParty-Makefiles.html
===== 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 $(top_srcdir). It always points to original top src-dir. AC_SUBST(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 =====
* https://idlebox.net/2009/apidocs/automake-1.11.zip/automake_8.html#SEC86
===== 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...
PKG_CHECK_MODULES(LIBGLADE, libxml-2.0 >= 2.4.10
atk >= 1.0.0
gtk+-2.0 >= 2.0.0)
AC_SUBST(LIBGLADE_LIBS)
AC_SUBST(LIBGLADE_CFLAGS)
and in Makefile.am.
INCLUDES = @LIBGLADE_CFLAGS@
libglade_LDADD = @LIBGLADE_LIBS@
Since autoconf defines Makefile variables for each substitution that it does, the last example could also be written as
INCLUDES = $(LIBGLADE_CFLAGS)
libglade_LDADD = $(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 ======
* http://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html
====== 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 =====
* http://cppunit.sourceforge.net/doc/lastest/money_example.html
* http://www.yolinux.com/TUTORIALS/CppUnit.html
* http://cppunit.sourceforge.net/doc/lastest/cppunit_cookbook.html
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