Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 553c425

Browse files
committed
Merge pull request arokem#140 from blink1073/master
Streamline mex build and install process
2 parents d1e1988 + ca8a877 commit 553c425

File tree

13 files changed

+113
-66
lines changed

13 files changed

+113
-66
lines changed

README.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ development of the two repositories has significantly diverged.
1212

1313
This implementation also includes an [IPython](http://ipython.org) `matlab_magic`
1414
extension, which provides a simple interface for weaving python and
15-
Matlab code together (requires ipython > 0.13).
15+
Matlab code together (requires ipython > 0.13).
1616

1717

1818
## Installation
@@ -37,7 +37,7 @@ If you intend to use the Matlab magic extension, you'll also need
3737
[Scipy](http://scipy.org/) and [Numpy](http://www.numpy.org/). These can be
3838
installed from PyPI, or using distributions such as
3939
[Anaconda](https://store.continuum.io/cshop/anaconda/) or [Enthought
40-
Canopy](https://store.enthought.com/downloads/)
40+
Canopy](https://store.enthought.com/downloads/)
4141

4242
Note thatIPython notebooks also depend on `pyzmq` so if you have IPython notebooks
4343
installed, you likely have `pyzmq` already.
@@ -54,10 +54,10 @@ This creates a matlab session class instance, into which you will be able to
5454
inject code and variables, and query for results. By default, when you use
5555
`start`, this will open whatever gets called when you type `matlab`
5656
in your Terminal, but you can also specify the location of your Matlab
57-
application when initializing your matlab session class:
57+
application when initializing your matlab session class:
5858

5959
mlab = Matlab(executable='/Applications/MATLAB_R2011a.app/bin/matlab')
60-
60+
6161
You can then start the Matlab server, which will kick off your matlab session,
6262
and create the connection between your Python interpreter and this session:
6363

@@ -80,7 +80,7 @@ In this case, the variable `a` is available on the Python side, by using
8080
the `get_variable` method:
8181

8282
mlab.get_variable('a')
83-
83+
8484
You can run any MATLAB functions contained within a .m file of the
8585
same name. For example, to call the function jk in jk.m:
8686

@@ -121,7 +121,11 @@ Rather than `~/startup.m`, Octave looks for an `~/.octaverc` file for
121121
commands to execute before every session. (This is a good place to manipulate
122122
the runtime path, for example).
123123

124-
### Matlab magic:
124+
Requires Version 3.8 or higher. Notice: Neither the MXE 3.8.1 nor the Cygwin 3.8.2 version is compatible on Windows. No Windows support will be available
125+
until a working version of Octave 3.8+ with Java support is released.
126+
127+
128+
### Matlab magic:
125129

126130
The Matlab magic allows you to use pymatbridge in the context of the IPython
127131
notebook format.
@@ -132,7 +136,7 @@ These lines will automatically start the matlab session for you. Then, you can
132136
simply decorate a line/cell with the '%matlab' or '%%matlab' decorator and
133137
write matlab code:
134138

135-
%%matlab
139+
%%matlab
136140
a = linspace(0.01,6*pi,100);
137141
plot(sin(a))
138142
grid on
@@ -143,14 +147,21 @@ More examples are provided in the `examples` directory
143147

144148
## Building the pymatbridge messenger from source
145149

146-
The installation of `pymatbridge` includes a binary of a mex function to communicate between
147-
Python and Matlab using the [0MQ](http://zeromq.org/) messaging library. This should work
150+
The installation of `pymatbridge` includes a binary of a mex function to communicate between
151+
Python and Matlab using the [0MQ](http://zeromq.org/) messaging library. This should work
148152
without any need for compilation on most computers. However, in some cases, you might want
149153
to build the pymatbridge messenger from source. To do so, you will need to follow the instructions below:
150154

151155
### Install zmq library
152156
Please refer to the [official guide](http://zeromq.org/intro:get-the-software) on how to
153-
build and install zmq. On Ubuntu, it is as simple as `sudo apt-get install libzmq3-dev`. After zmq is installed, make sure you can find the location where
157+
build and install zmq. On Ubuntu, it is as simple as `sudo apt-get install libzmq3-dev`.
158+
On Windows, suggest using the following method:
159+
- Install [MSYS2](http://sourceforge.net/projects/msys2/)
160+
- Run `$ pacman -S make`
161+
- From the zmq source directory, run: `$ sh configure --prefix=$(pwd) --build=x86_64-w64-mingw32`
162+
- Run `$ make`.
163+
164+
After zmq is installed, make sure you can find the location where
154165
libzmq is installed. The library extension name and default location on different systems
155166
are listed below.
156167

@@ -198,36 +209,37 @@ On MacOS, you can do this from the root of the pymatbridge code with:
198209
On Linux, you can add it to the RPATH:
199210

200211
patchelf --set-rpath <Path to your zmq lib directory> messenger/mexa64/messenger.mexa64
201-
212+
202213
### Install pyzmq
203-
After step 1 is finished, please grab the latest version of
204-
[pyzmq](http://zeromq.org/bindings:python) and follow the instructions on the official
205-
page. Note that pymatbridge is developed with pyzmq 14.0.0 and older versions might not
206-
be supported. If you have an old version of pyzmq, please update it.
214+
After step 1 is finished, please grab the latest version of
215+
[pyzmq](http://zeromq.org/bindings:python) and follow the instructions on the official
216+
page. Note that pymatbridge is developed with pyzmq 14.0.0 and older versions might not
217+
be supported. If you have an old version of pyzmq, please update it.
207218

208219
### Install pymatbridge
209-
After the steps above are done, you can install pymatbridge. Download the zip file of the
220+
After the steps above are done, you can install pymatbridge. Download the zip file of the
210221
latest release. Unzip it somewhere on your machine.
211222

212223
For Matlab:
213224

214225
cd messenger
215-
python make.py
226+
# edit local.cfg in the directory for your platform
227+
python make.py
216228
cd ..
217229
python setup.py install
218230

219231

220232
For Octave:
221233

222234
cd messenger/octave
223-
# edit make.py if not using Ubuntu-derivative
224-
python make.py
235+
# edit local_octave.cfg in the directory for your platform
236+
python make_octave.py
225237
cd ..
226238
python setup.py
227-
239+
228240
This should make the python-matlab-bridge import-able.
229241

230-
242+
231243
### Warnings
232244

233245
Python communicates with Matlab via an ad-hoc zmq messenger. This is inherently

messenger/__init__.py

Whitespace-only changes.

messenger/get_messenger_dir.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import sys
2+
import platform
3+
4+
5+
def get_messenger_dir():
6+
# Check the system platform first
7+
splatform = sys.platform
8+
9+
if splatform.startswith('linux'):
10+
messenger_dir = 'mexa64'
11+
elif splatform.startswith('darwin'):
12+
messenger_dir = 'mexmaci64'
13+
elif splatform.startswith('win32'):
14+
if splatform == "win32":
15+
# We have a win64 messenger, so we need to figure out if this is 32 or 64
16+
# bit Windows:
17+
if not platform.machine().endswith('64'):
18+
raise ValueError("pymatbridge does not work on win32")
19+
20+
# We further need to differniate 32 from 64 bit:
21+
maxint = sys.maxsize
22+
if maxint == 9223372036854775807:
23+
messenger_dir = 'mexw64'
24+
elif maxint == 2147483647:
25+
messenger_dir = 'mexw32'
26+
return messenger_dir

messenger/make.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
#!/usr/bin/python
22
from __future__ import print_function
33
import os
4-
import sys
5-
import fnmatch
4+
from get_messenger_dir import get_messenger_dir
65
import subprocess
76
import shutil
87

9-
# Check the system platform first
10-
platform = sys.platform
11-
print("This is a " + platform + " system")
12-
13-
if platform.startswith('linux'):
14-
messenger_dir = 'mexa64'
15-
elif platform.startswith('darwin'):
16-
messenger_dir = 'mexmaci64'
17-
elif platform.startswith('win32'):
18-
# We further need to differniate 32 from 64 bit:
19-
maxint = sys.maxint()
20-
if maxint == 9223372036854775807:
21-
messenger_dir = 'mexw64'
22-
elif maxint == 2147483647:
23-
messenger_dir = 'mexw32'
8+
messenger_dir = get_messenger_dir()
249

2510
# Open the configure file and start parsing
2611
with open(os.path.join(messenger_dir, 'local.cfg'), 'r') as config:

messenger/make_octave.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/python
2+
from __future__ import print_function
3+
import os
4+
from get_messenger_dir import get_messenger_dir
5+
import shutil
6+
import subprocess
7+
8+
messenger_dir = get_messenger_dir()
9+
10+
with open(os.path.join(messenger_dir, 'local_octave.cfg')) as fid:
11+
lines = fid.readlines()
12+
13+
cfg = {}
14+
for line in lines:
15+
name, path = line.split('=')
16+
cfg[name.lower()] = path.strip() or '.'
17+
18+
print("Building messenger.mex...")
19+
20+
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s" % cfg
21+
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
22+
print(make_cmd)
23+
subprocess.check_output(make_cmd.split())
24+
25+
messenger_exe = 'messenger.mex'
26+
messenger_loc = os.path.join(messenger_dir, messenger_exe)
27+
28+
shutil.move(messenger_exe, messenger_loc)
29+
os.remove('messenger.o')

messenger/mexa64/local_octave.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
OCTAVE_INC=/usr/include
2+
OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/
3+
ZMQ_INC=
4+
ZMQ_LIB=

messenger/mexa64/messenger.mex

20.6 KB
Binary file not shown.

messenger/mexmaci64/local_octave.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
OCTAVE_INC=/usr/include
2+
OCTAVE_LIB=/usr/lib/x86_64-linux-gnu/
3+
ZMQ_INC=
4+
ZMQ_LIB=

messenger/mexw64/local_octave.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
OCTAVE_INC="C:\Octave\Octave-3.8.2\include\octave-3.8.2\octave"
2+
OCTAVE_LIB="C:\Octave\Octave-3.8.2\lib\octave\3.8.2"
3+
ZMQ_INC="C:\zeromq-4.0.5\include"
4+
ZMQ_LIB="C:\zeromq-4.0.5\src\.libs"

messenger/octave/make.py

Lines changed: 0 additions & 7 deletions
This file was deleted.

messenger/octave/messenger.mex

-20.6 KB
Binary file not shown.

messenger/src/messenger.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ int initialize(char *socket_addr) {
2828
* Now the receiver buffer is pre-allocated
2929
* In the future we can possibly use multi-part messaging
3030
*/
31-
int listen(char *buffer, int buflen) {
31+
int listen_zmq(char *buffer, int buflen) {
3232
if (!initialized) {
3333
mexErrMsgTxt("Error: ZMQ session not initialized");
3434
}
@@ -106,7 +106,7 @@ void mexFunction(int nlhs, mxArray *plhs[],
106106
} else if (strcmp(cmd, "listen") == 0) {
107107
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
108108

109-
int byte_recvd = listen(recv_buffer, BUFLEN);
109+
int byte_recvd = listen_zmq(recv_buffer, BUFLEN);
110110

111111
/* Check if the received data is complete and correct */
112112
if ((byte_recvd > -1) && (byte_recvd <= BUFLEN)) {

setup.py

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
11
#!/usr/bin/env python
22
"""Setup file for python-matlab-bridge"""
33

4-
import platform
54
import os
65
import sys
76
import shutil
7+
import glob
8+
89

910
# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
1011
# update it when the contents of directories change.
1112
if os.path.exists('MANIFEST'):
1213
os.remove('MANIFEST')
1314

15+
1416
from distutils.core import setup
1517

16-
# Find the messenger binary file and copy it to /matlab folder.
1718

18-
def copy_bin(bin_path):
19-
if os.path.exists(bin_path):
20-
shutil.copy(bin_path, "./pymatbridge/matlab")
21-
return True
22-
else:
23-
return False
19+
# Find the messenger binary file(s) and copy it to /matlab folder.
20+
from messenger.get_messenger_dir import get_messenger_dir
21+
messenger_dir = get_messenger_dir()
22+
23+
for f in glob.glob("./messenger/%s/messenger.*" % messenger_dir):
24+
shutil.copy(f, "./pymatbridge/matlab")
2425

25-
if sys.platform == "win32":
26-
# We have a win64 messenger, so we need to figure out if this is 32 or 64
27-
# bit Windows:
28-
if not platform.machine().endswith('64'):
29-
raise ValueError("pymatbridge does not work on win32")
3026

31-
for copy_this in ["./messenger/mexmaci64/messenger.mexmaci64",
32-
"./messenger/mexa64/messenger.mexa64",
33-
"./messenger/mexw64/messenger.mexw64",
34-
"./messenger/octave/messenger.mex"]:
35-
copy_bin(copy_this)
36-
3727
# Get version and release info, which is all stored in pymatbridge/version.py
3828
ver_file = os.path.join('pymatbridge', 'version.py')
3929
exec(open(ver_file).read())

0 commit comments

Comments
 (0)