Windows¶
cpymad is linked against a library version of MAD-X, which means that in order
to build cpymad you first have to compile MAD-X from source. The official
madx
executable is not sufficient. These steps are described in the
following subsections:
Setup environment¶
Setting up a functional build environment requires more effort on windows than on other platforms, and there are many pitfalls if not using the right compiler toolchain (such as linking against DLLs that are not present on most target systems).
We recommend that you install conda. It has proven to be a reliable tool for this job. Specifically, I recommend getting Miniconda; anaconda should work too, but I wouldn’t recommend it because it ships many unnecessary components.
Note that while conda is used to setup a consistent environment for the build process, the generated cpymad build will be usable with other python distributions as well.
Install build tools:
After installing conda, open the conda command prompt.
We show the commands for the case of working inside a cmd.exe
terminal
(batch). If you prefer to work with powershell or bash on msys2, the workflow
(commands/arguments) will be mostly the same, with the only exception that you
have to adapt the syntax accordingly in some places.
Now create a build environment with cmake and setup the MinGW compiler toolchain:
conda create -n buildenv
conda activate buildenv
conda install -c anaconda cmake
conda install -c msys2 m2w64-toolchain
Get the sources:
Now download and extract the latest MAD-X release and cpymad release side by side.
Alternatively, use git if you want to build a development version from local checkout (unstable):
conda install git
git clone https://github.com/MethodicalAcceleratorDesign/MAD-X
git clone https://github.com/hibtc/cpymad
Build MAD-X¶
There are two major alternatives how to build MAD-X:
I recommend to build MAD-X as a static library as described below. This way, you won’t need to carry any
.dll
files around and you won’t run into version problems when having a multiple MAD-X library builds around.However, in some cases it may be easier to link cpymad dynamically against MAD-X, i.e. using a DLL. This comes at the cost of having to redistribute the
madx.dll
along. The choice is yours.
Note that if you’re planning on using MSVC to build the cpymad extension later on, you have to build MAD-X as shared library (DLL). With MinGW (recommended), both build types are supported.
In the following, we show the commands for the static build.
In the build environment, type:
mkdir MAD-X\build
cd MAD-X\build
cmake .. -G "MinGW Makefiles" ^
-DBUILD_SHARED_LIBS=OFF ^
-DMADX_STATIC=ON ^
-DCMAKE_INSTALL_PREFIX="../dist"
cmake --build . --target install
Note
For shared library builds, instead use -DBUILD_SHARED_LIBS=ON
.
If all went well the last command will have installed binaries and library
files to the MAD-X\dist
subfolder.
Save the path to this install directory in the MADXDIR
environment
variable. This variable will be used later by the setup.py
script to
locate the MAD-X headers and library, for example:
set "MADXDIR=C:\Users\<....>\MAD-X\dist"
Also, set the following variables according to the flags passed to the cmake command above:
set STATIC=1 # if -DMADX_STATIC=ON
set SHARED=1 # if -DBUILD_SHARED_LIBS=ON
Build cpymad¶
Using MinGW¶
For building cpymad you can simply reuse the build environment with the MinGW installation from above, and now also install the targeted python version into the build environment, e.g.:
conda install python=3.7 wheel cython
Note
If you want to build wheels for multiple python versions, just create a build environment for each target version, and don’t forget to install the same version of the m2w64 compiler toolchain.
Now invoke the following command, which will cythonize the .pyx
cython
module to .c
code as a side effect:
python setup.py build_py
Now comes the tricky part: we will have to manually build the C extension using gcc, because setuptools doesn’t know how to properly use our MinGW.
First set a few environment variables corresponding to the target platform and python version:
set py_ver=37
set file_tag=cp37-win_amd64
set dir_tag=win-amd64-cpython-37
On python 3.6 or earlier use the form set dir_tag=win-amd64-3.6
instead.
With these values set, you should be able to copy-paste the following commands:
set tempdir=build\temp.%dir_tag%\Release\src\cpymad
set libdir=build\lib.%dir_tag%\cpymad
mkdir %tempdir%
mkdir %libdir%
call %gcc% -mdll -O -Wall -DMS_WIN64 ^
-I %MADXDIR%\include ^
-I %pythondir%\include ^
-c src/cpymad/libmadx.c ^
-o %tempdir%\libmadx.obj ^
-std=gnu99
call %gcc% -shared -s ^
%tempdir%\libmadx.obj ^
-L %MADXDIR%\lib ^
-lmadx -lDISTlib -lptc -lgc-lib -lstdc++ -lgfortran ^
-lquadmath %pythondir%\python%py_ver%.dll -lmsvcr100 ^
-o %libdir%\libmadx.%file_tag%.pyd
For old versions of MAD-X, leave out -lDISTlib
from the second gcc call.
If this succeeds, you have most of the work behind you.
At this point, you may want to check the built .pyd
file with Dependency
Walker to verify that it depends only on system dependencies (except for
pythonXY.dll
, and in the case of dynamic linking madx.dll
).
We now proceed to build a so called wheel. Wheels are zip archives containing all the files ready for installation, as well as some metadata such as version numbers etc. The wheel can be built as follows:
python setup.py bdist_wheel
The .whl
file is named after the package and its target platform. This
file can now be used for installation on this or any other machine running the
same operating system and python version. Install as follows:
pip install dist\cpymad-*.whl
If you plan on changing cpymad code, do the following instead:
pip install -e .
Finally, do a quick check that your cpymad installation is working by typing the following:
python -c "import cpymad.libmadx as l; l.start()"
The MAD-X startup banner should appear. You can also run more tests as follows:
python test\test_madx.py
python test\test_util.py
Congratulations, you are now free to delete the MAD-X and cpymad folders (but keep your wheel!).
Using Visual Studio¶
Python’s official binaries are all compiled with the Visual C compiler and therefore this is the only officially supported method to build python C extensions on windows.
It is possible to build the cpymad C extension with Visual Studio, but there is a good reason that the above guide doesn’t use it:
Visual Studio doesn’t include a Fortran compiler which means that you still have to build MAD-X as described. Also, you have to build MAD-X as a shared library, because the static library created by MinGW most likely won’t be compatible with the Visual C compiler.
First, look up the correct Visual Studio version and download and install it directly from microsoft. It is possible that older versions are not supported anymore.
After that, activate the Visual Studio tools by calling vcvarsall.bat
.
Depending on your Visual Studio version and install path, this might look like
this:
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
Once you’ve accomplished that, the steps to build cpymad should actually be relatively simple (simpler than using MinGW in conda):
conda create -n py37 python=3.7
conda activate py37
conda install wheel cython
python setup.py build_ext --shared --madxdir=%MADXDIR%