Home | News | Documentation | Download

Using autotools


#1

I want use autotools to compile my root program. I have some files:

colonna.cpp integrale.cpp main.cpp rdTXOclass_2.cpp torre.cpp
colonna.h integrale.h rdTXOclass_2.h torre.h

only main.cpp and rdTXOclass2.cpp/h use root, the others are simple c++ programs. I create a Makefile . am like this:

bin_PROGRAMS = calibrazione

calibrazione_SOURCES = main.cpp integrale.cpp integrale.h rdTXOclass_2.cpp rdTXOclass_2.h colonna.cpp colonna.h torre.cpp torre.h

INCLUDES = $(shell root-config --cflags) $(shell root-config --libs) $(shell root-config --glibs)

when I lauch make it compile all files with root directives , but not the final linking:
g++ -g -O2 -o calibrazione main.o integrale.o rdTXOclass_2.o colonna.o torre.o

and it says stuff like this:
undefined reference to `TGraphErrors::TGraphErrors(int, float const*, float const*, float const*, float const*)’


#2

Hi.

INCLUDES = $(shell root-config --cflags) $(shell root-config --libs) $(shell root-config --glibs)
is wrong - you’re mixing compiler and linker flags, and INCLUDES should only contain the compiler’s include search path directives. You’ll have to add the root-config --glibs to the autotools library statement.

I’m sure you’ll spend far more time on this than just running “.L includes_all_sources.C+”, which loads all your code (via a file which #includes all your sources) as a shared library into ROOT, so you can execute your compiled code. But it’s of course up to you :wink:

Cheers, Axel.


#3

[quote=“Axel”]Hi.

INCLUDES = $(shell root-config --cflags) $(shell root-config --libs) $(shell root-config --glibs)
is wrong - you’re mixing compiler and linker flags, and INCLUDES should only contain the compiler’s include search path directives. You’ll have to add the root-config --glibs to the autotools library statement.

I’m sure you’ll spend far more time on this than just running “.L includes_all_sources.C+”, which loads all your code (via a file which #includes all your sources) as a shared library into ROOT, so you can execute your compiled code. But it’s of course up to you :wink:

Cheers, Axel.[/quote]

Thanks, but I prefer using autotools and gcc and not CINT


#4

You are mixing autotools with the common use of the Makefile.

In first you must in include in configure.ac file the ROOT_PATH macro. If you use this macro in your Makefile.am you can add:

program_CXXFLAGS = @ROOTCFLAGS@

that add the path of the ROOT includes

and

program_LDADD = @LIBS@ @ROOTLIBS@ @ROOTLIBDIR@

that add the linker flags.

“program” is yor program’s name.

This is because you in a not standard way have succes to set the includes but don’t put in any place the linker flags to use the ROOT libraries.

cheers.[/code][/list]


#5

Sorry, but in details how?


#6

dettails? ok.

I suppose you have at least a configure.ac and a Makefile.am file. The configure.ac have to contain a call to search, at configure script level, the ROOT libraries.

With ROOT are ditribuited several scripts and in particular the script root.m4, in this script exist the macro ROOT_PATH, in the script there are same examples, basically you can only add the row

ROOT_PATH

in the confgure.ac file.

When using the ROOT_PATH macro the configure find the ROOT libraries some variable are filled; the variables are documented in the script.

These variable are in the format used by automake substitution, so in you Makefile.am you can use the call

INCLUDES = @ROOTCFLAGS@

in my version of autotools realy I need to use AM_CFLAGS variable.

After the include in Makefile.am you must add the varibles with the library:

AM_LDFLAGS = @ROOTLIBS@ -L@ROOTLIBDIR@

and at the end reconfigure all.


#7

when I launch ./configure it says
./configure: line 3153: ROOT_PATH: command not found


#8

[quote=“wiso”][quote=“volpig”]
you can only add the row

ROOT_PATH

in the confgure.ac file.

[/quote]

when I launch ./configure it says
./configure: line 3153: ROOT_PATH: command not found[/quote]

Is possible that root.m4 is not in a directory read by autoconf; try to run autoconf using this command:

$ autoconf -I $ROOTSYS/build/misc

To have a common base you can attach your cnfigure.ac and the Makefile.am


#9

It is so, but I can do it?

autoconf: no input file

[quote=“volpig”]
To have a common base you can attach your cnfigure.ac and the Makefile.am[/quote]

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.57)
AC_INIT(a, 0.1, asd)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADER([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST

# Checks for library functions.
AC_CHECK_FUNCS([strstr])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT
bin_PROGRAMS = a

a_SOURCES = main.cpp colonna.h costanti.h integrale.h rdTXOclass_2.h torre.h torri.h colonna.cpp test.cpp torri.
cpp integrale.cpp rdTXOclass_2.cpp torre.cpp

a_CXXFLAGS = $(shell root-config --cflags)

a_LDADD = $(shell root-config --libs) $(shell root-config --glibs)

#10

I think you are near to the solution, try with this changes

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.57)
AC_INIT(a, 0.1, asd)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADER([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

# Checks for libraries.
ROOT_PATH

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST

# Checks for library functions.
AC_CHECK_FUNCS([strstr])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT
bin_PROGRAMS = a

a_SOURCES = main.cpp colonna.h costanti.h integrale.h rdTXOclass_2.h torre.h torri.h colonna.cpp test.cpp torri.
cpp integrale.cpp rdTXOclass_2.cpp torre.cpp

a_CXXFLAGS = @ROOTCFLAGS@

a_LDADD = -L@ROOTLIDIR@ @ROOTGLIBS@ @ROOTLIBS@

In previous post I have wrong, the sequence to reconfigure the autotools scripts is

$ aclocal -I $ROOTSYS/build/misc $ autoconf $ automake -afc


#11

it says:

Can't locate object method "path" via package "Request" at /usr/share/autoconf/Autom4te/C4che.pm line 69, <GEN1> line 217.

#12

[quote=“wiso”][quote=“volpig”]

Is possible that root.m4 is not in a directory read by autoconf; try to run autoconf using this command:

$ autoconf -I $ROOTSYS/build/misc

[/quote]

it says:

Can't locate object method "path" via package "Request" at /usr/share/autoconf/Autom4te/C4che.pm line 69, <GEN1> line 217. [/quote]

I don’t know this error message.

I can send you this exmple:

ROOT_PATH(,[
        AC_DEFINE([HAVE_ROOT],,[Root library])
        AC_CHECK_LIB([dl],[dlopen],[],AC_MSG_ERROR([Root libraries not linking properly]))
        ],AC_MSG_RESULT([Some parts of software will be not compiled]))
AM_CONDITIONAL(EXISTROOT,test x$no_root = "x")

this test also is ROOT library exists, I copied the root.m4 file in a subdirectory of the project, with a random name m4/ :slight_smile:, so I call aclocal in the main directory of the project with the syntax:

$ aclocal -I m4

#13

I retry:

this is the program alone.cpp:

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TPaveLabel.h"

int main(int argc,char **argv)
{
    TApplication theApp("App", &argc, argv);

    TCanvas *c = new TCanvas("Hello", "The Hello Canvas", 400, 400);
    c->cd();
    
    theApp.Run();

    return 0;
}

now the configure works well:

...
checking for root-config... /bin/root/bin/root-config
checking for root... /bin/root/bin/root
checking for rootcint... /bin/root/bin/rootcint
...

configure.ac :

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
AC_INIT(alone, 0.1)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([alone.cpp])
AC_CONFIG_HEADER([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

# Checks for libraries.
ROOT_PATH

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST

# Checks for library functions.

AC_CONFIG_FILES([Makefile])
AC_OUTPUT 

Makefile.am

bin_PROGRAMS = alone

alone_SOURCES = alone.cpp

alone_CXXFLAGS =  @ROOTCFLAGS@

alone_LDADD = -L @ROOTLIBDIR@ @ROOTGLIBS@ @ROOTLIBS@

the configure work, but when I compile with make it says:

make  all-am
make[1]: Entering directory `/home/ruggero/Documents/programmazione/root/alone'
g++  -g -O2   -o alone  alone-alone.o -L /bin/root/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lGui -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics
/bin/root/lib/libCint.so: undefined reference to `dlerror'
/bin/root/lib/libCore.so: undefined reference to `dladdr'
/bin/root/lib/libCint.so: undefined reference to `dlclose'
/bin/root/lib/libCint.so: undefined reference to `dlopen'
/bin/root/lib/libCint.so: undefined reference to `dlsym'
collect2: ld returned 1 exit status
make[1]: *** [alone] Error 1
make[1]: Leaving directory `/home/ruggero/Documents/programmazione/root/alone'
make: *** [all] Error 2

I’m using ROOT 5.13/06 and g++ (GCC) 4.1.0

Is there a tutorial / manual “how to use autotools with ROOT”?


#14

Hi wiso,
unfortunately seems that don’t many people use the autotools to compile the ROOT programs.

in the Makefile.am have you tried to use:

In any case probably you of some other directive to add the missing libriaries. In the check programs section try with this:

# Checks for programs. AC_CANONICAL_HOST AC_PROG_CXX AC_PROG_CC AC_PROG_RANLIB AC_LIBOBJ

and in the Makefie.am:

now I don’t have time to search in the documentation but I think that one of this macro or the simple insertion of the @LIBS@ variables can solve your problem.


#15

if I include

AC_CANONICAL_HOST 

in configure.ac when I lauch automake it says:

configure.ac:11: installing `./config.guess'
configure.ac:11: installing `./config.sub'

so I don’t include AC_CANONICAL_HOST

the configure woks well:

checking dependency style of gcc... gcc3
checking for ranlib... ranlib
checking for root-config... /bin/root/bin/root-config
checking for root... /bin/root/bin/root
checking for rootcint... /bin/root/bin/rootcint
checking how to run the C preprocessor... gcc -E
checking for egrep... grep -E

but when I compile:

cd . && /bin/sh /home/ruggero/programmazione/root/alone/missing --run autoheader
rm -f stamp-h1
touch config.h.in
cd . && /bin/sh ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-am
make[1]: Entering directory `/home/ruggero/Documents/programmazione/root/alone'
if g++ -DHAVE_CONFIG_H -I. -I. -I.    -I/bin/root/include -g -O2 -MT alone-main.o -MD -MP -MF ".deps/alone-main.Tpo" -c -o alone-main.o `test -f 'main.cpp' || echo './'`main.cpp; \
then mv -f ".deps/alone-main.Tpo" ".deps/alone-main.Po"; else rm -f ".deps/alone-main.Tpo"; exit 1; fi
g++  -g -O2   -o alone  alone-main.o -L/bin/root/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lGui -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics
/bin/root/lib/libCint.so: undefined reference to `dlerror'
/bin/root/lib/libCore.so: undefined reference to `dladdr'
/bin/root/lib/libCint.so: undefined reference to `dlclose'
/bin/root/lib/libCint.so: undefined reference to `dlopen'
/bin/root/lib/libCint.so: undefined reference to `dlsym'
collect2: ld returned 1 exit status
make[1]: *** [alone] Error 1
make[1]: Leaving directory `/home/ruggero/Documents/programmazione/root/alone'
make: *** [all] Error 2

the old alone.cpp is now main.cpp (I’ve correctly changed the name in configure.ac and Makefile.am)

not good! if you have a large program (like ROOT) how can you distribuite it? With a single Makefile for all users? If I have a pc linux, my friend a sparc computer, maybe I want to compile the source optimize with my processor… if I haven’t a optional library…

quite all (I know 2 program that doesn’t use gnu autools, one is geant4, in fact from my point of view it is hard to install) gnu programs are distribuite with configure/make installation method automatically created with autools.[/quote]


#16

To complete your distribution with config.guess and config.sub I think you have to lanch

$ automake -afc

I partially agree with you becuase I have a program that ROOT only if an option and the m4 macro work.

In any case have you tried also to add the “@LIBS@” in makefile.am? or you can add the -ldl option in the alone_LDADD variable add all will work.


#17

I’ve added the -ldl in Makefile.am:

alone_LDADD = -L@ROOTLIBDIR@ @ROOTGLIBS@ @ROOTLIBS@ @LIBS@ -ldl

now it woks (I don’t know why). Thank you very much!


#18

Your welcome :smiley:

the -ldl library work on dynamic libraries load and you don’t resolve symbols of this library.

[quote=“wiso”]I’ve added the -ldl in Makefile.am:

alone_LDADD = -L@ROOTLIBDIR@ @ROOTGLIBS@ @ROOTLIBS@ @LIBS@ -ldl

now it woks (I don’t know why). Thank you very much![/quote]