gcolumbus
gcolumbus

Reputation: 127

undefined reference to function while using static libraries

I'm attempting to write a program using a genetic algorithm which is a particular type of optimization algorithm. I found a free library for this task called "Evolutionary Objects" and implemented a very simple genetic algorithm instance. The program code, the build commands that netbeans implements, and finally the error messages that I receive are posted below in separate blocks. If you allow me your help, you'll see that something is going wrong with the cout function. When I searched the internet for similar difficulties, I found that people had been correcting the problem by simply using g++ rather than gcc yet I am already using g++, as you can see. Any help would be appreciated....

The program code is immediately below:

#include <stdexcept>
#include <iostream>
#include <eo>
#include <ga.h>

typedef eoBit<double> Indi;

double binary_value(const Indi & _indi)
{
  double sum = 0;
  for (unsigned i = 0; i < _indi.size(); i++)
    sum += _indi[i];
  return sum;
}

void main_function(int argc, char **argv)
{

  const unsigned int SEED = 42;      // seed for random number generator
  const unsigned int T_SIZE = 3;     // size for tournament selection
  const unsigned int VEC_SIZE = 16;   // Number of bits in genotypes
  const unsigned int POP_SIZE = 100;  // Size of population
  const unsigned int MAX_GEN = 400;  // Maximum number of generation before STOP
  const float CROSS_RATE = 0.8;      // Crossover rate
  const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
  const float MUT_RATE = 1.0;        // mutation rate

  rng.reseed(SEED);

  eoEvalFuncPtr<Indi> eval(  binary_value );

  eoPop<Indi> pop;

  for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)
    {
      Indi v;           // void individual, to be filled
      for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)
    {
      bool r = rng.flip(); // new value, random in {0,1}
      v.push_back(r);      // append that random value to v
    }
      eval(v);                 // evaluate it
      pop.push_back(v);        // and put it in the population
    }

  pop.sort();

  cout << "Initial Population" << endl;
  cout << pop;

  eoDetTournamentSelect<Indi> select(T_SIZE);  // T_SIZE in [2,POP_SIZE]
  eo1PtBitXover<Indi> xover;
  eoBitMutation<Indi>  mutation(P_MUT_PER_BIT);

  eoGenContinue<Indi> continuator(MAX_GEN);

  eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE, eval, continuator);

  gga(pop);

  pop.sort();
  cout << "FINAL Population\n" << pop << endl;
}

int main(int argc, char **argv)
{
main_function(argc, argv);
    return 1;
}
}

Netbeans shows me that it is doing this when attempting build:

make[1]: Entering directory `/home/gregemerson/EO_GA/EO_GA'
rm -f -r build/Debug
rm -f dist/Debug/GNU-Linux-x86/eo_ga
make[1]: Leaving directory `/home/gregemerson/EO_GA/EO_GA'


CLEAN SUCCESSFUL (total time: 94ms)

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/home/gregemerson/EO_GA/EO_GA'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/eo_ga
make[2]: Entering directory `/home/gregemerson/EO_GA/EO_GA'
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
g++    -c -g -I../../EO/EO/eo/src -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
mkdir -p dist/Debug/GNU-Linux-x86
g++     -o dist/Debug/GNU-Linux-x86/eo_ga build/Debug/GNU-Linux-x86/main.o -L../../EO/EO/eo/build/lib /home/gregemerson/EO/EO/eo/build/lib/libcma.a /home/gregemerson/EO/EO/eo/build/lib/libeoutils.a /home/gregemerson/EO/EO/eo/build/lib/libes.a /home/gregemerson/EO/EO/eo/build/lib/libga.a 

The error messages are immediately below:

/home/gregemerson/EO_GA/EO_GA/main.cpp:94: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
/home/gregemerson/EO_GA/EO_GA/main.cpp:99: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
/home/gregemerson/EO_GA/EO_GA/main.cpp:149: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
build/Debug/GNU-Linux-x86/main.o: In function `eoPop<eoBit<double> >::sortedPrintOn(std::basic_ostream<char, std::char_traits<char> >&) const':
/home/gregemerson/EO_GA/EO_GA/../../EO/EO/eo/src/eoPop.h:294: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
build/Debug/GNU-Linux-x86/main.o: In function `std::ostream_iterator<eoBit<double>, char, std::char_traits<char> >::operator=(eoBit<double> const&)':
/usr/include/c++/4.6/bits/stream_iterator.h:198: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/eo_ga] Error 1
make[2]: Leaving directory `/home/gregemerson/EO_GA/EO_GA'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/gregemerson/EO_GA/EO_GA'
make: *** [.build-impl] Error 2

Your response did correct for my cout(pop) problem. However, I'm now seeing similar errors in a headers for one of the static libraries that I'm using along with what looks to be related to one of the basic c++ libraries. I get the following. Does this make sense to you?

build/Debug/GNU-Linux-x86/main.o: In function `std::ostream_iterator<eoBit<double>, char, std::char_traits<char> >::operator=(eoBit<double> const&)':
/usr/include/c++/4.6/bits/stream_iterator.h:198: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'
build/Debug/GNU-Linux-x86/main.o: In function `eoPop<eoBit<double> >::sortedPrintOn(std::basic_ostream<char, std::char_traits<char> >&) const':
/home/gregemerson/EO_GA/EO_GA/../../EO/EO/eo/src/eoPop.h:294: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'

Upvotes: 1

Views: 1278

Answers (2)

Abdul Hameed
Abdul Hameed

Reputation: 11

Many peoples are experiencing this problem when they try to use EO C++ lib for first time. I also faced this problem and were able to find the solution. The problem is that the linker does not find the static libraries that have to be linked while building the EO programs. I am now able to successfully compile and use the first tutorial i.e. FirstBitGA.cpp & FirstRealGA.cpp with EO-1.3.1 on Ubunut 10.04 (LTS).

Note: I am writing the complete steps starting from installation, so be patient. Also replace the word 'username' with your user account.

<< Solution >>

  1. Download EO Lib from http://sourceforge.net/projects/eodev/files/latest/download?source=files
  2. Create a directory named EO; I create it in /home/username/ .
  3. Copy the EO Zip file to /home/username/EO and uncompressed it. This will create another directory named 'eo' under /home/username/EO.
  4. Now build the installation files by running the build script in /home/username/EO/eo/build_gcc_linux_release in terminal.
  5. The build script in step-4 will create a directory named 'release' under /home/username/EO/eo. In the release directory the 'lib' folder contains the libraries that have to be linked while compiling any EO program.
  6. Now two paths have to be provided to the compiler for successful compilation:

    6.1. The path to include files as a command line argument to g++ i.e. -I /home/username/EO/eo/src < OR > If you are using Qt creator IDE then enter the line ' INCLUDEPATH += /home/username/EO/eo/src' in the .pro file of the probject.

    6.2. The path to all link libraries with -L argument to g++ i.e.

    -L/home/username/EO/eo/release/lib/libcma.a /home/username/EO/eo/release/lib/libeo.a /home/username/EO/eo/release/lib/libeoserial/home/username/EO/eo/release/lib/libeoutils.a /home/username/EO/eo/release/lib/libes.a /home/username/EO/eo/release/lib/libga.a
    

    For Qt Creator users, enter the following lines into .pro file,

    LIBS += -L/home/username/EO/eo/release/lib/libcma.a /home/username/EO/eo/release/lib/libeo.a /home/username/EO/eo/release/lib/libeoserial.a /home/username/EO/eo/release/lib/libeoutils.a /home/username/EO/eo/release/lib/libes.a /home/username/EO/eo/release/lib/libga.a

  7. Enjoy

Upvotes: 1

Sam DeHaan
Sam DeHaan

Reputation: 10325

The issue is (for example) here:

cout << pop;

The error,

/home/gregemerson/EO_GA/EO_GA/main.cpp:94: undefined reference to 
`operator<<(std::basic_ostream<char, std::char_traits<char> >&, eoPrintable const&)'

Means that there is no basic function that knows how to push an eoPrintable object into an ostream.

Based on the link provided in the comments, this eoPop class has defined a few methods for printing: sortedPrintOn and printOn.

In order to use one of them to print to cout, you would do the following:

pop.printOn(cout); //or pop.printOn(std::cout) if you remove using namespace std;
pop.printSortedOn(cout);

Upvotes: 3

Related Questions