From 5c69ca2dce1d7ce334c7c2641cde424f94eb1a81 Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 18:25:17 -0400 Subject: [PATCH 1/6] Quote glob env values in wheels.yml Unquoted `*` in CIBW_BUILD and CIBW_SKIP caused YAML parse errors. --- .github/workflows/wheels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index f7629ee..70d6a0d 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -57,8 +57,8 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: cp310-* cp311-* cp312-* cp313-* - CIBW_SKIP: *-musllinux_* *-win32 + CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-*" + CIBW_SKIP: "*-musllinux_* *-win32" CIBW_ARCHS_LINUX: auto64 CIBW_ARCHS_WINDOWS: auto64 CIBW_ARCHS_MACOS: auto64 From 8c0a7b39f92463b6f5527055faa2ca1c4b18ce38 Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 18:29:51 -0400 Subject: [PATCH 2/6] Disable Eigen tests/docs during FetchContent build Eigen's FetchContent was configuring its entire test suite (CHOLMOD, UMFPACK, CUDA, Qt, Boost, etc.) causing slow builds and failures in isolated CI environments like manylinux. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0a4719..a397149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,9 @@ if(NOT Eigen3_FOUND) GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git GIT_TAG 3.4.0 ) + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE) + set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(eigen) # Point Eigen3_DIR to the build directory where Eigen3Config.cmake is generated From de7ab58bbc9f1dfe7f31b10d4e62230353ec3791 Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 18:34:20 -0400 Subject: [PATCH 3/6] Use FetchContent_Populate for Eigen to avoid target collision Eigen's unsupported/test/ creates a custom target named "autodiff" which collides with the real autodiff library when both are added via FetchContent_MakeAvailable. Since Eigen is header-only, use FetchContent_Populate to download without add_subdirectory, then create the Eigen3::Eigen target manually. --- CMakeLists.txt | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a397149..65ac5a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,22 +72,21 @@ if(NOT Eigen3_FOUND) GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git GIT_TAG 3.4.0 ) - set(BUILD_TESTING OFF CACHE BOOL "" FORCE) - set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE) - set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(eigen) - - # Point Eigen3_DIR to the build directory where Eigen3Config.cmake is generated - # so that downstream find_package(Eigen3) calls (e.g., from autodiff) can find it - set(Eigen3_DIR "${eigen_BINARY_DIR}" CACHE PATH "Path to Eigen3Config.cmake" FORCE) - - # Ensure Eigen3::Eigen target exists for direct usage - if(NOT TARGET Eigen3::Eigen) - add_library(Eigen3::Eigen INTERFACE IMPORTED) - set_target_properties(Eigen3::Eigen PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${eigen_SOURCE_DIR}" - ) + # Use FetchContent_Populate (not MakeAvailable) to download Eigen without + # adding it as a subdirectory. Eigen is header-only so no build step is + # needed, and add_subdirectory pulls in unsupported/test which creates a + # custom target called "autodiff" that collides with the real autodiff lib. + FetchContent_GetProperties(eigen) + if(NOT eigen_POPULATED) + FetchContent_Populate(eigen) endif() + + # Create the canonical Eigen3::Eigen target for our project and autodiff + add_library(Eigen3::Eigen INTERFACE IMPORTED) + set_target_properties(Eigen3::Eigen PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${eigen_SOURCE_DIR}" + ) + set(Eigen3_FOUND TRUE CACHE BOOL "" FORCE) endif() if (CDDP_CPP_CASADI) From 74d9381025b6c80299c5a9a51921cb964ab6ffd8 Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 18:43:30 -0400 Subject: [PATCH 4/6] Fix Eigen fetch: use MakeAvailable with EXCLUDE_FROM_ALL FetchContent_Populate is deprecated in CMake 4.x (CMP0169), so switch back to FetchContent_MakeAvailable. Use EXCLUDE_FROM_ALL to limit Eigen's scope and BUILD_TESTING=OFF to prevent Eigen's unsupported/test from creating an "autodiff" custom target that collides with the real autodiff library. Set Eigen3_DIR to the build tree so autodiff's find_package(Eigen3) can locate the generated Eigen3Config.cmake. --- CMakeLists.txt | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65ac5a4..9d9c11b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,26 +67,23 @@ find_package(Eigen3 3.4 QUIET NO_MODULE) # If Eigen3 is not found, fetch it and expose a proper Eigen3::Eigen target if(NOT Eigen3_FOUND) message(STATUS "Eigen3 not found. Downloading...") + # Disable Eigen tests/docs before fetching — Eigen's unsupported/test/ + # creates a custom target called "autodiff" that collides with the real + # autodiff library. + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE) + set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE) FetchContent_Declare( eigen GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git GIT_TAG 3.4.0 + EXCLUDE_FROM_ALL ) - # Use FetchContent_Populate (not MakeAvailable) to download Eigen without - # adding it as a subdirectory. Eigen is header-only so no build step is - # needed, and add_subdirectory pulls in unsupported/test which creates a - # custom target called "autodiff" that collides with the real autodiff lib. - FetchContent_GetProperties(eigen) - if(NOT eigen_POPULATED) - FetchContent_Populate(eigen) - endif() + FetchContent_MakeAvailable(eigen) - # Create the canonical Eigen3::Eigen target for our project and autodiff - add_library(Eigen3::Eigen INTERFACE IMPORTED) - set_target_properties(Eigen3::Eigen PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${eigen_SOURCE_DIR}" - ) - set(Eigen3_FOUND TRUE CACHE BOOL "" FORCE) + # Point Eigen3_DIR at the build tree so autodiff's find_package(Eigen3) + # finds the generated Eigen3Config.cmake + set(Eigen3_DIR "${eigen_BINARY_DIR}" CACHE PATH "" FORCE) endif() if (CDDP_CPP_CASADI) From 55d13cf5b958723adb56b025eff901b1de33265e Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 18:56:18 -0400 Subject: [PATCH 5/6] Fix Windows M_PI error and drop macos-13 runner - Add _USE_MATH_DEFINES for MSVC so M_PI is defined in - Remove macos-13 from build matrix (deprecated x86 runner) --- .github/workflows/publish.yml | 2 +- .github/workflows/wheels.yml | 2 +- CMakeLists.txt | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index af05f4d..223d72c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,7 +39,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest, macos-14] steps: - name: Check out repository diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 70d6a0d..f111455 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -40,7 +40,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest, macos-14] steps: - name: Check out repository diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d9c11b..1f9c2e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,6 +187,10 @@ target_link_libraries(${PROJECT_NAME} autodiff ) +if(MSVC) + target_compile_definitions(${PROJECT_NAME} PUBLIC _USE_MATH_DEFINES) +endif() + target_include_directories(${PROJECT_NAME} PUBLIC $ $ From e99c75eb387510178d23140b74f228aa29a91c28 Mon Sep 17 00:00:00 2001 From: Tomo Sasaki Date: Sat, 4 Apr 2026 19:29:26 -0400 Subject: [PATCH 6/6] Skip Eigen's CMake configure entirely via SOURCE_SUBDIR trick Eigen's full configure probes for Fortran, Qt4, CUDA, OpenMP etc. adding ~30s+ per wheel on Windows. Since Eigen is header-only, use SOURCE_SUBDIR pointing to a nonexistent path so FetchContent downloads the source without running add_subdirectory. Create the Eigen3::Eigen target manually and write a minimal Eigen3Config.cmake for autodiff. --- CMakeLists.txt | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f9c2e6..aeb9cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,22 +67,32 @@ find_package(Eigen3 3.4 QUIET NO_MODULE) # If Eigen3 is not found, fetch it and expose a proper Eigen3::Eigen target if(NOT Eigen3_FOUND) message(STATUS "Eigen3 not found. Downloading...") - # Disable Eigen tests/docs before fetching — Eigen's unsupported/test/ - # creates a custom target called "autodiff" that collides with the real - # autodiff library. - set(BUILD_TESTING OFF CACHE BOOL "" FORCE) - set(EIGEN_BUILD_DOC OFF CACHE BOOL "" FORCE) - set(EIGEN_BUILD_TESTING OFF CACHE BOOL "" FORCE) + # Fetch Eigen as header-only: SOURCE_SUBDIR points at a path with no + # CMakeLists.txt so MakeAvailable downloads the source without running + # Eigen's CMake. This avoids slow configure probes (Fortran, Qt, CUDA) + # and a target name collision with the real autodiff library. FetchContent_Declare( eigen GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git GIT_TAG 3.4.0 - EXCLUDE_FROM_ALL + SOURCE_SUBDIR _unused ) FetchContent_MakeAvailable(eigen) - # Point Eigen3_DIR at the build tree so autodiff's find_package(Eigen3) - # finds the generated Eigen3Config.cmake + add_library(Eigen3::Eigen INTERFACE IMPORTED) + set_target_properties(Eigen3::Eigen PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${eigen_SOURCE_DIR}" + ) + + # Write a minimal Eigen3Config.cmake so autodiff's find_package(Eigen3) + # finds it without needing Eigen's full configure step + file(WRITE "${eigen_BINARY_DIR}/Eigen3Config.cmake" + "set(Eigen3_FOUND TRUE)\n" + "if(NOT TARGET Eigen3::Eigen)\n" + " add_library(Eigen3::Eigen INTERFACE IMPORTED)\n" + " set_target_properties(Eigen3::Eigen PROPERTIES INTERFACE_INCLUDE_DIRECTORIES \"${eigen_SOURCE_DIR}\")\n" + "endif()\n" + ) set(Eigen3_DIR "${eigen_BINARY_DIR}" CACHE PATH "" FORCE) endif()