Я пишу программу конечных элементов на C++ с использованием библиотеки Eigen. Хотя компоновщик, похоже, не распознает все мои файлы.
Это ошибка, которую я получаю:
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
Мой основной файл следующий:
#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;
}
и речь идет о следующем файле, eigen_ext.cpp (некоторые функции я нашел на этом же форуме):
#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
Вот отрывок из файла stiff.cpp, содержащего начало функции жесткости, в которой вызывается функция извлечения:
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;
Все файлы, кроме main.cpp, имеют заголовок .hpp, содержащий ссылку на библиотеки и определения функций в эквиваленте .cpp.
Мой make-файл следующий:
#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)
Я использую g ++ версии 7.2.0 в macOS (установлен с помощью homebrew). Все объектные файлы существуют после компиляции, и у меня нет ошибок компиляции, кроме необнаруженных символов.
Прочитав повсюду о компоновке и библиотеках в течение нескольких недель, я все еще сталкиваюсь с той же проблемой. Думаю, проблему очень просто решить, но я не могу ее найти. По этой причине я решил спросить об этом здесь. Большое спасибо!
Большое спасибо за ваш ответ, но Eigen - это библиотека только для заголовков (в документации также говорится о добавлении ее вместе с -I). Когда я использую команду -l, она даже не находит библиотеку: /
Когда я компилирую тестовую программу, например, просто для того, чтобы напечатать квадратную нулевую матрицу с помощью Eigen, кажется, что она работает. Кажется, проблема в моих новых функциях.
Похоже, вы столкнулись с этой проблемой: stackoverflow.com/q/115703
Возможный дубликат Сохранение определений шаблонных функций C++ в файле .CPP





-I(верхний регистрi) - неправильный вариант для использования с компоновщиком. Эта опция добавляет каталог поиска для препроцессор для поиска файлов заголовков. Если вы хотите связать с библиотекой, используйте опцию-l(нижний регистрL), чтобы указать имя библиотеки.