# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: dotnet-pkg.eclass # @MAINTAINER: # Gentoo Dotnet project <dotnet@gentoo.org> # @AUTHOR: # Anna Figueiredo Gomes <navi@vlhl.dev> # Maciej Barć <xgqt@gentoo.org> # @SUPPORTED_EAPIS: 8 # @PROVIDES: dotnet-pkg-base nuget # @BLURB: common functions and variables for .NET packages # @DESCRIPTION: # This eclass is designed to help with building and installing packages that # use the .NET SDK. # It provides the required phase functions and special variables that make # it easier to write ebuilds for .NET packages. # If you do not use the exported phase functions, then consider using # the "dotnet-pkg-base.eclass" instead. # # .NET SDK is a open-source framework from Microsoft, it is a cross-platform # successor to .NET Framework. # # .NET packages require proper inspection before packaging: # - the compatible .NET SDK version has to be declared, # this can be done by inspecting the package's "*.proj" files, # unlike JAVA, .NET packages tend to lock onto one exact selected .NET SDK # version, so building with other .NET versions will be mostly unsupported, # - Nugets, packages' .NET dependencies, which are similar to JAVA's JARs, # have to be listed using either the "NUGETS" variable or bundled inside # a "prebuilt" archive, in second case also the "NUGET_PACKAGES" variable # has to be explicitly set. # - the main project file (*.proj) that builds the project has to be specified # by the "DOTNET_PROJECT" variable. case ${EAPI} in 8) ;; *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; esac if [[ -z ${_DOTNET_PKG_ECLASS} ]] ; then _DOTNET_PKG_ECLASS=1 inherit dotnet-pkg-base # Append to "RDEPEND" and "BDEPEND" "DOTNET_PKG_RDEPS" and "DOTNET_PKG_BDEPS" # generated by "dotnet-pkg-base" eclass. RDEPEND+=" ${DOTNET_PKG_RDEPS} " BDEPEND+=" ${DOTNET_PKG_BDEPS} " # @ECLASS_VARIABLE: DOTNET_PKG_BAD_PROJECTS # @DESCRIPTION: # List of projects to remove from all found solution (".sln") files. # The projects are removed in the "dotnet-pkg_src_prepare" function. # # This variable should be set after inheriting "dotnet-pkg.eclass". # # Default value is an empty array. # # Example: # @CODE # DOTNET_PKG_BAD_PROJECTS=( "${S}/BrokenTests" ) # DOTNET_PKG_PROJECTS=( "${S}/DotnetProject" ) # @CODE # # For more info see: "dotnet-pkg_remove-bad" function. DOTNET_PKG_BAD_PROJECTS=() # @ECLASS_VARIABLE: DOTNET_PKG_PROJECTS # @DEFAULT_UNSET # @DESCRIPTION: # Path to the main .NET project files (".csproj", ".fsproj", ".vbproj") # used by default by "dotnet-pkg_src_compile" phase function. # # In .NET version 6.0 and lower it was possible to build a project solution # (".sln") immediately with output to a specified directory ("--output DIR"), # but versions >= 7.0 deprecated this behavior. This means that # "dotnet-pkg-base_build" will fail when pointed to a solution or a directory # containing a solution file. # # This variable should be set after inheriting "dotnet-pkg.eclass", # it is also advised that it is set after the variable "${S}" is set. # "DOTNET_PKG_PROJECTS" can integrate with "S" (see the example below). # # Example: # @CODE # SRC_URI="..." # S="${WORKDIR}/${P}/src" # # LICENSE="MIT" # SLOT="0" # KEYWORDS="~amd64" # # DOTNET_PKG_PROJECTS=( "${S}/DotnetProject" ) # # src_prepare() { # ... # @CODE # @ECLASS_VARIABLE: DOTNET_PKG_RESTORE_EXTRA_ARGS # @DESCRIPTION: # Extra arguments to pass to the package restore, in the "src_configure" phase. # # This is passed only when restoring the specified "DOTNET_PROJECT". # Other project restorers do not use this variable. # # This variable should be set after inheriting "dotnet-pkg.eclass", # it is also advised that it is set after the variable # "DOTNET_PROJECT" (from "dotnet-pkg-base" eclass) is set. # # Default value is an empty array. # # For more info see the "DOTNET_PROJECT" variable and "dotnet-pkg_src_configure". DOTNET_PKG_RESTORE_EXTRA_ARGS=() # @ECLASS_VARIABLE: DOTNET_PKG_BUILD_EXTRA_ARGS # @DESCRIPTION: # Extra arguments to pass to the package build, in the "src_compile" phase. # # This is passed only when building the specified "DOTNET_PROJECT". # Other project builds do not use this variable. # # This variable should be set after inheriting "dotnet-pkg.eclass", # it is also advised that it is set after the variable # "DOTNET_PROJECT" (from "dotnet-pkg-base" eclass) is set. # # Default value is an empty array. # # Example: # @CODE # DOTNET_PKG_BUILD_EXTRA_ARGS=( -p:WarningLevel=0 ) # @CODE # # For more info see the "DOTNET_PROJECT" variable and "dotnet-pkg_src_compile". DOTNET_PKG_BUILD_EXTRA_ARGS=() # @ECLASS_VARIABLE: DOTNET_PKG_TEST_EXTRA_ARGS # @DESCRIPTION: # Extra arguments to pass to the package test, in the "src_test" phase. # # This is passed only when testing found ".sln" solution files # (see also "dotnet-pkg-base_foreach-solution"). # Other project builds do not use this variable. # # This variable should be set after inheriting "dotnet-pkg.eclass", # it is also advised that it is set after the variable # "DOTNET_PROJECT" (from "dotnet-pkg-base" eclass) is set. # # Default value is an empty array. # # Example: # @CODE # DOTNET_PKG_TEST_EXTRA_ARGS=( -p:RollForward=Major ) # @CODE # # For more info see the "DOTNET_PROJECT" variable and "dotnet-pkg_src_test". DOTNET_PKG_TEST_EXTRA_ARGS=() # @FUNCTION: dotnet-pkg_force-compat # @DESCRIPTION: # This function appends special options to all "DOTNET_PKG_*_EXTRA_ARGS" # variables in an attempt to force compatibility to the picked # "DOTNET_PKG_COMPAT" .NET SDK version. # # Call this function post-inherit. dotnet-pkg_force-compat() { if [[ -z ${DOTNET_PKG_COMPAT} ]] ; then die "DOTNET_PKG_COMPAT is not set" fi local -a force_extra_args=( -p:RollForward=Major -p:TargetFramework="net${DOTNET_PKG_COMPAT}" -p:TargetFrameworks="net${DOTNET_PKG_COMPAT}" ) DOTNET_PKG_RESTORE_EXTRA_ARGS+=( "${force_extra_args[@]}" ) DOTNET_PKG_BUILD_EXTRA_ARGS+=( "${force_extra_args[@]}" ) DOTNET_PKG_TEST_EXTRA_ARGS+=( "${force_extra_args[@]}" ) } # @FUNCTION: dotnet-pkg_pkg_setup # @DESCRIPTION: # Default "pkg_setup" for the "dotnet-pkg" eclass. # Pre-build configuration and checks. # # Calls "dotnet-pkg-base_pkg_setup". dotnet-pkg_pkg_setup() { [[ ${MERGE_TYPE} != binary ]] && dotnet-pkg-base_setup } # @FUNCTION: dotnet-pkg_src_unpack # @DESCRIPTION: # Default "src_unpack" for the "dotnet-pkg" eclass. # Unpack the package sources. # # Includes a special exception for nugets (".nupkg" files) - they are instead # copied into the "NUGET_PACKAGES" directory. dotnet-pkg_src_unpack() { nuget_link-system-nugets nuget_link-nuget-archives nuget_unpack-non-nuget-archives } # @FUNCTION: dotnet-pkg_remove-bad # @USAGE: <solution> # @DESCRIPTION: # Remove all projects specified by "DOTNET_PKG_BAD_PROJECTS" from a given # solution file. # # Used by "dotnet-pkg_src_prepare". dotnet-pkg_remove-bad() { debug-print-function "${FUNCNAME[0]}" "${@}" [[ -z ${1} ]] && die "${FUNCNAME[0]}: no solution file specified" local bad_project for bad_project in "${DOTNET_PKG_BAD_PROJECTS[@]}" ; do nonfatal dotnet-pkg-base_sln-remove "${1}" "${bad_project}" done } # @FUNCTION: dotnet-pkg_src_prepare # @DESCRIPTION: # Default "src_prepare" for the "dotnet-pkg" eclass. # Prepare the package sources. # # Run "dotnet-pkg-base_remove-global-json", "dotnet-pkg-base_remove-bad" # for each found solution file and prepare for using Nuget. dotnet-pkg_src_prepare() { dotnet-pkg-base_remove-global-json dotnet-pkg-base_foreach-solution "$(pwd)" dotnet-pkg_remove-bad find "$(pwd)" -maxdepth 1 -iname "nuget.config" -delete || die "${FUNCNAME[0]}: failed to remove unwanted \"NuGet.config\" config files" nuget_writeconfig "$(pwd)/" default } # @FUNCTION: dotnet-pkg_foreach-project # @USAGE: <args> ... # @DESCRIPTION: # Run a specified command for each project listed inside the "DOTNET_PKG_PROJECTS" # variable. # # Used by "dotnet-pkg_src_configure" and "dotnet-pkg_src_compile". dotnet-pkg_foreach-project() { debug-print-function "${FUNCNAME[0]}" "${@}" local dotnet_project for dotnet_project in "${DOTNET_PKG_PROJECTS[@]}" ; do ebegin "Running \"${*}\" for project: \"${dotnet_project##*/}\"" "${@}" "${dotnet_project}" eend $? "${FUNCNAME[0]}: failed for project: \"${dotnet_project}\"" || die done } # @FUNCTION: dotnet-pkg_src_configure # @DESCRIPTION: # Default "src_configure" for the "dotnet-pkg" eclass. # Configure the package. # # First show information about current .NET SDK that is being used, # then restore the project file specified by "DOTNET_PROJECT", # afterwards restore any found solutions. dotnet-pkg_src_configure() { dotnet-pkg-base_info dotnet-pkg_foreach-project \ dotnet-pkg-base_restore "${DOTNET_PKG_RESTORE_EXTRA_ARGS[@]}" dotnet-pkg-base_foreach-solution \ "$(pwd)" \ dotnet-pkg-base_restore "${DOTNET_PKG_RESTORE_EXTRA_ARGS[@]}" } # @FUNCTION: dotnet-pkg_src_compile # @DESCRIPTION: # Default "src_compile" for the "dotnet-pkg" eclass. # Build the package. # # Build the package using "dotnet build" in the directory specified by either # "DOTNET_PROJECT" or "S" (temporary build directory) variables. # # For more info see: "DOTNET_PROJECT" variable # and "dotnet-pkg-base_get-project" function. dotnet-pkg_src_compile() { dotnet-pkg_foreach-project \ dotnet-pkg-base_build "${DOTNET_PKG_BUILD_EXTRA_ARGS[@]}" } # @FUNCTION: dotnet-pkg_src_test # @DESCRIPTION: # Default "src_test" for the "dotnet-pkg" eclass. # Test the package. # # Test the package by testing any found solutions. # # It is very likely that this function will either not execute any tests or # will execute wrong or incomplete test suite. Maintainers should inspect if # any and/or correct tests are ran. dotnet-pkg_src_test() { dotnet-pkg-base_foreach-solution \ "$(pwd)" \ dotnet-pkg-base_test "${DOTNET_PKG_TEST_EXTRA_ARGS[@]}" } # @FUNCTION: dotnet-pkg_src_install # @DESCRIPTION: # Default "src_install" for the "dotnet-pkg" eclass. # Install the package. # # This is the default package install: # - install the compiled .NET package artifacts, # for more info see "dotnet-pkg-base_install" and "DOTNET_PKG_OUTPUT", # - create launcher from the .NET package directory to "/usr/bin", # phase will detect to choose either executable with capital letter # (common among .NET packages) or not, # - call "einstalldocs". # # It is very likely that this function is either insufficient or has to be # redefined in a ebuild. dotnet-pkg_src_install() { dotnet-pkg-base_install # /usr/bin/Nake -> /usr/share/nake-3.0.0/Nake if [[ -f "${D}/usr/share/${P}/${PN^}" ]] ; then dotnet-pkg-base_dolauncher "/usr/share/${P}/${PN^}" # Create a compatibility symlink and also for ease of use from CLI. dosym -r "/usr/bin/${PN^}" "/usr/bin/${PN}" elif [[ -f "${D}/usr/share/${P}/${PN}" ]] ; then dotnet-pkg-base_dolauncher "/usr/share/${P}/${PN}" fi einstalldocs } fi EXPORT_FUNCTIONS pkg_setup src_unpack src_prepare src_configure src_compile src_test src_install