1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
|
# 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} "$@"
[[ -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} "$@"
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
|