Using autotools

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*)’

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

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]

Sorry, but in details how?

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.

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

[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

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)

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

it says:

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

[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

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”?

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.

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]

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.

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!

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]