Я пытаюсь использовать swig
, чтобы обернуть некоторые c++
для python
, но не могу выполнить этап компоновки в компиляции.Я использую MacOS Mojave 10.14.4
и g++
из homebrew.
(g++ 8.3.0
).Следуя этому примеру , у меня появляется следующее Makefile
:
# standard compile options for the c++ executable
FLAGS = -fPIC -std=c++17
# the python interface through swig
PYTHONI = -I/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/include/python3.7m
PYTHONL = -Xlinker
# default super-target
all:
g++ $(FLAGS) -c saw.cpp -o saw.o
swig -c++ -python -o saw_wrap.cxx saw.i
g++ $(FLAGS) $(PYTHONI) -c saw_wrap.cxx -o saw_wrap.o
g++ $(PYTHONL) $(LIBFLAGS) -shared saw.o saw_wrap.o -o _saw.so
Обратите внимание, что я -std=c++17
и удалил -export-dynamic
.Но когда я запускаю make
, кажется, что все идет хорошо, за исключением этапа связывания:
g++ -fPIC -std=c++17 -c saw.cpp -o saw.o
swig -c++ -python -o saw_wrap.cxx saw.i
g++ -fPIC -std=c++17 -I/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c saw_wrap.cxx -o saw_wrap.o
g++ -Xlinker -shared saw.o saw_wrap.o -o _saw.so
ld: unknown option: -shared
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
Когда я удаляю опцию -shared
, я получаю больше ошибок.Как я могу это исправить?Я также пытался использовать python
distutils
, но это тоже не сработало.Я нервничаю, что когда я запускаю which ld
, я получаю /usr/bin/ld
против /usr/local/bin/g++
для which g++
.
Вот мой файл .i
для swig
:
видел.я
%module saw
%{
#include "saw.hpp"
using namespace std;
using namespace saw;
%}
%include "std_string.i"
%include "std_vector.i"
%include "std_sstream.i"
%include "saw.hpp"
saw.hpp
#ifndef __SAW_HPP__
#define __SAW_HPP__
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// #define DEBUG
using std::vector;
using std::string;
using std::ostream;
namespace saw
{
struct coord
{
int x;
int y;
int z;
string toString(int shift = 0) const;
};
class SAWalk
{
public:
SAWalk(vector<coord> path);
double displacement() { return displ; }
protected:
vector<coord> path;
double displ;
};
class SAWalkBuilder
{
public:
SAWalkBuilder() {}
SAWalk build(int num_steps) const;
static const int SIZE_M = 50;
};
ostream& operator<<(ostream& os, const coord& c);
}
#endif
saw.cpp
#include "saw.hpp"
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
#include <random>
#include <exception>
using std::string;
using std::ostringstream;
using std::cout;
using std::endl;
using std::random_device;
using std::default_random_engine;
using std::uniform_int_distribution;
using std::vector;
namespace saw
{
SAWalk::SAWalk(vector<coord> path) : path{path}
{
coord starting_coord = path[0];
coord final_coord = path[(int)path.size() - 1];
#ifdef DEBUG
cout << starting_coord.toString(-SAWalkBuilder::SIZE_M/2) << endl;
cout << final_coord.toString(-SAWalkBuilder::SIZE_M/2) << endl;
#endif
double r = sqrt(pow(final_coord.x - starting_coord.x, 2) + pow(final_coord.y - starting_coord.y, 2) + pow(final_coord.z - starting_coord.z,2));
displ = r;
}
SAWalk SAWalkBuilder::build(int num_steps) const
{
int visited[SIZE_M][SIZE_M][SIZE_M] = {}; // initalize to zero
vector<coord> path;
coord starting_coord = coord{SIZE_M/2, SIZE_M/2, SIZE_M/2};
path.push_back(starting_coord);
visited[starting_coord.x][starting_coord.y][starting_coord.z] = 1;
random_device rd;
default_random_engine generator(rd());
const int LOWER_BOUND = 1;
const int UPPER_BOUND = 6;
uniform_int_distribution<int> dist(LOWER_BOUND,UPPER_BOUND);
int rand_step;
int i = 0;
coord cur_coord = starting_coord;
while(i < num_steps)
{
rand_step = dist(generator);
switch(rand_step)
{
case 1: cur_coord.x += 1; break;
case 2: cur_coord.x -= 1; break;
case 3: cur_coord.y += 1; break;
case 4: cur_coord.y -= 1; break;
case 5: cur_coord.z += 1; break;
case 6: cur_coord.z -= 1; break;
default: throw std::domain_error("Invalid move propsosed."); break;
}
if (cur_coord.x == SIZE_M || cur_coord.y == SIZE_M || cur_coord.z == SIZE_M)
{
throw std::domain_error("Reached boundary of M");
}
if (visited[cur_coord.x][cur_coord.y][cur_coord.z] == 1)
{
#ifdef DEBUG
cout << "Tried to move to " << cur_coord.toString(-SIZE_M/2) << endl;
cout << "RESTARTED" << endl;
#endif
for (auto& coord : path)
{
visited[coord.x][coord.y][coord.z] = 0;
}
path.clear();
path.push_back(starting_coord);
visited[starting_coord.x][starting_coord.y][starting_coord.z] = 1;
cur_coord = starting_coord;
i = 0;
}
else
{
visited[cur_coord.x][cur_coord.y][cur_coord.z] = 1;
#ifdef DEBUG
cout << cur_coord.toString(-SIZE_M/2) << endl;
#endif
i++;
path.push_back(cur_coord);
}
}
#ifdef DEBUG
cout << "FINAL COORD" << endl;
cout << cur_coord.toString(-SIZE_M/2) << endl;
#endif
return SAWalk{path};
}
string coord::toString(int shift) const
{
ostringstream out;
out << "[" << x + shift << ", " << y + shift << ", " << z + shift << "]";
return out.str();
}
ostream& operator<<(ostream& os, const coord& c)
{
os << c.toString();
return os;
}
}