Issue with linking cgi fortran function(ran()) to g++

Hello,
I have been trying to link the function ran() that is being used in a fortran program that uses pgi’s libraries. The version is linux86 5.1.

Error output:

 g++    -c -o momentum.o momentum.cpp
g++    -c -o event.o event.cpp
g++ -g  -O2 `cernlib -u mathlib kernlib jetset74 packlib_noshift -lnsl -lcrypt -ldl` main.o constants.o nucleus.o particle.o flux.o difflum.o bessel.o pofb.o sigma.o momentum.o event.o  -o ../bin/starlight   `cernlib -u mathlib kernlib jetset74 packlib_noshift -lnsl -lcrypt -ldl` -L/usr/pgi/linux86/5.1/lib  -lpgftnrtl -lpgc
momentum.o(.text+0x3c7): In function `momenta::pickw(double&)':
: undefined reference to `ran_'
momentum.o(.text+0x97a): In function `momenta::picky(double&)':
: undefined reference to `ran_'
momentum.o(.text+0xc4f): In function `momenta::pickwy_vm(double&, double&)':
: undefined reference to `ran_'
momentum.o(.text+0xcff): In function `momenta::pickwy_vm(double&, double&)':
: undefined reference to `ran_'
momentum.o(.text+0xdd7): In function `momenta::pickwy_vm(double&, double&)':
: undefined reference to `ran_'
momentum.o(.text+0xfbf): more undefined references to `ran_' follow
collect2: ld returned 1 exit status
gmake: *** [../bin/starlight] Error 1

The makefile used to compile the fortran code:

#choose ONE of the following two lines, depending on operating system
include Makefile.Linux
#include Makefile.SunOS
#
BIN= ../bin
#

SLIB = `cernlib -u mathlib kernlib jetset74 packlib_noshift -lnsl -lcrypt -ldl`
#SLIB = `cernlib mathlib kernlib packlib jetset74 cernlib -u packlib_noshift -lnsl -lcrypt -ldl`
#SLIB = `cernlib -v pro mathlib packlib kernlib jetset74`
#
#CGLIB=`cernlib -v new -G mathlib`
#
#       Libraries
#
#
#CERNLIB=/cern/pro/lib
#LIBS= -L$(CERNLIB) -lmathlib -ljetset74 -lkernlib
#
# Additional suffixes
#
.SUFFIXES: .F .cdf  .car .cra
#
#      Executable Name
EXE = starlight
#
#
#          Fortran Sources
#
FSOURCES = starlight.f \
           vladimir.f \
           diffLum_vm.f \
           flux.f \
           formf.f \
           nrbw.f \
           sigma_A.f \
           sigmagp.f \
           vmomenta.f\
           sigmavm.f\
           rws.f\
           t.f\
           sigmavmw.f\
           setConst.f\
           momenta.f\
           decayEvent.f\
           taudecay.f\
           thetalep.f\
           transform.f\
           thephi.f\
          input.f\
           newparam.f\
           diffLum_2gamma.f\
           readDiffLum.f\
           sigmacalc.f\
           sigmadelta.f\
           sigma2.f\
           sigmui.f\
           pickw.f\
           picky.f\
           tablecalc.f\
           pp.f\
           pperpdist.f\
           writejetsetText.f\
           writejetsetGSTARtext.f\
           writejetsetNtuple.f\
           writeText.f\
           writeGSTARtext.f\
           writeNtuple.f\
           jtog.f\
           twodecay.f\
           pickwy_vm.f\
           heptup.f\
           photonbreakup.f\
           hadronbreakup.f\
           pttablegen.f\
           vmpt.f\
           vmsigmapt.f\
           nofe.f\
           radmul.F\
           PofB.f\

#
#      C Sources
#
CSOURCES =
#
#
#
# Objects list
#
OBJECTS= $(FSOURCES:.f=.o) \
         $(CSOURCES:.c=.o)
#
#
#
#---------
main:
        make $(BIN)/$(EXE)
#
# Target definitions
#
#
$(BIN)/$(EXE):  $(OBJECTS)
# use the following line to compile on Solaris
#       $(FC) -o $(BIN)/$(EXE) $(OBJECTS) $(SLIB) -L/opt/WS5.0/lib -lM77 -lM77 -lF77 -lsunmath
#use the following line to compile on Linux
        $(FC) -o $(BIN)/$(EXE) $(OBJECTS) $(SLIB) -L/usr/pgi/linux86/lib -lpgftnrtl -lpgc -L/usr/local/pkg/egcs-1.1.2-lhc/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.91.66 -lg2c
#
#
#    Second-level dependencies
#
.F.o:
        $(FC) -c -o $*.o $*.F

#  Cleanup

        rm -rf $(BIN)/starlight.dat
clean:

        rm -rf *.o

The makefile for the C++ portion:

### MAKEFILE (UNIX with X-win and OpenGL) ###

### C++ compiler
CC = g++ -g

### Optimization
OPTIMIZE = -O2

### Waring level
#WARNING =
WARNING = -c -Wall


### Xlib lib directory
#XLIB_LIB = -L/usr/X11R6/lib

### Xlib   include directory
#XLIB_INC  = -I/usr/X11R6/include

### Directory where to install executable files
INSTALL_DIR = ../bin
SOURCE_DIR = .

### Socket libraries to be linked
SOCKET_LIBS =


### Library
LIBS = `cernlib -u mathlib kernlib jetset74 packlib_noshift -lnsl -lcrypt -ldl`
# -lCore -lCint -lMatrix -lTree
#LIB_DIR = -L$(ROOTSYS)/lib

#ROOTLIBS       := $(shell root-config --libs)
#LIBS           = $(ROOTLIBS) $(SYSLIBS)

### Include-file directories
#INCLUDE_DIR   = -I$(ROOTSYS)/include


### Executalble files
EXEC = $(INSTALL_DIR)/starlight

### Object files
OBJ =  main.o constants.o nucleus.o particle.o flux.o difflum.o bessel.o pofb.o sigma.o momentum.o event.o
### binary directory



### Commpilation
$(EXEC): $(OBJ)
        @mkdir -p $(INSTALL_DIR)
        $(CC)  $(OPTIMIZE) $(LIBS) $(OBJ) -o $(EXEC)  $(SOCKET_LIBS) $(LIBS) -L/usr/pgi/linux86/5.1/lib  -lpgftnrtl -lpgc

        strip  $(EXEC)

#### clean

The part of the C++ that is complaining(or so I think):

#include <iostream>
#include <fstream>
using namespace std;
//#include <cstdlib>
#include <math.h>
#include "main.h"
#include "bessel.h"
#include "constants.h"
#include "nucleus.h"
#include "particle.h"
#include "flux.h"
#include "sigma.h"
#include "momentum.h"

//extern "C"{ extern float ran_(int* );}

momenta::momenta()
{
}
momenta::~momenta()
{
}
void momenta::pickw(double &w)
{

        double sgf=0.,signorm=0.,x=0.,remainarea=0.,remainw=0.,a=0.,b=0.,c=0.;


               x = ran_(&iseed);

.....


#ifndef MAIN_H
#define MAIN_H

        extern "C"{ extern double ran_(int* );}

#endif

It’s a class structure so maybe that has something to do with the way it is being referenced, but my experience with linking across languages is limited, so any help would be very beneficial. Thank you much.

Hi butter,

There are a number of possible causes for this but first make sure that the library or object where the ‘ran’ function is defined is included on the link line. If the library or object is being included, next check that the symbol ‘ran_’ is in the library or object as expected (nm libname.a | grep ‘ran_’ or nm objectname.o | grep ‘ran_’). Note that if you have compiled this library or object with another compiler like g77, then the symbol may have two underscores appended instead of one.

Hope this helps,

  • Mat