Skip to content

Commit

Permalink
[CI] Add a script to generate precompiled archives
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Oct 29, 2024
1 parent 29685b3 commit 04fe6ee
Show file tree
Hide file tree
Showing 3 changed files with 300 additions and 0 deletions.
115 changes: 115 additions & 0 deletions .github/julia/build_tarballs.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using BinaryBuilder, Pkg

haskey(ENV, "UNO_RELEASE") || error("The environment variable UNO_RELEASE is not defined.")
haskey(ENV, "UNO_COMMIT") || error("The environment variable UNO_COMMIT is not defined.")

name = "Uno"
version = VersionNumber(ENV["UNO_RELEASE"])

# Collection of sources required to complete build
sources = [
GitSource("https://github.com/cvanaret/Uno.git", ENV["UNO_COMMIT"])
]

# Bash recipe for building across all platforms
script = raw"""
# Export dependencies
mkdir ${prefix}/deps
cd ${libdir}
for file in $(ls .); do
if [[ -f $file ]]; then
if [[ -z $(ls -la $file | grep 'artifacts') ]]; then
cp -P ${file} ${prefix}/deps/${file}
else
cp -L ${file} ${prefix}/deps/${file}
fi
fi
done
cd ${prefix}
cp -rL share/licenses deps/licenses
chmod -R u=rwx deps
tar -czvf deps.tar.gz deps
rm -r deps
# Compile Uno
cd $WORKSPACE/srcdir/Uno
mkdir -p build
cd build
if [[ "${target}" == *apple* ]] || [[ "${target}" == *freebsd* ]]; then
OMP=omp
else
OMP=gomp
fi
# FortranCInterface_VERIFY fails on macOS, but it's not actually needed for the current build
sed -i 's/FortranCInterface_VERIFY(CXX)/# FortranCInterface_VERIFY(CXX)/g' ../CMakeLists.txt
cmake \
-DCMAKE_INSTALL_PREFIX=${prefix} \
-DCMAKE_PREFIX_PATH=${libdir} \
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TARGET_TOOLCHAIN} \
-DCMAKE_BUILD_TYPE=Release \
-DAMPLSOLVER=${libdir}/libasl.${dlext} \
-DHSL=${libdir}/libhsl.${dlext} \
-DMUMPS_INCLUDE_DIR=${includedir} \
-DMETIS_INCLUDE_DIR=${includedir} \
-DMUMPS_LIBRARY="${libdir}/libdmumps.${dlext}" \
-DMUMPS_COMMON_LIBRARY="${libdir}/libmumps_common.${dlext}" \
-DMUMPS_PORD_LIBRARY="${libdir}/libpord.${dlext}" \
-DMUMPS_MPISEQ_LIBRARY="${libdir}/libmpiseq.${dlext}" \
-DBLAS_LIBRARIES="${libdir}/libopenblas.${dlext}" \
-DLAPACK_LIBRARIES="${libdir}/libopenblas.${dlext}" \
..
make -j${nproc}
# Uno does not support `make install`. Manually copy for now.
install -v -m 755 "uno_ampl${exeext}" -t "${bindir}"
# Currently, Uno does not provide a shared library. This may be useful in the future once it has a C API.
# We just check that we can generate it, but we don't include it in the tarballs.
${CXX} -shared $(flagon -Wl,--whole-archive) libuno.a $(flagon -Wl,--no-whole-archive) -o libuno.${dlext} -L${libdir} -l${OMP} -lopenblas -ldmumps -lmetis -lhsl
cp libuno.a ${prefix}/lib/libuno.a
cp libuno.${dlext} "${libdir}/libuno.${dlext}
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms()
platforms = expand_gfortran_versions(platforms)

# The products that we will ensure are always built
products = [
ExecutableProduct("uno_ampl", :amplexe),
LibraryProduct("libuno", :libuno),
FileProduct("lib/libuno.a", :libuno_a),
]

# Dependencies that must be installed before this package can be built
dependencies = [
Dependency(PackageSpec(name="HSL_jll", uuid="017b0a0e-03f4-516a-9b91-836bbd1904dd")),
Dependency(PackageSpec(name="METIS_jll", uuid="d00139f3-1899-568f-a2f0-47f597d42d70")),
Dependency(PackageSpec(name="ASL_jll", uuid="ae81ac8f-d209-56e5-92de-9978fef736f9"), compat="0.1.3"),
# Most recent version compiled with OpenBLAS and not LBT
Dependency(PackageSpec(name="MUMPS_seq_jll", uuid="d7ed1dd3-d0ae-5e8e-bfb4-87a502085b8d"), compat="=5.4.1"),
Dependency(PackageSpec(name="OpenBLAS32_jll", uuid="656ef2d0-ae68-5445-9ca0-591084a874a2")),
# For OpenMP we use libomp from `LLVMOpenMP_jll` where we use LLVM as compiler (BSD systems),
# and libgomp from `CompilerSupportLibraries_jll` everywhere else.
Dependency(PackageSpec(name="CompilerSupportLibraries_jll", uuid="e66e0078-7015-5450-92f7-15fbd957f2ae"); platforms=filter(!Sys.isbsd, platforms)),
Dependency(PackageSpec(name="LLVMOpenMP_jll", uuid="1d63c593-3942-5779-bab2-d838dc0a180e"); platforms=filter(Sys.isbsd, platforms)),
HostBuildDependency(PackageSpec(name="CMake_jll", uuid="3f4e10e2-61f2-5801-8945-23b9d642d0e6")),
]

build_tarballs(
ARGS,
name,
version,
sources,
script,
platforms,
products,
dependencies;
julia_compat = "1.6",
preferred_gcc_version = v"10.2.0",
)
92 changes: 92 additions & 0 deletions .github/julia/generate_binaries.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Version
haskey(ENV, "UNO_RELEASE") || error("The environment variable UNO_RELEASE is not defined.")
version = VersionNumber(ENV["UNO_RELEASE"])
version2 = ENV["UNO_RELEASE"]
package = "Uno"

platforms = [
("aarch64-apple-darwin-libgfortran5" , "lib", "dylib"),
# ("aarch64-linux-gnu-libgfortran3" , "lib", "so" ),
# ("aarch64-linux-gnu-libgfortran4" , "lib", "so" ),
# ("aarch64-linux-gnu-libgfortran5" , "lib", "so" ),
# ("aarch64-linux-musl-libgfortran3" , "lib", "so" ),
# ("aarch64-linux-musl-libgfortran4" , "lib", "so" ),
# ("aarch64-linux-musl-libgfortran5" , "lib", "so" ),
# ("powerpc64le-linux-gnu-libgfortran3" , "lib", "so" ),
# ("powerpc64le-linux-gnu-libgfortran4" , "lib", "so" ),
# ("powerpc64le-linux-gnu-libgfortran5" , "lib", "so" ),
# ("x86_64-apple-darwin-libgfortran3" , "lib", "dylib"),
# ("x86_64-apple-darwin-libgfortran4" , "lib", "dylib"),
("x86_64-apple-darwin-libgfortran5" , "lib", "dylib"),
# ("x86_64-linux-gnu-libgfortran3" , "lib", "so" ),
# ("x86_64-linux-gnu-libgfortran4" , "lib", "so" ),
("x86_64-linux-gnu-libgfortran5" , "lib", "so" ),
# ("x86_64-linux-musl-libgfortran3" , "lib", "so" ),
# ("x86_64-linux-musl-libgfortran4" , "lib", "so" ),
# ("x86_64-linux-musl-libgfortran5" , "lib", "so" ),
# ("x86_64-unknown-freebsd-libgfortran3", "lib", "so" ),
# ("x86_64-unknown-freebsd-libgfortran4", "lib", "so" ),
# ("x86_64-unknown-freebsd-libgfortran5", "lib", "so" ),
# ("x86_64-w64-mingw32-libgfortran3" , "bin", "dll" ),
# ("x86_64-w64-mingw32-libgfortran4" , "bin", "dll" ),
("x86_64-w64-mingw32-libgfortran5" , "bin", "dll" ),
]


for (platform, libdir, ext) in platforms

tarball_name = "$package.v$version.$platform.tar.gz"

if isfile("products/$(tarball_name)")
# Unzip the tarball generated by BinaryBuilder.jl
isdir("products/$platform") && rm("products/$platform", recursive=true)
mkdir("products/$platform")
run(`tar -xzf products/$(tarball_name) -C products/$platform`)

if isfile("products/$platform/deps.tar.gz")
# Unzip the tarball of the dependencies
run(`tar -xzf products/$platform/deps.tar.gz -C products/$platform`)

# Copy the license of each dependency
for folder in readdir("products/$platform/deps/licenses")
cp("products/$platform/deps/licenses/$folder", "products/$platform/share/licenses/$folder")
end
rm("products/$platform/deps/licenses", recursive=true)

# Copy the shared library of each dependency
for file in readdir("products/$platform/deps")
cp("products/$platform/deps/$file", "products/$platform/$libdir/$file")
end

# Remove the folder used to unzip the tarball of the dependencies
rm("products/$platform/deps", recursive=true)
rm("products/$platform/deps.tar.gz", recursive=true)

# Create the archives *_binaries
isfile("$(package)_binaries.$version2.$platform.tar.gz") && rm("$(package)_binaries.$version2.$platform.tar.gz")
isfile("$(package)_binaries.$version2.$platform.zip") && rm("$(package)_binaries.$version2.$platform.zip")
cd("products/$platform")

# Create a folder with the version number of the package
mkdir("$(package)_binaries.$version2")
for folder in ("share", "modules", "lib", "bin")
cp(folder, "$(package)_binaries.$version2/$folder")
end

cd("$(package)_binaries.$version2")
if ext == "dll"
run(`zip -r --symlinks ../../../$(package)_binaries.$version2.$platform.zip share modules lib bin`)
else
run(`tar -czf ../../../$(package)_binaries.$version2.$platform.tar.gz share modules lib bin`)
end
cd("../../..")

# Remove the folder used to unzip the tarball generated by BinaryBuilder.jl
rm("products/$platform", recursive=true)
else
@warn("The tarball deps.tar.gz is missing in $(tarball_name)!")
end
else
@warn("The tarball for the platform $platform was not generated!")
end
end
93 changes: 93 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Release
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v2023.11.15
jobs:
build:
name: Uno -- Release ${{ github.ref_name }}
runs-on: ubuntu-latest
steps:
- name: Checkout Uno
uses: actions/checkout@v4
- name: Install Julia
uses: julia-actions/setup-julia@v2
with:
version: "1.7"
arch: x64
- name: Set the environment variables BINARYBUILDER_AUTOMATIC_APPLE, UNO_RELEASE, UNO_COMMIT
shell: bash
run: |
echo "BINARYBUILDER_AUTOMATIC_APPLE=true" >> $GITHUB_ENV
echo "UNO_RELEASE=${{ github.ref_name }}" >> $GITHUB_ENV
echo "UNO_COMMIT=${{ github.sha }}" >> $GITHUB_ENV
- name: Cross-compilation of Uno -- x86_64-linux-gnu-libgfortran5
run: |
julia --color=yes -e 'using Pkg; Pkg.add("BinaryBuilder")'
julia --color=yes .github/julia/build_tarballs.jl x86_64-linux-gnu-libgfortran5 --verbose
rm -r ~/.julia
- name: Cross-compilation of Uno -- x86_64-w64-mingw32-libgfortran5
run: |
julia --color=yes -e 'using Pkg; Pkg.add("BinaryBuilder")'
julia --color=yes .github/julia/build_tarballs.jl x86_64-w64-mingw32-libgfortran5 --verbose
rm -r ~/.julia
- name: Cross-compilation of Uno -- x86_64-apple-darwin-libgfortran5
run: |
julia --color=yes -e 'using Pkg; Pkg.add("BinaryBuilder")'
julia --color=yes .github/julia/build_tarballs.jl x86_64-apple-darwin-libgfortran5 --verbose
rm -r ~/.julia
- name: Cross-compilation of Uno -- aarch64-apple-darwin-libgfortran5
run: |
julia --color=yes -e 'using Pkg; Pkg.add("BinaryBuilder")'
julia --color=yes .github/julia/build_tarballs.jl aarch64-apple-darwin-libgfortran5 --verbose
rm -r ~/.julia
- name: Generate the binaries
run: julia --color=yes .github/julia/generate_binaries.jl
- name: Create a new release
uses: actions/create-release@v1
id: create_release
with:
draft: false
prerelease: false
release_name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
body:
env:
GITHUB_TOKEN: ${{ github.token }}
- name: upload Linux artifact
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Uno_binaries.${{ github.ref_name }}.x86_64-linux-gnu-libgfortran5.tar.gz
asset_name: Uno.${{ github.ref_name }}.linux.tar.gz
asset_content_type: application/gzip
- name: upload Mac (Intel) artifact
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Uno_binaries.${{ github.ref_name }}.x86_64-apple-darwin-libgfortran5.tar.gz
asset_name: Uno.${{ github.ref_name }}.mac-intel.tar.gz
asset_content_type: application/gzip
- name: upload Mac (ARM) artifact
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Uno_binaries.${{ github.ref_name }}.aarch64-apple-darwin-libgfortran5.tar.gz
asset_name: Uno.${{ github.ref_name }}.mac-arm.tar.gz
asset_content_type: application/gzip
- name: upload Windows artifact
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./Uno_binaries.${{ github.ref_name }}.x86_64-w64-mingw32-libgfortran5.zip
asset_name: Uno.${{ github.ref_name }}.windows.zip
asset_content_type: application/zip

0 comments on commit 04fe6ee

Please sign in to comment.