Distutils compiler options configuration - python

Maybe a stupid question, but I was wondering where Python's distutils get the compiler options from? It gets some linked directories wrong and I want to correct that once and for all.
I know there should be a prefix/lib/pythonver/distutils/distutils.cfg but I can't find any distutils.cfg anywhere on the computer. Obviously I haven't got a local setup.cfg or any $HOME/.pydistutils.cfg.
I'm using the Enthought 64-bit distribution, version 7.3 (Python 2.7) on Mac OS X 10.8.3
Cheers,
U.

I actually export them to the environment, just like for autotools' configure:
export CC=/usr/local/bin/clang
export CFLAGS=-I${HOME}/include
export LDFLAGS=-lboost
If you also need to override the linker separately:
export LDSHARED=/usr/local/bin/clang -shared
And if you don't like exporting the settings to your environment, do something like this for a one-time setting:
CC=/usr/local/bin/clang CFLAGS=-I${HOME}/include python setup.py build
If you want to find out what the default options were when python was build, use python-config --<flag>. Some flags are cflags, ldflags, libs or includes.

Compiler options are taken from CPython’s Makefile. IOW they are the same as the ones used to compile Python. You can override most of them on the command line as Evert described.
The global distutils.cfg is something that a sysadmin can create to set default options, not a file that is installed with Python.

Related

Is there a way to compile a python application into static binary?

What I'm trying to do is ship my code to a remote server, that may have different python version installed and/or may not have packages my app requires.
Right now to achieve such portability I have to build relocatable virtualenv with interpreter and code. That approach has some issues (for example, you have to manually copy a bunch of libraries into your virtualenv, since --always-copy doesn't work as expected) and generally slow.
There's (in theory) a way to build python itself statically.
I wonder if I could pack interpreter with my code into one binary and run my application as module. Something like that: ./mypython -m myapp run or ./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application.
There are two ways you could go about to solve your problem
Use a static builder, like freeze, or pyinstaller, or py2exe
Compile using cython
This answer explains how you can go about doing it using the second approach, since the first method is not cross platform and version, and has been explained in other answers. Also, using programs like pyinstaller typically results in huge file sizes, while using cython will result in a file that's much smaller
First, install cython.
sudo -H pip3 install cython
Then, you can use cython to generate a C file out of the Python .py file
(in reference to https://stackoverflow.com/a/22040484/5714445)
cython example_file.py --embed
Use GCC to compile it after getting your current python version (Note: The below assumes you are trying to compile it to Python3)
PYTHONLIBVER=python$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')$(python3-config --abiflags)
gcc -Os $(python3-config --includes) example_file.c -o output_bin_file $(python3-config --ldflags) -l$PYTHONLIBVER
You will now have a binary file output_bin_file, which is what you are looking for
Other things to note:
Change example_file.py to whatever file you are actually trying to compile.
Cython is used to use C-Type Variable definitions for static memory allocation to speed up Python programs. In your case however, you will still be using traditional Python definitions.
If you are using additional libraries (like opencv, for example), you might have to provide the directory to them using -L and then specify the name of the library using -l in the GCC Flags. For more information on this, please refer to GCC flags
The above method might not work for anaconda python, as you will likely have to install a version of gcc that is compatible with your conda-python.
You might wish to investigate Nuitka. It takes python source code and converts it in to C++ API calls. Then it compiles into an executable binary (ELF on Linux). It has been around for a few years now and supports a wide range of Python versions.
You will probably also get a performance improvement if you use it. Recommended.
You're probably looking for something like Freeze, which is able to compile your Python application with all its libraries into a static binary:
PyPi page of Freeze
Python Wiki page of Freeze
Sourceforge page of Freeze
If you are on a Mac you can use py2app to create a .app bundle, which starts your Django app when you double-click on it.
I described how to bundle Django and CherryPy into such a bundle at https://moosystems.com/articles/14-distribute-django-app-as-native-desktop-app-01.html
In the article I use pywebview to display your Django site in a local application window.
Freeze options:
https://pypi.python.org/pypi/bbfreeze/1.1.3
http://cx-freeze.sourceforge.net/
However, your target server should have the environment you want -> you should be able to 'create' it. If it doesn't, you should build your software to match the environment.
I found this handy guide on how to install custom version of python to a virtualenv, assuming you have ssh access: https://stackoverflow.com/a/5507373/5616110
In virtualenv, you should be able to pip install anything and you shouldn't need to worry about sudo privileges. Of course, having those and access to package manager like apt makes everything a lot easier.
I have created a docker image that relies on Nuitka and a custom statically linked python3.10 to create a static binary.
Did not test it extensively, if you have the chance please let me know if it works for your use case.
You can check it at:
https://github.com/joaompinto/docker-build-python-static-bin

what files to include with compiled f2py extension on Mac

I want to send somebody my compiled fortran extension on a Mac (compiled with f2py and gfortran).
Problem is that it doesn't work on other Macs unless they also instal xcode (2 GB, yikes!) and gfortran. So apparently there are some additional files missing when I just send the compiled extension.
Does anybody know what other files to include or (better) how to compile a fortran extension without needing to send any additional files?
Thanks,
Mark
Well, when you compile a module with f2py, it essentially creates a dynamic library (.so) which uses your system libraries. For instance, on my computer, the linking step is,
gfortran [...] -lpython2.7 -lgfortran -o ./my_f2py_module.so
Therefore, if you want to be able to execute the resulting f2py module on a different computer (assuming the same architecture), libpython2.7.so and libgfortran.so should be available there.
I don't know much about OS/X deployment, but I think you should
use a compiler present by default on Mac (i.e. clang), which should work with f2py. Or alternatively install gfortran on both systems.
make sure you link to the same version of python in both cases
Also use ldd ./my_f2py_module.so to list all the libraries that it is linked to. If some of them cannot be found on the current system, you will also see it with this command.

How do I replace my HPC gfortran with Homebrew gfortran?

I currently have Xcode (along with command line tools) and gfrotran from HPC installed on my Yosemite system, and would like to replace HPC's gfortran with Homebrew's (because I'm having trouble building Python packages with the HPC gfortran).
What are the steps to accomplish this?
I want to be sure that
HPC's gfortran is gone (I just want one Fortran) and
Apple's tools still work (for Xcode, Swift, OS X and iOS development, etc.)
and of course
that I have a working version of gfortran that reliably builds Python packages.
Can this be done? I see for example that Homebrew's gfortran is now packaged as part of gcc, so it looks like I'll end up with two versions gcc (which I'd like to avoid) or one that doesn't play well with Xcode.
What are the steps to accomplish 1-3?
I recently worked through this very same problem. This is how I got/have it working on my Yosemite system.
Some things about home-brew and the command line tools compilers:
The compiler you get through home-brew will overwrite the existing one if it is in the same place. If you have a fortran compiler that you obtained from the command line tools then it will not be affected.(Home-brew will warn you about this before doing anything)
The binaries for the compilers you get through the command line tools are in /usr/bin .
The compilers (and anything else) you obtain using home-brew are stored in the cellar ( /usr/local/Cellar)
and the executables are linked into the directory /usr/local/bin.
What to do?
Modify the path:
I only needed to use the compilers I got through home-brew so I moved /usr/local/bin to the top of my $path this ensures that the /usr/local/bin directory is searched before /usr/bin.
Use aliases :
You can create an alias for each compiler so that you can use them interchangeably as you wish. To create an alias you will have to modify your shell-rc file. On my system I use the tcsh, and to create an alias for the home-brew compiler I would add something similar to this to my ~/.cshrc file.
alias brewgfortran '/usr/local/bin/gfortran'
this now executes the home-brew gfortran-4.9 executable that is stored in my cellar and linked to /usr/local/bin/gfortran/
IF you absolutely want rid of the apple compilers you can of course remove them from the /usr/bin/ directory completely. I don't think this is the best idea though. I have shown you a few ways to avoid using them and if you ever needed them for some reason you would be SOL. I cant say if those tools you need will work without them as I have never used any of those, however I know it will build python packages for you (sorry hope this still helps)
NOTE: If you are not using the same shell as me the syntax for the alias is a little different (I think) just google it or man alias

Building PyCrypto with fastmath (gmp or mpir) via pip on Windows

I installed PyCrypto on Windows via pip but i was not able to build Crypto.PublicKey._fastmath because GMP was not found.
I know there is a binary version on voidspace but i would like to build the latest version of PyCrypto
The following one is a way to achieve your goal. There are other, probably better ways (e.g. based on Visual Studio), but this one has worked for me. Additionally, it does not use pip.
All operations are carried out on a command prompt.
Install Mingw, including MSYS and the Development Toolkit. This will give you a fairly complete Unix-like development environment.
Ensure that Mingw binaries are in PATH environment variable. You need MinGW\bin and MingGW\msys\1.0\bin.
Download MPIR sources in a temporary directory. It is important you do not use 2.5.1 because of a bug that will break the build. 2.5.0 is fine.
Build the MPIR library. This is fairly straightforward: execute bash configure followed by make.
HACK #1 Copy libmpir.a from mpir-2.5.0\.libs into C:\Python2.7.1\libs. This is necessary because distutils is broken and I could not find a way to direct it to the correct library location.
HACK #2 Edit C:\Python2.7.1\Lib\distutils\cygwincompiler.py and remove any occurrance of the string -mno-cygwin. The reason is explained here.
Download PyCrypto sources and unpack them in another temporary directory.
Set CPPFLAGS environment variable to the MPIR directory, which contains mpir.h.
HACK 3 Edit setup.py and add the following line in build_extension method:
self.__add_compiler_option(os.environ['CPPFLAGS'])
Run bash configure. You should see two lines saying:
checking for __gmpz_init in -lgmp... no
checking for __gmpz_init in -lmpir... yes
Execute python setup.py build -c mingw32. You should see no errors.
Execute python setup.py test to verify that everything is fine.
Execute python setup.py install to copy the files into your local Python repository.
Alternatively, run python setup.py bdist_wininst to create an installer.
I really hate all the various hacks, and I'd love to hear if they can be avoided.

python distutils C++ compilation

I am trying to build a python module for android.
While I can set a compiler with export CC=, I am not able to do the same for C++ compilers using export CXX=. It still uses the basic C compiler.
Can anyone help me to figure out how to configure the compilers while building python modules?
Thanks.
Here are some old instructions for Windows how to change the compiler
Create a file called 'distutils.cfg' in "C:\Python26\Lib\distutils".
Open it with a text editor ('notepad distutils.cfg') and fill in the following lines:
[build]
compiler=mingw32
The same should go for other platforms as well when you manage to locate distutils folder.
Howver setup.py / Python packages can do their own stuff and these must be resolved case-by-case basis.

Categories