Skip to content

Commit

Permalink
Build statically for Windows (#9)
Browse files Browse the repository at this point in the history
This fixes an issue where the import libraries were being zipped up instead of static libraries. As part of this, Gradle now executes vcpkg as part of the build, because it's likely the triplet needed to build for Windows will be forgotten.

Use overlay ports to force x86 Windows to use clapack and openblas

Add basic docs
  • Loading branch information
Gold856 authored Dec 4, 2024
1 parent c97cda8 commit 6e43303
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 53 deletions.
60 changes: 20 additions & 40 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ jobs:
- uses: lukka/[email protected]
with:
vcpkgGitCommitId: '29b2ea2d4b6197e66ef346e62ccbba35b55b7de5'
- run: vcpkg install
name: install packages
- run: ./gradlew publish ${{ matrix.build-options }}
name: Build with Gradle
- run: ls vcpkg_installed/*/lib/*
name: List dependent shared libraries
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
Expand All @@ -48,10 +48,10 @@ jobs:
include:
- artifact-name: WinArm64
tool-arch: amd64_arm64
build-options: -Pplatform=arm64-windows
build-options: -Pplatform=arm64-windows-static-md
- artifact-name: Win64
tool-arch: amd64
build-options: -Pplatform=x64-windows
build-options:

name: "Build - ${{ matrix.artifact-name }}"
runs-on: windows-2019
Expand All @@ -69,46 +69,26 @@ jobs:
- uses: ilammy/[email protected]
with:
arch: ${{ matrix.tool-arch }}
- run: vcpkg install --triplet=arm64-windows
name: install packages
if: matrix.artifact-name == 'WinArm64'
- run: vcpkg install --triplet=x64-windows
name: install packages
if: matrix.artifact-name == 'Win64'
- run: ./gradlew publish ${{ matrix.build-options }}
name: Build with Gradle
- run: ls vcpkg_installed/*/bin/*
name: List dependent DLLs
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: gradleDir/outputs/

build-mac:
name: "Build - macOS"
runs-on: macOS-14
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- run: brew install cmake ninja
name: install ninja
- uses: lukka/[email protected]
with:
vcpkgGitCommitId: '29b2ea2d4b6197e66ef346e62ccbba35b55b7de5'
- run: vcpkg install --triplet=x64-osx
name: install packages
- run: ./gradlew publish -Pplatform=x64-osx
name: Build with Gradle
- uses: actions/upload-artifact@v4
with:
name: macOS
path: gradleDir/outputs/
strategy:
fail-fast: false
matrix:
include:
- artifact-name: macOSArm
build-options: -Pplatform=arm64-osx
- artifact-name: macOS
build-options: -Pplatform=x64-osx

build-mac-arm:
name: "Build - macOS (Arm)"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: macOS-14
steps:
- uses: actions/checkout@v4
Expand All @@ -123,18 +103,18 @@ jobs:
- uses: lukka/[email protected]
with:
vcpkgGitCommitId: '29b2ea2d4b6197e66ef346e62ccbba35b55b7de5'
- run: vcpkg install --triplet=arm64-osx
name: install packages
- run: ./gradlew publish -Pplatform=arm64-osx
- run: ./gradlew publish ${{ matrix.build-options }}
name: Build with Gradle
- run: ls vcpkg_installed/*/lib/*
name: List dependent shared libraries
- uses: actions/upload-artifact@v4
with:
name: macOSArm
name: ${{ matrix.artifact-name }}
path: gradleDir/outputs/

make_universal:
name: Make Universal
needs: [build-mac, build-mac-arm]
needs: [build-mac]
runs-on: macos-14
steps:
- uses: actions/checkout@v4
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# External Ceres repo
This is the repo that builds ceres and its dependents for for use in wpical. It uses vcpkg to build all the dependencies and Gradle to package it for use in allwpilib.

# Getting Started
The build requirements are the same as [allwpilib](https://github.com/wpilibsuite/allwpilib/?tab=readme-ov-file#requirements).

1. Clone the repo with `git clone --recursive https://github.com/wpilibsuite/thirdparty-ceres.git`. This will also initialize the vcpkg submodule.
2. Build the libraries with `gradlew buildVcpkg` and publish the artifacts locally with `gradlew publish`.

## Important notes
### Overlay ports
There are two overlay ports for blas and lapack. By default on x86-64 Windows, vcpkg will use lapack-reference and its cblas feature, which is an issue because it requires shared libraries for the gfortran dependency, which we can't use for a static build. (The DLL list is libblas.dll, libgcc_s_seh-1.dll, libgfortran-5.dll, liblapack.dll, libquadmath-0.dll, libwinpthread-1.dll)

To solve this, overlay ports were used to override the blas port to use openblas and the lapack port to use clapack, avoiding the gfortran dependency and allowing a completely static build. This is the same setup as ARM Windows (which is where this setup was copied from.)

### Triplets
The vcpkg triplets used for Windows end in `-static-md`. This enables static library building, but dynamic linkage to the CRT, which [matches the way WPILib builds](https://github.com/wpilibsuite/native-utils/blob/main/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java#L45).
8 changes: 8 additions & 0 deletions overlayPorts/blas/blas.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
prefix=${pcfiledir}/../..

Name: BLAS
Description: Implementation of BLAS
Version:
Requires: @requires@
Libs: @libs@
Cflags: @cflags@
32 changes: 32 additions & 0 deletions overlayPorts/blas/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
SET(VCPKG_POLICY_EMPTY_PACKAGE enabled)

# Due to the interaction between BLAS and LAPACK, we need to choose implementations consistent with
# each other.
#
# First, if we are on Apple, we use the Accelerate framework.
#
# Then, we prefer to use openblas and lapack-reference for blas and lapack, respectively.

if(VCPKG_TARGET_IS_OSX OR VCPKG_TARGET_IS_IOS)
# Use Apple's accelerate framework where available
set(BLA_VENDOR Apple)
set(requires "")
set(libs "-framework Accelerate")
set(cflags "-framework Accelerate")
else()
set(BLA_VENDOR OpenBLAS)
set(requires openblas)
endif()

configure_file("${CMAKE_CURRENT_LIST_DIR}/blas.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/blas.pc" @ONLY)
if(NOT VCPKG_BUILD_TYPE)
configure_file("${CMAKE_CURRENT_LIST_DIR}/blas.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/blas.pc" @ONLY)
endif()

if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
set(BLA_STATIC ON)
else()
set(BLA_STATIC OFF)
endif()

configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/blas/vcpkg-cmake-wrapper.cmake" @ONLY)
9 changes: 9 additions & 0 deletions overlayPorts/blas/vcpkg-cmake-wrapper.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# BLA_VENDOR and BLA_STATIC are documented at:
# * https://cmake.org/cmake/help/latest/module/FindBLAS.html
# * https://cmake.org/cmake/help/latest/module/FindLAPACK.html

set(BLA_VENDOR @BLA_VENDOR@)
set(BLA_STATIC @BLA_STATIC@)
_find_package(${ARGS})
unset(BLA_VENDOR)
unset(BLA_STATIC)
19 changes: 19 additions & 0 deletions overlayPorts/blas/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$comment": "Keep the platform expressions in sync with the wrappers installed by the portfiles!",
"name": "blas",
"version-date": "2023-04-14",
"port-version": 1,
"description": "Metapackage for packages which provide BLAS",
"license": null,
"supports": "!(android & arm32) & !(android & x64)",
"dependencies": [
{
"name": "openblas",
"platform": "!osx & !ios"
},
{
"name": "vcpkg-cmake",
"host": true
}
]
}
9 changes: 9 additions & 0 deletions overlayPorts/lapack/lapack.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
prefix=${pcfiledir}/../..
libdir=${prefix}/lib

Name: LAPACK
Description: Implementation of LAPACK
Version:
Requires: @requires@
Libs: @libs@
Cflags: @cflags@
42 changes: 42 additions & 0 deletions overlayPorts/lapack/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
SET(VCPKG_POLICY_EMPTY_PACKAGE enabled)

if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
set(BLA_STATIC ON)
else()
set(BLA_STATIC OFF)
endif()

# See explanation of which lapack implementation is chosen in portfile.cmake in the blas port

set(BLA_VENDOR Generic)
set(installed_wrapper "${CURRENT_INSTALLED_DIR}/share/lapack/vcpkg-cmake-wrapper.cmake")
set(installed_module "${CURRENT_INSTALLED_DIR}/share/lapack/FindLAPACK.cmake")
if(VCPKG_TARGET_IS_OSX OR VCPKG_TARGET_IS_IOS)
# Use Apple's accelerate framework where available
set(BLA_VENDOR Apple)
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/lapack/vcpkg-cmake-wrapper.cmake" @ONLY)
set(libs "-framework Accelerate")
set(cflags "-framework Accelerate")
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/lapack.pc" @ONLY)
if(NOT VCPKG_BUILD_TYPE)
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/lapack.pc" @ONLY)
endif()
unset(installed_module)
elseif(VCPKG_TARGET_IS_UWP OR VCPKG_TARGET_IS_WINDOWS)
configure_file("${CURRENT_INSTALLED_DIR}/share/clapack/wrapper/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/lapack/vcpkg-cmake-wrapper.cmake" COPYONLY)
configure_file("${CURRENT_INSTALLED_DIR}/share/clapack/FindLAPACK.cmake" "${CURRENT_PACKAGES_DIR}/share/lapack/FindLAPACK.cmake" COPYONLY)
set(libs "-llapack -llibf2c")
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/lapack.pc" @ONLY)
if(NOT VCPKG_BUILD_TYPE)
set(libs "-llapack -llibf2c")
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/lapack.pc" @ONLY)
endif()
else()
configure_file("${CURRENT_INSTALLED_DIR}/share/lapack-reference/wrapper/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/lapack/vcpkg-cmake-wrapper.cmake" COPYONLY)
configure_file("${CURRENT_INSTALLED_DIR}/share/lapack-reference/FindLAPACK.cmake" "${CURRENT_PACKAGES_DIR}/share/lapack/FindLAPACK.cmake" COPYONLY)
set(requires "lapack-reference")
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/lapack.pc" @ONLY)
if(NOT VCPKG_BUILD_TYPE)
configure_file("${CMAKE_CURRENT_LIST_DIR}/lapack.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/lapack.pc" @ONLY)
endif()
endif()
15 changes: 15 additions & 0 deletions overlayPorts/lapack/vcpkg-cmake-wrapper.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# BLA_VENDOR and BLA_STATIC are documented at:
# * https://cmake.org/cmake/help/latest/module/FindBLAS.html
# * https://cmake.org/cmake/help/latest/module/FindLAPACK.html

_find_package(BLAS) # Find BLAS before setting BLA_VENDOR (Will set/unset BLA_VENDOR itself)
set(BLA_VENDOR @BLA_VENDOR@)
if(APPLE AND "@BLA_STATIC@" AND CMAKE_VERSION VERSION_LESS "3.17.0")
# avoid `-Wl,--(start|end)-group` and wrong lib suffix
set(BLA_STATIC 0)
else()
set(BLA_STATIC @BLA_STATIC@)
endif()
_find_package(${ARGS})
unset(BLA_VENDOR)
unset(BLA_STATIC)
23 changes: 23 additions & 0 deletions overlayPorts/lapack/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$comment": "Keep the platform expressions in sync with the wrappers installed by the portfiles!",
"name": "lapack",
"version-date": "2023-06-10",
"port-version": 2,
"description": "Metapackage for packages which provide LAPACK",
"license": null,
"supports": "!android",
"dependencies": [
{
"name": "clapack",
"platform": "uwp | windows"
},
{
"name": "lapack-reference",
"platform": "!osx & !ios & !uwp & !windows"
},
{
"name": "vcpkg-cmake",
"host": true
}
]
}
Loading

0 comments on commit 6e43303

Please sign in to comment.