Add NuGet package tools

This commit is contained in:
Davipb authored and Lukas Dürrenberger committed 2019-01-23 22:59:18 +01:00
1 parent 61f17e3c1d
commit d8e19e74ed
14 files changed
+680

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
*.sh eol=lf -text
*.ps1 eol=crlf -text
+9
View File
@@ -0,0 +1,9 @@
# Ignore .NET build artifacts
/*/bin/
/*/obj/
# Ignore compiled CSFML assemblies generated by the scripts
/*/runtimes/
# Ignore the intermediate folder used by scripts to compile CSFML
/Build/
+39
View File
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!-- Workaround to remove the NETStandard.Library NuGet reference without breaking everything -->
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<Version>2.5.0</Version>
<Authors>Laurent Gomila</Authors>
<PackageTags>sfml csfml</PackageTags>
<Copyright>Copyright © Laurent Gomila</Copyright>
<PackageLicenseExpression>Zlib</PackageLicenseExpression>
<PackageProjectUrl>https://www.sfml-dev.org/</PackageProjectUrl>
<PackageIconUrl>https://www.sfml-dev.org/images/sfml-icon.png</PackageIconUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="all" />
<!-- Workaround to remove the NETStandard.Library NuGet reference without breaking everything -->
<PackageReference Include="NETStandard.Library" Version="[1.6.0,)" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<Description>This package contains the native libraries for the C port of SFML, used as a dependency for SFML.Net</Description>
<Title>CSFML</Title>
</PropertyGroup>
<ItemGroup>
<None Pack="True" Include="runtimes/**" PackagePath="runtimes" />
</ItemGroup>
</Project>
+31
View File
@@ -0,0 +1,31 @@
# CSFML NuGet Packages
This directory contains all the files needed to build and package the native CSFML libraries for [SFML.Net](github.com/SFML/SFML.Net).
**All scripts must be run from the directory they are located in**.
That means that your current working directory (`$PWD`) must be the same where the script is.
All build scripts follow the same routine:
1. Clone the SFML repository at `Build/SFML`, if it isn't already there
1. Configure & compile SFML with cmake inside of `Build/(RID)/SFML`, where `(RID)` is the [Runtime Identifier](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog) for the target of the libraries being built
1. Configure & compile CSFML with cmake inside of `Build/(RID)/CSFML`
1. Copy the resulting libraries to `CSFML/runtimes/(RID)/native/`
* `build.win.ps1`
* A [PowerShell](https://github.com/PowerShell/PowerShell) script to build Windows native libraries. By default, both `win-x86` and `win-x64` are built. To build only one specific Runtime Identifier, pass it to the script as a parameter (`./build.win.ps1 win-x64`)
You must have Visual Studio 2017, cmake, and the Windows SDK 8.1 installed to run this script.
* `build.linux.sh`
* A [Bash](https://www.gnu.org/software/bash/) script to build libraries for a generic Linux distribution. The [Runtime Identifier](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog) of the linux distribution must be specified as a parameter to the script.
This generic script doesn't install any of its dependencies. As such, you must have cmake and make installed, as well as all [SFML Dependencies](https://www.sfml-dev.org/tutorials/2.5/compile-with-cmake.php#installing-dependencies) available to cmake.
* `build.docker.sh`, `build.docker.ps1`
* A script to build the native libraries for a Linux distribution in a Docker container. If no RID is specified as a parameter, all supported RIDs will be built. Currently, the supported RIDs are:
* `alpine-x64`
* `debian-x64` (compatible with derivatives such as Ubuntu and Linux Mint)
* `fedora-x64`
* `pushnuget.ps1`, `pushnuget.sh`
* A script to automatically build and push the NuGet package to nuget.org. Make sure that all the native libraries are in `CSFML/runtimes/` before running this.
* Other scripts
* Any script not mentioned here is intended for internal use by other scripts only and shouldn't be called directly.
+43
View File
@@ -0,0 +1,43 @@
Param(
[Parameter(Position = 0)]
[string] $RID
)
$ErrorActionPreference = "Stop"
if (-not $RID ) {
Write-Output "No RID specified, building all known RIDs"
./build.docker.ps1 "alpine-x64"
./build.docker.ps1 "debian-x64"
./build.docker.ps1 "fedora-x64"
exit
}
$Image = $null
$Shell = $null
switch ($RID) {
'alpine-x64' {
$Image = 'alpine'
$Shell = '/bin/sh'
}
'debian-x64' {
$Image = 'debian'
$Shell = '/bin/bash'
}
'fedora-x64' {
$Image = 'fedora'
$Shell = '/bin/bash'
}
Default {
Write-Error "Unknown Runtime Identifier $RID"
exit
}
}
Write-Host "Building $RID with image $Image using $Shell"
$RepoRoot = (Get-Item (git rev-parse --show-toplevel)).FullName
docker run --rm --mount "type=bind,source=$RepoRoot,destination=/csfml/" $Image $Shell -c "cd /csfml/tools/nuget/; ./docker.$RID.sh"
exit $LastExitCode
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
# Automatically exit on error
set -e
if [[ -z "$1" ]]; then
echo 'No Runtime Identifier specified, running all known RIDs'
./build.docker.sh "alpine-x64"
./build.docker.sh "debian-x64"
./build.docker.sh "fedora-x64"
exit 0
fi
RID="$1"
case "$RID" in
'alpine-x64')
Image='alpine'
Shell='/bin/sh'
;;
'debian-x64')
Image='debian'
Shell='/bin/bash'
;;
'fedora-x64')
Image='fedora'
Shell='/bin/bash'
;;
*)
echo "Unknown Runtime Identifier $RID"
exit 1
;;
esac
echo "Building $RID using image $Image with $Shell"
RepoRoot="$(realpath "$(git rev-parse --show-toplevel)")"
docker run --rm --mount "type=bind,source=$RepoRoot,destination=/csfml/" "$Image" "$Shell" -c "cd /csfml/tools/nuget/; ./docker.$RID.sh"
+155
View File
@@ -0,0 +1,155 @@
#!/bin/bash
# Automatically exit on error
set -e
# ========================= #
# PRELUDE: A note on rpaths #
# ========================= #
# Unlike Windows, Linux doesn't search the current directory by default when searching for shared libraries (.so)
# It only searches the system default directories (usually /lib and /usr/lib) and the paths in LD_LIBRARY_PATH
# The .NET Runtime will find the CSFML library in its NuGet packages just fine, but that library will then request
# the OS for libsfml-(module).so, and the .NET Runtime will have no say in how that SFML library is found.
# Without SFML installed globally on the system, this will fail, causing the loading of CSFML to fail, causing the
# .NET Runtime to think the CSFML library doesn't exist or is invalid.
# And so, we need to set the rpath of the CSFML library.
# The rpath is a special value embedded straight into a library that specifies to the OS a list of folders where
# other libraries that it references may be found.
# $ORIGIN, a kind-of environment variable, can be used in rpath to point to the folder where the library currently is.
# To let the OS know that we intend to use $ORIGIN, we need to add the ORIGIN flag to our ELF with the -z origin
# gcc linker option
# Since CSFML and SFML will always be deployed on the same folder by NuGet, we just need to add an rpath to CSFML
# that points to $ORIGIN, causing the OS to search the current folder for SFML, without interference from .NET
# We also add the same rpath to SFML itself for future-proofing, in case we ever decide to ship some Linux SFML
# dependencies on the Native package.
# =================================================== #
# STEP 1: Setup all variables needed during the build #
# =================================================== #
if [[ -z "$1" ]]; then
echo "Please specify the platform Runtime Identifier as an argument to this script"
exit 1
fi
echo "Please note that all SFML dependencies must be installed and available to cmake. SFML does not ship with its linux dependencies."
RID="$1"
SFMLBranch="2.5.x" # The branch or tag of the SFML repository to be cloned
CSFMLDir="$(realpath "$(git rev-parse --show-toplevel)")" # The directory of the source code of CSFML
OutDir="./CSFML/runtimes/$RID/native" # The base directory of all CSFML modules, used to copy the final libraries
mkdir -p "$OutDir"
OutDir="$(realpath "$OutDir")"
echo "Building $RID"
mkdir -p "Build"
pushd "Build"
# ================== #
# STEP 2: Clone SFML #
# ================== #
if [[ ! -d "SFML/.git" ]]; then
echo "Cloning SFML"
rm -rf "SFML"
git clone --branch "$SFMLBranch" --depth 1 "git://github.com/SFML/SFML.git" "SFML"
fi
SFMLDir="$(realpath SFML)"
# ================== #
# STEP 3: Build SFML #
# ================== #
rm -rf "$RID"
mkdir -p "$RID"
pushd "$RID"
echo "Building SFML"
mkdir -p SFML
pushd SFML
SFMLBuiltDir="$(realpath .)" # The directory where SFML was built to. Used later to direct cmake when building CSFML
mkdir -p lib
# The directory that contains the final SFML libraries
# Since linux libraries don't support static linking from a shared library, this is used to copy the
# SFML shared libraries together with the CSFML shared libraries into SFML.Net
SFMLLibDir="$(realpath lib)"
cmake -E env LDFLAGS="-z origin" \
cmake \
'-DBUILD_SHARED_LIBS=1' \
'-DCMAKE_BUILD_TYPE=Release' \
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$SFMLLibDir" \
'-DCMAKE_BUILD_WITH_INSTALL_RPATH=1' \
'-DCMAKE_INSTALL_RPATH=$ORIGIN' \
"$SFMLDir"
cmake --build . --config Release
popd # Pop SFML
# =================== #
# STEP 4: Build CSFML #
# =================== #
echo "Building CSFML using SFML at $SFMLBuiltDir"
mkdir -p CSFML
pushd CSFML
mkdir -p lib
CSFMLLibDir="$(realpath lib)" # The directory that contains the final CSFML libraries. Used to copy the result into SFML.Net
cmake -E env LDFLAGS="-z origin" \
cmake \
"-DSFML_DIR=$SFMLBuiltDir" \
'-DBUILD_SHARED_LIBS=1' \
'-DCMAKE_BUILD_TYPE=Release' \
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$CSFMLLibDir" \
'-DCMAKE_BUILD_WITH_INSTALL_RPATH=1' \
'-DCMAKE_INSTALL_RPATH=$ORIGIN' \
"$CSFMLDir"
cmake --build . --config Release
# ======================================== #
# STEP 5: Copy result to the NuGet folders #
# ======================================== #
# Copies one SFML and CSFML module into the NuGet package
# The module name must be passed to this function as an argument, in lowercase
# This function then copies $SFMLLibDir/libsfml-(module).so and
# $CSFMLLibDir/libcsfml-(module).so into $OutDir
copymodule()
{
MODULE="$1"
mkdir -p "$OutDir"
# Note the wildcard at the end of the first argument
# We are copying every versioned file here, not just the .so
# (libsfml-audio.so, libsfml-audio.so.2, libsfml-audio.so.2.5, etc)
# This is needed because of the way linux searches for libraries based
# one their SONAME
cp "$SFMLLibDir/libsfml-$MODULE.so"* "$OutDir"
cp "$CSFMLLibDir/libcsfml-$MODULE.so" "$OutDir"
}
copymodule audio
copymodule graphics
copymodule system
copymodule window
popd # Pop CSFML
popd # Pop $RID
popd # Pop Build
+204
View File
@@ -0,0 +1,204 @@
Param(
[Parameter(Position = 0)]
[string] $RID
)
$ErrorActionPreference = "Stop"
# =================================================== #
# STEP 1: Setup all variables needed during the build #
# =================================================== #
if (-not $RID) {
Write-Output "No RID specified, building all known RIDs"
./build.win.ps1 "win-x86"
./build.win.ps1 "win-x64"
exit
}
$Generator = 'Visual Studio 15 2017'
switch ($RID) {
'win-x86' {
$Architecture = 'Win32'
}
'win-x64' {
$Architecture = 'x64'
}
Default {
Write-Error "Unknown RID '$RID'"
exit
}
}
Write-Output "Building $RID"
Write-Output "Using $Generator as the cmake generator"
Write-Output "Using architecture $Architecture"
$SFMLBranch = "2.5.x" # The branch or tag of the SFML repository to be cloned
$CSFMLDir = (Get-Item (git rev-parse --show-toplevel)).FullName # The directory of the source code of CSFML
$OutDir = (Get-Item ./CSFML/runtimes/$RID/native).FullName # The directory of all CSFML modules, used to copy the final dlls
<#
.SYNOPSIS
Ensures that the last command run was a success, checking its exit code.
#>
function Ensure-Success() {
if ($LastExitCode -ne 0) {
exit
}
}
<#
.SYNOPSIS
Creates a new subdirectory of the current working directory and pushes it into the directory
stack with Push-Location, so that it can be reverted with Pop-Location.
.PARAMETER path
The path to create and push.
#>
function New-Push($path) {
New-Item -ItemType Directory -ErrorAction Ignore $path > $null
Push-Location $path > $null
}
New-Push "Build"
# ================== #
# STEP 2: Clone SFML #
# ================== #
If (-not (Test-Path "SFML/.git")) {
Write-Output "Cloning SFML"
Remove-Item -Recurse -Force -ErrorAction Ignore "SFML" > $null
git clone --branch "$SFMLBranch" --depth 1 "git://github.com/SFML/SFML.git" "SFML"
Ensure-Success
}
Push-Location "SFML"
$SFMLDir = (Get-Item .).FullName
switch ($RID) {
'win-x86' {
$SFMLExtLibs = (Get-Item ./extlibs/libs-msvc-universal/x86).FullName
$SFMLAudioExtras = (Get-Item ./extlibs/bin/x86).FullName
}
'win-x64' {
$SFMLExtLibs = (Get-Item ./extlibs/libs-msvc-universal/x64).FullName
$SFMLAudioExtras = (Get-Item ./extlibs/bin/x64).FullName
}
Default {
Write-Error "Unknown RID '$RID'"
exit
}
}
Pop-Location # Pop SFML
# ================== #
# STEP 3: Build SFML #
# ================== #
Remove-Item -Recurse -Force -ErrorAction Ignore "$RID"
New-Push "$RID"
Write-Output "Building SFML"
New-Push SFML
$SFMLBuiltDir = Get-Location # The directory where SFML was built to. Used later to direct cmake when building CSFML
cmake `
'-DBUILD_SHARED_LIBS=0' `
'-DCMAKE_BUILD_TYPE=Release' `
'-DCMAKE_SYSTEM_VERSION=8.1' `
'-DSFML_USE_STATIC_STD_LIBS=1' `
"-G$Generator" `
"-A$Architecture" `
$SFMLDir
Ensure-Success
cmake --build . --config Release -- '-verbosity:minimal'
Ensure-Success
Pop-Location # Pop SFML
# =================== #
# STEP 4: Build CSFML #
# =================== #
Write-Output "Building CSFML using SFML at $SFMLBuiltDir"
New-Push CSFML
New-Item -ItemType Directory lib > $null
$CSFMLLibDir = (Get-Item lib).FullName; # The directory where the final CSFML dlls are located
cmake `
"-DSFML_DIR=$SFMLBuiltDir" `
'-DCSFML_LINK_SFML_STATICALLY=1' `
"-DCMAKE_LIBRARY_PATH=$SFMLExtLibs" `
`
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$CSFMLLibDir" `
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=$CSFMLLibDir" `
`
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=$CSFMLLibDir" `
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE=$CSFMLLibDir" `
`
"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=$CSFMLLibDir" `
"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=$CSFMLLibDir" `
`
'-DCMAKE_SYSTEM_VERSION=8.1' `
'-DSTATIC_STD_LIBS=1' `
`
"-DBUILD_SHARED_LIBS=1" `
'-DCMAKE_BUILD_TYPE=Release' `
`
"-G$generator" `
"-A$Architecture" `
`
$CSFMLDir
Ensure-Success
cmake --build . --config Release -- '-verbosity:minimal'
Ensure-Success
# ======================================== #
# STEP 5: Copy result to the NuGet folders #
# ======================================== #
Write-Output "Copying CSFML modules"
<#
.SYNOPSIS
Copies a specific CSFML module into its proper NuGet project
.DESCRIPTION
This function locates a file named csfml-(module)-2.dll inside of the
folder specified by $CSFMLLibDir and copies it to $OutDir/CSFML/runtimes/(RID)/native/csfml-(module).dll.
Notice how it removes the "-2" at the end, to make the name compatible with other platforms.
.PARAMETER module
The case-insensitive name of the module to copy.
#>
function Copy-Module($module) {
Write-Output "Copying CSFML $module"
New-Item -ItemType Directory $OutDir -ErrorAction Ignore > $null
Copy-Item "$CSFMLLibDir/csfml-$module-2.dll" "$OutDir/csfml-$module.dll" -Force > $null
}
Copy-Module 'Audio'
Copy-Module 'Graphics'
Copy-Module 'System'
Copy-Module 'Window'
Write-Output "Copying Audio module extra files"
Copy-Item "$SFMLAudioExtras/*" "$OutDir/CSFML/runtimes/$RID/native"
Pop-Location # Pop CSFML
Pop-Location # Pop $RID
Pop-Location # Pop Build
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
# Alpine Linux doesn't come with bash by default, so we need to bootstrap everything with sh
# Automatically exit on error
set -e
apk add \
bash \
git \
freetype-dev \
libx11-dev \
libxrandr-dev \
eudev-dev \
mesa-dev \
flac-dev \
libogg-dev \
libvorbis-dev \
openal-soft-dev \
libpthread-stubs \
cmake \
make \
g++
./build.linux.sh alpine-x64
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# Automatically exit on error
set -e
apt-get update
apt-get install -y \
git \
libfreetype6-dev \
xorg-dev \
libxrandr-dev \
libudev-dev \
libgl1-mesa-dev \
libflac-dev \
libogg-dev \
libvorbis-dev \
libvorbisenc2 \
libvorbisfile3 \
libopenal-dev \
libpthread-stubs0-dev \
cmake \
g++
./build.linux.sh debian-x64
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# Automatically exit on error
set -e
dnf install -y \
git \
freetype-devel \
xorg-x11-server-devel \
libXrandr-devel \
systemd-devel \
mesa-libEGL-devel \
flac-devel \
libogg-devel \
libvorbis-devel \
openal-soft-devel \
gcc-c++ \
cmake \
make
./build.linux.sh fedora-x64
+34
View File
@@ -0,0 +1,34 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSFML", "CSFML\CSFML.csproj", "{A0261C3A-E44E-40E3-8030-C14E3272B720}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|x64.ActiveCfg = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|x64.Build.0 = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|x86.ActiveCfg = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Debug|x86.Build.0 = Debug|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|Any CPU.Build.0 = Release|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|x64.ActiveCfg = Release|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|x64.Build.0 = Release|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|x86.ActiveCfg = Release|Any CPU
{A0261C3A-E44E-40E3-8030-C14E3272B720}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
+28
View File
@@ -0,0 +1,28 @@
Param(
[Parameter(Mandatory, Position = 0)]
[string]$APIKey
)
dotnet build -c Release
if ($LASTEXITCODE -ne 0) {
Write-Error "Build failed"
exit 1
}
$count = 0
$packages = (Get-ChildItem */bin/Release/*.nupkg)
foreach ($package in $packages) {
Write-Progress "Pushing packages" -CurrentOperation "Pushing $($package.Name)" -PercentComplete (($count * 100.0) / $packages.Length)
dotnet nuget push -k $APIKey -s https://api.nuget.org/v3/index.json $package.FullName
if ($LASTEXITCODE -ne 0) {
Write-Error "Unable to push $($package.Name)"
exit 1
}
$count++
}
Write-Progress "Done" -Completed
Write-Output "Successfully pushed $count packages"
+21
View File
@@ -0,0 +1,21 @@
#!/bin/sh
# Automatically exit on error
set -e
if [ -z "$1" ]; then
echo "Specify the NuGet API Key as a parameter to this script"
exit 1
fi
dotnet build -c Release
# Find every file that matches the glob ./*/bin/Release/*.nupkg
# and push it to nuget.org using the key specified as a parameter
# to this script
find \
-type f \
-regex "\./\w+/bin/Release/[^/]+\.nupkg" \
-exec dotnet nuget push -k "$1" -s "https://api.nuget.org/v3/index.json" "{}" ";"