-
Notifications
You must be signed in to change notification settings - Fork 0
Windows recipe patterns
Building things on Windows can be a little bit tricky and annoying because there are 3 different compilers to contend with (VS 2008 for Py 2.7-Py3.2, VS 2010 for Py 3.3-Py3.4, and VS 2015 for Py 3.5+). Hopefully the patterns here help you get started faster.
This is often used to feed the correct platform to msbuild, or to adjust configuration steps.
if "%ARCH%" == "64" (
set ARCH=x64
) else (
set ARCH=Win32
)
You have at least 2 options using CMake with Visual Studio.
Visual Studio includes a tool called NMake that is much like Make on Linux/Mac. CMake can output NMake makefiles. These makefiles are compiled with whatever compiler is active for conda-build. This means no additional configuration for you to support multiple Python platforms.
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% ..\
cmake --build . --target INSTALL --config Release
The downside of NMake is that it does not build in parallel, and there are occasionally strange corner cases that prevent it from working. If you're having problems with it, try generating version-specific solution files instead. This is more complicated in terms of bld.bat file, but perhaps simpler from the standpoint of taking the path more traveled.
REM write a temporary batch file to map cl.exe version to visual studio version
echo @echo 15=9 2008> msvc_versions.bat
echo @echo 16=10 2010>> msvc_versions.bat
echo @echo 19=14 2015>> msvc_versions.bat
REM Run cl.exe to find which version our compiler is
for /f "delims=" %%A in ('cl /? 2^>^&1 ^| findstr /C:"Version"') do set "CL_TEXT=%%A"
FOR /F "tokens=1,2 delims==" %%i IN ('msvc_versions.bat') DO echo %CL_TEXT% | findstr /C:"Version %%i" > nul && set VSTRING=%%j && goto FOUND
EXIT 1
:FOUND
if "%ARCH%" == "64" (
set "VSTRING=%VSTRING%Win64"
)
REM Trim trailing whitespace that may prevent CMake from finding which generator to use
call :TRIM VSTRING %VSTRING%
cd build
cmake -G "Visual Studio %VSTRING%" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% ..
cmake --build . --target INSTALL --config Release
:TRIM
SetLocal EnableDelayedExpansion
set Params=%*
for /f "tokens=1*" %%a in ("!Params!") do EndLocal & set %1=%%b
exit /B
You don't actually need solution files for each different VS version you want. Instead, you can take a VS 2008 solution and update it as necessary.
devenv.exe FreeImage.2008.sln /Upgrade
msbuild FreeImage.2008.sln /property:Configuration=Release /property:Platform=%ARCH%
It is sometimes helpful to pass characteristics about your Python environment that Conda-build does not make available as an environment variable. You can obtain these values by executing print statements:
for /f "delims=" %%A in ('%PREFIX%\python -c "import sys; print(sys.version_info.major)"') DO SET PY_MAJOR=%%A
for /f "delims=" %%A in ('%PREFIX%\python -c "import sys; print(sys.version_info.minor)"') DO SET PY_MINOR=%%A
Visual Studio 2008 did not include stdint.h. You can download them using:
curl -O http://msinttypes.googlecode.com/svn/trunk/stdint.h
Note that you need curl as a build-time requirement for this to work.
Finally, copy this downloaded file wherever your recipe looks for include files. For example, if your source code working folder has an include folder:
copy stdint.h %SRC_DIR%\include\stdint.h
Very related to above. Many recipes compensate for the lack of stdint.h by including their own definitions. Where recipes do not limit the scope correctly, these symbols conflict with those that Microsoft provides, and you need to fix the includes to avoid duplicate symbols.
The preprocessor lines where stdint.h is should be:
#if defined(_MSC_VER) && _MSC_VER >= 1600
#include "stdint.h"
#else
#include "<internal library stdint definitions>"
#endif