-./configure --prefix=`pwd`/mingw --host=i586-mingw32msvc --enable-shared --disable-static --without-matlab --without-octave && make -j4 && make install
+#!/bin/sh
+set -e
+
+rm -rf mingw
+
+./configure --prefix=`pwd`/mingw --host=i586-mingw32msvc --enable-shared --disable-static --without-matlab --without-octave --without-python --without-guile && make -j4 && make install
 
 cd mingw/bin
 for dll in *.dll; do
      lib /def:libnlopt-0.def
 
 To compile the Matlab plugin, use the Matlab "mex" compiler on the file
-nlopt_minimize_constrained.c (being sure to link to the libnlopt DLL).
+nlopt_optimize.c (being sure to link to the libnlopt DLL) in the matlab
+subdirectory.
+
+To build the Python plugin (assuming that you have Python and Numpy
+installed), do:
+   python setup.py build_ext --inplace
 
 They were compiled by the GNU C compiler for MinGW, specifically:
 EOF
 
 # grep -v "nlopt-util.h" octave/nlopt_minimize_constrained-mex.c > mingw/nlopt_minimize_constrained.c
 
+nlopt_vers=`grep PACKAGE_VERSION config.h |cut -d" " -f3 |tr -d \"`
+
+mkdir mingw/matlab
+cd octave
+cp `grep 'MFILES =' Makefile.am | cut -d= -f2` ../mingw/matlab
+cp `grep 'm_DATA =' Makefile.am | cut -d\) -f2` ../mingw/matlab
+cp nlopt_optimize-mex.c ../mingw/matlab/nlopt_optimize.c
+cd ..
+
+mkdir mingw/python
+cp swig/nlopt.py swig/nlopt-python.cpp mingw/python
+cat > mingw/python/setup.py <<EOF
+from distutils.core import setup, Extension
+nlopt_module = Extension('_nlopt',
+                           sources=['nlopt-python.cpp'],
+                           libraries=['libnlopt-0'],
+                           )
+setup (name = 'nlopt',
+       version = '${nlopt_vers}',
+       author      = "Steven G. Johnson",
+       description = """NLopt nonlinear-optimization library""",
+       ext_modules = [nlopt_module],
+       py_modules = ["nlopt"],
+       )
+EOF
+
 nlopt_vers=`grep PACKAGE_VERSION config.h |cut -d" " -f3 |tr -d \"`
 zip=nlopt-${nlopt_vers}-dll.zip
 rm -f $zip
 zip -vj $zip mingw/bin/*.dll mingw/bin/*.exe
-zip -vjgl $zip mingw/bin/*.def mingw/include/* README COPYING COPYRIGHT NEWS README-WINDOWS  # octave/*.m mingw/nlopt_minimize_constrained.c
+zip -vjgl $zip mingw/bin/*.def mingw/include/* mingw/python/* README COPYING COPYRIGHT NEWS README-WINDOWS
+
+cd mingw
+zip -vgl ../$zip matlab/*
+cd ..
 
 nlopt_algorithm nlopt_local_search_alg_nonderiv = NLOPT_LN_COBYLA;
 int nlopt_local_search_maxeval = -1; /* no maximum by default */
 
+NLOPT_STDCALL
 void nlopt_get_local_search_algorithm(nlopt_algorithm *deriv,
                                      nlopt_algorithm *nonderiv,
                                      int *maxeval)
      *maxeval = nlopt_local_search_maxeval;
 }
 
+NLOPT_STDCALL
 void nlopt_set_local_search_algorithm(nlopt_algorithm deriv,
                                      nlopt_algorithm nonderiv,
                                      int maxeval)
 
 int nlopt_stochastic_population = 0;
 
+NLOPT_STDCALL
 int nlopt_get_stochastic_population(void) { 
      return nlopt_stochastic_population; }
+NLOPT_STDCALL
 void nlopt_set_stochastic_population(int pop) { 
      nlopt_stochastic_population = pop <= 0 ? 0 : (unsigned) pop; }
 
 /*************************************************************************/
 
+NLOPT_STDCALL
 nlopt_result nlopt_minimize_econstrained(
      nlopt_algorithm algorithm,
      int n, nlopt_func_old f, void *f_data,
      return ret;
 }
 
+NLOPT_STDCALL
 nlopt_result nlopt_minimize_constrained(
      nlopt_algorithm algorithm,
      int n, nlopt_func_old f, void *f_data,
          xtol_rel, xtol_abs, ftol_rel, ftol_abs, maxeval, maxtime);
 }
 
+NLOPT_STDCALL
 nlopt_result nlopt_minimize(
      nlopt_algorithm algorithm,
      int n, nlopt_func_old f, void *f_data,
 
 
 /*************************************************************************/
 
-void nlopt_destroy(nlopt_opt opt)
+NLOPT_STDCALL void nlopt_destroy(nlopt_opt opt)
 {
      if (opt) {
          if (opt->munge_on_destroy) {
      }
 }
 
-nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
+NLOPT_STDCALL nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
 {
      nlopt_opt opt;
 
      return NULL;
 }
 
-nlopt_opt nlopt_copy(const nlopt_opt opt)
+NLOPT_STDCALL nlopt_opt nlopt_copy(const nlopt_opt opt)
 {
      nlopt_opt nopt = NULL;
      if (opt) {
 
 /*************************************************************************/
 
-nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
+NLOPT_STDCALL nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 {
      if (opt) {
          opt->f = f; opt->f_data = f_data;
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f, void *f_data)
+NLOPT_STDCALL nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 {
      if (opt) {
          opt->f = f; opt->f_data = f_data;
 
 /*************************************************************************/
 
-nlopt_result nlopt_set_lower_bounds(nlopt_opt opt, const double *lb)
+NLOPT_STDCALL nlopt_result nlopt_set_lower_bounds(nlopt_opt opt, const double *lb)
 {
      if (opt && (opt->n == 0 || lb)) {
          memcpy(opt->lb, lb, sizeof(double) * (opt->n));
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_set_lower_bounds1(nlopt_opt opt, double lb)
+NLOPT_STDCALL nlopt_result nlopt_set_lower_bounds1(nlopt_opt opt, double lb)
 {
      if (opt) {
          unsigned i;
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_get_lower_bounds(nlopt_opt opt, double *lb)
+NLOPT_STDCALL nlopt_result nlopt_get_lower_bounds(nlopt_opt opt, double *lb)
 {
      if (opt && (opt->n == 0 || lb)) {
          memcpy(lb, opt->lb, sizeof(double) * (opt->n));
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_set_upper_bounds(nlopt_opt opt, const double *ub)
+NLOPT_STDCALL nlopt_result nlopt_set_upper_bounds(nlopt_opt opt, const double *ub)
 {
      if (opt && (opt->n == 0 || ub)) {
          memcpy(opt->ub, ub, sizeof(double) * (opt->n));
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_set_upper_bounds1(nlopt_opt opt, double ub)
+NLOPT_STDCALL nlopt_result nlopt_set_upper_bounds1(nlopt_opt opt, double ub)
 {
      if (opt) {
          unsigned i;
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_get_upper_bounds(nlopt_opt opt, double *ub)
+NLOPT_STDCALL nlopt_result nlopt_get_upper_bounds(nlopt_opt opt, double *ub)
 {
      if (opt && (opt->n == 0 || ub)) {
          memcpy(ub, opt->ub, sizeof(double) * (opt->n));
                       (a) == NLOPT_LD_AUGLAG ||        \
                       (a) == NLOPT_LD_AUGLAG_EQ)
 
-nlopt_result nlopt_remove_inequality_constraints(nlopt_opt opt)
+NLOPT_STDCALL nlopt_result nlopt_remove_inequality_constraints(nlopt_opt opt)
 {
      if (!opt) return NLOPT_INVALID_ARGS;
      if (opt->munge_on_destroy) {
      return NLOPT_SUCCESS;
 }
 
-static nlopt_result add_constraint(unsigned *m, unsigned *m_alloc,
+NLOPT_STDCALL static nlopt_result add_constraint(unsigned *m, unsigned *m_alloc,
                                   nlopt_constraint **c,
                                   nlopt_func fc, void *fc_data,
                                   double tol)
      return NLOPT_SUCCESS;
 }
 
-nlopt_result nlopt_add_inequality_constraint(nlopt_opt opt,
+NLOPT_STDCALL nlopt_result nlopt_add_inequality_constraint(nlopt_opt opt,
                                             nlopt_func fc, void *fc_data,
                                             double tol)
 {
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_remove_equality_constraints(nlopt_opt opt)
+NLOPT_STDCALL nlopt_result nlopt_remove_equality_constraints(nlopt_opt opt)
 {
      if (!opt) return NLOPT_INVALID_ARGS;
      if (opt->munge_on_destroy) {
      return NLOPT_SUCCESS;
 }
 
-nlopt_result nlopt_add_equality_constraint(nlopt_opt opt,
+NLOPT_STDCALL nlopt_result nlopt_add_equality_constraint(nlopt_opt opt,
                                           nlopt_func h, void *h_data,
                                           double tol)
 {
 
 /*************************************************************************/
 
-#define SET(param, T, arg)                             \
-   nlopt_result nlopt_set_##param(nlopt_opt opt, T arg)        \
-   {                                                   \
-       if (opt) {                                      \
-            opt->arg = arg;                            \
-            return NLOPT_SUCCESS;                      \
-       }                                               \
-       return NLOPT_INVALID_ARGS;                      \
+#define SET(param, T, arg)                                             \
+   NLOPT_STDCALL nlopt_result nlopt_set_##param(nlopt_opt opt, T arg)  \
+   {                                                                   \
+       if (opt) {                                                      \
+            opt->arg = arg;                                            \
+            return NLOPT_SUCCESS;                                      \
+       }                                                               \
+       return NLOPT_INVALID_ARGS;                                      \
    }
 
 
-#define GET(param, T, arg) T nlopt_get_##param(const nlopt_opt opt) {  \
-        return opt->arg;                                               \
+#define GET(param, T, arg) NLOPT_STDCALL       \
+   T nlopt_get_##param(const nlopt_opt opt) {  \
+        return opt->arg;                       \
    }
 
 #define GETSET(param, T, arg) GET(param, T, arg) SET(param, T, arg)
 GETSET(ftol_abs, double, ftol_abs)
 GETSET(xtol_rel, double, xtol_rel)
 
-nlopt_result nlopt_set_xtol_abs(nlopt_opt opt, const double *xtol_abs)
+NLOPT_STDCALL nlopt_result nlopt_set_xtol_abs(nlopt_opt opt, const double *xtol_abs)
 {
      if (opt) {
          memcpy(opt->xtol_abs, xtol_abs, opt->n & sizeof(double));
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_set_xtol_abs1(nlopt_opt opt, const double xtol_abs)
+NLOPT_STDCALL nlopt_result nlopt_set_xtol_abs1(nlopt_opt opt, const double xtol_abs)
 {
      if (opt) {
          unsigned i;
      return NLOPT_INVALID_ARGS;
 }
 
-nlopt_result nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_abs)
+NLOPT_STDCALL nlopt_result nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_abs)
 {
      memcpy(xtol_abs, opt->xtol_abs, opt->n & sizeof(double));
      return NLOPT_SUCCESS;
 
 /*************************************************************************/
 
-nlopt_result nlopt_set_force_stop(nlopt_opt opt, int force_stop)
+NLOPT_STDCALL nlopt_result nlopt_set_force_stop(nlopt_opt opt, int force_stop)
 {
      if (opt) {
          opt->force_stop = force_stop;
 }
 
 GET(force_stop, int, force_stop)
-nlopt_result nlopt_force_stop(nlopt_opt opt) { 
+NLOPT_STDCALL nlopt_result nlopt_force_stop(nlopt_opt opt) { 
      return nlopt_set_force_stop(opt, 1); 
 }
 
 
 /*************************************************************************/
 
-nlopt_result nlopt_set_local_optimizer(nlopt_opt opt,
+NLOPT_STDCALL nlopt_result nlopt_set_local_optimizer(nlopt_opt opt,
                                       const nlopt_opt local_opt)
 {
      if (opt) {
 
 /*************************************************************************/
 
-nlopt_result nlopt_set_initial_step1(nlopt_opt opt, double dx)
+NLOPT_STDCALL nlopt_result nlopt_set_initial_step1(nlopt_opt opt, double dx)
 {
      unsigned i;
      if (!opt || dx == 0) return NLOPT_INVALID_ARGS;
      return NLOPT_SUCCESS;
 }
 
-nlopt_result nlopt_set_initial_step(nlopt_opt opt, const double *dx)
+NLOPT_STDCALL nlopt_result nlopt_set_initial_step(nlopt_opt opt, const double *dx)
 {
      unsigned i;
      if (!opt) return NLOPT_INVALID_ARGS;
      return NLOPT_SUCCESS;
 }
 
-nlopt_result nlopt_get_initial_step(const nlopt_opt opt, const double *x, 
+NLOPT_STDCALL nlopt_result nlopt_get_initial_step(const nlopt_opt opt, const double *x, 
                                    double *dx)
 {
      if (!opt) return NLOPT_INVALID_ARGS;
      return NLOPT_SUCCESS;
 }
 
-nlopt_result nlopt_set_default_initial_step(nlopt_opt opt, const double *x)
+NLOPT_STDCALL nlopt_result nlopt_set_default_initial_step(nlopt_opt opt, const double *x)
 {
      const double *lb, *ub;
      unsigned i;
 
 /*************************************************************************/
 
-void nlopt_set_munge(nlopt_opt opt,
+NLOPT_STDCALL void nlopt_set_munge(nlopt_opt opt,
                     nlopt_munge munge_on_destroy,
                     nlopt_munge munge_on_copy) {
      if (opt) {