mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-07-11 01:24:01 +02:00
3rdParty: update SDL_net
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@ jobs:
|
||||
${{ matrix.platform.msys-env }}-ninja
|
||||
${{ matrix.platform.msys-env }}-perl
|
||||
- name: Get SDL3_net sources
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Install Ninja
|
||||
if: ${{ !contains(matrix.platform.shell, 'msys2') }}
|
||||
uses: aseprite/get-ninja@main
|
||||
|
||||
+242
-241
@@ -24,12 +24,12 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Set up SDL sources'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
path: 'SDL'
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
--github \
|
||||
--debug
|
||||
- name: 'Store source archives'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace}}/dist'
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '/tmp'
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
run: |
|
||||
${{ steps.tar.outputs.path }}/build-scripts/test-versioning.sh
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
@@ -139,224 +139,225 @@ jobs:
|
||||
cmake --build /tmp/build --verbose
|
||||
# ctest --test-dir /tmp/build --no-tests=error --output-on-failure
|
||||
|
||||
# dmg:
|
||||
# needs: [src]
|
||||
# runs-on: macos-latest
|
||||
# outputs:
|
||||
# dmg: ${{ steps.releaser.outputs.dmg }}
|
||||
# steps:
|
||||
# - name: 'Set up Python'
|
||||
# uses: actions/setup-python@v5
|
||||
# with:
|
||||
# python-version: '3.11'
|
||||
# - name: 'Fetch build-release.py'
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# ref: ${{ inputs.commit }}
|
||||
# sparse-checkout: 'build-scripts/build-release.py'
|
||||
# - name: 'Download source archives'
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# name: sources
|
||||
# path: '${{ github.workspace }}'
|
||||
# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
|
||||
# id: tar
|
||||
dmg:
|
||||
needs: [src]
|
||||
runs-on: macos-latest
|
||||
outputs:
|
||||
dmg: ${{ steps.releaser.outputs.dmg }}
|
||||
steps:
|
||||
- name: 'Set up Python'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
- name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
|
||||
id: tar
|
||||
run: |
|
||||
mkdir -p "${{ github.workspace }}/tardir"
|
||||
tar -C "${{ github.workspace }}/tardir" -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
|
||||
echo "path=${{ github.workspace }}/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
|
||||
# - name: 'Download external dependencies'
|
||||
# run: |
|
||||
# mkdir -p "${{ github.workspace }}/tardir"
|
||||
# tar -C "${{ github.workspace }}/tardir" -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
|
||||
# echo "path=${{ github.workspace }}/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
|
||||
## - name: 'Download external dependencies'
|
||||
## run: |
|
||||
## sh "${{ steps.tar.outputs.path }}/external/download.sh" --depth 1
|
||||
# - name: 'Build SDL3_net.dmg'
|
||||
# id: releaser
|
||||
# shell: bash
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# run: |
|
||||
# python build-scripts/build-release.py \
|
||||
# --actions dmg \
|
||||
# --commit ${{ inputs.commit }} \
|
||||
# --root "${{ steps.tar.outputs.path }}" \
|
||||
# --github \
|
||||
# --debug
|
||||
# - name: 'Store DMG image file'
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: dmg
|
||||
# path: '${{ github.workspace }}/dist'
|
||||
#
|
||||
# dmg-verify:
|
||||
# needs: [dmg, src]
|
||||
# runs-on: macos-latest
|
||||
# steps:
|
||||
# - name: 'Set up Python'
|
||||
# uses: actions/setup-python@v5
|
||||
# with:
|
||||
# python-version: '3.11'
|
||||
# - name: 'Fetch build-release.py'
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# ref: ${{ inputs.commit }}
|
||||
# sparse-checkout: 'build-scripts/build-release.py'
|
||||
# - name: 'Download source archives'
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# name: sources
|
||||
# path: '${{ github.workspace }}'
|
||||
# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
|
||||
# id: src
|
||||
# run: |
|
||||
# mkdir -p /tmp/tardir
|
||||
# tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
|
||||
# echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
|
||||
# - name: 'Download dependencies'
|
||||
# id: deps
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# run: |
|
||||
# python build-scripts/build-release.py \
|
||||
# --actions download \
|
||||
# --commit ${{ inputs.commit }} \
|
||||
# --root "${{ steps.src.outputs.path }}" \
|
||||
# --github \
|
||||
# --debug
|
||||
# - name: 'Mount dependencies'
|
||||
# id: deps-mount
|
||||
# run: |
|
||||
# hdiutil attach "${{ steps.deps.outputs.dep-path }}/SDL3-${{ steps.deps.outputs.dep-sdl-version }}.dmg"
|
||||
# sdl_mount_pount="/Volumes/SDL3"
|
||||
# if [ ! -d "$sdl_mount_pount/SDL3.xcframework" ]; then
|
||||
# echo "Cannot find SDL3.xcframework!"
|
||||
# exit 1
|
||||
# fi
|
||||
# echo "path=${sdl_mount_pount}" >>$GITHUB_OUTPUT
|
||||
# - name: 'Download ${{ needs.dmg.outputs.dmg }}'
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# name: dmg
|
||||
# path: '${{ github.workspace }}'
|
||||
# - name: 'Mount ${{ needs.dmg.outputs.dmg }}'
|
||||
# id: mount
|
||||
# run: |
|
||||
# hdiutil attach '${{ github.workspace }}/${{ needs.dmg.outputs.dmg }}'
|
||||
# mount_point="/Volumes/${{ needs.src.outputs.project }}"
|
||||
# if [ ! -d "$mount_point/${{ needs.src.outputs.project }}.xcframework" ]; then
|
||||
# echo "Cannot find ${{ needs.src.outputs.project }}.xcframework!"
|
||||
# exit 1
|
||||
# fi
|
||||
# echo "mount-point=${mount_point}">>$GITHUB_OUTPUT
|
||||
# - name: 'CMake (configure + build) Darwin'
|
||||
# run: |
|
||||
# set -e
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
# -DCMAKE_SYSTEM_NAME=Darwin \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -Werror=dev \
|
||||
# -B build_darwin
|
||||
# cmake --build build_darwin --config Release --verbose
|
||||
#
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/macos-arm64_x86_64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/macos-arm64_x86_64" \
|
||||
# -DCMAKE_SYSTEM_NAME=Darwin \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -B build_darwin2
|
||||
# cmake --build build_darwin2 --config Release --verbose
|
||||
#
|
||||
# - name: 'CMake (configure + build) iOS'
|
||||
# run: |
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
# -DCMAKE_SYSTEM_NAME=iOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
# -Werror=dev \
|
||||
# -B build_ios
|
||||
# cmake --build build_ios --config Release --verbose
|
||||
#
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/ios-arm64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/ios-arm64" \
|
||||
# -DCMAKE_SYSTEM_NAME=iOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
# -B build_ios2
|
||||
# cmake --build build_ios2 --config Release --verbose
|
||||
# - name: 'CMake (configure + build) tvOS'
|
||||
# run: |
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
# -DCMAKE_SYSTEM_NAME=tvOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
# -Werror=dev \
|
||||
# -B build_tvos
|
||||
# cmake --build build_tvos --config Release --verbose
|
||||
#
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/tvos-arm64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/tvos-arm64" \
|
||||
# -DCMAKE_SYSTEM_NAME=tvOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
# -B build_tvos2
|
||||
# cmake --build build_tvos2 --config Release --verbose
|
||||
# - name: 'CMake (configure + build) iOS simulator'
|
||||
# run: |
|
||||
# sysroot=$(xcodebuild -version -sdk iphonesimulator Path)
|
||||
# echo "sysroot=$sysroot"
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
# -DCMAKE_SYSTEM_NAME=iOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
# -Werror=dev \
|
||||
# -B build_ios_simulator
|
||||
# cmake --build build_ios_simulator --config Release --verbose
|
||||
#
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/ios-arm64_x86_64-simulator;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/ios-arm64_x86_64-simulator" \
|
||||
# -DCMAKE_SYSTEM_NAME=iOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
# -B build_ios_simulator2
|
||||
# cmake --build build_ios_simulator2 --config Release --verbose
|
||||
# - name: 'CMake (configure + build) tvOS simulator'
|
||||
# run: |
|
||||
# sysroot=$(xcodebuild -version -sdk appletvsimulator Path)
|
||||
# echo "sysroot=$sysroot"
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
# -DCMAKE_SYSTEM_NAME=tvOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
# -Werror=dev \
|
||||
# -B build_tvos_simulator
|
||||
# cmake --build build_tvos_simulator --config Release --verbose
|
||||
#
|
||||
# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
# -DTEST_SHARED=TRUE \
|
||||
# -DTEST_STATIC=FALSE \
|
||||
# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/tvos-arm64_x86_64-simulator;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/tvos-arm64_x86_64-simulator" \
|
||||
# -DCMAKE_SYSTEM_NAME=tvOS \
|
||||
# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
# -DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
# -B build_tvos_simulator2
|
||||
# cmake --build build_tvos_simulator2 --config Release --verbose
|
||||
# sh "${{ steps.tar.outputs.path }}/external/download.sh" --depth 1
|
||||
- name: 'Build SDL3_net.dmg'
|
||||
id: releaser
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
python build-scripts/build-release.py \
|
||||
--actions dmg \
|
||||
--commit ${{ inputs.commit }} \
|
||||
--root "${{ steps.tar.outputs.path }}" \
|
||||
--github \
|
||||
--debug
|
||||
- name: 'Store DMG image file'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: dmg
|
||||
path: '${{ github.workspace }}/dist'
|
||||
|
||||
dmg-verify:
|
||||
needs: [dmg, src]
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: 'Set up Python'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
- name: 'Untar ${{ needs.src.outputs.src-tar-gz }}'
|
||||
id: src
|
||||
run: |
|
||||
mkdir -p /tmp/tardir
|
||||
tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}"
|
||||
echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT
|
||||
- name: 'Download dependencies'
|
||||
id: deps
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
python build-scripts/build-release.py \
|
||||
--actions download \
|
||||
--commit ${{ inputs.commit }} \
|
||||
--root "${{ steps.src.outputs.path }}" \
|
||||
--github \
|
||||
--debug
|
||||
- name: 'Mount dependencies'
|
||||
id: deps-mount
|
||||
run: |
|
||||
hdiutil attach "${{ steps.deps.outputs.dep-path }}/SDL3-${{ steps.deps.outputs.dep-sdl-version }}.dmg"
|
||||
sdl_mount_pount="/Volumes/SDL3"
|
||||
if [ ! -d "$sdl_mount_pount/SDL3.xcframework" ]; then
|
||||
echo "Cannot find SDL3.xcframework!"
|
||||
exit 1
|
||||
fi
|
||||
echo "path=${sdl_mount_pount}" >>$GITHUB_OUTPUT
|
||||
- name: 'Download ${{ needs.dmg.outputs.dmg }}'
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: dmg
|
||||
path: '${{ github.workspace }}'
|
||||
- name: 'Mount ${{ needs.dmg.outputs.dmg }}'
|
||||
id: mount
|
||||
run: |
|
||||
hdiutil attach '${{ github.workspace }}/${{ needs.dmg.outputs.dmg }}'
|
||||
mount_point="/Volumes/${{ needs.src.outputs.project }}"
|
||||
if [ ! -d "$mount_point/${{ needs.src.outputs.project }}.xcframework" ]; then
|
||||
echo "Cannot find ${{ needs.src.outputs.project }}.xcframework!"
|
||||
exit 1
|
||||
fi
|
||||
echo "mount-point=${mount_point}">>$GITHUB_OUTPUT
|
||||
- name: 'CMake (configure + build) Darwin'
|
||||
run: |
|
||||
set -e
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
-DCMAKE_SYSTEM_NAME=Darwin \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-Werror=dev \
|
||||
-B build_darwin
|
||||
cmake --build build_darwin --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/macos-arm64_x86_64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/macos-arm64_x86_64" \
|
||||
-DCMAKE_SYSTEM_NAME=Darwin \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-B build_darwin2
|
||||
cmake --build build_darwin2 --config Release --verbose
|
||||
|
||||
- name: 'CMake (configure + build) iOS'
|
||||
run: |
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-Werror=dev \
|
||||
-B build_ios
|
||||
cmake --build build_ios --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/ios-arm64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/ios-arm64" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-B build_ios2
|
||||
cmake --build build_ios2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) tvOS'
|
||||
run: |
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-Werror=dev \
|
||||
-B build_tvos
|
||||
cmake --build build_tvos --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/tvos-arm64;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/tvos-arm64" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-B build_tvos2
|
||||
cmake --build build_tvos2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) iOS simulator'
|
||||
run: |
|
||||
sysroot=$(xcodebuild -version -sdk iphonesimulator Path)
|
||||
echo "sysroot=$sysroot"
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-Werror=dev \
|
||||
-B build_ios_simulator
|
||||
cmake --build build_ios_simulator --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/ios-arm64_x86_64-simulator;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/ios-arm64_x86_64-simulator" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-B build_ios_simulator2
|
||||
cmake --build build_ios_simulator2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) tvOS simulator'
|
||||
run: |
|
||||
sysroot=$(xcodebuild -version -sdk appletvsimulator Path)
|
||||
echo "sysroot=$sysroot"
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-Werror=dev \
|
||||
-B build_tvos_simulator
|
||||
cmake --build build_tvos_simulator --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_SHARED=TRUE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }}/SDL3_net.xcframework/tvos-arm64_x86_64-simulator;${{ steps.deps-mount.outputs.path }}/SDL3.xcframework/tvos-arm64_x86_64-simulator" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-B build_tvos_simulator2
|
||||
cmake --build build_tvos_simulator2 --config Release --verbose
|
||||
|
||||
msvc:
|
||||
needs: [src]
|
||||
runs-on: windows-2025
|
||||
@@ -370,12 +371,12 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -401,7 +402,7 @@ jobs:
|
||||
--github `
|
||||
--debug
|
||||
- name: 'Store MSVC archives'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: msvc
|
||||
path: '${{ github.workspace }}/dist'
|
||||
@@ -411,7 +412,7 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: 'Fetch .github/actions/setup-ninja/action.yml'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: |
|
||||
@@ -424,7 +425,7 @@ jobs:
|
||||
- name: Set up ninja
|
||||
uses: ./.github/actions/setup-ninja
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -454,7 +455,7 @@ jobs:
|
||||
unzip "${{ steps.deps.outputs.dep-path }}/SDL3-devel-${{ steps.deps.outputs.dep-sdl-version }}-VC.zip"
|
||||
echo "path=${{ github.workspace }}/deps-vc" >>$env:GITHUB_OUTPUT
|
||||
- name: 'Download MSVC binaries'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: msvc
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -529,7 +530,7 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
@@ -538,7 +539,7 @@ jobs:
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -560,7 +561,7 @@ jobs:
|
||||
--github \
|
||||
--debug
|
||||
- name: 'Store MinGW archives'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: mingw
|
||||
path: '${{ github.workspace }}/dist'
|
||||
@@ -574,7 +575,7 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.commit }}
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
@@ -583,7 +584,7 @@ jobs:
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -619,7 +620,7 @@ jobs:
|
||||
mkdir -p /tmp/deps-mingw/cmake
|
||||
cp -rv /tmp/deps-mingw-extract/sdl3/SDL3-${{ steps.deps.outputs.dep-sdl-version }}/cmake/* /tmp/deps-mingw/cmake
|
||||
- name: 'Download MinGW binaries'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: mingw
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -665,7 +666,7 @@ jobs:
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: 'Fetch build-release.py'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Setup Android NDK'
|
||||
@@ -675,7 +676,7 @@ jobs:
|
||||
local-cache: false
|
||||
ndk-version: r28c
|
||||
- name: 'Setup Java JDK'
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
@@ -684,7 +685,7 @@ jobs:
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y ninja-build
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
@@ -708,7 +709,7 @@ jobs:
|
||||
--github \
|
||||
--debug
|
||||
- name: 'Store Android archive(s)'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: android
|
||||
path: '${{ github.workspace }}/dist'
|
||||
@@ -721,17 +722,17 @@ jobs:
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: 'Download source archives'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: sources
|
||||
path: '${{ github.workspace }}'
|
||||
- name: 'Download Android .aar archive'
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: android
|
||||
path: '${{ github.workspace }}'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
build/
|
||||
buildbot/
|
||||
!build-scripts/
|
||||
/VERSION.txt
|
||||
|
||||
*.so
|
||||
|
||||
Vendored
+2
-2
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = git@github.com:libsdl-org/SDL_net.git
|
||||
branch = main
|
||||
commit = cb287ed74f612f137e29fab9dfc08b3dc87a67e4
|
||||
parent = d23f381dfa7d85acfa198a20d5cf5b202676b297
|
||||
commit = 4dd85af45d8597f93796815fba0defa5d499be21
|
||||
parent = 02eef161e7f4ac7a4deebd0115574b7a27c5f58f
|
||||
method = merge
|
||||
cmdver = 0.4.9
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
+34
-22
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# Simple DirectMedia Layer
|
||||
# Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
# Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
#
|
||||
# This software is provided 'as-is', without any express or implied
|
||||
# warranty. In no event will the authors be held liable for any damages
|
||||
@@ -37,6 +37,11 @@ my $versionfname = 'include/SDL_version.h';
|
||||
my $versionmajorregex = '\A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z';
|
||||
my $versionminorregex = '\A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z';
|
||||
my $versionmicroregex = '\A\#define\s+SDL_MICRO_VERSION\s+(\d+)\Z';
|
||||
my $wikidocsectionsym = 'SDL_WIKI_DOCUMENTATION_SECTION';
|
||||
my $forceinlinesym = 'SDL_FORCE_INLINE';
|
||||
my $deprecatedsym = 'SDL_DEPRECATED';
|
||||
my $declspecsym = '(?:SDLMAIN_|SDL_)?DECLSPEC';
|
||||
my $callconvsym = 'SDLCALL';
|
||||
my $mainincludefname = 'SDL.h';
|
||||
my $selectheaderregex = '\ASDL.*?\.h\Z';
|
||||
my $projecturl = 'https://libsdl.org/';
|
||||
@@ -147,6 +152,12 @@ if (defined $optionsfname) {
|
||||
$envvardesc = $val, next if $key eq 'envvardesc';
|
||||
$envvarsymregex = $val, next if $key eq 'envvarsymregex';
|
||||
$envvarsymreplace = $val, next if $key eq 'envvarsymreplace';
|
||||
$wikidocsectionsym = $val, next if $key eq 'wikidocsectionsym';
|
||||
$forceinlinesym = $val, next if $key eq 'forceinlinesym';
|
||||
$deprecatedsym = $val, next if $key eq 'deprecatedsym';
|
||||
$declspecsym = $val, next if $key eq 'declspecsym';
|
||||
$callconvsym = $val, next if $key eq 'callconvsym';
|
||||
|
||||
}
|
||||
}
|
||||
close(OPTIONS);
|
||||
@@ -750,6 +761,7 @@ sub print_undocumented_section {
|
||||
}
|
||||
}
|
||||
|
||||
# !!! FIXME: generalize this for other libraries to use.
|
||||
sub strip_fn_declaration_metadata {
|
||||
my $decl = shift;
|
||||
$decl =~ s/SDL_(PRINTF|SCANF)_FORMAT_STRING\s*//; # don't want this metadata as part of the documentation.
|
||||
@@ -1153,7 +1165,7 @@ while (my $d = readdir(DH)) {
|
||||
} elsif ($ignoring_lines) {
|
||||
push @contents, $_;
|
||||
next;
|
||||
} elsif (/\A\s*\#\s*ifndef\s+SDL_WIKI_DOCUMENTATION_SECTION\s*\Z/) {
|
||||
} elsif (/\A\s*\#\s*ifndef\s+$wikidocsectionsym\s*\Z/) {
|
||||
$ignoring_lines = 1;
|
||||
push @contents, $_;
|
||||
next;
|
||||
@@ -1162,13 +1174,13 @@ while (my $d = readdir(DH)) {
|
||||
#print("CATEGORY FOR '$dent' CHANGED TO " . (defined($current_wiki_category) ? "'$current_wiki_category'" : '(undef)') . "\n");
|
||||
push @contents, $_;
|
||||
next;
|
||||
} elsif (/\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC/) { # a function declaration without a doxygen comment?
|
||||
} elsif (/\A\s*extern\s+(?:$deprecatedsym\s+|)$declspecsym/) { # a function declaration without a doxygen comment?
|
||||
$symtype = 1; # function declaration
|
||||
@templines = ();
|
||||
$decl = $_;
|
||||
$str = '';
|
||||
$has_doxygen = 0;
|
||||
} elsif (/\A\s*SDL_FORCE_INLINE/) { # a (forced-inline) function declaration without a doxygen comment?
|
||||
} elsif (/\A\s*$forceinlinesym/) { # a (forced-inline) function declaration without a doxygen comment?
|
||||
$symtype = 1; # function declaration
|
||||
@templines = ();
|
||||
$decl = $_;
|
||||
@@ -1235,9 +1247,9 @@ while (my $d = readdir(DH)) {
|
||||
$lineno++ if defined $decl;
|
||||
$decl = '' if not defined $decl;
|
||||
chomp($decl);
|
||||
if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC/) {
|
||||
if ($decl =~ /\A\s*extern\s+(?:$deprecatedsym\s+|)$declspecsym/) {
|
||||
$symtype = 1; # function declaration
|
||||
} elsif ($decl =~ /\A\s*SDL_FORCE_INLINE/) {
|
||||
} elsif ($decl =~ /\A\s*$forceinlinesym/) {
|
||||
$symtype = 1; # (forced-inline) function declaration
|
||||
} elsif ($decl =~ /\A\s*\#\s*define\s+/) {
|
||||
$symtype = 2; # macro
|
||||
@@ -1274,7 +1286,7 @@ while (my $d = readdir(DH)) {
|
||||
}
|
||||
$headercategorydocs{$current_wiki_category} = $sym;
|
||||
} elsif ($symtype == 1) { # a function
|
||||
my $is_forced_inline = ($decl =~ /\A\s*SDL_FORCE_INLINE/);
|
||||
my $is_forced_inline = ($decl =~ /\A\s*$forceinlinesym/);
|
||||
|
||||
if ($is_forced_inline) {
|
||||
if (not $decl =~ /\)\s*(\{.*|)\s*\Z/) {
|
||||
@@ -1311,14 +1323,14 @@ while (my $d = readdir(DH)) {
|
||||
|
||||
my $paramsstr = undef;
|
||||
|
||||
if (!$is_forced_inline && $decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC\w*\s+(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) {
|
||||
$sym = $8;
|
||||
$rettype = "$3$4$5$6";
|
||||
$paramsstr = $9;
|
||||
} elsif ($is_forced_inline && $decl =~ /\A\s*SDL_FORCE_INLINE\s+(SDL_DEPRECATED\s+|)(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(.*?)\s*\((.*?)\);/) {
|
||||
if (!$is_forced_inline && $decl =~ /\A\s*extern\s+(?:$deprecatedsym\s+|)$declspecsym\w*\s+(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(\*?)\s*$callconvsym\s+(.*?)\s*\((.*?)\);/) {
|
||||
$sym = $6;
|
||||
$rettype = "$2$3$4$5";
|
||||
$rettype = "$1$2$3$4$5";
|
||||
$paramsstr = $7;
|
||||
} elsif ($is_forced_inline && $decl =~ /\A\s*$forceinlinesym\s+(?:$deprecatedsym\s+|)(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(.*?)\s*\((.*?)\);/) {
|
||||
$sym = $5;
|
||||
$rettype = "$1$2$3$4";
|
||||
$paramsstr = $6;
|
||||
} else {
|
||||
#print "Found doxygen but no function sig:\n$str\n\n";
|
||||
foreach (@templines) {
|
||||
@@ -1384,7 +1396,7 @@ while (my $d = readdir(DH)) {
|
||||
|
||||
$decl = $_;
|
||||
$temp = $decl;
|
||||
$temp =~ s/\Aextern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC\w*\s+(.*?)\s+(\*?)SDLCALL\s+/$3$4 /;
|
||||
$temp =~ s/\Aextern\s+(?:$deprecatedsym\s+|)$declspecsym\w*\s+(.*?)\s+(\*?)$callconvsym\s+/$1$2 /;
|
||||
$shrink_length = length($decl) - length($temp);
|
||||
$decl = $temp;
|
||||
} else {
|
||||
@@ -2259,10 +2271,10 @@ if ($copy_direction == 1) { # --copy-to-headers
|
||||
|
||||
$desc =~ s/[\s\n]+\Z//ms;
|
||||
|
||||
if (0) { # !!! FIXME: disabled because it's not currently suitable for general use, but for manually inspecting the output, it can be useful.
|
||||
if (($desc =~ /\A[A-Z]/) && (not $desc =~ /\ASDL_/)) {
|
||||
print STDERR "WARNING: $sym\'s '\\param $arg' text starts with a capital letter: '$desc'. Fixing.\n";
|
||||
$desc = lcfirst($desc);
|
||||
if (0) {
|
||||
if (($desc =~ /\A[a-z]/) && (not $desc =~ /$apiprefixregex/)) {
|
||||
print STDERR "WARNING: $sym\'s '\\param $arg' text starts with a lowercase letter: '$desc'. Fixing.\n";
|
||||
$desc = ucfirst($desc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2306,8 +2318,8 @@ if ($copy_direction == 1) { # --copy-to-headers
|
||||
}
|
||||
$desc =~ s/[\s\n]+\Z//ms;
|
||||
|
||||
if (0) { # !!! FIXME: disabled because it's not currently suitable for general use, but for manually inspecting the output, it can be useful.
|
||||
if (($desc =~ /\A[A-Z]/) && (not $desc =~ /\ASDL_/)) {
|
||||
if (0) {
|
||||
if (($desc =~ /\A[A-Z]/) && (not $desc =~ /$apiprefixregex/)) {
|
||||
print STDERR "WARNING: $sym\'s '\\returns' text starts with a capital letter: '$desc'. Fixing.\n";
|
||||
$desc = lcfirst($desc);
|
||||
}
|
||||
@@ -2451,7 +2463,7 @@ if ($copy_direction == 1) { # --copy-to-headers
|
||||
} else {
|
||||
die("Unexpected symbol type $symtype!");
|
||||
}
|
||||
my $str = "This $symtypename is available since SDL 3.0.0.";
|
||||
my $str = "This $symtypename is available since $projectshortname 3.0.0.";
|
||||
$sections{'Version'} = wordwrap(wikify($wikitype, $str)) . "\n";
|
||||
}
|
||||
}
|
||||
@@ -2916,7 +2928,7 @@ __EOF__
|
||||
$str .= ".\\\" Please report issues in this manpage's content at:\n";
|
||||
$str .= ".\\\" $bugreporturl\n";
|
||||
$str .= ".\\\" Please report issues in the generation of this manpage from the wiki at:\n";
|
||||
$str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$sym\n";
|
||||
$str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$sym\n"; # !!! FIXME: if this becomes a problem for other projects, we'll generalize this.
|
||||
$str .= ".\\\" $projectshortname can be found at $projecturl\n";
|
||||
|
||||
# Define a .URL macro. The "www.tmac" thing decides if we're using GNU roff (which has a .URL macro already), and if so, overrides the macro we just created.
|
||||
|
||||
@@ -164,6 +164,22 @@ function(get_git_head_revision _refspecvar _hashvar)
|
||||
"${GIT_DATA}/grabRef.cmake" @ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
# Fallback for reftable or other storage formats
|
||||
if(NOT HEAD_HASH OR HEAD_HASH STREQUAL "")
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE HEAD_HASH
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(HEAD_HASH "")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${_refspecvar}
|
||||
"${HEAD_REF}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
@@ -25,19 +25,21 @@ if(HEAD_CONTENTS MATCHES "ref")
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
else()
|
||||
elseif(EXISTS "@GIT_DIR@/packed-refs")
|
||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
elseif(EXISTS "@GIT_DIR@/reftable/tables.list")
|
||||
configure_file("@GIT_DIR@/reftable/tables.list" "@GIT_DATA@/reftable-tables.list" COPYONLY)
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
if(NOT HEAD_HASH AND EXISTS "@GIT_DATA@/head-ref")
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
||||
|
||||
+20
-6
@@ -3,6 +3,9 @@
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CMakePushCheckState)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.18")
|
||||
include(CheckLinkerFlag)
|
||||
endif()
|
||||
|
||||
macro(sdl_calculate_derived_version_variables MAJOR MINOR MICRO)
|
||||
set(SO_VERSION_MAJOR "0")
|
||||
@@ -241,11 +244,14 @@ function(sdl_check_project_in_subfolder relative_subfolder name vendored_option)
|
||||
endfunction()
|
||||
|
||||
macro(sdl_check_linker_flag flag var)
|
||||
# FIXME: Use CheckLinkerFlag module once cmake minimum version >= 3.18
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}")
|
||||
check_c_source_compiles("int main() { return 0; }" ${var} FAIL_REGEX "(unsupported|syntax error|unrecognized option)")
|
||||
cmake_pop_check_state()
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.18")
|
||||
check_linker_flag(C "${flag}" "${var}")
|
||||
else()
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}")
|
||||
check_c_source_compiles("int main() { return 0; }" ${var} FAIL_REGEX "(unsupported|syntax error|unrecognized option)")
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(SDL_detect_linker)
|
||||
@@ -283,7 +289,6 @@ endfunction()
|
||||
function(sdl_target_link_options_no_undefined TARGET)
|
||||
if(NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES ".*OpenBSD.*")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang")
|
||||
target_link_options(${TARGET} PRIVATE "-Wl,-undefined,error")
|
||||
else()
|
||||
sdl_check_linker_flag("-Wl,--no-undefined" HAVE_WL_NO_UNDEFINED)
|
||||
if(HAVE_WL_NO_UNDEFINED AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") AND WIN32))
|
||||
@@ -318,6 +323,15 @@ function(sdl_add_warning_options TARGET)
|
||||
else()
|
||||
target_compile_options(${TARGET} PRIVATE -Werror)
|
||||
endif()
|
||||
get_property(target_type TARGET ${TARGET} PROPERTY TYPE)
|
||||
if(NOT (APPLE OR MSVC))
|
||||
if(target_type MATCHES "SHARED_LIBRARY|MODULE_LIBRARY")
|
||||
sdl_check_linker_flag("-Wl,-fatal-warnings" HAVE_WL_FATAL_WARNINGS)
|
||||
if(HAVE_WL_FATAL_WARNINGS)
|
||||
target_link_options(${TARGET} PRIVATE "-Wl,-fatal-warnings")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
SDL_net: A simple networking library for use with SDL
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
+532
-253
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
SDL_net: A simple networking library for use with SDL
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -171,6 +171,7 @@ static int WindowsPoll(struct pollfd *fds, unsigned int nfds, int timeout)
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
@@ -179,7 +180,11 @@ static int WindowsPoll(struct pollfd *fds, unsigned int nfds, int timeout)
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID)
|
||||
#define USE_NETLINK 1
|
||||
#endif
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#else
|
||||
@@ -206,6 +211,14 @@ int NET_Version(void)
|
||||
return SDL_NET_VERSION;
|
||||
}
|
||||
|
||||
typedef enum NET_AddressType
|
||||
{
|
||||
NET_ADDRTYPE_UNKNOWN=-1,
|
||||
NET_ADDRTYPE_UNICAST,
|
||||
NET_ADDRTYPE_MULTICAST,
|
||||
NET_ADDRTYPE_BROADCAST
|
||||
} NET_AddressType;
|
||||
|
||||
struct NET_Address
|
||||
{
|
||||
char *hostname;
|
||||
@@ -213,13 +226,24 @@ struct NET_Address
|
||||
char *errstr;
|
||||
SDL_AtomicInt refcount;
|
||||
SDL_AtomicInt status; // This is actually a NET_Status.
|
||||
NET_AddressType type;
|
||||
struct addrinfo *ainfo;
|
||||
NET_Address *resolver_next; // a linked list for the resolution job queue.
|
||||
};
|
||||
|
||||
typedef struct NetworkInterfaces
|
||||
{
|
||||
char *name;
|
||||
int index;
|
||||
NET_Address *address;
|
||||
NET_Address *broadcast;
|
||||
} NetworkInterfaces;
|
||||
|
||||
|
||||
#define MIN_RESOLVER_THREADS 2
|
||||
#define MAX_RESOLVER_THREADS 10
|
||||
|
||||
// Address resolver state...
|
||||
static NET_Address *resolver_queue = NULL;
|
||||
static SDL_Thread *resolver_threads[MAX_RESOLVER_THREADS];
|
||||
static SDL_Mutex *resolver_lock = NULL;
|
||||
@@ -229,6 +253,13 @@ static SDL_AtomicInt resolver_num_threads;
|
||||
static SDL_AtomicInt resolver_num_requests;
|
||||
static SDL_AtomicInt resolver_percent_loss;
|
||||
|
||||
// Network interface state...
|
||||
static SDL_InitState interface_init;
|
||||
static SDL_RWLock *interface_rwlock = NULL;
|
||||
static int num_interfaces = 0;
|
||||
static NetworkInterfaces *interfaces = NULL;
|
||||
static SDL_AtomicInt interfaces_have_changed;
|
||||
|
||||
// between lo and hi (inclusive; it can return lo or hi itself, too!).
|
||||
static int RandomNumberBetween(const int lo, const int hi)
|
||||
{
|
||||
@@ -326,6 +357,470 @@ static bool SetGetAddrInfoErrorBool(const char *msg, int err)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int MakeSocketNonblocking(Socket handle)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
DWORD one = 1;
|
||||
return ioctlsocket(handle, FIONBIO, &one);
|
||||
#else
|
||||
return fcntl(handle, F_SETFL, fcntl(handle, F_GETFL, 0) | O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool WouldBlock(const int err)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
return (err == WSAEWOULDBLOCK);
|
||||
#else
|
||||
return ((err == EWOULDBLOCK) || (err == EAGAIN) || (err == EINPROGRESS));
|
||||
#endif
|
||||
}
|
||||
|
||||
static NET_Address *CreateSDLNetAddrFromSockAddr(const struct sockaddr *saddr, SockLen saddrlen);
|
||||
|
||||
|
||||
|
||||
/* Network interface enumeration... */
|
||||
static void FreeNetworkInterfaces(NetworkInterfaces *ifaces, int num_ifaces)
|
||||
{
|
||||
for (int i = 0; i < num_ifaces; i++) {
|
||||
NET_UnrefAddress(ifaces[i].address);
|
||||
NET_UnrefAddress(ifaces[i].broadcast);
|
||||
SDL_free(ifaces[i].name);
|
||||
}
|
||||
SDL_free(ifaces);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
static HANDLE interface_change_notifications_handle;
|
||||
|
||||
static VOID WINAPI NetworkInterfaceChangedCallback(PVOID ctx, PMIB_IPINTERFACE_ROW row, MIB_NOTIFICATION_TYPE type)
|
||||
{
|
||||
SDL_SetAtomicInt(&interfaces_have_changed, 1);
|
||||
}
|
||||
|
||||
static bool InitInterfaceChangeNotifications(void) // WINDOWS VERSION
|
||||
{
|
||||
// this would need to use NotifyAddrChange for Windows XP, but it doesn't work with IPv6 before Vista.
|
||||
//return (NotifyAddrChange(&addr_change_notification_handle, &overlapped) == ERROR_IO_PENDING);
|
||||
|
||||
// !!! FIXME: this function is available on Vista and later.
|
||||
return (NotifyIpInterfaceChange(AF_UNSPEC, NetworkInterfaceChangedCallback, NULL, FALSE, &interface_change_notifications_handle) == NO_ERROR);
|
||||
}
|
||||
|
||||
static void QuitInterfaceChangeNotifications(void) // WINDOWS VERSION
|
||||
{
|
||||
CancelMibChangeNotify2(interface_change_notifications_handle);
|
||||
interface_change_notifications_handle = 0;
|
||||
}
|
||||
|
||||
static void RefreshInterfaces(void) // WINDOWS VERSION
|
||||
{
|
||||
// MSDN docs say start with a 15K buffer, which usually works on the first
|
||||
// try, instead of trying to query for size, allocate, and then retry,
|
||||
// since this tends to be more expensive.
|
||||
ULONG buflen = 15 * 1024;
|
||||
IP_ADAPTER_ADDRESSES *addrs = NULL;
|
||||
ULONG rc;
|
||||
|
||||
do {
|
||||
SDL_free(addrs);
|
||||
addrs = (IP_ADAPTER_ADDRESSES *) SDL_malloc(buflen);
|
||||
if (!addrs) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
rc = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &buflen);
|
||||
} while (rc == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
SDL_free(addrs);
|
||||
return;
|
||||
}
|
||||
|
||||
int new_num_interfaces = 0;
|
||||
for (IP_ADAPTER_ADDRESSES *i = addrs; i != NULL; i = i->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS *j = i->FirstUnicastAddress; j != NULL; j = j->Next) {
|
||||
new_num_interfaces++;
|
||||
}
|
||||
}
|
||||
|
||||
NetworkInterfaces *new_interfaces = (NetworkInterfaces *) SDL_calloc(new_num_interfaces + 1, sizeof (*new_interfaces));
|
||||
if (!new_interfaces) {
|
||||
SDL_free(addrs);
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (IP_ADAPTER_ADDRESSES *i = addrs; i != NULL; i = i->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS *j = i->FirstUnicastAddress; j != NULL; j = j->Next) {
|
||||
NET_Address *addr = CreateSDLNetAddrFromSockAddr(j->Address.lpSockaddr, j->Address.iSockaddrLength);
|
||||
if (addr) {
|
||||
new_interfaces[count].address = addr;
|
||||
if (j->Address.lpSockaddr->sa_family == AF_INET6) {
|
||||
new_interfaces[count].index = i->Ipv6IfIndex;
|
||||
} else if (j->Address.lpSockaddr->sa_family == AF_INET) { // if this is IPv4, calculate the broadcast address.
|
||||
SOCKADDR_IN bcast;
|
||||
SDL_assert(j->Address.iSockaddrLength == sizeof (bcast));
|
||||
SDL_memcpy(&bcast, (const SOCKADDR_IN *) j->Address.lpSockaddr, sizeof (SOCKADDR_IN));
|
||||
bcast.sin_addr.S_un.S_addr |= htonl(~((1 << (32 - j->OnLinkPrefixLength)) - 1));
|
||||
new_interfaces[count].broadcast = CreateSDLNetAddrFromSockAddr((const struct sockaddr *) &bcast, sizeof (bcast));
|
||||
new_interfaces[count].broadcast->type = NET_ADDRTYPE_BROADCAST;
|
||||
new_interfaces[count].index = i->IfIndex;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_num_interfaces = count; // in case we dropped one somewhere.
|
||||
|
||||
SDL_LockRWLockForWriting(interface_rwlock);
|
||||
NetworkInterfaces *old_interfaces = interfaces;
|
||||
const int old_num_interfaces = num_interfaces;
|
||||
interfaces = new_interfaces;
|
||||
num_interfaces = new_num_interfaces;
|
||||
SDL_UnlockRWLock(interface_rwlock);
|
||||
FreeNetworkInterfaces(old_interfaces, old_num_interfaces);
|
||||
|
||||
SDL_free(addrs);
|
||||
}
|
||||
|
||||
#elif defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_OPENBSD) || defined(SDL_PLATFORM_NETBSD)
|
||||
|
||||
// AF_NETLINK covers Linux (and by extension Android). PF_ROUTE covers the BSDs (and by extension Apple platforms).
|
||||
// This doesn't cover all Unix platforms that ever existed, but this hits just about everything that is still being maintained seriously.
|
||||
|
||||
static SDL_Thread *interface_change_notifications_thread = NULL;
|
||||
static SDL_AtomicInt interface_change_notifications_flag; // !!! FIXME
|
||||
|
||||
static int SDLCALL LinuxInterfaceChangeNotificationThread(void *data)
|
||||
{
|
||||
#ifdef USE_NETLINK
|
||||
const int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
#else
|
||||
const int fd = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||
#endif
|
||||
if (fd == -1) {
|
||||
return 0; // oh well.
|
||||
}
|
||||
|
||||
// !!! FIXME: don't make this non-blocking, find a more efficient way to terminate the thread.
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
struct sockaddr_nl addr;
|
||||
SDL_zero(addr);
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pid = getpid();
|
||||
addr.nl_groups = RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR;
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
|
||||
close(fd);
|
||||
return 0; // oh well.
|
||||
}
|
||||
#elif defined(RO_MSGFILTER)
|
||||
const unsigned char filter[] = { RTM_IFANNOUNCE, RTM_IFINFO, RTM_NEWADDR, RTM_DELADDR, RTM_CHGADDR };
|
||||
setsockopt(fd, PF_ROUTE, RO_MSGFILTER, &filter, sizeof (filter));
|
||||
#endif
|
||||
|
||||
while (SDL_GetAtomicInt(&interface_change_notifications_flag) == 0) {
|
||||
Uint8 buf[8192];
|
||||
struct iovec iov = { buf, sizeof (buf) };
|
||||
struct msghdr msg;
|
||||
SDL_zero(msg);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
struct sockaddr_nl sa;
|
||||
SDL_zero(sa);
|
||||
msg.msg_name = &sa;
|
||||
msg.msg_namelen = sizeof (sa);
|
||||
#endif
|
||||
|
||||
const ssize_t br = recvmsg(fd, &msg, 0);
|
||||
if (br < 0) {
|
||||
if (WouldBlock(LastSocketError())) {
|
||||
SDL_Delay(300);
|
||||
continue;
|
||||
}
|
||||
// quit if there's a failure. Presumably this is because another thread close()'d the socket, to unblock the thread and request termination.
|
||||
break;
|
||||
}
|
||||
|
||||
// we don't currently bother parsing for specifics, we just use this as a signal to reenumerate interfaces.
|
||||
//for (struct nlmsghdr *i = buf; NLMSG_OK(i, br); i = NLMSG_NEXT(i, br)) {}
|
||||
SDL_Log("Network interfaces changed!");
|
||||
SDL_SetAtomicInt(&interfaces_have_changed, 1);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool InitInterfaceChangeNotifications(void) // LINUX/BSD VERSION
|
||||
{
|
||||
interface_change_notifications_thread = SDL_CreateThread(LinuxInterfaceChangeNotificationThread, "SDLNetIfaceEnum", NULL);
|
||||
return (interface_change_notifications_thread != NULL);
|
||||
}
|
||||
|
||||
static void QuitInterfaceChangeNotifications(void) // LINUX/BSD VERSION
|
||||
{
|
||||
if (interface_change_notifications_thread) {
|
||||
SDL_SetAtomicInt(&interface_change_notifications_flag, 1);
|
||||
SDL_WaitThread(interface_change_notifications_thread, NULL);
|
||||
SDL_SetAtomicInt(&interface_change_notifications_flag, 0);
|
||||
}
|
||||
interface_change_notifications_thread = NULL;
|
||||
}
|
||||
|
||||
static void RefreshInterfaces(void) // LINUX/BSD VERSION
|
||||
{
|
||||
#ifdef USE_NETLINK
|
||||
// Android has getifaddrs() in Android 24, but we still target 21, so do it the hard way. Since this works on normal Linux, we'll just use it there, too.
|
||||
const int sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||
if (sock < 0) {
|
||||
return; // oh well.
|
||||
}
|
||||
|
||||
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
// Ask for the address information.
|
||||
typedef struct reqstruct
|
||||
{
|
||||
struct nlmsghdr header;
|
||||
struct ifaddrmsg msg;
|
||||
} reqstruct;
|
||||
|
||||
reqstruct req;
|
||||
SDL_zero(req);
|
||||
req.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
|
||||
req.header.nlmsg_type = RTM_GETADDR;
|
||||
req.header.nlmsg_len = NLMSG_LENGTH(sizeof (req.msg));
|
||||
req.msg.ifa_family = AF_UNSPEC;
|
||||
|
||||
if (send(sock, &req, req.header.nlmsg_len, 0) != req.header.nlmsg_len) {
|
||||
close(sock);
|
||||
return; // oh well.
|
||||
}
|
||||
|
||||
int new_num_interfaces = 0;
|
||||
NetworkInterfaces *new_interfaces = NULL;
|
||||
|
||||
Uint8 buffer[64 * 1024];
|
||||
ssize_t br;
|
||||
while ((br = recv(sock, buffer, sizeof (buffer), 0)) > 0) {
|
||||
for (const struct nlmsghdr *header = (const struct nlmsghdr *) buffer; NLMSG_OK(header, (size_t) br); header = NLMSG_NEXT(header, br)) {
|
||||
if (header->nlmsg_type == NLMSG_DONE) {
|
||||
goto succeeded; // we got it all.
|
||||
} else if (header->nlmsg_type == NLMSG_ERROR) {
|
||||
goto failed; // uhoh.
|
||||
} else if (header->nlmsg_type == RTM_NEWADDR) {
|
||||
// strictly speaking, one interface can have multiple IP addresses, so you might have multiple addresses with the same interface index.
|
||||
void *ptr = SDL_realloc(new_interfaces, sizeof (*new_interfaces) * (new_num_interfaces + 1));
|
||||
if (!ptr) {
|
||||
goto failed;
|
||||
}
|
||||
new_interfaces = (NetworkInterfaces *) ptr;
|
||||
NetworkInterfaces *iface = &new_interfaces[new_num_interfaces];
|
||||
SDL_zerop(iface);
|
||||
|
||||
const struct ifaddrmsg *msg = (const struct ifaddrmsg *) (NLMSG_DATA(header));
|
||||
size_t payload_len = IFA_PAYLOAD(header);
|
||||
for (const struct rtattr *attr = IFA_RTA(msg); RTA_OK(attr, payload_len); attr = RTA_NEXT(attr, payload_len)) {
|
||||
const bool isbroadcast = (attr->rta_type == IFA_BROADCAST);
|
||||
if (isbroadcast || (attr->rta_type == IFA_ADDRESS)) {
|
||||
// this gives us the raw bytes of an address, but not the actual sockaddr_* layout, so we have to go with known protocols. :/
|
||||
AddressStorage addrstorage;
|
||||
SockLen addrlen = 0;
|
||||
SDL_zero(addrstorage);
|
||||
addrstorage.ss_family = msg->ifa_family;
|
||||
if (addrstorage.ss_family == AF_INET) {
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *) &addrstorage;
|
||||
SDL_memcpy(&sa->sin_addr, RTA_DATA(attr), RTA_PAYLOAD(attr));
|
||||
addrlen = sizeof (*sa);
|
||||
} else if (addrstorage.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &addrstorage;
|
||||
SDL_memcpy(&sa6->sin6_addr, RTA_DATA(attr), RTA_PAYLOAD(attr));
|
||||
addrlen = sizeof (*sa6);
|
||||
} else {
|
||||
continue; // unknown protocol family.
|
||||
}
|
||||
|
||||
NET_Address **paddr = isbroadcast ? &iface->broadcast : &iface->address;
|
||||
SDL_assert(*paddr == NULL); // shouldn't be two of these attributes on a single RTM_NEWADDR.
|
||||
*paddr = CreateSDLNetAddrFromSockAddr((const struct sockaddr *) &addrstorage, addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (iface->address) {
|
||||
iface->index = msg->ifa_index;
|
||||
if (iface->broadcast) {
|
||||
iface->broadcast->type = NET_ADDRTYPE_BROADCAST;
|
||||
}
|
||||
|
||||
char interface_name[IF_NAMESIZE];
|
||||
if (if_indextoname((unsigned int) iface->index, interface_name) == NULL) { // miraculously, this function is in Android 21; nothing else is, though! We could have done this with netlink too, but this is the easy button.
|
||||
interface_name[0] = '\0';
|
||||
}
|
||||
|
||||
iface->name = SDL_strdup(interface_name);
|
||||
if (!iface->name) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
new_num_interfaces++;
|
||||
} else {
|
||||
NET_UnrefAddress(iface->broadcast); // just in case.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
succeeded:
|
||||
close(sock);
|
||||
SDL_LockRWLockForWriting(interface_rwlock);
|
||||
NetworkInterfaces *old_interfaces = interfaces;
|
||||
const int old_num_interfaces = num_interfaces;
|
||||
interfaces = new_interfaces;
|
||||
num_interfaces = new_num_interfaces;
|
||||
SDL_UnlockRWLock(interface_rwlock);
|
||||
FreeNetworkInterfaces(old_interfaces, old_num_interfaces);
|
||||
return;
|
||||
|
||||
failed:
|
||||
close(sock);
|
||||
FreeNetworkInterfaces(new_interfaces, new_num_interfaces);
|
||||
// if this was a failure case, oh well, old (maybe incorrect) ones will have to stand.
|
||||
#else
|
||||
struct ifaddrs *ifaddr = NULL;
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
return; // oh well.
|
||||
}
|
||||
|
||||
NetworkInterfaces *new_interfaces = NULL;
|
||||
int new_num_interfaces = 0;
|
||||
for (struct ifaddrs *i = ifaddr; i != NULL; i = i->ifa_next) {
|
||||
if (i->ifa_name != NULL) {
|
||||
new_num_interfaces++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_num_interfaces) {
|
||||
goto succeeded;
|
||||
}
|
||||
|
||||
new_interfaces = SDL_calloc(new_num_interfaces, sizeof (*new_interfaces));
|
||||
if (!new_interfaces) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
NetworkInterfaces *iface = &new_interfaces[0];
|
||||
for (struct ifaddrs *i = ifaddr; i != NULL; i = i->ifa_next, iface++) {
|
||||
if (i->ifa_name == NULL) {
|
||||
continue; // i guess.
|
||||
}
|
||||
|
||||
// !!! FIXME: getifaddrs doesn't return the sockaddr length, so we have to go with known protocols. :/
|
||||
if (i->ifa_addr->sa_family == AF_INET) {
|
||||
iface->address = CreateSDLNetAddrFromSockAddr(i->ifa_addr, sizeof (struct sockaddr_in));
|
||||
if (i->ifa_flags & IFF_BROADCAST) {
|
||||
iface->broadcast = CreateSDLNetAddrFromSockAddr(i->ifa_broadaddr, sizeof (struct sockaddr_in));
|
||||
}
|
||||
} else if (i->ifa_addr->sa_family == AF_INET6) {
|
||||
iface->address = CreateSDLNetAddrFromSockAddr(i->ifa_addr, sizeof (struct sockaddr_in6));
|
||||
} else {
|
||||
new_num_interfaces--;
|
||||
iface--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iface->address) {
|
||||
if (iface->broadcast) {
|
||||
iface->broadcast->type = NET_ADDRTYPE_BROADCAST;
|
||||
}
|
||||
|
||||
iface->index = (int) if_nametoindex(i->ifa_name);
|
||||
iface->name = SDL_strdup(i->ifa_name);
|
||||
if (!iface->name) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char *ptr = SDL_strchr(iface->address->human_readable, '%'); // chop off interface name.
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
} else {
|
||||
NET_UnrefAddress(iface->broadcast); // just in case.
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
succeeded:
|
||||
if (ifaddr) {
|
||||
freeifaddrs(ifaddr);
|
||||
}
|
||||
|
||||
SDL_LockRWLockForWriting(interface_rwlock);
|
||||
NetworkInterfaces *old_interfaces = interfaces;
|
||||
const int old_num_interfaces = num_interfaces;
|
||||
interfaces = new_interfaces;
|
||||
num_interfaces = new_num_interfaces;
|
||||
SDL_UnlockRWLock(interface_rwlock);
|
||||
FreeNetworkInterfaces(old_interfaces, old_num_interfaces);
|
||||
return;
|
||||
|
||||
failed:
|
||||
if (ifaddr) {
|
||||
freeifaddrs(ifaddr);
|
||||
}
|
||||
FreeNetworkInterfaces(new_interfaces, new_num_interfaces);
|
||||
// if this was a failure case, oh well, old (maybe incorrect) ones will have to stand.
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#error implement me for your platform.
|
||||
#endif
|
||||
|
||||
|
||||
static bool InterfacesReady(void)
|
||||
{
|
||||
if (SDL_ShouldInit(&interface_init)) {
|
||||
if (!interface_rwlock) {
|
||||
interface_rwlock = SDL_CreateRWLock();
|
||||
}
|
||||
if (!interface_rwlock || !InitInterfaceChangeNotifications()) {
|
||||
SDL_SetInitialized(&interface_init, false);
|
||||
return false;
|
||||
}
|
||||
SDL_SetAtomicInt(&interfaces_have_changed, 1); // force refresh at start.
|
||||
SDL_SetInitialized(&interface_init, true);
|
||||
}
|
||||
|
||||
// if there were changes, mark it as unchanged and then we'll enumerate. So if it changes again while enumerating, we'll pick that up next time.
|
||||
if (SDL_CompareAndSwapAtomicInt(&interfaces_have_changed, 1, 0)) {
|
||||
RefreshInterfaces();
|
||||
#if 0
|
||||
SDL_Log("NETWORK INTERFACE REFRESH");
|
||||
for (int i = 0; i < num_interfaces; i++) {
|
||||
const NetworkInterfaces *iface = &interfaces[i];
|
||||
SDL_Log("Interface %d ('%s')", iface->index, iface->name);
|
||||
SDL_Log(" - address %s", iface->address->human_readable);
|
||||
if (iface->broadcast) {
|
||||
SDL_Log(" - broadcast %s", iface->broadcast->human_readable);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// this blocks!
|
||||
static NET_Status ResolveAddress(NET_Address *addr)
|
||||
{
|
||||
@@ -354,6 +849,8 @@ static NET_Status ResolveAddress(NET_Address *addr)
|
||||
|
||||
addr->human_readable = SDL_strdup(buf);
|
||||
addr->ainfo = ainfo;
|
||||
addr->type = NET_ADDRTYPE_UNICAST;
|
||||
|
||||
return NET_SUCCESS; // success (zero means "still in progress").
|
||||
}
|
||||
|
||||
@@ -479,6 +976,8 @@ static NET_Address *CreateSDLNetAddrFromSockAddr(const struct sockaddr *saddr, S
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr->type = NET_ADDRTYPE_UNICAST; // until told otherwise.
|
||||
|
||||
addr->human_readable = SDL_strdup(hostbuf);
|
||||
if (!addr->human_readable) {
|
||||
freeaddrinfo(addr->ainfo);
|
||||
@@ -588,6 +1087,26 @@ void NET_Quit(void)
|
||||
|
||||
resolver_queue = NULL;
|
||||
|
||||
if (SDL_ShouldQuit(&interface_init)) {
|
||||
QuitInterfaceChangeNotifications();
|
||||
SDL_SetAtomicInt(&interfaces_have_changed, 0);
|
||||
if (interfaces) {
|
||||
FreeNetworkInterfaces(interfaces, num_interfaces);
|
||||
}
|
||||
if (interface_rwlock) {
|
||||
SDL_DestroyRWLock(interface_rwlock);
|
||||
}
|
||||
interfaces = NULL;
|
||||
num_interfaces = 0;
|
||||
interface_rwlock = NULL;
|
||||
SDL_SetInitialized(&interface_init, false);
|
||||
}
|
||||
|
||||
// asserts to catch that these shouldn't have ever been set if we never initialized interface_init...
|
||||
SDL_assert(!interfaces);
|
||||
SDL_assert(!interface_rwlock);
|
||||
SDL_assert(num_interfaces == 0);
|
||||
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
@@ -770,41 +1289,9 @@ void NET_SimulateAddressResolutionLoss(int percent_loss)
|
||||
SDL_SetAtomicInt(&resolver_percent_loss, SDL_clamp(percent_loss, 0, 100));
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
typedef struct EnumerateNetAddrTableData
|
||||
{
|
||||
NET_Address **retval;
|
||||
int count;
|
||||
int real_count;
|
||||
} EnumerateNetAddrTableData;
|
||||
|
||||
static void SDLCALL EnumerateNetAddrTable(void *userdata, SDL_PropertiesID props, const char *name)
|
||||
{
|
||||
NET_Address *netaddr = SDL_GetPointerProperty(props, name, NULL);
|
||||
if (netaddr) {
|
||||
NET_RefAddress(netaddr);
|
||||
EnumerateNetAddrTableData *data = (EnumerateNetAddrTableData *) userdata;
|
||||
SDL_assert(data->real_count < data->count);
|
||||
data->retval[data->real_count++] = netaddr;
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL CleanupNetAddrTable(void *userdata, void *value)
|
||||
{
|
||||
NET_UnrefAddress((NET_Address *) value);
|
||||
}
|
||||
|
||||
static int SDLCALL CompareNetAddrQsort(const void *a, const void *b)
|
||||
{
|
||||
return NET_CompareAddresses(*(NET_Address **) a, *(NET_Address **) b);
|
||||
}
|
||||
#endif
|
||||
|
||||
NET_Address **NET_GetLocalAddresses(int *num_addresses)
|
||||
{
|
||||
int count = 0;
|
||||
NET_Address **retval = NULL;
|
||||
|
||||
int dummy_addresses;
|
||||
if (!num_addresses) {
|
||||
num_addresses = &dummy_addresses;
|
||||
@@ -812,209 +1299,20 @@ NET_Address **NET_GetLocalAddresses(int *num_addresses)
|
||||
|
||||
*num_addresses = 0;
|
||||
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
// !!! FIXME: maybe LoadLibrary(iphlpapi) on the first call, since most
|
||||
// !!! FIXME: things won't ever use this.
|
||||
NET_Address **retval = NULL;
|
||||
|
||||
// MSDN docs say start with a 15K buffer, which usually works on the first
|
||||
// try, instead of trying to query for size, allocate, and then retry,
|
||||
// since this tends to be more expensive.
|
||||
ULONG buflen = 15 * 1024;
|
||||
IP_ADAPTER_ADDRESSES *addrs = NULL;
|
||||
ULONG rc;
|
||||
|
||||
do {
|
||||
SDL_free(addrs);
|
||||
addrs = (IP_ADAPTER_ADDRESSES *) SDL_malloc(buflen);
|
||||
if (!addrs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
rc = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &buflen);
|
||||
} while (rc == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
SetSocketError("GetAdaptersAddresses failed", rc);
|
||||
SDL_free(addrs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (IP_ADAPTER_ADDRESSES *i = addrs; i != NULL; i = i->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS *j = i->FirstUnicastAddress; j != NULL; j = j->Next) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
retval = (NET_Address **) SDL_calloc(((size_t)count) + 1, sizeof (NET_Address *));
|
||||
if (!retval) {
|
||||
SDL_free(addrs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (IP_ADAPTER_ADDRESSES *i = addrs; i != NULL; i = i->Next) {
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS *j = i->FirstUnicastAddress; j != NULL; j = j->Next) {
|
||||
NET_Address *addr = CreateSDLNetAddrFromSockAddr(j->Address.lpSockaddr, j->Address.iSockaddrLength);
|
||||
if (addr) {
|
||||
retval[count++] = addr;
|
||||
if (InterfacesReady()) {
|
||||
SDL_LockRWLockForReading(interface_rwlock);
|
||||
const int total = num_interfaces;
|
||||
retval = (NET_Address **) SDL_malloc((total + 1) * sizeof (NET_Address *));
|
||||
if (retval) {
|
||||
for (int i = 0; i < total; i++) {
|
||||
retval[i] = NET_RefAddress(interfaces[i].address);
|
||||
}
|
||||
retval[total] = NULL;
|
||||
*num_addresses = total;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(addrs);
|
||||
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
// Android has getifaddrs() in Android 24, but we still target 21, so do it the hard way.
|
||||
const int sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||
if (sock < 0) {
|
||||
SetLastSocketError("Failed to create AF_NETLINK socket");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
// Ask for the address information.
|
||||
typedef struct reqstruct
|
||||
{
|
||||
struct nlmsghdr header;
|
||||
struct ifaddrmsg msg;
|
||||
} reqstruct;
|
||||
|
||||
reqstruct req;
|
||||
SDL_zero(req);
|
||||
req.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
|
||||
req.header.nlmsg_type = RTM_GETADDR;
|
||||
req.header.nlmsg_len = NLMSG_LENGTH(sizeof (req.msg));
|
||||
req.msg.ifa_family = AF_UNSPEC;
|
||||
|
||||
if (send(sock, &req, req.header.nlmsg_len, 0) != req.header.nlmsg_len) {
|
||||
SetLastSocketError("Failed to send request to AF_NETLINK socket");
|
||||
close(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// this can produce duplicate entries for various reasons; use an SDL_PropertiesID to keep a unique table.
|
||||
const SDL_PropertiesID addr_table = SDL_CreateProperties();
|
||||
if (!addr_table) {
|
||||
close(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Uint8 buffer[64 * 1024];
|
||||
ssize_t br;
|
||||
while ((br = recv(sock, buffer, sizeof (buffer), 0)) > 0) {
|
||||
for (const struct nlmsghdr *header = (const struct nlmsghdr *) buffer; NLMSG_OK(header, (size_t) br); header = NLMSG_NEXT(header, br)) {
|
||||
if (header->nlmsg_type == NLMSG_DONE) {
|
||||
break; // we got it all.
|
||||
} else if (header->nlmsg_type == NLMSG_ERROR) {
|
||||
// uhoh.
|
||||
NET_FreeLocalAddresses(retval);
|
||||
retval = NULL;
|
||||
break;
|
||||
} else if (header->nlmsg_type == RTM_NEWADDR) {
|
||||
const struct ifaddrmsg *msg = (const struct ifaddrmsg *) (NLMSG_DATA(header));
|
||||
size_t payload_len = IFA_PAYLOAD(header);
|
||||
for (const struct rtattr *attr = IFA_RTA(msg); RTA_OK(attr, payload_len); attr = RTA_NEXT(attr, payload_len)) {
|
||||
if ((attr->rta_type != IFA_ADDRESS) && (attr->rta_type != IFA_LOCAL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// this gives us the raw bytes of an address, but not the actual sockaddr_* layout, so we have to go with known protocols. :/
|
||||
AddressStorage addrstorage;
|
||||
SockLen addrlen = 0;
|
||||
SDL_zero(addrstorage);
|
||||
addrstorage.ss_family = msg->ifa_family;
|
||||
if (addrstorage.ss_family == AF_INET) {
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *) &addrstorage;
|
||||
SDL_memcpy(&sa->sin_addr, RTA_DATA(attr), RTA_PAYLOAD(attr));
|
||||
addrlen = sizeof (*sa);
|
||||
} else if (addrstorage.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &addrstorage;
|
||||
SDL_memcpy(&sa6->sin6_addr, RTA_DATA(attr), RTA_PAYLOAD(attr));
|
||||
addrlen = sizeof (*sa6);
|
||||
} else {
|
||||
continue; // unknown protocol family.
|
||||
}
|
||||
|
||||
NET_Address *netaddr = CreateSDLNetAddrFromSockAddr((const struct sockaddr *) &addrstorage, addrlen);
|
||||
if (!netaddr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *key = NET_GetAddressString(netaddr);
|
||||
if (!key) {
|
||||
NET_UnrefAddress(netaddr);
|
||||
} else {
|
||||
SDL_SetPointerPropertyWithCleanup(addr_table, key, netaddr, CleanupNetAddrTable, NULL);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
retval = (NET_Address **) SDL_calloc(count + 1, sizeof (NET_Address *));
|
||||
if (retval) {
|
||||
EnumerateNetAddrTableData data = { retval, count, 0 };
|
||||
SDL_EnumerateProperties(addr_table, EnumerateNetAddrTable, &data);
|
||||
count = data.real_count;
|
||||
SDL_qsort(retval, count, sizeof (*retval), CompareNetAddrQsort);
|
||||
}
|
||||
|
||||
SDL_DestroyProperties(addr_table); // will unref all addresses still in the table, but we took a reference too.
|
||||
|
||||
#else
|
||||
struct ifaddrs *ifaddr;
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
SDL_SetError("getifaddrs failed: %s", strerror(errno));
|
||||
return NULL; // oh well.
|
||||
}
|
||||
|
||||
for (struct ifaddrs *i = ifaddr; i != NULL; i = i->ifa_next) {
|
||||
if (i->ifa_name != NULL) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
retval = (NET_Address **) SDL_calloc(count + 1, sizeof (NET_Address *));
|
||||
if (!retval) {
|
||||
if (ifaddr) {
|
||||
freeifaddrs(ifaddr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (struct ifaddrs *i = ifaddr; i != NULL; i = i->ifa_next) {
|
||||
if (i->ifa_name != NULL) {
|
||||
NET_Address *addr = NULL;
|
||||
// !!! FIXME: getifaddrs doesn't return the sockaddr length, so we have to go with known protocols. :/
|
||||
if (i->ifa_addr->sa_family == AF_INET) {
|
||||
addr = CreateSDLNetAddrFromSockAddr(i->ifa_addr, sizeof (struct sockaddr_in));
|
||||
} else if (i->ifa_addr->sa_family == AF_INET6) {
|
||||
addr = CreateSDLNetAddrFromSockAddr(i->ifa_addr, sizeof (struct sockaddr_in6));
|
||||
}
|
||||
|
||||
if (addr) {
|
||||
retval[count++] = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ifaddr) {
|
||||
freeifaddrs(ifaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
*num_addresses = count;
|
||||
|
||||
// try to shrink allocation.
|
||||
void *ptr = SDL_realloc(retval, (((size_t) count) + 1) * sizeof (NET_Address *));
|
||||
if (ptr) {
|
||||
retval = (NET_Address **) ptr;
|
||||
SDL_UnlockRWLock(interface_rwlock);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -1074,25 +1372,6 @@ struct NET_StreamSocket
|
||||
Uint64 simulated_failure_until;
|
||||
};
|
||||
|
||||
static int MakeSocketNonblocking(Socket handle)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
DWORD one = 1;
|
||||
return ioctlsocket(handle, FIONBIO, &one);
|
||||
#else
|
||||
return fcntl(handle, F_SETFL, fcntl(handle, F_GETFL, 0) | O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool WouldBlock(const int err)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
return (err == WSAEWOULDBLOCK) ? true : false;
|
||||
#else
|
||||
return ((err == EWOULDBLOCK) || (err == EAGAIN) || (err == EINPROGRESS)) ? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
NET_StreamSocket *NET_CreateClient(NET_Address *addr, Uint16 port)
|
||||
{
|
||||
if (addr == NULL) {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Simple DirectMedia Layer
|
||||
# Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
# Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
#
|
||||
# This software is provided 'as-is', without any express or implied
|
||||
# warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ BEGIN
|
||||
VALUE "FileDescription", "SDL_net\0"
|
||||
VALUE "FileVersion", "3, 0, 0, 0\0"
|
||||
VALUE "InternalName", "SDL_net\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL3_net.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "3, 0, 0, 0\0"
|
||||
|
||||
Reference in New Issue
Block a user