0

I am writing a finite element program in C++ using the Eigen library. Though, the linker doesn't seems to recognize all my files.

This is the error I get:

Undefined symbols for architecture x86_64:
  "Eigen::Matrix<float, 3, 1, 0, 3, 1> pear::extract<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Block<Eigen::Ma
trix<int, -1, -1, 0, -1, -1>, 1, -1, false> >(Eigen::Matrix<float, -1, 1, 0, -1, 1> const&, Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1>, 1, -1,
false> const&)", referenced from:
      pear::stiff(Eigen::Matrix<float, -1, 1, 0, -1, 1>&, Eigen::Matrix<float, -1, 1, 0, -1, 1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&) in stiff.o
  "Eigen::Matrix<float, -1, 1, 0, -1, 1> pear::load_csv<Eigen::Matrix<float, -1, 1, 0, -1, 1> >(std::__cxx11::basic_string<char, std::char_traits<char>
, std::allocator<char> > const&)", referenced from:
      _main in main.o
  "Eigen::Matrix<int, -1, -1, 0, -1, -1> pear::load_csv<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::__cxx11::basic_string<char, std::char_traits<char>
, std::allocator<char> > const&)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64

My main file is the following one:

#include "eigen_ext.hpp"
#include "stiff.hpp"
#include <iostream>
#include <Eigen/Core>

int main(int args, char *argv[]) {
  Eigen::MatrixXf stiff_matrix;
  Eigen::MatrixXi node;
  Eigen::VectorXf xp, yp;

  node = pear::load_csv<Eigen::MatrixXi>("../mesh/node.csv");
  xp = pear::load_csv<Eigen::VectorXf>("../mesh/xp.csv");
  yp = pear::load_csv<Eigen::VectorXf>("../mesh/yp.csv");
  return 0;
}

and the file in question is the following one, eigen_ext.cpp (I founded some of the functions on this same forum):

#include "eigen_ext.hpp"

namespace pear {
template <typename T1, typename T2, typename T3>
T1 extract(const T2 &full, const T3 &ind) {
  int num_indices = ind.innerSize();
  T1 target(num_indices);
  for (int i = 0; i < num_indices; i++) {
    target[i] = full[ind[i]];
  }
  return target;
} // namespace
  // peartemplate<typenameT1,typenameT2,typenameT3>T1extract(constT2&full,constT3&ind)

template <typename M> M load_csv(const std::string &path) {
  std::ifstream indata;
  indata.open(path);
  std::string line;
  std::vector<double> values;
  uint64_t rows = 0;
  while (std::getline(indata, line)) {
    std::stringstream lineStream(line);
    std::string cell;
    while (std::getline(lineStream, cell, ',')) {
      values.push_back(std::stod(cell));
    }
    ++rows;
  }
  return Eigen::Map<
      const Eigen::Matrix<typename M::Scalar, M::RowsAtCompileTime,
                          M::ColsAtCompileTime, Eigen::RowMajor>>(
      values.data(), rows, values.size() / rows);
}

} // namespace pear

Here is an excerpt of the stiff.cpp containing the beginning of the stiff function, where the extract function is called:

MatrixXf stiff(VectorXf &xp, VectorXf &yp, MatrixXi &node) {
  /*
  xp(i) : x-coordinates of the nodes
  yp (i): y-coordinates of the nodes
  node(i,j,k) : edges matrix (for each triangle, the indices of the three nodes)
  */

  /*
  m : number of triangles of triangulation
  n : number of vertices of triangulation (edges??)
  */
  int n = node.rows(); // number of vertices
  int m = n - 2; // each points creates a new triangle except for the two first
                 // ones (can be seen as a variation of Euler's characteristic)

  // stiff matrix declaration
  MatrixXf S = MatrixXf::Zero(n, n), Dphi(3, 2);
  Vector3f x = Vector3f::Zero(), y = Vector3f::Zero();
  float D = 1;
  int i, j;

All files except the main.cpp have a .hpp header containing reference to the libraries and the definitions of the functions in the .cpp equivalent.

My makefile is the following one:

#MAKEFILE FOR WIT PROJECT

.PHONY: clean all info

#CXX = g++
CXX = gcc-7
#CXX = clang

TARGETS := eigen_ext stiff tests main
SOURCES := $(TARGETS:=.cpp)
OBJS    := $(TARGETS:=.o)

OFLAGS := -O2 -O3 -ffast-math
PARALLELFLAGS:= -D_GLIBCXX_PARALLEL -fopenmp -pthread -DUSEOMP
CXXFLAGS := -Wall -std=c++14 -v
LDFLAGS  :=
LIBS :=  -lstdc++ -I../Eigen
LIPOPT :=
OPENMPLIB :=

EXAMPLE_DEPS = Makefile

all: main

clean:
    rm -f $(OBJS) $(TARGETS)

info:
    @echo Compiler:  CXX      = $(CXX)
    @echo Compile command: COMPILE.cc  = $(COMPILE.cc)
    @echo Link command:    LINK.cc     = $(LINK.cc)

eigen_ext.o: eigen_ext.cpp $(EXAMPLE_DEPS)
    @$(CXX) -c $(CXXFLAGS) $(OFLAGS) $(LIBS) -o eigen_ext.o eigen_ext.cpp
stiff.o: stiff.cpp $(EXAMPLE_DEPS)
    @$(CXX) -c $(CXXFLAGS) $(OFLAGS) $(LIBS) -o stiff.o stiff.cpp
main.o: main.cpp $(EXAMPLE_DEPS)
    @$(CXX) -c $(CXXFLAGS) $(OFLAGS) $(LIBS) -o main.o main.cpp
main: main.o stiff.o eigen_ext.o
    @$(CXX) $(LDFLAGS) -o main main.o stiff.o eigen_ext.o $(LIBS)

I am using g++ version 7.2.0 in macOS (installed with homebrew). All the object files exist after compilation and I have no compilation error except the not founded symbols.

After reading everywhere about linking and libraries for weeks, I am still stuck at the same problem. I suppose the problem is very simple to solve, though, I cannot find it. For this reasons, I decided to ask it here. Thank you very much!

  • `-I` (upper case `i`) is the wrong option to use with the linker. That option adds a search-directory for the the *preprocessor to look for header files*. If you want to link with a library use the `-l` (lower-case `L`) option to specify the library name. – Some programmer dude Mar 22 '18 at 17:27
  • Thank you very much for your answer, but Eigen is a header only library (the documentation also says to add it with `-I`). When I use the `-l` command, it doesn't even find a library :/ – hdeplaen Mar 22 '18 at 19:41
  • When I compile a test program, just to print a square zero matrix with Eigen for example, it seems to work. My new functions seem to be the problem. – hdeplaen Mar 22 '18 at 19:45
  • It looks like you are facing this problem: https://stackoverflow.com/q/115703/ – chtz Mar 23 '18 at 10:17
  • Possible duplicate of [Storing C++ template function definitions in a .CPP file](https://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file) – chtz Mar 23 '18 at 18:23

0 Answers0