diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 000000000000..79c57b563feb
Binary files /dev/null and b/.DS_Store differ
diff --git a/.github/workflows/cmake_builds.yml b/.github/workflows/cmake_builds.yml
index 87100895f152..fe74ab1491c4 100644
--- a/.github/workflows/cmake_builds.yml
+++ b/.github/workflows/cmake_builds.yml
@@ -73,6 +73,13 @@ jobs:
export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/install-gdal/lib
$GITHUB_WORKSPACE/install-gdal/bin/gdalinfo --version
PYTHONPATH=$GITHUB_WORKSPACE/install-gdal/lib/python3/dist-packages python3 -c "from osgeo import gdal;print(gdal.VersionInfo(None))"
+ - name: Rerun using Mono
+ run: |
+ cd $GITHUB_WORKSPACE/superbuild/build
+ rm -rf swig/csharp
+ cmake ${CMAKE_OPTIONS} -DCSHARP_MONO=ON -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror -DGDAL_USE_PUBLICDECOMPWT:BOOL=ON ..
+ cmake --build $GITHUB_WORKSPACE/superbuild/build --target install -j $(nproc)
+ ctest --test-dir $GITHUB_WORKSPACE/superbuild/build -V -R "^csharp.*"
- name: Standalone Python bindings build
run: |
(cd $GITHUB_WORKSPACE/superbuild/build/gdal/swig/python && python setup.py sdist)
@@ -122,9 +129,8 @@ jobs:
# libxml2 disabled because currently causes a 'Imported target "LibXml2::LibXml2" includes non-existent path "/mingw64/include/libxml2" in its INTERFACE_INCLUDE_DIRECTORIES'
# Disable mySQL since C:/mysql/lib/mysqlclient.lib (unrelated to msys) is found, which causes linking issues
# Disable Python bindings because of 'ValueError: filename D:/a/gdal/gdal/swig/python/osgeo/__init__.py does not start with the input_base_dir D:/a/gdal/gdal/swig/python/osgeo/\' when running lib2to3
- # BUILD_CSHARP_BINDINGS=OFF because we get "AssemblyInfo.cs(98,12): error CS0246: The type or namespace name 'SecurityRules' could not be found (are you missing a using directive or an assembly reference?)" with Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.9031 for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
- name: Configure
- run: cmake -DCMAKE_BUILD_TYPE=release -G "${env:generator}" "-DCMAKE_C_COMPILER_LAUNCHER=c:\tools\msys64\mingw64\bin\ccache.exe" "-DCMAKE_CXX_COMPILER_LAUNCHER=c:\tools\msys64\mingw64\bin\ccache.exe" "-DCMAKE_PREFIX_PATH=C:\tools\msys64\mingw64" "-DCMAKE_UNITY_BUILD=${env:CMAKE_UNITY_BUILD}" -S . -B "build" -DLIBXML2_INCLUDE_DIR=C:/tools/msys64/mingw64/include -DGDAL_USE_LIBXML2:BOOL=OFF -DGDAL_USE_MYSQL:BOOL=OFF -DBUILD_PYTHON_BINDINGS:BOOL=OFF -DBUILD_CSHARP_BINDINGS=OFF -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror
+ run: cmake -DCMAKE_BUILD_TYPE=release -G "${env:generator}" "-DCMAKE_C_COMPILER_LAUNCHER=c:\tools\msys64\mingw64\bin\ccache.exe" "-DCMAKE_CXX_COMPILER_LAUNCHER=c:\tools\msys64\mingw64\bin\ccache.exe" "-DCMAKE_PREFIX_PATH=C:\tools\msys64\mingw64" "-DCMAKE_UNITY_BUILD=${env:CMAKE_UNITY_BUILD}" -S . -B "build" -DLIBXML2_INCLUDE_DIR=C:/tools/msys64/mingw64/include -DGDAL_USE_LIBXML2:BOOL=OFF -DGDAL_USE_MYSQL:BOOL=OFF -DBUILD_PYTHON_BINDINGS:BOOL=OFF -DBUILD_CSHARP_BINDINGS=ON -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror
working-directory: ${{ github.workspace }}
- name: Build
run: cmake --build build -j 3
@@ -178,10 +184,9 @@ jobs:
# Note that the leading space in CMAKE_C/CXX_FLAGS=" /WX" is due to using Bash on Windows that would
# otherwise interpret /bla has a file relative to the Bash root directory and would replace it by a path like c:\Program Files\git\WX
# BUILD_JAVA_BINDINGS=OFF because we get "Error occurred during initialization of VM. Corrupted ZIP library: C:\Miniconda\envs\gdalenv\Library\bin\zip.dll" when running java. Not reproducible on a standard VM
- # BUILD_CSHARP_BINDINGS=OFF because we get "AssemblyInfo.cs(98,12): error CS0246: The type or namespace name 'SecurityRules' could not be found (are you missing a using directive or an assembly reference?)" with Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.9031 for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
run: |
mkdir -p $GITHUB_WORKSPACE/build
- cmake -A ${architecture} -G "${generator}" "-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal" "-DCMAKE_C_COMPILER_LAUNCHER=clcache" "-DCMAKE_CXX_COMPILER_LAUNCHER=clcache" "-DCMAKE_PREFIX_PATH=${CONDA_PREFIX}" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DJASPER_LIBRARY_RELEASE:FILEPATH= -DLIBKML_BASE_LIBRARY:FILEPATH= -DGDAL_ENABLE_PLUGINS:BOOL=ON -DGDAL_ENABLE_PLUGINS_NO_DEPS:BOOL=ON -DGDAL_USE_PUBLICDECOMPWT:BOOL=ON -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=OFF -DGDAL_USE_MYSQL:BOOL=OFF -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX"
+ cmake -A ${architecture} -G "${generator}" "-DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal" "-DCMAKE_C_COMPILER_LAUNCHER=clcache" "-DCMAKE_CXX_COMPILER_LAUNCHER=clcache" "-DCMAKE_PREFIX_PATH=${CONDA_PREFIX}" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build" -DJASPER_LIBRARY_RELEASE:FILEPATH= -DLIBKML_BASE_LIBRARY:FILEPATH= -DGDAL_ENABLE_PLUGINS:BOOL=ON -DGDAL_ENABLE_PLUGINS_NO_DEPS:BOOL=ON -DGDAL_USE_PUBLICDECOMPWT:BOOL=ON -DBUILD_JAVA_BINDINGS=OFF -DBUILD_CSHARP_BINDINGS=ON -DGDAL_USE_MYSQL:BOOL=OFF -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX"
- name: Build
shell: bash -l {0}
run: cmake --build $GITHUB_WORKSPACE/build --config Release -j 2
@@ -233,7 +238,7 @@ jobs:
- name: Configure
run: |
mkdir -p $GITHUB_WORKSPACE/build
- cmake -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal ${CMAKE_OPTIONS} -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror "-DCMAKE_C_COMPILER_LAUNCHER=ccache" "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build"
+ cmake -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install-gdal ${CMAKE_OPTIONS} -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror "-DCMAKE_C_COMPILER_LAUNCHER=ccache" "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build"
- name: Build
run: |
cmake --build $GITHUB_WORKSPACE/build -j 3
@@ -247,3 +252,42 @@ jobs:
GITHUB_WORKFLOW: "MacOS build"
- name: Install
run: cmake --build $GITHUB_WORKSPACE/build --target install -j 3
+
+ build-windows-conda-csharp-only:
+ runs-on: windows-latest
+ env:
+ architecture: x64
+ generator: Visual Studio 16 2019
+
+ steps:
+ # To avoid git clone to mess with the line endings of GDAL autotest data
+ # files that look like text, but should be handled as binary content
+ - name: Set git core.autocrlf to false
+ run: |
+ git config --global core.autocrlf false
+ - name: Checkout GDAL
+ uses: actions/checkout@v2
+ - uses: conda-incubator/setup-miniconda@v2
+ with:
+ activate-environment: gdalenv
+ python-version: 3.7
+ channels: conda-forge
+ - name: Install dependency
+ shell: bash -l {0}
+ run: |
+ conda install --yes --quiet --name gdalenv curl libiconv icu git python=3.7 swig numpy pytest pytest-env zlib clcache lxml
+ conda install --yes --quiet --name gdalenv -c conda-forge libgdal
+ - name: Configure
+ shell: bash -l {0}
+ run: |
+ mkdir -p $GITHUB_WORKSPACE/build
+ cmake -A ${architecture} -G "${generator}" -DGDAL_CSHARP_ONLY=ON -DCMAKE_C_FLAGS=" /WX" -DCMAKE_CXX_FLAGS=" /WX" -S "$GITHUB_WORKSPACE" -B "$GITHUB_WORKSPACE/build"
+ - name: Build
+ shell: bash -l {0}
+ run: cmake --build $GITHUB_WORKSPACE/build --config Release --target csharp_samples -j 2
+ - name: test (with ctest)
+ shell: bash -l {0}
+ run: |
+ ctest --test-dir $GITHUB_WORKSPACE/build -C Release -V -j 3 -R "^csharp.*"
+ env:
+ SKIP_OGR_GMLAS_HUGE_PROCESSING_TIME: YES
diff --git a/cmake/modules/thirdparty/DotnetImports.props.in b/cmake/modules/thirdparty/DotnetImports.props.in
new file mode 100644
index 000000000000..74f35a551f2c
--- /dev/null
+++ b/cmake/modules/thirdparty/DotnetImports.props.in
@@ -0,0 +1,7 @@
+
+
+ ${_DN_OUTPUT_PATH}/
+ ${_DN_VERSION}
+ ${_DN_CUSTOM_BUILDPROPS}
+
+
\ No newline at end of file
diff --git a/cmake/modules/thirdparty/FindCSharp.cmake b/cmake/modules/thirdparty/FindCSharp.cmake
index f67e753406f4..835952ed390d 100644
--- a/cmake/modules/thirdparty/FindCSharp.cmake
+++ b/cmake/modules/thirdparty/FindCSharp.cmake
@@ -1,6 +1,9 @@
#
# A CMake Module for finding and using C# (.NET and Mono).
#
+#The following variables are consumed:
+# CSHARP_MONO - set to yes to force the use of Mono. Default is look for .NET first
+#
# The following variables are set:
# CSHARP_FOUND - set to ON if C# is found
# CSHARP_USE_FILE - the path to the C# use file
@@ -16,8 +19,6 @@
# Copyright (c) 2006-2010 Mathieu Malaterre
#
-# TODO: ADD ABILITY TO SELECT WHICH C# COMPILER eg. .NET or Mono (if both exist). For the moment, .NET is selected above Mono.
-
# Make sure find package macros are included
include( FindPackageHandleStandardArgs )
@@ -33,19 +34,19 @@ if( NOT ${CSHARP_PLATFORM} MATCHES "x86|x64|anycpu|itanium" )
message( FATAL_ERROR "The C# target platform '${CSHARP_PLATFORM}' is not valid. Please enter one of the following: x86, x64, anycpu, or itanium" )
endif( )
-if( WIN32 )
- find_package( DotNetFrameworkSdk )
- if( NOT CSHARP_DOTNET_FOUND )
- find_package( Mono )
- endif( )
-else( UNIX )
+if( CSHARP_MONO )
find_package( Mono )
-endif( )
+else()
+ find_package( Dotnet )
+ if( NOT DOTNET_FOUND )
+ find_package( Mono )
+ endif()
+endif()
-if( CSHARP_DOTNET_FOUND )
+if( DOTNET_FOUND )
set( CSHARP_TYPE ".NET" CACHE STRING "Using the .NET compiler" )
- set( CSHARP_VERSION ${CSHARP_DOTNET_VERSION} CACHE STRING "C# .NET compiler version" FORCE )
- set( CSHARP_COMPILER ${CSHARP_DOTNET_COMPILER_${CSHARP_DOTNET_VERSION}} CACHE STRING "Full path to .NET compiler" FORCE )
+ set( CSHARP_VERSION ${DOTNET_VERSION} CACHE STRING "C# .NET compiler version" FORCE )
+ set( CSHARP_COMPILER ${DOTNET_EXE} CACHE STRING "Full path to .NET compiler" FORCE )
set( CSHARP_INTERPRETER "" CACHE INTERNAL "Interpreter not required for .NET" FORCE )
elseif( CSHARP_MONO_FOUND )
set( CSHARP_TYPE "Mono" CACHE STRING "Using the Mono compiler" )
diff --git a/cmake/modules/thirdparty/FindDotNetFrameworkSdk.cmake b/cmake/modules/thirdparty/FindDotNetFrameworkSdk.cmake
deleted file mode 100644
index 3d84a536c878..000000000000
--- a/cmake/modules/thirdparty/FindDotNetFrameworkSdk.cmake
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# A CMake Module for finding C# .NET.
-#
-# The following variables are set:
-# CSHARP_DOTNET_FOUND
-# CSHARP_DOTNET_COMPILER_${version} eg. "CSHARP_DOTNET_COMPILER_v4.0.30319"
-# CSHARP_DOTNET_VERSION eg. "v4.0.30319"
-# CSHARP_DOTNET_VERSIONS eg. "v2.0.50727, v3.5, v4.0.30319"
-# DotNetFrameworkSdk_USE_FILE
-#
-# Additional references can be found here:
-# .NET SDK 1.1: http://www.microsoft.com/downloads/details.aspx?FamilyID=9b3a2ca6-3647-4070-9f41-a333c6b9181d&displaylang=en
-# .NET SDK 2.0: http://www.microsoft.com/downloads/details.aspx?FamilyID=fe6f2099-b7b4-4f47-a244-c96d69c35dec&displaylang=en
-# .NET SDK 3.5: http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en
-# C# Compiler options: http://msdn.microsoft.com/en-us/library/2fdbz5xd(v=VS.71).aspx
-#
-# This file is based on the work of GDCM:
-# http://gdcm.svn.sf.net/viewvc/gdcm/trunk/CMake/FindDotNETFrameworkSDK.cmake
-# Copyright (c) 2006-2010 Mathieu Malaterre
-#
-
-set( csharp_dotnet_valid 1 )
-if( DEFINED CSHARP_DOTNET_FOUND )
- # The .NET compiler has already been found
- # It may have been reset by the user, verify it is correct
- if( NOT DEFINED CSHARP_DOTNET_COMPILER_${CSHARP_DOTNET_VERSION} )
- set( csharp_dotnet_version_user ${CSHARP_DOTNET_VERSION} )
- set( csharp_dotnet_valid 0 )
- set( CSHARP_DOTNET_FOUND 0 )
- set( CSHARP_DOTNET_VERSION "CSHARP_DOTNET_VERSION-NOTVALID" CACHE STRING "C# .NET compiler version, choices: ${CSHARP_DOTNET_VERSIONS}" FORCE )
- message( FATAL_ERROR "The C# .NET version '${csharp_dotnet_version_user}' is not valid. Please enter one of the following: ${CSHARP_DOTNET_VERSIONS}" )
- endif( )
-endif( )
-
-unset( CSHARP_DOTNET_VERSIONS CACHE ) # Clear versions
-
-# Get the framework directory based on platform
-if( ${CSHARP_PLATFORM} MATCHES "x64|itanium" )
- set( csharp_dotnet_framework_dir "$ENV{windir}/Microsoft.NET/Framework64" )
-else( )
- set( csharp_dotnet_framework_dir "$ENV{windir}/Microsoft.NET/Framework" )
-endif( )
-
-# Search for .NET versions
-string( REPLACE "\\" "/" csharp_dotnet_framework_dir ${csharp_dotnet_framework_dir} )
-file( GLOB_RECURSE csharp_dotnet_executables "${csharp_dotnet_framework_dir}/csc.exe" )
-list( SORT csharp_dotnet_executables )
-list( REVERSE csharp_dotnet_executables )
-foreach ( csharp_dotnet_executable ${csharp_dotnet_executables} )
- if( csharp_dotnet_valid )
- # Extract version number (eg. v4.0.30319)
- # TODO: Consider using REGEX
- string( REPLACE "${csharp_dotnet_framework_dir}/" "" csharp_dotnet_version_temp ${csharp_dotnet_executable} )
- string( REPLACE "/csc.exe" "" csharp_dotnet_version_temp ${csharp_dotnet_version_temp} )
-
- # Add variable holding executable
- set( CSHARP_DOTNET_COMPILER_${csharp_dotnet_version_temp} ${csharp_dotnet_executable} CACHE STRING "C# .NET compiler ${csharp_dotnet_version}" FORCE )
- mark_as_advanced( CSHARP_DOTNET_COMPILER_${csharp_dotnet_version_temp} )
- endif( )
-
- # Create a list of supported compiler versions
- if( NOT DEFINED CSHARP_DOTNET_VERSIONS )
- set( CSHARP_DOTNET_VERSIONS "${csharp_dotnet_version_temp}" CACHE STRING "Available C# .NET compiler versions" FORCE )
- else( )
- set( CSHARP_DOTNET_VERSIONS "${CSHARP_DOTNET_VERSIONS}, ${csharp_dotnet_version_temp}" CACHE STRING "Available C# .NET compiler versions" FORCE )
- endif( )
- mark_as_advanced( CSHARP_DOTNET_VERSIONS )
-
- # We found at least one .NET compiler version
- set( CSHARP_DOTNET_FOUND 1 CACHE INTERNAL "Boolean indicating if C# .NET was found" )
-endforeach( csharp_dotnet_executable )
-
-if( CSHARP_DOTNET_FOUND )
- # Report the found versions
- message( STATUS "Found the following C# .NET versions: ${CSHARP_DOTNET_VERSIONS}" )
-
- # Set the compiler version
- # Do not force, so that the user can manually select their own version if they wish
- if ( DEFINED CSHARP_DOTNET_COMPILER_v2.0.50727 )
- # If available, select .NET v2.0.50727 (this is the minimal version as it supports generics, and allows use of VS2008)
- set( CSHARP_DOTNET_VERSION "v2.0.50727" CACHE STRING "C# .NET compiler version" )
- else( )
- # Select the highest version (first in reverse sorted list)
- list( GET CSHARP_DOTNET_VERSIONS 0 csharp_dotnet_version_temp )
- set( CSHARP_DOTNET_VERSION ${csharp_dotnet_version_temp} CACHE STRING "C# .NET compiler version" )
- endif( )
- mark_as_advanced( CSHARP_DOTNET_VERSION )
-endif( )
-
-# Set USE_FILE
-get_filename_component( current_list_path ${CMAKE_CURRENT_LIST_FILE} PATH )
-set( DotNetFrameworkSdk_USE_FILE ${current_list_path}/UseDotNetFrameworkSdk.cmake )
diff --git a/cmake/modules/thirdparty/FindDotnet.cmake b/cmake/modules/thirdparty/FindDotnet.cmake
new file mode 100644
index 000000000000..f088e7f0bdf5
--- /dev/null
+++ b/cmake/modules/thirdparty/FindDotnet.cmake
@@ -0,0 +1,483 @@
+#.rst
+# from https://github.com/microsoft/GraphEngine/blob/master/cmake/FindDotnet.cmake
+# published under MIT licence https://github.com/microsoft/GraphEngine/blob/master/LICENSE.md
+# edited 2021 Paul Harwood
+#
+# FindDotnet
+# ----------
+#
+# Find DotNet executable, and initialize functions for adding dotnet projects.
+#
+# Results are reported in the following variables::
+#
+# DOTNET_FOUND - True if dotnet executable is found
+# DOTNET_EXE - Dotnet executable
+# DOTNET_VERSION - Dotnet version as reported by dotnet executable
+# NUGET_EXE - Nuget executable (WIN32 only)
+# NUGET_CACHE_PATH - Nuget package cache path
+#
+# The following functions are defined to add dotnet/msbuild projects:
+#
+# ADD_DOTNET -- add a project to be built by dotnet.
+#
+# ```
+# ADD_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU]
+# [CONFIG configuration]
+# [PLATFORM platform]
+# [PACKAGE nuget_package_dependencies... ]
+# [VERSION nuget_package_version]
+# [DEPENDS depend_nuget_packages... ]
+# [OUTPUT_PATH output_path]
+# [CUSTOM_BUILDPROPS value....]
+# [SOURCES additional_csproj_dependencies... ]
+# [ARGUMENTS additional_build_args...]
+# [PACK_ARGUMENTS additional_pack_args...])
+# ```
+#
+# RUN_DOTNET -- Run a project with `dotnet run`. The `OUTPUT` argument represents artifacts
+# produced by running the .NET program, and can be consumed from other build steps.
+#
+# ```
+# RUN_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU]
+# [ARGUMENTS program_args...]
+# [OUTPUT outputs...]
+# [CONFIG configuration]
+# [PLATFORM platform]
+# [DEPENDS depend_nuget_packages... ]
+# [OUTPUT_PATH output_path relative to cmake binary output dir]
+# [CUSTOM_BUILDPROPS value....]
+# [SOURCES additional_file_dependencies... ])
+# ```
+#
+# ADD_MSBUILD -- add a project to be built by msbuild. Windows-only. When building in Unix systems, msbuild targets are skipped.
+#
+# ```
+# ADD_MSBUILD( [RELEASE|DEBUG] [X86|X64|ANYCPU]
+# [CONFIG configuration]
+# [PLATFORM platform]
+# [PACKAGE output_nuget_packages... ]
+# [DEPENDS depend_nuget_packages... ]
+# [CUSTOM_BUILDPROPS value....]
+# [SOURCES additional_file_dependencies... ]
+# [ARGUMENTS additional_build_args...]
+# [PACK_ARGUMENTS additional_pack_args...])
+# ```
+#
+# SMOKETEST_DOTNET -- add a dotnet smoke test project to the build. The project will be run during a build,
+# and if the program fails to build or run, the build fails. Currently only .NET Core App framework is supported.
+# Multiple smoke tests will be run one-by-one to avoid global resource conflicts.
+#
+# SMOKETEST_DOTNET( [RELEASE|DEBUG] [X86|X64|ANYCPU]
+# [ARGUMENTS program_args...]
+# [CONFIG configuration]
+# [PLATFORM platform]
+# [DEPENDS depend_nuget_packages... ]
+# [OUTPUT_PATH output_path relative to cmake binary output dir]
+# [CUSTOM_BUILDPROPS value....]
+# [SOURCES additional_file_dependencies... ])
+#
+# For all the above functions, `RELEASE|DEBUG` overrides `CONFIG`, `X86|X64|ANYCPU` overrides PLATFORM.
+#
+#
+# DOTNET_REGISTER_LOCAL_REPOSITORY -- register a local NuGet package repository.
+#
+# ```
+# DOTNET_REGISTER_LOCAL_REPOSITORY(repo_name repo_path)
+# ```
+#
+# TEST_DOTNET -- add a dotnet test project to ctest. The project will be run with `dotnet test`,
+# and trx test reports will be generated in the build directory. For Windows, all target frameworks
+# are tested against. For other platforms, only .NET Core App is tested against.
+# Test failures will not fail the build.
+# Tests are only run with `ctest -C `, not with `cmake --build ...`
+#
+# ```
+# TEST_DOTNET(
+# [ARGUMENTS additional_dotnet_test_args...]
+# [OUTPUT_PATH output_path relative to cmake binary output dir])
+# ```
+#
+# GEN_DOTNET_PROPS -- Generates a Directory.Build.props file. The created file is populated with MSBuild properties:
+# - DOTNET_PACKAGE_VERSION: a version string that can be referenced in the actual project file as $(DOTNET_PACKAGE_VERSION).
+# The version string value can be set with PACKAGE_VERSION argument, and defaults to '1.0.0'.
+# - XPLAT_LIB_DIR: points to the cmake build root directory.
+# - OutputPath: Points to the cmake binary directory (overridden by OUTPUT_PATH, relatively). Therefore, projects built without cmake will consistently output
+# to the cmake build directory.
+# - Custom properties can be injected with XML_INJECT argument, which injects an arbitrary string into the project XML file.
+#
+# ```
+# GEN_DOTNET_PROPS(
+# [PACKAGE_VERSION version]
+# [XML_INJECT xml_injection])
+# ```
+#
+# Require 3.5 for batch copy multiple files
+
+cmake_minimum_required(VERSION 3.5.0)
+
+IF(DOTNET_FOUND)
+ RETURN()
+ENDIF()
+
+SET(NUGET_CACHE_PATH "~/.nuget/packages")
+FIND_PROGRAM(DOTNET_EXE dotnet)
+SET(DOTNET_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+IF(NOT DOTNET_EXE)
+ SET(DOTNET_FOUND FALSE)
+ IF(Dotnet_FIND_REQUIRED)
+ MESSAGE(SEND_ERROR "Command 'dotnet' is not found.")
+ ENDIF()
+ RETURN()
+ENDIF()
+
+EXECUTE_PROCESS(
+ COMMAND ${DOTNET_EXE} --version
+ OUTPUT_VARIABLE DOTNET_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+IF(WIN32)
+ FIND_PROGRAM(NUGET_EXE nuget PATHS ${CMAKE_BINARY_DIR}/tools)
+ IF(NUGET_EXE)
+ MESSAGE("-- Found nuget: ${NUGET_EXE}")
+ ELSE()
+ SET(NUGET_EXE ${CMAKE_BINARY_DIR}/tools/nuget.exe)
+ MESSAGE("-- Downloading nuget...")
+ FILE(DOWNLOAD https://dist.nuget.org/win-x86-commandline/latest/nuget.exe ${NUGET_EXE})
+ MESSAGE("nuget.exe downloaded and saved to ${NUGET_EXE}")
+ ENDIF()
+ENDIF()
+
+FUNCTION(DOTNET_REGISTER_LOCAL_REPOSITORY repo_name repo_path)
+ MESSAGE("-- Registering NuGet local repository '${repo_name}' at '${repo_path}'.")
+ GET_FILENAME_COMPONENT(repo_path ${repo_path} ABSOLUTE)
+ IF(WIN32)
+ STRING(REPLACE "/" "\\" repo_path ${repo_path})
+ EXECUTE_PROCESS(COMMAND ${NUGET_EXE} sources list OUTPUT_QUIET)
+ EXECUTE_PROCESS(COMMAND ${NUGET_EXE} sources Remove -Name "${repo_name}" OUTPUT_QUIET ERROR_QUIET)
+ EXECUTE_PROCESS(COMMAND ${NUGET_EXE} sources Add -Name "${repo_name}" -Source "${repo_path}")
+ ELSE()
+ GET_FILENAME_COMPONENT(nuget_config ~/.nuget/NuGet/NuGet.Config ABSOLUTE)
+ EXECUTE_PROCESS(COMMAND ${DOTNET_EXE} nuget locals all --list OUTPUT_QUIET)
+ EXECUTE_PROCESS(COMMAND sed -e "/${repo_name}/d" -i'' "${nuget_config}")
+ EXECUTE_PROCESS(COMMAND sed -e "s## \\n #g" -i'' "${nuget_config}")
+ ENDIF()
+ENDFUNCTION()
+
+FUNCTION(DOTNET_GET_DEPS _DN_PROJECT arguments)
+ CMAKE_PARSE_ARGUMENTS(
+ # prefix
+ _DN
+ # options (flags)
+ "RELEASE;DEBUG;X86;X64;ANYCPU;NETCOREAPP"
+ # oneValueArgs
+ "NAME;CONFIG;PLATFORM;VERSION;OUTPUT_PATH"
+ # multiValueArgs
+ "PACKAGE;DEPENDS;ARGUMENTS;PACK_ARGUMENTS;OUTPUT;SOURCES;CUSTOM_BUILDPROPS,BUILD_OPTIONS"
+ # the input arguments
+ ${arguments})
+
+ GET_FILENAME_COMPONENT(_DN_abs_proj "${_DN_PROJECT}" ABSOLUTE)
+ GET_FILENAME_COMPONENT(_DN_proj_dir "${_DN_abs_proj}" DIRECTORY)
+ GET_FILENAME_COMPONENT(_DN_projname "${_DN_PROJECT}" NAME)
+ STRING(REGEX REPLACE "\\.[^.]*$" "" _DN_projname_noext ${_DN_projname})
+
+ FILE(GLOB_RECURSE DOTNET_deps
+ ${_DN_proj_dir}/*.cs
+ ${_DN_proj_dir}/*.fs
+ ${_DN_proj_dir}/*.vb
+ ${_DN_proj_dir}/*.xaml
+ ${_DN_proj_dir}/*.resx
+ ${_DN_proj_dir}/*.xml
+ ${_DN_proj_dir}/*.*proj
+ ${_DN_proj_dir}/*.cs
+ ${_DN_proj_dir}/*.config)
+ LIST(APPEND DOTNET_deps ${_DN_SOURCES})
+ SET(_DN_deps "")
+ FOREACH(dep ${DOTNET_deps})
+ IF(NOT dep MATCHES /obj/ AND NOT dep MATCHES /bin/)
+ LIST(APPEND _DN_deps ${dep})
+ ENDIF()
+ ENDFOREACH()
+
+
+ IF(_DN_RELEASE)
+ SET(_DN_CONFIG Release)
+ ELSEIF(_DN_DEBUG)
+ SET(_DN_CONFIG Debug)
+ ENDIF()
+
+ IF(NOT _DN_CONFIG)
+ SET(_DN_CONFIG "$<$:Debug>$<$>:Release>")
+ ENDIF()
+
+ # If platform is not specified, do not pass the Platform property.
+ # dotnet will pick the default Platform.
+
+ IF(_DN_X86)
+ SET(_DN_PLATFORM x86)
+ ELSEIF(_DN_X64)
+ SET(_DN_PLATFORM x64)
+ ELSEIF(_DN_ANYCPU)
+ SET(_DN_PLATFORM "AnyCPU")
+ ENDIF()
+
+ # If package version is not set, first fallback to DOTNET_PACKAGE_VERSION
+ # If again not set, defaults to 1.0.0
+ IF(NOT _DN_VERSION)
+ SET(_DN_VERSION ${DOTNET_PACKAGE_VERSION})
+ ENDIF()
+ IF(NOT _DN_VERSION)
+ SET(_DN_VERSION "1.0.0")
+ ENDIF()
+
+ # Set the output path to the binary directory.
+ # Build outputs in separated output directories prevent overwriting.
+ # Later we then copy the outputs to the destination.
+
+ IF(NOT _DN_OUTPUT_PATH)
+ SET(_DN_OUTPUT_PATH ${_DN_projname_noext})
+ ENDIF()
+
+ GET_FILENAME_COMPONENT(_DN_OUTPUT_PATH ${_DN_OUTPUT_PATH} ABSOLUTE)
+
+ # In a cmake build, the XPLAT libraries are always copied over.
+ # Set the proper directory for .NET projects.
+ SET(_DN_XPLAT_LIB_DIR ${CMAKE_BINARY_DIR})
+
+ SET(DOTNET_PACKAGES ${_DN_PACKAGE} PARENT_SCOPE)
+ SET(DOTNET_CONFIG ${_DN_CONFIG} PARENT_SCOPE)
+ SET(DOTNET_PLATFORM ${_DN_PLATFORM} PARENT_SCOPE)
+ SET(DOTNET_DEPENDS ${_DN_DEPENDS} PARENT_SCOPE)
+ SET(DOTNET_SOURCES ${_DN_SOURCES} PARENT_SCOPE)
+ if(_DN_NAME)
+ SET(DOTNET_PROJNAME ${_DN_NAME} PARENT_SCOPE)
+ else()
+ SET(DOTNET_PROJNAME ${_DN_projname_noext} PARENT_SCOPE)
+ endif()
+ SET(DOTNET_PROJPATH ${_DN_abs_proj} PARENT_SCOPE)
+ SET(DOTNET_PROJDIR ${_DN_proj_dir} PARENT_SCOPE)
+ SET(DOTNET_ARGUMENTS ${_DN_ARGUMENTS} PARENT_SCOPE)
+ SET(DOTNET_RUN_OUTPUT ${_DN_OUTPUT} PARENT_SCOPE)
+ SET(DOTNET_PACKAGE_VERSION ${_DN_VERSION} PARENT_SCOPE)
+ SET(DOTNET_OUTPUT_PATH ${_DN_OUTPUT_PATH} PARENT_SCOPE)
+ SET(DOTNET_deps ${_DN_deps} PARENT_SCOPE)
+
+ IF(_DN_PLATFORM)
+ SET(_DN_PLATFORM_PROP "/p:Platform=${_DN_PLATFORM}")
+ ENDIF()
+
+ SET(_DN_IMPORT_PROP ${CMAKE_CURRENT_BINARY_DIR}/${_DN_projname}.imports.props)
+ CONFIGURE_FILE(${DOTNET_MODULE_DIR}/DotnetImports.props.in ${_DN_IMPORT_PROP})
+ SET(_DN_IMPORT_ARGS "/p:DirectoryBuildPropsPath=${_DN_IMPORT_PROP}")
+
+ SET(DOTNET_IMPORT_PROPERTIES ${_DN_IMPORT_ARGS} PARENT_SCOPE)
+ SET(DOTNET_BUILD_PROPERTIES ${_DN_PLATFORM_PROP} ${_DN_IMPORT_ARGS} PARENT_SCOPE)
+ SET(DOTNET_BUILD_OPTIONS ${_DN_BUILD_OPTIONS} PARENT_SCOPE)
+ SET(DOTNET_PACK_OPTIONS --include-symbols ${_DN_PACK_OPTIONS} ${_DN_PACK_ARGUMENTS} PARENT_SCOPE)
+
+ENDFUNCTION()
+
+MACRO(ADD_DOTNET_DEPENDENCY_TARGETS )
+ FOREACH(dep ${DOTNET_DEPENDS})
+ ADD_DEPENDENCIES(${DOTNET_PROJNAME} ${dep})
+ if(CMAKE_VERBOSE_MAKEFILE)
+ MESSAGE(" ${DOTNET_PROJNAME} has dependency ${dep}")
+ endif()
+ ENDFOREACH()
+
+ FOREACH(pkg ${DOTNET_PACKAGES})
+ if( NOT( TARGET DOTNET_PURGE_${pkg} ) )
+ STRING(TOLOWER ${pkg} pkg_lowercase)
+ GET_FILENAME_COMPONENT(cache_path ${NUGET_CACHE_PATH}/${pkg_lowercase} ABSOLUTE)
+ IF(WIN32)
+ SET(rm_command powershell -NoLogo -NoProfile -NonInteractive -Command "Remove-Item -Recurse -Force -ErrorAction Ignore '${cache_path}'\; exit 0")
+ ELSE()
+ SET(rm_command rm -rf ${cache_path})
+ ENDIF()
+ ADD_CUSTOM_TARGET(
+ DOTNET_PURGE_${pkg}
+ COMMAND ${CMAKE_COMMAND} -E echo "======= [x] Purging nuget package cache for ${pkg}"
+ COMMAND ${rm_command}
+ DEPENDS ${DOTNET_deps}
+ )
+ endif ( NOT( TARGET DOTNET_PURGE_${pkg} ) )
+ ADD_DEPENDENCIES(${DOTNET_PROJNAME} DOTNET_PURGE_${pkg})
+ if(CMAKE_VERBOSE_MAKEFILE)
+ MESSAGE("==== ${DOTNET_PROJNAME} uses nuget package ${pkg}")
+ endif()
+ ENDFOREACH()
+ENDMACRO()
+
+MACRO(DOTNET_BUILD_COMMANDS)
+ IF(${DOTNET_IS_MSBUILD})
+ SET(build_dotnet_cmds
+ COMMAND ${CMAKE_COMMAND} -E echo "======= Building msbuild project ${DOTNET_PROJNAME} [${DOTNET_CONFIG} ${DOTNET_PLATFORM}]"
+ COMMAND ${NUGET_EXE} restore -Force ${DOTNET_PROJPATH}
+ COMMAND ${DOTNET_EXE} msbuild ${DOTNET_PROJPATH} /t:Clean ${DOTNET_BUILD_PROPERTIES} /p:Configuration="${DOTNET_CONFIG}"
+ COMMAND ${DOTNET_EXE} msbuild ${DOTNET_PROJPATH} /t:Build ${DOTNET_BUILD_PROPERTIES} /p:Configuration="${DOTNET_CONFIG}" ${DOTNET_ARGUMENTS})
+ SET(build_dotnet_type "msbuild")
+ ELSE()
+ SET(build_dotnet_cmds
+ COMMAND ${CMAKE_COMMAND} -E echo "======= Building .NET project ${DOTNET_PROJNAME} [${DOTNET_CONFIG} ${DOTNET_PLATFORM}]")
+ foreach (_src ${DOTNET_SOURCES} )
+ LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} add ${DOTNET_PROJPATH} reference ${_src})
+ endforeach ()
+ foreach ( _pkg ${DOTNET_PACKAGES} )
+ set(_ADD_PROPERTIES)
+ if ( _pkg MATCHES "^OSGeo*.")
+ set(_ADD_PROPERTIES --version "${DOTNET_PACKAGE_VERSION}")
+ endif()
+ LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} add ${DOTNET_PROJPATH} package ${_ADD_PROPERTIES} ${_pkg})
+ endforeach()
+ LIST(APPEND build_dotnet_cmds
+ COMMAND ${DOTNET_EXE} clean ${DOTNET_PROJPATH} ${DOTNET_BUILD_PROPERTIES}
+ COMMAND ${DOTNET_EXE} build -c ${DOTNET_CONFIG} ${DOTNET_BUILD_PROPERTIES} ${DOTNET_BUILD_OPTIONS} ${DOTNET_ARGUMENTS} ${DOTNET_PROJPATH})
+ SET(build_dotnet_type "dotnet")
+ ENDIF()
+
+ # DOTNET_OUTPUTS refer to artifacts produced, that the proj_name target depends on.
+ SET(DOTNET_OUTPUTS)
+ if(CMAKE_VERBOSE_MAKEFILE)
+ IF(NOT DOTNET_PACKAGES})
+ MESSAGE("-- Adding ${build_dotnet_type} project ${DOTNET_PROJPATH} (version ${DOTNET_PACKAGE_VERSION})")
+ ELSE()
+ MESSAGE("-- Adding ${build_dotnet_type} project ${DOTNET_PROJPATH} (no nupkg)")
+ ENDIF()
+ endif()
+
+ LIST(APPEND build_dotnet_cmds COMMAND ${DOTNET_EXE} pack
+ --no-build --no-restore ${DOTNET_PROJPATH}
+ -c ${DOTNET_CONFIG} ${DOTNET_BUILD_PROPERTIES} ${DOTNET_PACK_OPTIONS}
+ --output ${CMAKE_CURRENT_BINARY_DIR} -p:PackageVersion=${DOTNET_PACKAGE_VERSION} )
+ LIST(APPEND DOTNET_OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.buildtimestamp)
+ LIST(APPEND build_dotnet_cmds COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.buildtimestamp)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${DOTNET_OUTPUTS}
+ VERBATIM
+ DEPENDS ${DOTNET_deps} ${DOTNET_PROJPATH}
+ ${build_dotnet_cmds}
+ )
+ ADD_CUSTOM_TARGET(
+ ${DOTNET_PROJNAME} ALL
+ DEPENDS ${DOTNET_OUTPUTS})
+
+ENDMACRO()
+
+FUNCTION(ADD_DOTNET DOTNET_PROJECT)
+ DOTNET_GET_DEPS(${DOTNET_PROJECT} "${ARGN}")
+ SET(DOTNET_IS_MSBUILD FALSE)
+ DOTNET_BUILD_COMMANDS()
+ ADD_DOTNET_DEPENDENCY_TARGETS()
+ENDFUNCTION()
+
+FUNCTION(ADD_MSBUILD DOTNET_PROJECT)
+ IF(NOT WIN32)
+ MESSAGE("-- Building non-Win32, skipping ${DOTNET_PROJECT}")
+ RETURN()
+ ENDIF()
+
+ DOTNET_GET_DEPS(${DOTNET_PROJECT} "${ARGN}")
+ SET(DOTNET_IS_MSBUILD TRUE)
+ DOTNET_BUILD_COMMANDS()
+ ADD_DOTNET_DEPENDENCY_TARGETS()
+ENDFUNCTION()
+
+FUNCTION(RUN_DOTNET DOTNET_PROJECT)
+ DOTNET_GET_DEPS(${DOTNET_PROJECT} "${ARGN};NETCOREAPP")
+ MESSAGE("-- Adding dotnet run project ${DOTNET_PROJECT}")
+ FILE(MAKE_DIRECTORY ${DOTNET_OUTPUT_PATH})
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp ${DOTNET_RUN_OUTPUT}
+ DEPENDS ${DOTNET_deps}
+ COMMAND ${DOTNET_EXE} restore ${DOTNET_PROJPATH} ${DOTNET_IMPORT_PROPERTIES}
+ COMMAND ${DOTNET_EXE} clean ${DOTNET_PROJPATH} ${DOTNET_BUILD_PROPERTIES}
+ COMMAND ${DOTNET_EXE} build --no-restore ${DOTNET_PROJPATH} -c ${DOTNET_CONFIG} ${DOTNET_BUILD_PROPERTIES} ${DOTNET_BUILD_OPTIONS}
+ # XXX tfm
+ COMMAND ${DOTNET_EXE} ${DOTNET_OUTPUT_PATH}/netcoreapp3.1/${DOTNET_PROJNAME}.dll ${DOTNET_ARGUMENTS}
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp
+ WORKING_DIRECTORY ${DOTNET_OUTPUT_PATH})
+ ADD_CUSTOM_TARGET(
+ ${DOTNET_PROJNAME}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp ${DOTNET_RUN_OUTPUT})
+ ADD_DOTNET_DEPENDENCY_TARGETS()
+ENDFUNCTION()
+
+FUNCTION(TEST_DOTNET DOTNET_PROJECT)
+ DOTNET_GET_DEPS(${DOTNET_PROJECT} "${ARGN}")
+ MESSAGE("-- Adding dotnet test project ${DOTNET_PROJECT}")
+ IF(WIN32)
+ SET(test_framework_args "")
+ ELSE()
+ SET(test_framework_args -f netcoreapp3.1)
+ ENDIF()
+
+ ADD_TEST(NAME ${DOTNET_PROJNAME}
+ COMMAND ${DOTNET_EXE} test ${test_framework_args} --results-directory "${CMAKE_BINARY_DIR}" --logger trx ${DOTNET_ARGUMENTS}
+ WORKING_DIRECTORY ${DOTNET_OUTPUT_PATH})
+
+ENDFUNCTION()
+
+SET_PROPERTY(GLOBAL PROPERTY DOTNET_LAST_SMOKETEST "")
+
+FUNCTION(SMOKETEST_DOTNET DOTNET_PROJECT)
+ MESSAGE("-- Adding dotnet smoke test project ${DOTNET_PROJECT}")
+ IF(WIN32)
+ RUN_DOTNET(${DOTNET_PROJECT} "${ARGN}")
+ ELSE()
+ RUN_DOTNET(${DOTNET_PROJECT} "${ARGN}")
+ ENDIF()
+
+ DOTNET_GET_DEPS(${DOTNET_PROJECT} "${ARGN}")
+ ADD_CUSTOM_TARGET(
+ ${DOTNET_PROJNAME}
+ ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOTNET_PROJNAME}.runtimestamp)
+ ADD_DOTNET_DEPENDENCY_TARGETS()
+ GET_PROPERTY(_dn_last_smoketest GLOBAL PROPERTY DOTNET_LAST_SMOKETEST)
+ IF(_dn_last_smoketest)
+ MESSAGE("${_dn_last_smoketest} -> SMOKETEST_${DOTNET_PROJNAME}")
+ ADD_DEPENDENCIES(${DOTNET_PROJNAME} ${_dn_last_smoketest})
+ ENDIF()
+ # Chain the smoke tests together so they are executed sequentially
+ SET_PROPERTY(GLOBAL PROPERTY DOTNET_LAST_SMOKETEST SMOKETEST_${DOTNET_PROJNAME})
+
+ENDFUNCTION()
+
+SET(DOTNET_IMPORTS_TEMPLATE ${CMAKE_CURRENT_LIST_DIR}/DotnetImports.props.in)
+
+FUNCTION(GEN_DOTNET_PROPS target_props_file)
+ CMAKE_PARSE_ARGUMENTS(
+ # prefix
+ _DNP
+ # options (flags)
+ ""
+ # oneValueArgs
+ "PACKAGE_VERSION;XML_INJECT"
+ # multiValueArgs
+ ""
+ # the input arguments
+ ${ARGN})
+
+ IF(NOT _DNP_PACKAGE_VERSION)
+ SET(_DNP_PACKAGE_VERSION 1.0.0)
+ ENDIF()
+
+ IF(_DNP_XML_INJECT)
+ SET(_DN_CUSTOM_BUILDPROPS ${_DNP_XML_INJECT})
+ ENDIF()
+
+ SET(_DN_OUTPUT_PATH ${CMAKE_BINARY_DIR})
+ SET(_DN_XPLAT_LIB_DIR ${CMAKE_BINARY_DIR})
+ SET(_DN_VERSION ${_DNP_PACKAGE_VERSION})
+ CONFIGURE_FILE(${DOTNET_IMPORTS_TEMPLATE} ${target_props_file})
+ UNSET(_DN_OUTPUT_PATH)
+ UNSET(_DN_XPLAT_LIB_DIR)
+ UNSET(_DN_VERSION)
+ENDFUNCTION()
+
+
+MESSAGE("-- Found .NET toolchain: ${DOTNET_EXE} (version ${DOTNET_VERSION})")
+SET(DOTNET_FOUND TRUE)
\ No newline at end of file
diff --git a/doc/source/api/csharp/csharp_compile_cmake.rst b/doc/source/api/csharp/csharp_compile_cmake.rst
new file mode 100644
index 000000000000..6b795a459e4d
--- /dev/null
+++ b/doc/source/api/csharp/csharp_compile_cmake.rst
@@ -0,0 +1,167 @@
+.. _csharp_compile_cmake:
+
+================================================================================
+Compiling the C# bindings - CMake Scripts
+================================================================================
+
+This page describes the primary steps when creating the GDAL/OGR C# binaries from the source using the new CMake scripts.
+
+In most cases this is not necessary and it is better to use one of the pre-compiled sources, such as `GisInternals `__ or Conda.
+
+You can either build the bindings as part of a full GDAL build - or standalone on top of an existing installation.
+
+Requirements
+++++++++++++
+
+The build environment has the following dependencies:
+
+* CMake 3.10 or later
+* the appropriate C++ build environment (i.e. gcc or Visual Studio etc).
+* SWIG 4
+* .NET 5.0 or Mono
+
+.NET Build Toolchain
+++++++++++++++++++++
+
+The build scipts can use either .NET 5.0 and :file:`dotnet.exe` or Mono and :file:`msc.exe` to compile the bindings.
+
+.NET is used for preference if it found on all platforms but the use of Mono can be forced using a command line variable.
+
+Building as part of a GDAL Build
+++++++++++++++++++++++++++++++++
+
+The build environment uses the following variables:
+
++---------------------------+------------+-----------------------------------------------+
+| CSHARP_MONO | Boolean | Forces the use of Mono |
++---------------------------+------------+-----------------------------------------------+
+| CSHARP_LIBRARY_VERSION | String | Set the .NET version for the shared libraries |
++---------------------------+------------+-----------------------------------------------+
+| CSHARP_APPLICATION_VERSION| String | Set the .NET version for the sample apps |
++---------------------------+------------+-----------------------------------------------+
+| GDAL_CSHARP_ONLY | Boolean | Build standalone on GDAL binaries |
++---------------------------+------------+-----------------------------------------------+
+| BUILD_CSHARP_BINDINGS | Boolean | Build the C# bindings DEFAULT ON |
++---------------------------+------------+-----------------------------------------------+
+
+Building with .NET
+------------------
+
+If the build environment has .NET 5.0 installed and GDAL is built, then the c# bindings will be built using .NET by default.
+
+The details of building GDAL are documented elsewhere, but there are likely to be variants of the following commands run from the root directory of the gdal repository:
+
+.. code-block::
+
+ cmake -DCMAKE_INSTALL_PREFIX ../install -B ../build -S .
+ cmake --build ../build --config Release
+ cmake --build ../build --config Release --target install
+
+The C# bindings and sample apps are installed in the install directory (in the above case that would be `../install`, in the `share/csharp` sub folder. There would be the following files:
+
+* :file:`gdal_csharp.dll`
+* :file:`ogr_csharp.dll`
+* :file:`osr_csharp.dll`
+* :file:`gdalconst_csharp.dll`
+* :file:`gdal_wrap.dll` or :file:`libgdal_wrap.so` or :file:`libgdal_wrap.dylib`
+* :file:`ogr_wrap.dll` or :file:`libogr_wrap.so` or :file:`libogr_wrap.dylib`
+* :file:`osr_wrap.dll` or :file:`libosr_wrap.so` or :file:`libosr_wrap.dylib`
+* :file:`osr_wrap.dll` or :file:`libosr_wrap.so` or :file:`libosr_wrap.dylib`
+* :file:`gdalconst_wrap.dll` or :file:`libgdalconst_wrap.so` or :file:`libgdalconst_wrap.dylib`
+* various sample applications - as \*.exe on Windows, or just as \* on Unix, along with \*.dll for each app and the runtime config files.
+
+There are also subdirectories for each of the sample apps, holding the config files.
+
+There are also the following NuGET packages:
+
+* :file:`OSGeo.GDAL`
+* :file:`OSGeo.OGR`
+* :file:`OSgeo.OSR`
+* :file:`OSGeo.GDAL.CONST`
+* various sample application
+
+Using the .NET Bindings
+-----------------------
+
+The easiest way to use the bindings in developement would be use the NuGET packages created.
+
+To do this you need to add a local repistory pointing to the GDAL install directory. `This is explained here `__ .
+
+Once this is done, you add the GDAL packages into your project as normal.
+
+.. note:: These packages only install the bindings and do not install core GDAL. It is for you as the developer to make sure that the GDAL binaries are available in the search path.
+
+
+.. note:: The NuGET packages are created with the same version number as the version of GDAL in the build system.
+ If you are building in a GIT repository, then the build system automatically makes the version with a x.y.z-dev pre-release tag.
+ This means that to load the package into Visual Studio (for instance), you have to tick the pre-release box.
+ This is all intentional and not a bug.
+
+
+Building on Mono
+----------------
+
+If the build environment does not have .NET 5.0 or msbuild installed and GDAL is built, then the c# bindings will be built using Mono by default. Mono building can also be forced
+by setting CSHARP_MONO.
+
+The details of building GDAL are documented elsewhere, but the there are likely to be variants of the following commands run from the root directory of the gdal repository:
+
+.. code-block::
+
+ cmake -DCMAKE_INSTALL_PREFIX ../install -DCSHARP_MONO=ON -B ../build -S .
+ cmake --build ../build --config Release
+ cmake --build ../build --config Release --target install
+
+The C# bindings and sample apps are installed in the install directory (in the above case that would be `../install`, in the `share/csharp` sub folder. There would be the following files:
+
+* :file:`gdal_csharp.dll`
+* :file:`ogr_csharp.dll`
+* :file:`osr_csharp.dll`
+* :file:`gdalconst_csharp.dll`
+* :file:`gdal_wrap.dll` or :file:`libgdal_wrap.so` or :file:`libgdal_wrap.dylib`
+* :file:`ogr_wrap.dll` or :file:`libogr_wrap.so` or :file:`libogr_wrap.dylib`
+* :file:`osr_wrap.dll` or :file:`libosr_wrap.so` or :file:`libosr_wrap.dylib`
+* :file:`osr_wrap.dll` or :file:`libosr_wrap.so` or :file:`libosr_wrap.dylib`
+* :file:`gdalconst_wrap.dll` or :file:`libgdalconst_wrap.so` or :file:`libgdalconst_wrap.dylib`
+* various sample applications as \*.exe on all platforms.
+
+Using the Mono Bindings
+-----------------------
+
+Note that the bindings created by this process will only work with Mono.
+
+To run one of the prebuilt executables - you can run them with Mono as follows :
+
+:program:`mono GDALInfo.exe`
+
+Both the managed libraries (i.e. the DLLs) and the unmanaged libraries must be available to Mono.
+This is in more detail in `the Mono documentation `__
+
+Building Standalone
++++++++++++++++++++
+
+The Bindings using both the .NET or Mono toolchains can be build on top of an existing implementation of GDAL
+that includes the include files and libs - for instance the Conda distribution.
+
+To do this, Cmake must be run with the GDAL_CSHARP_ONLY flag set and only one of the following targets should be built:
+
+
++--------------------------------+---------------------------------+
+| csharp_binding | Just the bindings |
++--------------------------------+---------------------------------+
+| csharp_samples | The bindings and the sample apps|
++--------------------------------+---------------------------------+
+
+.. note:: Do not build the install target when running standalone, it will fail!
+
+.. note:: Do not run a bare ctest command on this build, it will likely fail! Use something like `ctest -R "^csharp.*"` instead.
+
+As an example:
+
+.. code-block::
+
+ cmake -DGDAL_CSHARP_ONLY=ON -B ../build -S .
+ cmake --build ../build --config Release --target csharp_samples
+
+The output from this build is axactly the same as documented as above, except that the outputs will be in `../build/swig/csharp` and some of the sub folders.
+
diff --git a/doc/source/api/csharp/csharp_compile.rst b/doc/source/api/csharp/csharp_compile_legacy.rst
similarity index 99%
rename from doc/source/api/csharp/csharp_compile.rst
rename to doc/source/api/csharp/csharp_compile_legacy.rst
index a097df791fd5..da817c98207a 100644
--- a/doc/source/api/csharp/csharp_compile.rst
+++ b/doc/source/api/csharp/csharp_compile_legacy.rst
@@ -1,7 +1,7 @@
-.. _csharp_compile:
+.. _csharp_compile_legacy:
================================================================================
-Compiling the C# bindings
+Compiling the C# bindings - Legacy Scripts
================================================================================
This page describes the primary steps when creating the GDAL/OGR C# binaries from the source.
diff --git a/doc/source/api/csharp/index.rst b/doc/source/api/csharp/index.rst
index 12030bad118f..885cd2905d18 100644
--- a/doc/source/api/csharp/index.rst
+++ b/doc/source/api/csharp/index.rst
@@ -44,7 +44,8 @@ Related Documents
.. toctree::
:maxdepth: 1
- csharp_compile
+ csharp_compile_legacy
+ csharp_compile_cmake
csharp_raster
csharp_vector
csharp_usage
diff --git a/gdal.cmake b/gdal.cmake
index 570a0160d33e..ea7fbc863a60 100644
--- a/gdal.cmake
+++ b/gdal.cmake
@@ -26,6 +26,9 @@ option(OGR_BUILD_OPTIONAL_DRIVERS "Whether to build OGR optional drivers by defa
# libgdal shared/satic library generation
option(BUILD_SHARED_LIBS "Set ON to build shared library" ON)
+# Option to set preferred C# compiler
+option(CSHARP_MONO "Whether to force the C# compiler to be Mono" OFF)
+
# ######################################################################################################################
# Detect available warning flags
diff --git a/swig/csharp/CMakeLists.txt b/swig/csharp/CMakeLists.txt
index fabe7ca3944c..ca3a8f98b35f 100644
--- a/swig/csharp/CMakeLists.txt
+++ b/swig/csharp/CMakeLists.txt
@@ -1,4 +1,10 @@
-include(GdalStandardIncludes)
+option(GDAL_CSHARP_ONLY "Compile C# bindings on existing GDAL installation" OFF)
+
+if (GDAL_CSHARP_ONLY)
+ find_package(GDAL REQUIRED)
+else ()
+ include(GdalStandardIncludes)
+endif ()
if (CMAKE_CXX_FLAGS)
string(REPLACE "-Werror" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
@@ -9,16 +15,82 @@ set(GDAL_CSHARP_INSTALL_DIR
"${CMAKE_INSTALL_DATADIR}/csharp"
CACHE PATH "Installation sub-directory for CSharp bindings")
-# function for csharp build
-function (gdal_csharp_dll)
+set(CSHARP_LIBRARY_VERSION
+ "net5.0"
+ CACHE STRING ".NET version to be used for libraries")
+set(CSHARP_APPLICATION_VERSION
+ "net5.0"
+ CACHE STRING ".NET version to be used for the sample Applicatons")
+set(CSHARP_CONFIG
+ "RELEASE"
+ CACHE STRING "Config to be used to compile the C# artefacts > RELEASE|CONFIG")
+
+set(_VERSION_STRING ${GDAL_VERSION_NO_DEV_SUFFIX})
+if (GDAL_DEV_SUFFIX)
+ set(_VERSION_STRING ${_VERSION_STRING}-${GDAL_DEV_SUFFIX})
+endif ()
+
+# based on https://stackoverflow.com/questions/39258250/how-to-detect-if-64-bit-msvc-with-cmake TODO - this not going to
+# cope with ARM architectures
+if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ set(CSHARP_RID "osx-x64")
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(CSHARP_RID "linux-x64")
+elseif ("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64")
+ set(CSHARP_RID "win-x64")
+elseif ("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32")
+ set(CSHARP_RID "win-32")
+endif ()
+
+# needed because of differnces in the packages
+if (DOTNET_FOUND)
+ set(CSHARP_DRAWING "System.Drawing.Common")
+else ()
+ set(CSHARP_DRAWING "System.Drawing")
+endif ()
+
+# setup local NuGet repository
+if (DOTNET_FOUND)
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} _DN_REPO_PATH)
+ dotnet_register_local_repository("local" ${_DN_REPO_PATH})
+endif ()
+
+# Cop[y build files
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gdal.snk ${CMAKE_CURRENT_BINARY_DIR}/gdal.snk COPYONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Directory.Build.props ${CMAKE_CURRENT_BINARY_DIR}/Directory.Build.props
+ COPYONLY)
+
+# Crate some placemarker packages for dependencies
+if (DOTNET_FOUND)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/osgeo.gdal.core.csproj.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/osgeo.gdal.core.csproj")
+ add_dotnet(
+ ${CMAKE_CURRENT_BINARY_DIR}/osgeo.gdal.core.csproj
+ ${CSHARP_CONFIG}
+ NAME
+ OSGeo.GDAL.Core
+ VERSION
+ ${_VERSION_STRING}
+ OUTPUT_PATH
+ ${CMAKE_CURRENT_BINARY_DIR})
+else ()
+ add_custom_target(OSGeo.GDAL.Core)
+endif ()
+
+# function for csharp wrapper build
+function (gdal_csharp_wrap)
+ # Setup
set(_options)
- set(_oneValueArgs WRAPPER SWIG_INTERFACE NAMESPACE TARGET TARGET_SUBDIR)
- set(_multiValueArgs DEPENDS)
+ set(_oneValueArgs WRAPPER SWIG_INTERFACE NAMESPACE TARGET_SUBDIR)
cmake_parse_arguments(_CSHARP "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
set(_CSHARP_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR})
+
+ # Run the SWIG interface build
add_custom_command(
+ # create the sub folde
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_WRAPPER}.cpp
COMMAND ${CMAKE_COMMAND} -E make_directory ${_CSHARP_WORKING_DIRECTORY}
+ # SWIG command
COMMAND
${SWIG_EXECUTABLE} -namespace ${_CSHARP_NAMESPACE} -outdir ${_CSHARP_WORKING_DIRECTORY} -DSWIG2_CSHARP -dllimport
${_CSHARP_WRAPPER} -Wall -I${PROJECT_SOURCE_DIR}/swig/include -I${PROJECT_SOURCE_DIR}/swig/include/csharp
@@ -26,71 +98,207 @@ function (gdal_csharp_dll)
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${GDAL_SWIG_COMMON_INCLUDE} ${PROJECT_SOURCE_DIR}/swig/include/csharp/typemaps_csharp.i
${_CSHARP_SWIG_INTERFACE})
- set_source_files_properties(${_CSHARP_WRAPPER} PROPERTIES GENERATED 1)
+ # add the wrapper dll
+ set_source_files_properties(${_CSHARP_WRAPPER} PROPERTIES GENERATED 1)
add_library(${_CSHARP_WRAPPER} SHARED ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_WRAPPER}.cpp)
- gdal_standard_includes(${_CSHARP_WRAPPER})
- target_link_libraries(${_CSHARP_WRAPPER} PRIVATE $)
-
- set(_depends)
- if (_CSHARP_DEPENDS)
- set(_CSHARP_DEPENDS_ARGS "-DCSHARP_DEPENDS=${_CSHARP_DEPENDS}")
- string(REPLACE ";" "\\;" _CSHARP_DEPENDS_ARGS "${_CSHARP_DEPENDS_ARGS}")
- foreach (_dep IN LISTS _CSHARP_DEPENDS)
- list(APPEND _depends ${CMAKE_CURRENT_BINARY_DIR}/${_dep})
- endforeach ()
+ if (GDAL_CSHARP_ONLY)
+ include_directories(${GDAL_INCLUDE_DIR})
+ target_link_libraries(${_CSHARP_WRAPPER} PRIVATE ${GDAL_LIBRARY})
+ else ()
+ gdal_standard_includes(${_CSHARP_WRAPPER})
+ target_link_libraries(${_CSHARP_WRAPPER} PRIVATE $)
endif ()
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET}
- COMMAND
- ${CMAKE_COMMAND} "-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" "-DBUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}"
- "-DCSHARP_COMPILER=${CSHARP_COMPILER}" "-DCSHARP_TARGET=${_CSHARP_TARGET}" ${_CSHARP_DEPENDS_ARGS}
- "-DTARGET_SUBDIR=${_CSHARP_TARGET_SUBDIR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/build_dll.cmake"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- VERBATIM
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_WRAPPER}.cpp ${_depends} ${CMAKE_CURRENT_BINARY_DIR}/gdal.snk
- ${CMAKE_CURRENT_SOURCE_DIR}/AssemblyInfo.cs)
install(
TARGETS ${_CSHARP_WRAPPER}
COMPONENT csharp
DESTINATION ${GDAL_CSHARP_INSTALL_DIR})
+endfunction (gdal_csharp_wrap)
+
+# function for xxx_csharp.dll build
+function (gdal_csharp_dll)
+
+ # Setup
+ set(_options)
+ set(_oneValueArgs TARGET TARGET_SUBDIR WRAP_DLL PACKAGE_NAME)
+ set(_multiValueArgs DEPENDS SYSTEM_DEPENDS)
+ cmake_parse_arguments(_CSHARP "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ get_filename_component(_root ${_CSHARP_TARGET} NAME_WE)
+
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}.csproj" _CSHARP_PROJ)
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}" _CSHARP_PROJ_PATH)
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_CSHARP_TARGET}" _CSHARP_DLL_TARGET)
+ set(CSC_OPTIONS /unsafe /debug:full /target:library /out:${_CSHARP_DLL_TARGET})
+ if (WIN32)
+ list(APPEND CSC_OPTIONS /define:CLR4)
+ endif ()
+ set(_PACKAGE_NAME ${_CSHARP_PACKAGE_NAME})
+
+ # Setup dependencies
+ set(_dlls)
+ set(_deps csharp_interface)
+ if (_CSHARP_DEPENDS)
+ foreach (_dep IN LISTS _CSHARP_DEPENDS)
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_dep}" _dep)
+ get_filename_component(_filename ${_dep} NAME)
+ list(APPEND _dlls ${_filename}.dll)
+ list(APPEND CSC_OPTIONS /r:${_dep}.dll)
+ endforeach ()
+ endif (_CSHARP_DEPENDS)
+ if (_CSHARP_SYSTEM_DEPENDS)
+ foreach (_dep IN LISTS _CSHARP_SYSTEM_DEPENDS)
+ if (_dep MATCHES "^OSGeo")
+ list(APPEND _deps ${_dep})
+ endif ()
+ endforeach ()
+ endif ()
+
+ # run the c# build
+ if (DOTNET_FOUND)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/dll_template.csproj"
+ "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}.csproj.in")
+ file(
+ GENERATE
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}-$.csproj
+ INPUT ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}.csproj.in)
+ add_custom_command(
+ COMMAND ${CMAKE_COMMAND} -E "copy_if_different"
+ "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}-$.csproj" "${_CSHARP_PROJ}"
+ VERBATIM PRE_BUILD
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_root}-$.csproj"
+ OUTPUT ${_CSHARP_PROJ})
+ add_dotnet(
+ ${_CSHARP_PROJ}
+ ${CSHARP_CONFIG}
+ NAME
+ ${_PACKAGE_NAME}
+ VERSION
+ ${_VERSION_STRING}
+ OUTPUT_PATH
+ ${_CSHARP_PROJ_PATH}
+ DEPENDS
+ ${_deps}
+ PACKAGE
+ ${_CSHARP_SYSTEM_DEPENDS})
+
+ else ()
+ if (CMAKE_VERBOSE_MAKEFILE)
+ message("BUILDING : " ${_CSHARP_TARGET} " : " ${CSHARP_COMPILER} ${CSC_OPTIONS} /out:${_CSHARP_TARGET})
+ endif ()
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET}
+ COMMAND
+ ${CMAKE_COMMAND} "-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" "-DCSC_OPTIONS=${CSC_OPTIONS}"
+ "-DCSHARP_COMPILER=${CSHARP_COMPILER}" "-DTARGET_SUBDIR=${_CSHARP_PROJ_PATH}"
+ -DWORKING=${CMAKE_CURRENT_BINARY_DIR} -P "${CMAKE_CURRENT_SOURCE_DIR}/add_dll_xsc.cmake"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ VERBATIM
+ DEPENDS csharp_interface ${CMAKE_CURRENT_BINARY_DIR}/gdal.snk ${CMAKE_CURRENT_SOURCE_DIR}/AssemblyInfo.cs)
+ add_custom_target(${_PACKAGE_NAME} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET})
+ add_custom_command(
+ TARGET ${_PACKAGE_NAME}
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo
+ "copy ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_CSHARP_TARGET} ${CMAKE_CURRENT_BINARY_DIR}"
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_CSHARP_TARGET}
+ ${CMAKE_CURRENT_BINARY_DIR})
+ if (_CSHARP_SYSTEM_DEPENDS)
+ add_dependencies(${_PACKAGE_NAME} ${_CSHARP_SYSTEM_DEPENDS})
+ endif ()
+ endif ()
+
+ set(_CSHARP_IMPORTS ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET_SUBDIR}/${_CSHARP_TARGET})
+ if (DOTNET_FOUND)
+ list(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${_PACKAGE_NAME}.${_VERSION_STRING}.nupkg)
+ endif ()
install(
- FILES ${CMAKE_CURRENT_BINARY_DIR}/${_CSHARP_TARGET}
+ FILES ${_CSHARP_IMPORTS}
COMPONENT csharp
DESTINATION ${GDAL_CSHARP_INSTALL_DIR})
endfunction ()
# ######################################################################################################################
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gdal.snk ${CMAKE_CURRENT_BINARY_DIR}/gdal.snk COPYONLY)
+gdal_csharp_wrap(
+ NAMESPACE
+ OSGeo.GDAL
+ WRAPPER
+ gdalconst_wrap
+ SWIG_INTERFACE
+ ${PROJECT_SOURCE_DIR}/swig/include/gdalconst.i
+ TARGET_SUBDIR
+ const)
-gdal_csharp_dll(
- TARGET gdalconst_csharp.dll
- NAMESPACE OSGeo.GDAL
- WRAPPER gdalconst_wrap
- SWIG_INTERFACE ${PROJECT_SOURCE_DIR}/swig/include/gdalconst.i TARGET_SUBDIR const)
+gdal_csharp_wrap(
+ NAMESPACE
+ OSGeo.OSR
+ WRAPPER
+ osr_wrap
+ SWIG_INTERFACE
+ ${PROJECT_SOURCE_DIR}/swig/include/osr.i
+ TARGET_SUBDIR
+ osr)
+
+gdal_csharp_wrap(
+ NAMESPACE
+ OSGeo.OGR
+ WRAPPER
+ ogr_wrap
+ SWIG_INTERFACE
+ ${PROJECT_SOURCE_DIR}/swig/include/ogr.i
+ TARGET_SUBDIR
+ ogr)
+
+gdal_csharp_wrap(
+ NAMESPACE
+ OSGeo.GDAL
+ WRAPPER
+ gdal_wrap
+ SWIG_INTERFACE
+ ${PROJECT_SOURCE_DIR}/swig/include/gdal.i
+ TARGET_SUBDIR
+ gdal)
+
+gdal_csharp_dll(TARGET gdalconst_csharp.dll TARGET_SUBDIR const WRAP_DLL gdalconst_wrap PACKAGE_NAME OSGeo.GDAL.CONST)
gdal_csharp_dll(
TARGET osr_csharp.dll
- NAMESPACE OSGeo.OSR
- WRAPPER osr_wrap
- SWIG_INTERFACE ${PROJECT_SOURCE_DIR}/swig/include/osr.i TARGET_SUBDIR osr)
+ TARGET_SUBDIR
+ osr
+ WRAP_DLL
+ osr_wrap
+ PACKAGE_NAME
+ OSGeo.OSR
+ SYSTEM_DEPENDS
+ OSGeo.GDAL.Core)
gdal_csharp_dll(
- TARGET ogr_csharp.dll
- NAMESPACE OSGeo.OGR
- WRAPPER ogr_wrap
- SWIG_INTERFACE ${PROJECT_SOURCE_DIR}/swig/include/ogr.i TARGET_SUBDIR ogr
- DEPENDS osr_csharp.dll)
+ TARGET ogr_csharp.dll TARGET_SUBDIR ogr WRAP_DLL ogr_wrap
+ DEPENDS osr_csharp
+ gdalconst_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OSR
+ OSGeo.GDAL.CONST
+ OSGeo.GDAL.Core
+ PACKAGE_NAME
+ OSGeo.OGR)
gdal_csharp_dll(
- TARGET gdal_csharp.dll
- NAMESPACE OSGeo.GDAL
- WRAPPER gdal_wrap
- SWIG_INTERFACE ${PROJECT_SOURCE_DIR}/swig/include/gdal.i TARGET_SUBDIR gdal
- DEPENDS ogr_csharp.dll osr_csharp.dll)
+ TARGET gdal_csharp.dll TARGET_SUBDIR gdal
+ DEPENDS osr_csharp
+ ogr_csharp
+ gdalconst_csharp
+ WRAP_DLL
+ gdal_wrap
+ SYSTEM_DEPENDS
+ OSGeo.OSR
+ OSGeo.OGR
+ OSGeo.GDAL.CONST
+ OSGeo.GDAL.Core
+ PACKAGE_NAME
+ OSGeo.GDAL)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gdal;ogr;osr;const")
@@ -98,186 +306,466 @@ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "gdal;ogr;osr;co
# sample commands
function (gdal_build_csharp_sample)
+
+ # setup arguments
set(_options)
set(_oneValueArgs SOURCE OUTPUT)
set(_multiValueArgs DEPENDS SYSTEM_DEPENDS)
cmake_parse_arguments(_GBCS "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
set(CSC_OPTIONS)
- set(_depends)
- foreach (_dep IN LISTS _GBCS_DEPENDS)
- list(APPEND CSC_OPTIONS /r:${_dep})
- list(APPEND _depends "${CMAKE_CURRENT_BINARY_DIR}/${_dep}")
- endforeach ()
- foreach (_dep IN LISTS _GBCS_SYSTEM_DEPENDS)
- list(APPEND CSC_OPTIONS /r:${_dep})
- endforeach ()
+
+ # setup project file
+ get_filename_component(_folder ${_GBCS_OUTPUT} NAME_WE)
+ set(_GBCS_PROJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/${_folder})
+ set(_GBCS_PROJ ${_GBCS_PROJ_PATH}/${_folder})
+ file(TO_NATIVE_PATH "${_GBCS_PROJ}" _GBCS_PROJ_NATIVE)
+ file(TO_NATIVE_PATH "${_GBCS_PROJ_PATH}" _GBCS_PROJ_PATH_NATIVE)
+ file(MAKE_DIRECTORY ${_GBCS_PROJ_PATH})
+
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_folder}/${_GBCS_OUTPUT}" _GBCS_OUTPUT_NATIVE)
+
+ # Setup dependencies
+ set(_dlls)
+ if (_GBCS_DEPENDS)
+ foreach (_dep IN LISTS _GBCS_DEPENDS)
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_dep}" _dep)
+ get_filename_component(_filename ${_dep} NAME)
+ list(APPEND _dlls ${_filename}.dll)
+ list(APPEND CSC_OPTIONS /r:${_dep}.dll)
+ endforeach ()
+ endif (_GBCS_DEPENDS)
+ if (_GBCS_SYSTEM_DEPENDS)
+ foreach (_dep IN LISTS _GBCS_SYSTEM_DEPENDS)
+ if (NOT _dep MATCHES "^OSGeo*.")
+ list(APPEND CSC_OPTIONS /r:${_dep}.dll)
+ endif ()
+ endforeach ()
+ endif (_GBCS_SYSTEM_DEPENDS)
+
file(TO_NATIVE_PATH "${_GBCS_SOURCE}" SOURCE_NATIVE)
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_GBCS_OUTPUT}
- COMMAND ${CSHARP_COMPILER} ${CSC_OPTIONS} /out:${_GBCS_OUTPUT} ${SOURCE_NATIVE}
- DEPENDS ${_depends} ${_GBCS_SOURCE})
+ # build the sample exe
+ if (DOTNET_FOUND)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/exe_template.csproj" "${_GBCS_PROJ}.csproj")
+ add_dotnet(
+ ${_GBCS_PROJ_NATIVE}.csproj
+ ${CSHARP_CONFIG}
+ NAME
+ OSGeo.GDAL.Samples.${_folder}
+ VERSION
+ ${_VERSION_STRING}
+ OUTPUT_PATH
+ ${_GBCS_PROJ_PATH_NATIVE}
+ DEPENDS
+ csharp_binding
+ PACKAGE
+ ${_GBCS_SYSTEM_DEPENDS})
+
+ else ()
+ if (CMAKE_VERBOSE_MAKEFILE)
+ message(
+ "BUILDING : "
+ ${_GBCS_OUTPUT}
+ " : "
+ ${CSHARP_COMPILER}
+ ${CSC_OPTIONS}
+ /out:${_GBCS_OUTPUT_NATIVE}
+ ${SOURCE_NATIVE})
+ endif ()
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_GBCS_OUTPUT}
+ COMMAND ${CMAKE_COMMAND} -E echo "Building ${_GBCS_OUTPUT_NATIVE}"
+ COMMAND ${CSHARP_COMPILER} ${CSC_OPTIONS} /out:${_GBCS_OUTPUT_NATIVE} ${SOURCE_NATIVE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ VERBATIM
+ DEPENDS csharp_binding ${_GBCS_SOURCE})
+ add_custom_target(OSGeo.GDAL.Samples.${_folder} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_GBCS_OUTPUT})
+ if (_GBCS_SYSTEM_DEPENDS)
+ foreach (_dep in LISTS _GBCS_SYSTEM_DEPENDS)
+ if (_dep MATCHES "^OSGeo*")
+ add_dependencies(${_GBCS_OUTPUT} ${_dep})
+ endif ()
+ endforeach ()
+ endif ()
+ endif ()
+
+ set(_GCBS_IMPORTS)
+ if (DOTNET_FOUND)
+ if (WIN32)
+ list(APPEND _GCBS_IMPORTS ${_GBCS_PROJ}.exe)
+ else ()
+ list(APPEND _GCBS_IMPORTS ${_GBCS_PROJ})
+ endif ()
+ list(APPEND _GCBS_IMPORTS ${_GBCS_PROJ}.dll)
+ list(APPEND ${_GBCS_PROJ}.nupkg)
+ install(
+ DIRECTORY ${_GBCS_PROJ_PATH}
+ COMPONENT csharp
+ DESTINATION ${GDAL_CSHARP_INSTALL_DIR}
+ FILES_MATCHING
+ PATTERN "*.json")
+ else ()
+ list(APPEND _GCBS_IMPORTS ${CMAKE_CURRENT_BINARY_DIR}/${_folder}/${_GBCS_OUTPUT})
+ endif ()
+
+ install(
+ FILES ${_GCBS_IMPORTS}
+ COMPONENT csharp
+ DESTINATION ${GDAL_CSHARP_INSTALL_DIR})
+
endfunction ()
+# Build the samples
gdal_build_csharp_sample(
OUTPUT
- ogrinfo.exe
+ OgrInfo.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/ogrinfo.cs
DEPENDS
- ogr_csharp.dll
- osr_csharp.dll)
+ ogr_csharp
+ osr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OSR
+ OSGeo.OGR)
+
gdal_build_csharp_sample(
OUTPUT
- createdata.exe
+ CreateData.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/createdata.cs
DEPENDS
- ogr_csharp.dll
- osr_csharp.dll)
-gdal_build_csharp_sample(OUTPUT OSRTransform.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/OSRTransform.cs DEPENDS
- osr_csharp.dll)
+ ogr_csharp
+ osr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR
+ OSGeo.OSR)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ OSRTransform.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/OSRTransform.cs
+ DEPENDS
+ osr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OSR)
+
gdal_build_csharp_sample(
OUTPUT
GDALRead.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALRead.cs
DEPENDS
- gdal_csharp.dll
+ gdal_csharp
SYSTEM_DEPENDS
- System.Drawing.dll)
+ OSGeo.GDAL
+ ${CSHARP_DRAWING})
+
gdal_build_csharp_sample(
OUTPUT
GDALReadDirect.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALReadDirect.cs
DEPENDS
- gdal_csharp.dll
+ gdal_csharp
SYSTEM_DEPENDS
- System.Drawing.dll)
+ OSGeo.GDAL
+ ${CSHARP_DRAWING})
+
gdal_build_csharp_sample(
OUTPUT
GDALAdjustContrast.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALAdjustContrast.cs
DEPENDS
- gdal_csharp.dll
+ gdal_csharp
SYSTEM_DEPENDS
- System.Drawing.dll)
+ OSGeo.GDAL
+ ${CSHARP_DRAWING})
+
gdal_build_csharp_sample(
OUTPUT
GDALDatasetRasterIO.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALDatasetRasterIO.cs
DEPENDS
- gdal_csharp.dll
+ gdal_csharp
SYSTEM_DEPENDS
- System.Drawing.dll)
-gdal_build_csharp_sample(OUTPUT GDALWrite.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALWrite.cs DEPENDS
- gdal_csharp.dll)
-gdal_build_csharp_sample(OUTPUT GDALDatasetWrite.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALDatasetWrite.cs
- DEPENDS gdal_csharp.dll)
-gdal_build_csharp_sample(OUTPUT GDALColorTable.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALColorTable.cs DEPENDS
- gdal_csharp.dll)
-gdal_build_csharp_sample(OUTPUT WKT2WKB.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/WKT2WKB.cs DEPENDS ogr_csharp.dll)
-gdal_build_csharp_sample(OUTPUT OGRGEOS.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/OGRGEOS.cs DEPENDS ogr_csharp.dll)
-gdal_build_csharp_sample(OUTPUT ReadXML.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/ReadXML.cs DEPENDS gdal_csharp.dll)
+ OSGeo.GDAL
+ ${CSHARP_DRAWING})
+
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALWrite.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALWrite.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALDatasetWrite.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALDatasetWrite.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALColorTable.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALColorTable.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ WKT2WKB.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/WKT2WKB.cs
+ DEPENDS
+ ogr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ OGRGEOS.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/OGRGEOS.cs
+ DEPENDS
+ ogr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ ReadXML.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/ReadXML.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
+
gdal_build_csharp_sample(
OUTPUT
GDALInfo.exe
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALInfo.cs
DEPENDS
- gdal_csharp.dll
- osr_csharp.dll)
-gdal_build_csharp_sample(OUTPUT GDALOverviews.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALOverviews.cs DEPENDS
- gdal_csharp.dll)
-gdal_build_csharp_sample(OUTPUT GDALCreateCopy.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALCreateCopy.cs DEPENDS
- gdal_csharp.dll)
-gdal_build_csharp_sample(OUTPUT GDALGetHistogram.exe SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALGetHistogram.cs
- DEPENDS gdal_csharp.dll)
+ gdal_csharp
+ osr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL
+ OSGeo.OSR)
-add_custom_target(
- csharp_samples
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ogrinfo.exe
- ${CMAKE_CURRENT_BINARY_DIR}/createdata.exe
- ${CMAKE_CURRENT_BINARY_DIR}/OSRTransform.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALRead.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALReadDirect.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALAdjustContrast.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALDatasetRasterIO.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALWrite.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALDatasetWrite.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALColorTable.exe
- ${CMAKE_CURRENT_BINARY_DIR}/WKT2WKB.exe
- ${CMAKE_CURRENT_BINARY_DIR}/OGRGEOS.exe
- ${CMAKE_CURRENT_BINARY_DIR}/ReadXML.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALInfo.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALOverviews.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALCreateCopy.exe
- ${CMAKE_CURRENT_BINARY_DIR}/GDALGetHistogram.exe)
-add_custom_target(
- csharp_binding ALL
- DEPENDS gdalconst_csharp.dll
- osr_csharp.dll
- ogr_csharp.dll
- gdal_csharp.dll
- gdalconst_wrap
- osr_wrap
- ogr_wrap
- gdal_wrap
- csharp_samples)
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALOverviews.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALOverviews.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
-if (CSHARP_INTERPRETER OR WIN32)
- include(GdalSetTestEnv)
- gdal_set_test_env(TEST_ENV)
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALCreateCopy.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALCreateCopy.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
- file(TO_NATIVE_PATH "/" _separator)
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALGetHistogram.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALGetHistogram.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
- if (WIN32)
- set(NEW_TEST_ENV)
- foreach (_env IN LISTS TEST_ENV)
- if (_env MATCHES "^PATH=.*$")
- string(REPLACE ";" "\\;" _env "${_env}")
- list(APPEND NEW_TEST_ENV "${_env}\\;$>")
- else ()
- list(APPEND NEW_TEST_ENV "${_env}")
- endif ()
- endforeach ()
- set(TEST_ENV "${NEW_TEST_ENV}")
- endif ()
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALTest.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALTest.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
- add_test(NAME csharp_createdata COMMAND ${CSHARP_INTERPRETER} createdata.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data pointlayer)
- add_test(NAME csharp_ogrinfo COMMAND ${CSHARP_INTERPRETER} ogrinfo.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}pointlayer.shp)
- add_test(NAME csharp_GDALWrite COMMAND ${CSHARP_INTERPRETER} GDALWrite.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample.tif)
- add_test(NAME csharp_GDALDatasetWrite COMMAND ${CSHARP_INTERPRETER} GDALDatasetWrite.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample.tif)
- add_test(
- NAME csharp_GDALCreateCopy
- COMMAND
- ${CSHARP_INTERPRETER} GDALCreateCopy.exe ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample.tif
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample2.tif)
- add_test(NAME csharp_GDALOverviews
- COMMAND ${CSHARP_INTERPRETER} GDALOverviews.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample.tif NEAREST 2 4)
- add_test(NAME csharp_GDALInfo COMMAND ${CSHARP_INTERPRETER} GDALInfo.exe
- ${CMAKE_CURRENT_SOURCE_DIR}${_separator}Data${_separator}sample.tif)
- add_test(NAME csharp_OSRTransform COMMAND ${CSHARP_INTERPRETER} OSRTransform.exe)
-
- foreach (
- test_name IN
- ITEMS csharp_createdata
- csharp_ogrinfo
- csharp_GDALWrite
- csharp_GDALDatasetWrite
- csharp_GDALCreateCopy
- csharp_GDALOverviews
- csharp_GDALInfo
- csharp_OSRTransform)
- set_property(TEST ${test_name} PROPERTY ENVIRONMENT "${TEST_ENV}")
- endforeach ()
+gdal_build_csharp_sample(
+ OUTPUT
+ OGRLayerAlg.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/OGRLayerAlg.cs
+ DEPENDS
+ osr_csharp
+ ogr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR
+ OSGeo.OSR)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ OGRFeatureEdit.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/OGRFeatureEdit.cs
+ DEPENDS
+ osr_csharp
+ ogr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR
+ OSGeo.OSR)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ GDALWarp.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALWarp.cs
+ DEPENDS
+ gdal_csharp
+ SYSTEM_DEPENDS
+ OSGeo.GDAL)
+
+gdal_build_csharp_sample(
+ OUTPUT
+ GetCRSInfo.exe
+ SOURCE
+ ${CMAKE_CURRENT_SOURCE_DIR}/apps/GetCRSInfo.cs
+ DEPENDS
+ osr_csharp
+ SYSTEM_DEPENDS
+ OSGeo.OGR)
+
+# Custom Target to make the C# wrap Libraries and use SWIG to build the .cs files
+add_custom_target(csharp_interface DEPENDS gdalconst_wrap osr_wrap ogr_wrap gdal_wrap)
+# Custom Target to make the c# bindings - will be run as part of ALL but can also be built seperately
+add_custom_target(csharp_binding ALL DEPENDS csharp_interface OSGeo.GDAL.CONST OSGeo.GDAL OSGeo.OGR OSGeo.OSR)
+
+# Custom Target to build the C# bindings and the sample binaries
+add_custom_target(
+ csharp_samples ALL
+ DEPENDS csharp_binding
+ OSGeo.GDAL.Samples.OgrInfo
+ OSGeo.GDAL.Samples.CreateData
+ OSGeo.GDAL.Samples.OSRTransform
+ OSGeo.GDAL.Samples.GDALRead
+ OSGeo.GDAL.Samples.GDALReadDirect
+ OSGeo.GDAL.Samples.GDALAdjustContrast
+ OSGeo.GDAL.Samples.GDALDatasetRasterIO
+ OSGeo.GDAL.Samples.GDALWrite
+ OSGeo.GDAL.Samples.GDALDatasetWrite
+ OSGeo.GDAL.Samples.GDALColorTable
+ OSGeo.GDAL.Samples.WKT2WKB
+ OSGeo.GDAL.Samples.OGRGEOS
+ OSGeo.GDAL.Samples.ReadXML
+ OSGeo.GDAL.Samples.GDALInfo
+ OSGeo.GDAL.Samples.GDALOverviews
+ OSGeo.GDAL.Samples.GDALCreateCopy
+ OSGeo.GDAL.Samples.GDALGetHistogram
+ OSGeo.GDAL.Samples.GDALTest
+ OSGeo.GDAL.Samples.OGRLayerAlg
+ OSGeo.GDAL.Samples.GDALWarp
+ OSGeo.GDAL.Samples.OGRFeatureEdit
+ OSGeo.GDAL.Samples.GetCRSInfo.exe)
+
+# set up the tests
+
+include(GdalSetTestEnv)
+gdal_set_test_env(TEST_ENV)
+set(_ex)
+if (CSHARP_INTERPRETER)
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} _MONO_PATH)
+ list(APPEND TEST_ENV "MONO_PATH=${_MONO_PATH}")
+ set(_ex ".exe")
endif ()
+
+add_test(
+ NAME csharp_createdata
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} CreateData/CreateData${_ex} Data pointlayer)
+set_property(TEST csharp_createdata PROPERTY ENVIRONMENT "${TEST_ENV}")
+add_test(
+ NAME csharp_ogrinfo
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} OgrInfo/OgrInfo${_ex} Data/pointlayer.shp)
+set_property(TEST csharp_ogrinfo PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_ogrinfo PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_osrtransform
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} OSRTransform/OSRTransform${_ex})
+set_property(TEST csharp_osrtransform PROPERTY ENVIRONMENT "${TEST_ENV}")
+add_test(
+ NAME csharp_gdalwrite
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALWrite/GDALWrite${_ex} Data/sample.tif)
+set_property(TEST csharp_gdalwrite PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdalwrite PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_gdaldatasetwrite
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALDatasetWrite/GDALDatasetWrite${_ex} Data/sample1.tif)
+set_property(TEST csharp_gdaldatasetwrite PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdaldatasetwrite PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_gdalcreatecopy
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALCreateCopy/GDALCreateCopy${_ex} Data/sample.tif Data/sample2.tif)
+set_property(TEST csharp_gdalcreatecopy PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdalcreatecopy PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_gdalreaddirect
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALReadDirect/GDALReadDirect${_ex} Data/sample.tif Data/sample.png)
+set_property(TEST csharp_gdalreaddirect PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdalreaddirect PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_gdaloverviews
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALOverviews/GDALOverviews${_ex} Data/sample.tif NEAREST 2 4)
+set_property(TEST csharp_gdaloverviews PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdaloverviews PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_gdalinfo
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GDALInfo/GDALInfo${_ex} Data/sample.tif)
+set_property(TEST csharp_gdalinfo PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_gdalinfo PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_ogrlayeralg
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} OGRLayerAlg/OGRLayerAlg${_ex} Intersection Data/pointlayer.shp pointlayer
+ Data/pointlayer.shp pointlayer Data intersectionresult)
+set_property(TEST csharp_ogrlayeralg PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_ogrlayeralg PROPERTY DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_ogrlayeralgresult
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} OgrInfo/OgrInfo${_ex} Data/intersectionresult.shp)
+set_property(TEST csharp_ogrlayeralgresult PROPERTY ENVIRONMENT "${TEST_ENV}")
+set_property(TEST csharp_ogrlayeralgresult PROPERTY DEPENDS csharp_ogrlayeralg)
+# GDALWarp test disabled until updated and the dependency on autotest is reomved dur to possible clash with a standalone
+# build add_test( NAME csharp_gdalwarp WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CSHARP_INTERPRETER}
+# GDALWarp/GDALWarp Data/testwarp.tif "-of GTiff -t_srs EPSG:32645 -overwrite" "../../autotest/gcore/data/byte.tif")
+# set_property(TEST csharp_gdalwarp PROPERTY ENVIRONMENT "${TEST_ENV}") set_property(TEST csharp_gdalwarp PROPERTY
+# DEPENDS csharp_createdata)
+add_test(
+ NAME csharp_getcrsinfo
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CSHARP_INTERPRETER} GetCRSInfo/GetCRSInfo${_ex} "EPSG" 20)
+set_property(TEST csharp_getcrsinfo PROPERTY ENVIRONMENT "${TEST_ENV}")
diff --git a/swig/csharp/Directory.Build.props b/swig/csharp/Directory.Build.props
new file mode 100644
index 000000000000..6ab5f83539ac
--- /dev/null
+++ b/swig/csharp/Directory.Build.props
@@ -0,0 +1,6 @@
+
+
+ obj\$(MSBuildProjectName)\
+ bin\$(MSBuildProjectName)\
+
+
\ No newline at end of file
diff --git a/swig/csharp/add_dll_xsc.cmake b/swig/csharp/add_dll_xsc.cmake
new file mode 100644
index 000000000000..8c2d2094ad06
--- /dev/null
+++ b/swig/csharp/add_dll_xsc.cmake
@@ -0,0 +1,11 @@
+
+file(GLOB SOURCES "${TARGET_SUBDIR}/*.cs")
+list(APPEND SOURCES ${SOURCE_DIR}/AssemblyInfo.cs)
+set(NATIVE_SOURCES)
+foreach(_src IN LISTS SOURCES)
+ file(TO_NATIVE_PATH "${_src}" _src)
+ list(APPEND NATIVE_SOURCES "${_src}")
+endforeach()
+execute_process(
+ COMMAND ${CSHARP_COMPILER} ${CSC_OPTIONS} ${NATIVE_SOURCES}
+ WORKING_DIRECTORY ${WORKING})
diff --git a/swig/csharp/apps/GDALEmpty.cs b/swig/csharp/apps/GDALEmpty.cs
new file mode 100644
index 000000000000..8ed8881f8462
--- /dev/null
+++ b/swig/csharp/apps/GDALEmpty.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace testapp
+{
+ class GdalTest
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Testing GDAL C# Bindings");
+ }
+ }
+}
diff --git a/swig/csharp/apps/GDALTest.cs b/swig/csharp/apps/GDALTest.cs
new file mode 100644
index 000000000000..05851dfc2f4d
--- /dev/null
+++ b/swig/csharp/apps/GDALTest.cs
@@ -0,0 +1,15 @@
+using System;
+using OSGeo.GDAL;
+
+namespace testapp
+{
+ class GdalTest
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Testing GDAL C# Bindings");
+ Gdal.UseExceptions();
+ Console.WriteLine($"Gdal version {Gdal.VersionInfo(null)}");
+ }
+ }
+}
diff --git a/swig/csharp/build_dll.cmake b/swig/csharp/build_dll.cmake
deleted file mode 100644
index 8c212c9804af..000000000000
--- a/swig/csharp/build_dll.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-set(CSC_OPTIONS /unsafe /debug:full /target:library /out:${CSHARP_TARGET})
-if(CSHARP_DEPENDS)
- foreach(_depends IN LISTS CSHARP_DEPENDS)
- list(APPEND CSC_OPTIONS /r:${_depends})
- endforeach ()
-endif()
-if(WIN32)
- list(APPEND CSC_OPTIONS /define:CLR4)
-endif()
-file(GLOB SOURCES "${BUILD_DIR}/${TARGET_SUBDIR}/*.cs")
-list(APPEND SOURCES ${SOURCE_DIR}/AssemblyInfo.cs)
-set(NATIVE_SOURCES)
-foreach(_src IN LISTS SOURCES)
- file(TO_NATIVE_PATH "${_src}" _src)
- list(APPEND NATIVE_SOURCES "${_src}")
-endforeach()
-execute_process(
- COMMAND ${CSHARP_COMPILER} ${CSC_OPTIONS} ${NATIVE_SOURCES}
- # COMMAND_ECHO STDOUT
- WORKING_DIRECTORY ${BUILD_DIR})
diff --git a/swig/csharp/dll_template.csproj b/swig/csharp/dll_template.csproj
new file mode 100644
index 000000000000..e0cf5ad8e5bf
--- /dev/null
+++ b/swig/csharp/dll_template.csproj
@@ -0,0 +1,18 @@
+
+
+ library
+ ${CSHARP_LIBRARY_VERSION}
+ ${CSHARP_RID}
+ ${GDAL_VERSION_MAJOR}.${GDAL_VERSION_MINOR}.${GDAL_VERSION_REV}
+ ..\gdal.snk
+ true
+ true
+ ${_PACKAGE_NAME}
+ GDAL Contributors
+ GDAL Project
+ Copyright GDAL Contributors
+
+
+
+
+
\ No newline at end of file
diff --git a/swig/csharp/exe_template.csproj b/swig/csharp/exe_template.csproj
new file mode 100644
index 000000000000..77b3b822d5ab
--- /dev/null
+++ b/swig/csharp/exe_template.csproj
@@ -0,0 +1,13 @@
+
+
+ Exe
+ ${CSHARP_APPLICATION_VERSION}
+ ${CSHARP_RID}
+ false
+ ${GDAL_VERSION_MAJOR}.${GDAL_VERSION_MINOR}.${GDAL_VERSION_REV}
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/swig/csharp/osgeo.gdal.core.csproj.in b/swig/csharp/osgeo.gdal.core.csproj.in
new file mode 100644
index 000000000000..ebd17b17f3dd
--- /dev/null
+++ b/swig/csharp/osgeo.gdal.core.csproj.in
@@ -0,0 +1,11 @@
+
+
+ ${CSHARP_LIBRARY_VERSION}
+ ${CSHARP_RID}
+ ${GDAL_VERSION_MAJOR}.${GDAL_VERSION_MINOR}.${GDAL_VERSION_REV}
+ false
+
+
+
+
+
\ No newline at end of file