====== 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