Compiling root macro

Hello,

I would like to be able to compile a root macro so that a user with just the correct root libraries can run it through a command like ./Sum
I don’t know if this is possible and am having difficulty tracking down instructions and tutorials concerning compiling scripts within root.
I took a very simple summation code from a website example:

Sum.C

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

void sum() {
  int max=0;
  cout << "Type in upper limit ";
  cin >> max;

  int sum = 0;
  for ( int i = 0; i <= max; ++i) {
    sum += i;
  }

  cout << "The sum of 1.." << max << " is " << sum << endl;
}

And I have attempted to compile it through my normal c++ method but receive the errors:

herbie@herbie-laptop:~/Documents/root/rootinput$ gcc -o sum sum.C
/usr/lib/gcc/i486-linux-gnu/4.4.1/…/…/…/…/lib/crt1.o: In function _start': /build/buildd/eglibc-2.10.1/csu/../sysdeps/i386/elf/start.S:115: undefined reference tomain’
/tmp/ccwUsCsH.o: In function sum()': sum.C:(.text+0x19): undefined reference tostd::cout’
sum.C:(.text+0x1e): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' sum.C:(.text+0x2c): undefined reference tostd::cin’
sum.C:(.text+0x31): undefined reference to std::basic_istream<char, std::char_traits<char> >::operator>>(int&)' sum.C:(.text+0x6a): undefined reference tostd::cout’
sum.C:(.text+0x6f): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' sum.C:(.text+0x7b): undefined reference tostd::basic_ostream<char, std::char_traits >::operator<<(int)'
sum.C:(.text+0x8b): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' sum.C:(.text+0x9a): undefined reference tostd::basic_ostream<char, std::char_traits >::operator<<(int)‘
sum.C:(.text+0xa2): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)' sum.C:(.text+0xaa): undefined reference tostd::basic_ostream<char, std::char_traits >::operator<<(std::basic_ostream<char, std::char_traits >& (*)(std::basic_ostream<char, std::char_traits >&))’
/tmp/ccwUsCsH.o: In function __static_initialization_and_destruction_0(int, int)': sum.C:(.text+0xd1): undefined reference tostd::ios_base::Init::Init()'
sum.C:(.text+0xd6): undefined reference to std::ios_base::Init::~Init()' /tmp/ccwUsCsH.o:(.eh_frame+0x12): undefined reference to__gxx_personality_v0’
collect2: ld returned 1 exit status
herbie@herbie-laptop:~/Documents/root/rootinput$

Any help would be fantastic. I’m afraid that I’m fairly new to root, so I dont know much of the technical details, but I’d very much like to get this to work.
Many Thanks.

Geoff Herbert

PS, Am I also correct in thinking that if I wanted to take the input from the command line, then I would write the code as:

Sum.C

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

void sum(int max=0) {

  int sum = 0;
  for ( int i = 0; i <= max; ++i) {
    sum += i;
  }

  cout << "The sum of 1.." << max << " is " << sum << endl;
}

Thanks.

You need a main program:

#include <TROOT.h>
#include <iostream>

using namespace std;

int  main () {
   int max=0;
   cout << "Type in upper limit ";
   cin >> max;

   int sum = 0;
   for ( int i = 0; i <= max; ++i) {
      sum += i;
   }

   cout << "The sum of 1.." << max << " is " << sum << endl;
}

I am using the following script file to compile and link little ROOT applications:

set -x
g++ -O2 -pipe -Wall -W -Woverloaded-virtual -fPIC -Iinclude  -pthread \
-I $ROOTSYS/include -o $1.o -c $1.cxx


g++ -O2 -m32 $1.o -L$ROOTSYS/lib -lCore -lCint -lRIO -lNet -lHist -lGraf \
-lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore \
-lThread -pthread -lm -ldl -rdynamic  -o $1

Example:

pcphsft55> doroot sum
+ g++ -O2 -pipe -Wall -W -Woverloaded-virtual -fPIC -Iinclude -pthread -I /home/couet/root/include -o sum.o -c sum.cxx
+ g++ -O2 -m32 sum.o -L/home/couet/root/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic -o sum
pcphsft55> ./sum
Type in upper limit 10
The sum of 1..10 is 55

Hi Couet,

Thanks for the help. I should have spotted that basic c++ error of no main function. Sorry.

I’ve now re-written the code to be:

#include <iostream>
#include <TCanvas.h>
#include <TColor.h>
#include <TH1.h>
#include <TLegend.h>
#include <TROOT>

using namespace std;


int  main ()
{
  int max=0;
  cout << "Type in upper limit ";
  cin >> max;
  int sum = 0;
  for ( int i = 0; i <= max; ++i)
    {
    sum += i;
    }
  cout << "The sum of 1 to " << max << " is " << sum << endl;
}

If I comment out the root include statements then it compiles fine using g++ -o Sum Sum.C
and then runs fine.

However with the include statements left in, it porduces the errors

sum.C:2:21: error: TCanvas.h: No such file or directory
sum.C:3:20: error: TColor.h: No such file or directory
sum.C:4:17: error: TH1.h: No such file or directory
sum.C:5:21: error: TLegend.h: No such file or directory
sum.C:6:17: error: TROOT: No such file or directory

So I now understand why you are running such a script, since g++ can’t find the root libraries.

I am therefore using the script you gave me:

set -x
g++ -O2 -pipe -Wall -W -Woverloaded-virtual -fPIC -Iinclude  -pthread \
-I $ROOTSYS/include -o $1.o -c $1.cxx


g++ -O2 -m32 $1.o -L$ROOTSYS/lib -lCore -lCint -lRIO -lNet -lHist -lGraf \
-lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore \
-lThread -pthread -lm -ldl -rdynamic  -o $1

which I have saved as “doroot” and am attempting to run it as:
herbie@herbie-laptop:~/Documents/root/rootinput$ doroot sum.C
doroot: command not found

but receive the error above.

I don’t really understand this wrapper script. I understand what the aim of it is, but I don’t understand how to run it or how it works.

Many thanks for your help.
Geoff Herbert

I would also like to be able to pass the input as a command line argument, eg.
herbie@herbie-laptop:~/Documents/root/rootinput$ ./sum 100
The sum of 1 to 100 is 5050

But I can’t get main() to accept command line arguments. It either wants none, or it wants 2. I really dont understand this. Surely there is a way to pass command line arguments.

the script should be make executable:
chmod +x doroot
and put in a directory pointed by $PATH
also $ROOTSYS should be defined.

Sorry, I’m afraid that I’m also very new to linux.
What should the $ROOTSYS be replaced with?
and I have renamed sum.C to be sum.cxx Is this what I am supposed to do?

and I am now trying to run the script as ./doroot sum
Is this correct?

Also, what do you mean by I should put it in a directory pointed to by $PATH

Sorry, but I really am very new to linux

Many Thanks,

Geoff Herbert

This is now fixed.