当我遇到以下问题时,我正在尝试为我的论文项目编译一些代码:clang链接器不断告诉我一些符号已在不同的目标文件中重复;查看其他有类似问题的用户,这看起来像是Xcode问题(我在2012年中期在Macbook Pro上运行,macOS High Sierra),但是我一直使用clang遵循类似的规则进行编译,但从未发现类似的问题错误。
这些是我的密码;我将包括标题,源代码和makefile ev_mpi.hpp
#ifndef RANK_RNG_OFFSET
#define RANK_RNG_OFFSET 1000
#endif
#include <mpi.h>
namespace ev_mpi {
bool MPI_Is_initialized (void)
{
int is_parallel;
MPI_Initialized( &is_parallel );
return (bool)is_parallel;
}
template<class data_type> MPI_Datatype MPI_Data_convert(void);
template<> MPI_Datatype MPI_Data_convert<char>(void) { return MPI_CHAR; }
template<> MPI_Datatype MPI_Data_convert<short int>(void) { return MPI_SHORT; }
template<> MPI_Datatype MPI_Data_convert<int>(void) { return MPI_INT; }
template<> MPI_Datatype MPI_Data_convert<long int>(void) { return MPI_LONG; }
template<> MPI_Datatype MPI_Data_convert<unsigned char>(void) { return MPI_UNSIGNED_CHAR; }
template<> MPI_Datatype MPI_Data_convert<unsigned short int>(void) { return MPI_UNSIGNED_SHORT; }
template<> MPI_Datatype MPI_Data_convert<unsigned int>(void) { return MPI_UNSIGNED; }
template<> MPI_Datatype MPI_Data_convert<unsigned long int>(void) { return MPI_UNSIGNED_LONG; }
template<> MPI_Datatype MPI_Data_convert<float>(void) { return MPI_FLOAT; }
template<> MPI_Datatype MPI_Data_convert<double>(void) { return MPI_DOUBLE; }
template<> MPI_Datatype MPI_Data_convert<long double>(void) { return MPI_LONG_DOUBLE; }
int MPI_Get_rank(MPI_Comm comm = MPI_COMM_WORLD)
{
int rank;
MPI_Comm_rank(comm, &rank);
return rank;
}
int MPI_Get_size(MPI_Comm comm = MPI_COMM_WORLD)
{
int size;
MPI_Comm_size(comm, &size);
return size;
}
int MPI_Seed_rank (int seed)
{
if ( MPI_Is_initialized() )
return seed + RANK_RNG_OFFSET*MPI_Get_rank();
else
return seed;
}
}
#endif /* EV_MPI_HPP */
ev_constants.hpp
#ifndef EV_CONSTANTS_HPP
#define EV_CONSTANTS_HPP
#ifndef real_number
#define real_number double
#endif
namespace ev_const {
constexpr double pi = 3.141592653589793238462643383279502884197;
constexpr double pio2 = 1.57079632679489661923132169163975144209858;
constexpr double pi2 = 6.283185307179586476925286766559005768394;
constexpr double sqrt2 = 1.41421356237309504880168872420969807856967;
constexpr double euler = 0.5772156649015328606065120900824024310422;
constexpr float pi_s = 3.141592653589793238462643383279502884197;
constexpr float pio2_s = 1.57079632679489661923132169163975144209858;
constexpr float pi2_s = 6.283185307179586476925286766559005768394;
}
#endif /* EV_CONSTANTS_HPP */
ev_utilities.hpp
#ifndef EV_UTILITIES
#define EV_UTILITIES
#include "ev_constants.hpp"
#include "ev_mpi.hpp"
#include <Eigen/Dense>
#include <iostream>
#include <cassert>
#include <algorithm>
#ifndef MPI_DEFAULT_TAG
#define MPI_DEFAULT_TAG 0
#endif
namespace ev_utility {
inline int power_n(int x, unsigned int n)
{
if (n == 0)
return 1;
else if (n%2 == 0)
return power_n(x, n/2)*power_n(x, n/2);
else
return x*power_n(x, n/2)*power_n(x, n/2);
}
template<unsigned N> struct power_impl {
template<typename T>
static T calc(const T &x) {
if (N%2 == 0)
return power_impl<N/2>::calc(x*x);
else if (N%3 == 0)
return power_impl<N/3>::calc(x*x*x);
return power_impl<N-1>::calc(x)*x;
}
};
template<> struct power_impl<0> {
template<typename T>
static T calc(const T &) {
return 1;
}
};
template<unsigned N, typename T>
inline T power(const T &x) {
return power_impl<N>::calc(x);
}
template <class data_type, int StorageOrder = Eigen::RowMajor>
class MaskMatrix {
protected:
typedef typename Eigen::Matrix<data_type, Eigen::Dynamic, Eigen::Dynamic, StorageOrder> DynamicMatrix;
int low_x, up_x, low_y, up_y;
int dim_x, dim_y;
DynamicMatrix data;
public:
MaskMatrix ( int lx, int ux, int ly, int uy ):
low_x(lx), up_x(ux), low_y(ly), up_y(uy), dim_x(ux-lx), dim_y(uy-ly), data(dim_x, dim_y)
{ }
MaskMatrix ( int lx, int ux, int ly, int uy, const data_type& dfl ):
MaskMatrix(lx,ux,ly,uy) { data.fill(dfl); }
MaskMatrix ( int lx, int ux, int ly, int uy, const DynamicMatrix& rhs ):
low_x(lx), up_x(ux), low_y(ly), up_y(uy), dim_x(ux-lx), dim_y(uy-ly), data(rhs)
{ }
MaskMatrix ( int l, int u ): MaskMatrix(l, u, l, u) { }
MaskMatrix ( int l, int u, const data_type& dfl ): MaskMatrix(l, u, l, u, dfl) { }
MaskMatrix ( int l, int u, const DynamicMatrix& rhs ): MaskMatrix(l, u, l, u, rhs) { }
MaskMatrix& operator = (const MaskMatrix& rhs)
{
if ( rhs.dim_x != dim_x || rhs.dim_y != dim_y )
std::cerr << "Matrix dimensions do not agree" << std::endl;
else
data = rhs.data;
return *this;
}
void swap ( MaskMatrix& rhs )
{
if ( rhs.dim_x != dim_x || rhs.dim_y != dim_y )
std::cerr << "Matrix dimensions do not agree" << std::endl;
else
data.swap(rhs.data);
}
inline int idx_i(const int& i) const
{
return i - low_x;
}
inline int idx_j(const int& j) const
{
return j - low_y;
}
void send_block
(int block_i, int block_j, int block_x, int block_y, int recv_rank,
int tag = MPI_DEFAULT_TAG, MPI_Comm comm = MPI_COMM_WORLD)
{
assert( ev_mpi::MPI_Is_initialized() );
DynamicMatrix data_block = data.block(idx_i(block_i), idx_j(block_j), block_x, block_y);
MPI_Send(data_block.data(), block_x*block_y, ev_mpi::MPI_Data_convert<data_type>(), recv_rank, tag, comm);
}
void recv_block
(int block_i, int block_j, int block_x, int block_y, int send_rank,
int tag = MPI_DEFAULT_TAG, MPI_Comm comm = MPI_COMM_WORLD, MPI_Status* stat = MPI_STATUS_IGNORE)
{
assert( ev_mpi::MPI_Is_initialized() );
DynamicMatrix data_block(block_x, block_y);
MPI_Recv(data_block.data(), block_x*block_y, ev_mpi::MPI_Data_convert<data_type>(), send_rank, tag, comm, stat);
data.block(idx_i(block_i), idx_j(block_j), block_x, block_y) = data_block;
}
~MaskMatrix()
{ }
data_type& operator () (int i, int j)
{
return data( idx_i(i), idx_j(j) );
}
const data_type& operator () (int i, int j) const
{
return data( idx_i(i), idx_j(j) );
}
void transpose ( void )
{
data.transposeInPlace();
int temp;
temp = low_x; low_x = low_y; low_y = temp;
temp = low_x; low_y = low_x; low_x = temp;
temp = up_x; up_x = up_y; up_y = temp;
temp = up_y; up_y = up_x; up_x = temp;
temp = dim_x; dim_x = dim_y; dim_y = temp;
}
MaskMatrix submatrix ( int lx, int ux, int ly, int uy )
{
MaskMatrix sub( lx, ux, ly, uy, data.block(idx_i(lx), idx_j(ly-low_y), ux-lx, uy-ly) );
return sub;
}
};
template <class data_type, int StorageOrder = Eigen::RowMajor>
class MaskMatrixMPI : public MaskMatrix<data_type, StorageOrder>
{
protected:
typedef MaskMatrix<data_type,StorageOrder> Base;
typedef typename Base::DynamicMatrix DynamicMatrix;
const MaskMatrix<int>& rank_schema;
int n_cut;
int ux_recv[8], lx_recv[8];
int uy_recv[8], ly_recv[8];
int ux_send[8], lx_send[8];
int uy_send[8], ly_send[8];
int rank_exc[8];
void inline set_schema()
{
rank_exc[0] = rank_schema(Base::low_x, Base::low_y);
rank_exc[1] = rank_schema(Base::low_x+n_cut, Base::low_y);
rank_exc[2] = rank_schema(Base::up_x-n_cut, Base::low_y);
rank_exc[3] = rank_schema(Base::up_x-n_cut, Base::low_y+n_cut);
rank_exc[4] = rank_schema(Base::up_x-n_cut, Base::up_y-n_cut);
rank_exc[5] = rank_schema(Base::low_x+n_cut, Base::up_y-n_cut);
rank_exc[6] = rank_schema(Base::low_x, Base::up_y-n_cut);
rank_exc[7] = rank_schema(Base::low_x, Base::low_y+n_cut);
lx_recv[0] = Base::low_x; ly_recv[0] = Base::low_y;
ux_recv[0] = Base::low_x+n_cut; uy_recv[0] = Base::low_y+n_cut;
lx_recv[1] = Base::low_x+n_cut; ly_recv[1] = Base::low_y;
ux_recv[1] = Base::up_x-n_cut; uy_recv[1] = Base::low_y+n_cut;
lx_recv[2] = Base::up_x-n_cut; ly_recv[2] = Base::low_y;
ux_recv[2] = Base::up_x; uy_recv[2] = Base::low_y+n_cut;
lx_recv[3] = Base::up_x-n_cut; ly_recv[3] = Base::low_y+n_cut;
ux_recv[3] = Base::up_x; uy_recv[3] = Base::up_y-n_cut;
lx_recv[4] = Base::up_x-n_cut; ly_recv[4] = Base::up_y-n_cut;
ux_recv[4] = Base::up_x; uy_recv[4] = Base::up_y;
lx_recv[5] = Base::low_x+n_cut; ly_recv[5] = Base::up_y-n_cut;
ux_recv[5] = Base::up_x-n_cut; uy_recv[5] = Base::up_y;
lx_recv[6] = Base::low_x; ly_recv[6] = Base::up_y-n_cut;
ux_recv[6] = Base::low_x+n_cut; uy_recv[6] = Base::up_y;
lx_recv[7] = Base::low_x; ly_recv[7] = Base::low_y+n_cut;
ux_recv[7] = Base::low_x+n_cut; uy_recv[7] = Base::up_y-n_cut;
lx_send[0] = Base::low_x+n_cut; ly_send[0] = Base::low_y+n_cut;
ux_send[0] = Base::low_x+2*n_cut; uy_send[0] = Base::low_y+2*n_cut;
lx_send[1] = Base::low_x+n_cut; ly_send[1] = Base::low_y+n_cut;
ux_send[1] = Base::up_x-n_cut; uy_send[1] = Base::low_y+2*n_cut;
lx_send[2] = Base::up_x-2*n_cut; ly_send[2] = Base::low_y+n_cut;
ux_send[2] = Base::up_x-n_cut; uy_send[2] = Base::low_y+2*n_cut;
lx_send[3] = Base::up_x-2*n_cut; ly_send[3] = Base::low_y+n_cut;
ux_send[3] = Base::up_x-n_cut; uy_send[3] = Base::up_y-n_cut;
lx_send[4] = Base::up_x-2*n_cut; ly_send[4] = Base::up_y-2*n_cut;
ux_send[4] = Base::up_x-n_cut; uy_send[4] = Base::up_y-n_cut;
lx_send[5] = Base::low_x+n_cut; ly_send[5] = Base::up_y-2*n_cut;
ux_send[5] = Base::up_x-n_cut; uy_send[5] = Base::up_y-n_cut;
lx_send[6] = Base::low_x+n_cut; ly_send[6] = Base::up_y-2*n_cut;
ux_send[6] = Base::low_x+2*n_cut; uy_send[6] = Base::up_y-n_cut;
lx_send[7] = Base::low_x+n_cut; ly_send[7] = Base::low_y+n_cut;
ux_send[7] = Base::low_x+2*n_cut; uy_send[7] = Base::up_y-n_cut;
}
public:
MaskMatrixMPI( const MaskMatrix<data_type>& data_, const MaskMatrix<int>& rs, int nc ):
MaskMatrix<data_type>(data_), rank_schema(rs), n_cut(nc) { set_schema(); }
void send_block
( int idx, int tag = MPI_DEFAULT_TAG, MPI_Comm comm = MPI_COMM_WORLD )
{
assert(rank_exc[idx] != -1);
Base::send_block(lx_send[idx], ly_send[idx], ux_send[idx]-lx_send[idx], uy_send[idx]-ly_send[idx], rank_exc[idx], tag, comm);
}
void recv_block
( int idx, int tag = MPI_DEFAULT_TAG, MPI_Comm comm = MPI_COMM_WORLD, MPI_Status* stat = MPI_STATUS_IGNORE )
{
assert(rank_exc[idx] != -1);
Base::recv_block(lx_recv[idx], ly_recv[idx], ux_recv[idx]-lx_recv[idx], uy_recv[idx]-ly_recv[idx], rank_exc[idx], tag, comm, stat);
}
inline int idx_from_rank(const int& r) const
{
auto it = std::find(rank_exc, rank_exc+8, r);
if ( it == rank_exc+8 )
return -1;
else
return (int)(it-rank_exc);
}
inline int rank_from_idx(const int& i) const
{
return rank_exc[i];
}
inline void print_rank_exc(void) const
{
for (int i = 0; i<8; ++i)
std::cout << rank_exc[i] << " ";
std::cout << std::endl;
}
};
}
#endif /* EV_UTILITIES */
ev_numeric.hpp
#ifndef EV_NUMERIC_HPP
#define EV_NUMERIC_HPP
#include "ev_utilities.hpp"
#include <functional>
#include <vector>
#include <iterator>
#include <cmath>
#include <iostream>
#include <limits>
namespace ev_numeric
{
std::vector<real_number> spline (std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator,
int, real_number, real_number);
real_number splint (std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator,
std::vector<real_number>::const_iterator, int, real_number);
class
Polint
{
private:
std::vector<real_number>::const_iterator xa_begin;
std::vector<real_number>::const_iterator xa_end;
std::vector<real_number>::const_iterator ya_begin;
std::vector<real_number>::const_iterator ya_end;
real_number x;
int n, ns;
real_number den, dif, dift, ho, hp, w;
std::vector<real_number> c, d;
void polint_init(void);
public:
Polint() = default;
Polint(std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator,
std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator, real_number);
// Interpolate over given vector
void interpolate(real_number&, real_number&);
// Interpolate over new vector
void interpolate(std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator,
std::vector<real_number>::const_iterator, std::vector<real_number>::const_iterator,
real_number, real_number&, real_number&);
};
class
RombergIntegrator {
private:
int JMAX = 14, K = 5;
int JMAXP = JMAX+1, KM = K-1;
real_number EPS = 1.0e-9;
std::function<real_number(real_number)> func;
std::function<real_number(real_number)> funk = [this](real_number x) {
return func(1.0/x)/(x*x);
};
real_number a, b; // extremes (finite)
real_number aa, bb; // extreme (infinite)
Polint interpolator;
void integration_step(const std::function<real_number(real_number)>&, const real_number&, const real_number&,
const int&, real_number&) const;
void mid_point (const int&, real_number&) const;
void mid_point_inf (const int&, real_number&) const;
public:
enum integral_type {finite, infinite};
RombergIntegrator() = default;
RombergIntegrator(int JMAX_, int K_, real_number EPS_):
JMAX(JMAX_), K(K_), JMAXP(JMAX_+1), KM(K_-1), EPS(EPS_), interpolator() { }
RombergIntegrator(std::function<real_number(real_number)> func_, real_number a_, real_number b_):
func(func_), a(a_), b(b_), aa(1.0/b_), bb(1.0/a_), interpolator() { }
RombergIntegrator(int JMAX_, int K_, real_number EPS_,
std::function<real_number(real_number)> func_, real_number a_, real_number b_ )
{
RombergIntegrator(JMAX_, K_, EPS_);
RombergIntegrator(func_, a_, b_);
}
real_number integrate(integral_type);
real_number integrate(std::function<real_number(real_number)>, real_number, real_number, integral_type);
inline void set_jmax(int new_jmax) { JMAX = new_jmax; JMAXP = JMAX+1; }
inline void set_k(int new_k) { K = new_k; KM = K-1; }
inline void set_eps(real_number new_eps) { EPS = new_eps; }
inline int get_jmax(void) const { return JMAX; }
inline int get_k(void) const { return K; }
inline real_number get_eps(void) const { return EPS; }
~RombergIntegrator() = default;
};
}
#endif /* EV_NUMERIC_HPP */
ev_numeric.cpp
#include "ev_numeric.hpp"
std::vector<real_number>
ev_numeric::spline
(std::vector<real_number>::const_iterator x, std::vector<real_number>::const_iterator y,
int n, real_number yp1, real_number ypn)
{
std::vector<real_number> y2(n), u(n);
real_number sig, p, qn, un;
if (yp1 > .99e30) {
y2[0] = 0.0;
u[0] = 0.0;
}
else {
y2[0] = -0.5;
u[0] = ( 3.0 / (x[1]-x[0]))*((y[1]-y[0] ) / ( x[1]-x[0])-yp1 );
}
for (int i = 1; i<n-1; ++i) {
sig = ( x[i]-x[i-1]) / (x[i+1]-x[i-1] );
p = sig * y2[i-1] + 2.0;
y2[i] = (sig-1.0) / p;
u[i] = (6.0*((y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])
/(x[i]-x[i-1]))/(x[i+1]-x[i-1])-sig*u[i-1])/p;
}
if (ypn > .99e30) {
qn = 0.0;
un = 0.0;
}
else {
qn = 0.5;
un = (3.0/(x[n-1]-x[n-2]))*(ypn-(y[n-1]-y[n-2])/(x[n-1]-x[n-2]));
}
y2[n-1]=(un-qn*u[n-2])/(qn*y2[n-2]+1.0);
for (int k = n-2; k>=0; --k) {
y2[k]=y2[k]*y2[k+1]+u[k];
}
return y2;
}
real_number
ev_numeric::splint (std::vector<real_number>::const_iterator xa, std::vector<real_number>::const_iterator ya,
std::vector<real_number>::const_iterator y2a, int n, real_number x)
{
int klo = 1, khi = n, k;
while (khi-klo > 1) {
k = (khi+klo)/2;
if (xa[k-1] > x) {
khi = k;
}
else {
klo = k;
}
}
real_number h = xa[khi-1] - xa[klo-1];
if ( h == 0.0 )
std::cerr << "Bad xa input in splint" << std::endl;
real_number a = (xa[khi-1]-x) / h;
real_number b = (x-xa[klo-1]) / h;
return a*ya[klo-1]+b*ya[khi-1]+((a*a*a-a)*y2a[klo-1]+(b*b*b-b)*y2a[khi-1])*(h*h) / 6.0;
}
ev_numeric::Polint::Polint
(std::vector<real_number>::const_iterator xa_begin_, std::vector<real_number>::const_iterator xa_end_,
std::vector<real_number>::const_iterator ya_begin_, std::vector<real_number>::const_iterator ya_end_, real_number x_):
xa_begin(xa_begin_), xa_end(xa_end_), ya_begin(ya_begin_), ya_end(ya_end_),
x(x_), dif(abs(x-xa_begin_[0])), c(ya_begin_, ya_end_), d(ya_begin_, ya_end_),
n(std::distance(xa_begin, xa_end))
{
polint_init();
}
void
ev_numeric::Polint::polint_init
(void)
{
ns = 1;
for (int i = 0; i<n; ++i) {
dift = abs(x-xa_begin[i]);
if (dift <= dif) {
ns = i;
dif = dift;
}
}
}
void
ev_numeric::Polint::interpolate
(real_number& y, real_number& dy)
{
y = ya_begin[ns];
ns = ns-1;
for (int m = 0; m<n-1; ++m) {
for (int i = 0; i<n-m; ++i) {
ho = xa_begin[i] - x;
hp = xa_begin[i+m] - x;
w = c[i+1] - d[i];
den = ho - hp;
if ( den == 0.0 )
{
std::cerr << "Failure in polint" << std::endl;
return;
}
den = w/den;
d[i] = hp*den;
c[i] = ho*den;
}
if ( 2*ns <= n-m )
dy = c[ns+1];
else
{
dy = d[ns];
ns = ns-1;
}
y = y + dy;
}
dif = abs(x-xa_begin[0]);
c.assign(ya_begin, ya_end);
d.assign(ya_begin, ya_end);
polint_init();
}
void
ev_numeric::Polint::interpolate
(std::vector<real_number>::const_iterator xa_begin_new, std::vector<real_number>::const_iterator xa_end_new,
std::vector<real_number>::const_iterator ya_begin_new, std::vector<real_number>::const_iterator ya_end_new,
real_number x_new, real_number& y, real_number& dy)
{
xa_begin = xa_begin_new; xa_end = xa_end_new; ya_begin = ya_begin_new; ya_end = ya_end_new; x = x_new;
dif = abs(x-xa_begin[0]);
c.assign(ya_begin, ya_end);
d.assign(ya_begin, ya_end);
n = std::distance(xa_begin, xa_end);
polint_init();
interpolate(y, dy);
}
void
ev_numeric::RombergIntegrator::integration_step
(const std::function<real_number(real_number)>& FUNC,
const real_number& A, const real_number& B, const int& n, real_number& s) const
{
int it;
real_number del, ddel, sum, x;
if (n==1)
s = (B-A) * func( 0.5*(A+B) );
else {
it = ev_utility::power_n(3, n-2);
del = (B-A) / (3.0*it);
ddel = 2*del;
x = A + 0.5*del;
sum = 0.0;
for (int j = 0; j<it; ++j) {
sum += FUNC(x);
x += ddel;
sum += FUNC(x);
x += del;
}
s = ( s+(B-A)*sum/it )/3.0;
}
}
void
ev_numeric::RombergIntegrator::mid_point
(const int& n, real_number& s) const
{
integration_step(func, a, b, n, s);
}
void
ev_numeric::RombergIntegrator::mid_point_inf
(const int& n, real_number& s) const
{
integration_step(funk, aa, bb, n, s);
}
real_number
ev_numeric::RombergIntegrator::integrate
(integral_type type)
{
real_number dss, ss;
std::vector<real_number> h(JMAXP, 0.0), s(JMAXP, 0.0);
h[0]=1.0;
for( int j=0; j<JMAX; ++j ) {
switch (type) {
case finite:
mid_point(j+1, s[j]);
break;
case infinite:
mid_point_inf(j+1, s[j]);
break;
default:
std::cerr << "failure in qromo (unrecognized type of integral)" << std::endl;
break;
}
if(j >= KM) {
interpolator.interpolate(h.cbegin()+(j-KM), h.cend()-(JMAXP-j), s.cbegin()+(j-KM), s.cend()-(JMAXP-j),
0.0, ss, dss);
if (abs(dss) <= EPS*abs(ss))
return ss;
}
s[j+1] = s[j];
h[j+1] = h[j]/9.0;
}
std::cerr << "Too many steps in qromo" << std::endl;
return ss;
}
real_number
ev_numeric::RombergIntegrator::integrate
(std::function<real_number(real_number)> FUNC, real_number A, real_number B, integral_type type)
{
func = FUNC;
a = A; bb = 1/A;
b = B; aa = 1/B;
return integrate(type);
}
main.cpp(虚拟)
#include "ev_numeric.hpp"
int main() {
return 0;
}
Makefile:
CXX = mpicxx
STANDARD = -std=c++11
WARNINGS = -Wall
OPTIMIZATION = -g
CXXFLAGS = $(WARNINGS) $(STANDARD) $(OPTIMIZATION)
CPPFLAGS = -I/usr/local/Cellar/eigen/3.3.7/include/eigen3
EXEC = main
SRC = ev_numeric.cpp $(EXEC).cpp
HEADS = ev_mpi.hpp ev_constants.hpp ev_utilities.hpp ev_numeric.hpp
OBJS = ev_numeric.o $(EXEC).o
.DEFAULT_GOAL = all
ev_numeric.o $(EXEC).o: ev_mpi.hpp
ev_numeric.o $(EXEC).o: ev_constants.hpp
ev_numeric.o $(EXEC).o: ev_numeric.hpp
ev_numeric.o $(EXEC).o: ev_utilities.hpp
.PHONY: all clean distclean
all: $(EXEC)
$(EXEC): $(OBJS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTIMIZATION) $^ -o $@
$(OBJS): $(SRC) $(HEADS)
clean:
$(RM) $(EXEC)
distclean:
$(RM) $(EXEC)
$(RM) *.o
我收到以下错误:
MacBook-Pro-4:enskog_vlasov_cpp macbookpro$ make
mpicxx -Wall -std=c++11 -g -I/usr/local/Cellar/eigen/3.3.7/include/eigen3 -c -o ev_numeric.o ev_numeric.cpp
ev_numeric.cpp:72:59: warning: field 'd' will be initialized after field 'n' [-Wreorder]
x(x_), dif(abs(x-xa_begin_[0])), c(ya_begin_, ya_end_), d(ya_begin_, ya_end_),
^
1 warning generated.
mpicxx -Wall -std=c++11 -g -I/usr/local/Cellar/eigen/3.3.7/include/eigen3 -c -o main.o main.cpp
mpicxx -I/usr/local/Cellar/eigen/3.3.7/include/eigen3 -Wall -std=c++11 -g -g ev_numeric.o main.o -o main
duplicate symbol __ZN6ev_mpi16MPI_Data_convertItEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIsEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertImEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIlEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIjEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIiEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIhEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIfEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIeEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIdEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi16MPI_Data_convertIcEEP15ompi_datatype_tv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi18MPI_Is_initializedEv in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi12MPI_Get_rankEP19ompi_communicator_t in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi12MPI_Get_sizeEP19ompi_communicator_t in:
ev_numeric.o
main.o
duplicate symbol __ZN6ev_mpi13MPI_Seed_rankEi in:
ev_numeric.o
main.o
ld: 15 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
现在,我不明白的是,这个问题是否与如何编写ev_mpi.hpp中的函数的声明Makefile有关。 有人可以帮忙吗?