Skip to content

DIPlib Build on Windows/MSVC: PyDIP Issue #205

@AleksandraWill

Description

@AleksandraWill

Component
PyDIP / CMake build scripts.
The DIPlib source code as of 19-07-2025.

Describe the bug
PyDIP check MSB8066

Image
36>[doctest] test cases:  104 |  104 passed | 0 failed | 0 skipped
36>[doctest] assertions: 3684 | 3684 passed | 0 failed |
36>[doctest] Status: SUCCESS!
36>Building Custom Rule C:/Users/Aleksandra/Libraries/diplib/src/CMakeLists.txt
41>PyDIPjavaio.vcxproj -> C:\Users\Aleksandra\Libraries\diplib\build\pydip\Release\PyDIPjavaio.cp312-win_amd64.pyd
14>PyDIP_bin.vcxproj -> C:\Users\Aleksandra\Libraries\diplib\build\pydip\Release\PyDIP_bin.cp312-win_amd64.pyd
38>Finished generating code
38>PyDIPviewer.vcxproj -> C:\Users\Aleksandra\Libraries\diplib\build\pydip\Release\PyDIPviewer.cp312-win_amd64.pyd
42>------ Build started: Project: PyDIP, Configuration: Release x64 ------
43>------ Build started: Project: ALL_BUILD, Configuration: Release x64 ------
42>1>
42>Building Custom Rule C:/Users/Aleksandra/Libraries/diplib/pydip/CMakeLists.txt
43>Building Custom Rule C:/Users/Aleksandra/Libraries/diplib/CMakeLists.txt
44>------ Build started: Project: staging, Configuration: Release x64 ------
45>------ Skipped Build: Project: INSTALL, Configuration: Release x64 ------
45>Project not selected to build for this solution configuration 
44>1>
44>Building Custom Rule C:/Users/Aleksandra/Libraries/diplib/pydip/CMakeLists.txt
46>------ Build started: Project: bdist_wheel, Configuration: Release x64 ------
47>------ Build started: Project: PyDIP_check, Configuration: Release x64 ------
47>1>
47>Could not load PyDIP binary extension. Did you install the Microsoft Visual C++ Redistributable?
47>Traceback (most recent call last):
47>  File "C:\Users\Aleksandra\Libraries\diplib\build\pydip\Release\unit_tests.py", line 20, in <module>
47>    import staging.diplib
47>  File "C:\Users\Aleksandra\Libraries\diplib\build\pydip\Release\staging\diplib\__init__.py", line 39, in <module>
47>    from .PyDIP_bin import *
47>ImportError: DLL load failed while importing PyDIP_bin: Nie mo┐na odnalečŠ okreťlonego modu│u.
47>The system cannot find the batch label specified - VCEnd
47>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(237,5): error MSB8066: Custom build for 'C:\Users\Aleksandra\Libraries\diplib\build\CMakeFiles\7230119ff65d6f90253a09b4db4b6fb9\PyDIP_check.rule' exited with code 1.
47>Done building project "PyDIP_check.vcxproj" -- FAILED.
48>------ Skipped Build: Project: check, Configuration: Release x64 ------
48>Project not selected to build for this solution configuration 
46>1>
46>* Getting build dependencies for wheel...
46>C:\Users\Aleksandra\Libraries\python_libs\env_312\Lib\site-packages\setuptools\command\bdist_wheel.py:103: RuntimeWarning: Config variable 'Py_DEBUG' is unset, Python ABI tag may be incorrect
46>  if get_flag("Py_DEBUG", hasattr(sys, "gettotalrefcount"), warn=(impl == "cp")):
Image

To Reproduce
configuration in CMake GUI:

DIPlib-CMake-configuration-report.txt

Image Image Image Image Image

I modified CMakeLists.txt files during the DipLib build, in part because Vigra was previously built with OpenEXR.
A linking error with the source-built FreeType was resolved by linking the Vcpkg-installed FreeType library.

  • root/CMakeLists.txt:
# OpenMP
find_package(OpenMP)
if(OpenMP_CXX_FOUND OR OPENMP_FOUND) # OPENMP_FOUND for CMake <= 3.8
   set(DIP_ENABLE_MULTITHREADING ON CACHE BOOL "Enable multithreading support")
endif()

# Add this here:
find_package(OpenEXR REQUIRED)
find_package(Freetype REQUIRED)

include(${CMAKE_CURRENT_LIST_DIR}/tools/compiler_flags.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/tools/update_deps_file.cmake)
  • src/CMakeLists.xt
# Use FreeType
find_package(Freetype)
if(FREETYPE_FOUND)
   set(DIP_ENABLE_FREETYPE ON CACHE BOOL "Enable linking against FreeType, for better text rendering in images")
else()
   set(DIP_ENABLE_FREETYPE OFF CACHE BOOL "Enable linking against FreeType, for better text rendering in images")
endif()
if(DIP_ENABLE_FREETYPE)
   target_include_directories(DIP PRIVATE ${FREETYPE_INCLUDE_DIRS})
   target_link_libraries(DIP PRIVATE Freetype::Freetype)
   target_compile_definitions(DIP PRIVATE DIP_CONFIG_HAS_FREETYPE)
endif()

I have modified file:

  • src\library\physical_dimensions.cpp (lines 518-623):
#ifdef DIP_CONFIG_ENABLE_UNICODE

      dip::Units f = dip::Units::Meter();
      DOCTEST_CHECK(( f ).String() == "m" );
      DOCTEST_CHECK(( f ).StringUnicode() == "m" );
      DOCTEST_CHECK(( f * f ).String() == "m^2" );
      DOCTEST_CHECK(( f * f ).StringUnicode() == u8"m\u00B2" );
      DOCTEST_CHECK(( f * f * f ).String() == "m^3" );
      DOCTEST_CHECK(( f * f * f ).StringUnicode() == u8"m\u00B3" );
      DOCTEST_CHECK(( f * f * f * f ).String() == "m^4" );
      DOCTEST_CHECK(( f * f * f * f ).StringUnicode() == u8"m\u2074" );
      DOCTEST_CHECK(( dip::Units() / f ).String() == "m^-1" );
      DOCTEST_CHECK(( dip::Units() / f ).StringUnicode() == u8"m\u207B\u00B9" );
      DOCTEST_CHECK(( dip::Units() / f / f ).String() == "m^-2" );
      DOCTEST_CHECK(( dip::Units() / f / f ).StringUnicode() == u8"m\u207B\u00B2" );
      DOCTEST_CHECK(( dip::Units() / f / f / f ).String() == "m^-3" );
      DOCTEST_CHECK(( dip::Units() / f / f / f ).StringUnicode() == u8"m\u207B\u00B3" );
      DOCTEST_CHECK(( dip::Units() / f / f / f / f ).String() == "m^-4" );
      DOCTEST_CHECK(( dip::Units() / f / f / f / f ).StringUnicode() == u8"m\u207B\u2074" );
      DOCTEST_CHECK( f == dip::Units( "m" ));
      DOCTEST_CHECK( f * f == dip::Units( "m^2" ));
      DOCTEST_CHECK( f * f == dip::Units( "m^2" ));
      DOCTEST_CHECK( f * f * f == dip::Units( "m^3" ));
      DOCTEST_CHECK( f * f * f == dip::Units( "m^3" ));
      DOCTEST_CHECK( f * f * f * f == dip::Units( "m^4" ));
      DOCTEST_CHECK( f * f * f * f == dip::Units( "m^4" ));
      DOCTEST_CHECK( dip::Units() / f == dip::Units( "m^-1" ));
      DOCTEST_CHECK( dip::Units() / f == dip::Units( "m^-1" ));
      DOCTEST_CHECK( dip::Units() / f / f == dip::Units( "m^-2" ));
      DOCTEST_CHECK( dip::Units() / f / f == dip::Units( "m^-2" ));
      DOCTEST_CHECK( dip::Units() / f / f / f == dip::Units( "m^-3" ));
      DOCTEST_CHECK( dip::Units() / f / f / f == dip::Units( "m^-3" ));
      DOCTEST_CHECK( dip::Units() / f / f / f / f == dip::Units( "m^-4" ));
      DOCTEST_CHECK( dip::Units() / f / f / f / f == dip::Units( "m^-4" ));

      dip::Units g = dip::Units::Second();
      DOCTEST_CHECK(( f / g ).String() == "m/s" );
      DOCTEST_CHECK(( f / g ).StringUnicode() == "m/s" );
      DOCTEST_CHECK(( f / g / g ).String() == "m/s^2" );
      DOCTEST_CHECK(( f / g / g ).StringUnicode() == u8"m/s\u00B2" );
      DOCTEST_CHECK(( f / g / g / g ).String() == "m/s^3" );
      DOCTEST_CHECK(( f / g / g / g ).StringUnicode() == u8"m/s\u00B3" );
      DOCTEST_CHECK(( f / g / g / g / g ).String() == "m/s^4" );
      DOCTEST_CHECK(( f / g / g / g / g ).StringUnicode() == u8"m/s\u2074" );
      DOCTEST_CHECK(( g / f ).String() == "s/m" );
      DOCTEST_CHECK(( g / f ).StringUnicode() == "s/m" );
      DOCTEST_CHECK(( g / f / f ).String() == "s/m^2" );
      DOCTEST_CHECK(( g / f / f ).StringUnicode() == u8"s/m\u00B2" );
      DOCTEST_CHECK(( g * g / f ).String() == "s^2/m" );
      DOCTEST_CHECK(( g * g / f ).StringUnicode() == u8"s\u00B2/m" );
      DOCTEST_CHECK(( g * f ).String() == "m.s" );
      DOCTEST_CHECK(( g * f ).StringUnicode() == u8"m\u00B7s" );
      DOCTEST_CHECK( f / g == dip::Units( "m/s" ));
      DOCTEST_CHECK( f / g / g == dip::Units( "m/s^2" ));
      DOCTEST_CHECK( f / g / g == dip::Units( "m/s^2" ));
      DOCTEST_CHECK( f / g / g / g == dip::Units( "m/s^3" ));
      DOCTEST_CHECK( f / g / g / g == dip::Units( "m/s^3" ));
      DOCTEST_CHECK( f / g / g / g / g == dip::Units( "m/s^4" ));
      DOCTEST_CHECK( f / g / g / g / g == dip::Units( "m/s^4" ));
      DOCTEST_CHECK( g / f == dip::Units( "s/m" ));
      DOCTEST_CHECK( g / f / f == dip::Units( "s/m^2" ));
      DOCTEST_CHECK( g / f / f == dip::Units( "s/m^2" ));
      DOCTEST_CHECK( g * g / f == dip::Units( "s^2/m" ));
      DOCTEST_CHECK( g * g / f == dip::Units( "s^2/m" ));
      DOCTEST_CHECK( g * f == dip::Units( "m.s" ));
      DOCTEST_CHECK( g * f == dip::Units( "m.s" ));

      DOCTEST_CHECK(( dip::Units::Millimeter() ).String() == "mm" );
      DOCTEST_CHECK(( dip::Units::Millimeter() ).StringUnicode() == "mm" );
      DOCTEST_CHECK(( dip::Units::Millimeter() * dip::Units::Millimeter() ).String() == "mm^2" );
      DOCTEST_CHECK(( dip::Units::Millimeter() * dip::Units::Millimeter() ).StringUnicode() == u8"mm\u00B2" );
      DOCTEST_CHECK(( dip::Units::Millimeter() * dip::Units::Meter() ).String() == "10^3.mm^2" );
      DOCTEST_CHECK(( dip::Units::Millimeter() * dip::Units::Meter() ).StringUnicode() == u8"10\u00B3\u00B7mm\u00B2" );
      DOCTEST_CHECK(( dip::Units::Kilometer() * dip::Units::Meter() ).String() == "10^3.m^2" );
      DOCTEST_CHECK(( dip::Units::Kilometer() * dip::Units::Meter() ).StringUnicode() == u8"10\u00B3\u00B7m\u00B2" );
      DOCTEST_CHECK( dip::Units::Millimeter() == dip::Units( "mm" ));
      DOCTEST_CHECK( dip::Units::Millimeter() * dip::Units::Millimeter() == dip::Units( "mm^2" ));
      DOCTEST_CHECK( dip::Units::Millimeter() * dip::Units::Millimeter() == dip::Units( "mm^2" ));
      DOCTEST_CHECK( dip::Units::Millimeter() * dip::Units::Meter() == dip::Units( "10^3.mm^2" ));
      DOCTEST_CHECK( dip::Units::Millimeter() * dip::Units::Meter() == dip::Units( "10^3.mm^2" ));
      DOCTEST_CHECK( dip::Units::Kilometer() * dip::Units::Meter() == dip::Units( "10^3.m^2" ));
      DOCTEST_CHECK( dip::Units::Kilometer() * dip::Units::Meter() == dip::Units( "10^3.m^2" ));

      DOCTEST_CHECK(( dip::Units( "10^6.mm^2" )).String() == "m^2" );
      DOCTEST_CHECK(( dip::Units( "10^6.mm^2" )).StringUnicode() == u8"m\u00B2" );

      DOCTEST_CHECK(( dip::Units( "km/s" )).String() == "km/s" );
      DOCTEST_CHECK(( dip::Units( "km/s" )).StringUnicode() == "km/s" );
      DOCTEST_CHECK(( dip::Units( "km.cd.rad.px" )).String() == "km.cd.rad.px" );
      DOCTEST_CHECK(( dip::Units( "km.cd.rad.px" )).StringUnicode() == u8"km\u00B7cd\u00B7rad\u00B7px" );
      DOCTEST_CHECK(( dip::Units( u8"km\u00B7cd\u00B7rad\u00B7px" )).StringUnicode() == u8"km\u00B7cd\u00B7rad\u00B7px" );
      DOCTEST_CHECK(( dip::Units( "km.cd/rad.px" )).String() == "km.cd.px/rad" );
      DOCTEST_CHECK(( dip::Units( "km.cd/rad.px" )).StringUnicode() == u8"km\u00B7cd\u00B7px/rad" );
      DOCTEST_CHECK(( dip::Units( u8"km\u00B7cd/rad\u00B7px" )).StringUnicode() == u8"km\u00B7cd\u00B7px/rad" );
      DOCTEST_CHECK(( dip::Units( "10^3.km^-1.cd^-2/K" )).String() == "m^-1/K/cd^2" );
      DOCTEST_CHECK(( dip::Units( "10^3.km^-1.cd^-2/K" )).StringUnicode() == u8"m\u207B\u00B9/K/cd\u00B2" );

      DOCTEST_CHECK_THROWS( dip::Units( "q" ));                // non-existing units
      DOCTEST_CHECK_THROWS( dip::Units( "m^2-" ));
      DOCTEST_CHECK_THROWS( dip::Units( "m^2-" ));  // m^2-
      DOCTEST_CHECK_THROWS( dip::Units( "m^-" ));
      DOCTEST_CHECK_THROWS( dip::Units( "m^-" ));        // m^-
      DOCTEST_CHECK_THROWS( dip::Units( "uum" ));
      DOCTEST_CHECK_THROWS( dip::Units( "uum" ));  // uum

#else

Python libraries:
requirements.txt

Libraries installed via .\vcpkg install in manifest mode:
vcpkg.json

System information:

  • Windows 11 Home, 24H2
  • Python 3.12.10
  • MATLAB Version: 24.2.0.2806996 (R2024b) Update 3
  • Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.14.12
VisualStudio.17.Release/17.14.12+36408.4
Microsoft .NET Framework
Version 4.8.09032
Installed Version: Community
Visual C++ 2022   00482-90000-00000-AA424
ASP.NET and Web Tools   17.14.122.59099
Azure App Service Tools v3.0.0   17.14.122.59099
C# Tools   4.14.0-3.25359.3+6dbcfd2f553ef1ef0ac48878ab17d18c1360735d
Common Azure Tools   1.10
Cookiecutter   17.0.25079.8
GitHub Copilot   17.14.995.13737
IncrediBuild Build Acceleration   1.6.0.7
Intel® C++ Compiler   2025.2
Intel® DPC++ Compatibility Tool   2025.2
Intel® oneAPI DPC++ Compiler   2025.2
Intel® oneAPI Menu & Samples   10.10.392.9731
Intel® Performance Libraries   2025.2
Intel® VTune™ Profiler 2025   1.3.39
Linux Core Dump Debugging   1.0.9.36401
Microsoft Azure Tools for Visual Studio   2.9
Microsoft JVM Debugger   1.0
NuGet Package Manager   6.14.1
Python - Profiling support   17.0.25079.8
Python - VC Project Support   17.0.23055.1
Python with Pylance   17.0.25079.8
Razor (ASP.NET Core)   17.14.3.2530601+3372435431977e91904a23ceb1eab689badc1bd9
SQL Server Data Tools   17.14.26.0
Test Adapter for Boost.Test   1.0
Test Adapter for Google Test   1.0
TypeScript Tools   17.0.40502.2001
Visual Basic Tools   4.14.0-3.25359.3+6dbcfd2f553ef1ef0ac48878ab17d18c1360735d
Visual C++ for Linux and Mac Development   1.0.9.36401
Visual F# Tools   17.14.0-beta.25230.7+c1a9d78ad4a474a716ccffb4367ed5151e3f7c9f
Visual Studio IntelliCode   2.2

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions