Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
418acdd
Initial plan
Copilot Jan 9, 2026
d08f626
Add Linux build support - fix system checks and Makefile issues
Copilot Jan 9, 2026
7d7ff7c
Fix sed and cache directory issues for Linux builds
Copilot Jan 9, 2026
7fcbf2e
Address PR feedback: remove ProjectInspector.csproj files, use 'place…
Copilot Jan 12, 2026
c5ff867
Skip runtime directory on Linux to avoid native compilation
Copilot Jan 13, 2026
e807828
Add GitHub Actions workflow to verify Linux builds
Copilot Jan 13, 2026
9863bda
Remove accidentally added build artifact file
Copilot Jan 15, 2026
e348f28
Simplify Linux build workflow based on PR feedback
Copilot Jan 15, 2026
a21bcfb
Fix Linux build issues: XCODE_VERSION/URL unconditioned, fix DotNetGl…
Copilot Jan 15, 2026
a717133
Fix sed syntax for Linux in create-makefile-fragment.sh
Copilot Jan 15, 2026
b321c1f
Fix case-sensitivity: rename quicklookUI.cs to quicklookui.cs
Copilot Jan 15, 2026
aa692f5
Fix case-sensitivity: rename ILLink.Substitutions files to match plat…
Copilot Jan 15, 2026
3245a76
Skip AppleDocReader (macOS-only tool) on Linux for documentation gene…
Copilot Jan 15, 2026
5696bcd
Merge branch 'main' into copilot/make-repository-build-linux
rolfbjarne Jan 16, 2026
17478cd
Skip Windows package builds on Linux
Copilot Jan 16, 2026
8e7d97a
Skip xmllint XML validation on Linux (xmllint not available)
Copilot Jan 16, 2026
1456993
Skip native registrar builds in mmp/mtouch on Linux (require Xcode)
Copilot Jan 16, 2026
15c2f11
Fix git blame caret issue in create-make-config.sh for Linux builds
Copilot Jan 16, 2026
20e527b
Use parallel make in Linux build workflow for improved build speed
Copilot Jan 23, 2026
47a15c4
Merge main and add ProjectInspector.csproj to .gitignore
Copilot Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
29 changes: 29 additions & 0 deletions .github/workflows/linux-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# yamllint disable rule:line-length rule:document-start rule:truthy
name: Linux Build Verification
on:
pull_request:

permissions:
contents: read

jobs:
linux-build:
name: Verify Linux Build
runs-on: ubuntu-latest

steps:
- name: 'Checkout'
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- name: Check system dependencies
run: |
set -ex
./system-dependencies.sh

- name: Build on Linux
run: |
set -ex
make -j$(nproc)
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Make.config.inc
Make.config.local
configure.inc
dotnet.config
ProjectInspector.csproj
_ios-build
_mac-build
_build
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[submodule "external/Xamarin.MacDev"]
path = external/Xamarin.MacDev
url = ../../dotnet/macios-devtools
url = https://github.com/dotnet/macios-devtools
branch = main

4 changes: 4 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
<MicrosoftBuildFrameworkPackageVersion>$(MicrosoftBuildPackageVersion)</MicrosoftBuildFrameworkPackageVersion>
<MicrosoftBuildTasksCorePackageVersion>$(MicrosoftBuildPackageVersion)</MicrosoftBuildTasksCorePackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>$(MicrosoftBuildPackageVersion)</MicrosoftBuildUtilitiesCorePackageVersion>
<NUnitPackageVersion>4.4.0</NUnitPackageVersion>
<NUnitConsoleRunnerPackageVersion>3.22.0</NUnitConsoleRunnerPackageVersion>
<NUnit3TestAdapterPackageVersion>6.1.0</NUnit3TestAdapterPackageVersion>
<NUnitXmlTestLoggerPackageVersion>3.1.15</NUnitXmlTestLoggerPackageVersion>
<MicrosoftNETTestSdkPackageVersion>18.0.1</MicrosoftNETTestSdkPackageVersion>
<!-- Fix transient dependency issue found by component governance 4.7.0 -> 4.7.2 brought by Microsoft.Build package -->
<SystemDrawingCommonPackageVersion>4.7.2</SystemDrawingCommonPackageVersion>
<!-- Fix transient dependency issue found by component governance 4.7.0 -> 4.7.1 brought by Microsoft.Build.Tasks.Core package -->
Expand Down
13 changes: 13 additions & 0 deletions Make.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
include $(TOP)/mk/subdirs.mk

# Detect if we're building on Linux
UNAME_S:=$(shell uname -s)
ifeq ($(UNAME_S),Linux)
IS_LINUX=1
endif

# Common cURL command:
# --fail: return an exit code if the connection succeeded, but returned an HTTP error code.
# --location: follow redirects
Expand Down Expand Up @@ -203,6 +209,7 @@ MACCATALYST_NUGET_VERSION_FULL=$(MACCATALYST_NUGET_VERSION_NO_METADATA)$(NUGET_B
# Xcode version should have both a major and a minor version (even if the minor version is 0)
XCODE_VERSION=26.2
XCODE_URL=https://dl.internalx.com/internal-files/xcodes/Xcode_26.2.xip
ifndef IS_LINUX
XCODE_DEVELOPER_ROOT=/Applications/Xcode_26.2.0.app/Contents/Developer
XCODE_PRODUCT_BUILD_VERSION:=$(shell /usr/libexec/PlistBuddy -c 'Print :ProductBuildVersion' $(XCODE_DEVELOPER_ROOT)/../version.plist 2>/dev/null || echo " $(shell tput setaf 1 2>/dev/null)The required Xcode ($(XCODE_VERSION)) is not installed in $(basename $(basename $(XCODE_DEVELOPER_ROOT)))$(shell tput sgr0 2>/dev/null)" >&2)

Expand All @@ -224,6 +231,12 @@ endif
# Tell both Xcode and our build logic which Xcode we're using.
export DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT)
export MD_APPLE_SDK_ROOT=$(abspath $(XCODE_DEVELOPER_ROOT)/../..)
else
# On Linux, set placeholder Xcode values
XCODE_PRODUCT_BUILD_VERSION=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot the XCODE_VERSION and XCODE_URL variables don't need to be conditioned on Linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit a21bcfb. XCODE_VERSION and XCODE_URL are now set unconditionally (outside the ifndef IS_LINUX block).

XCODE_IS_STABLE=true
XCODE_IS_PREVIEW=false
endif

# We don't need to be told there are workload updates
export DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE=true
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ SUBDIRS=builds runtime src msbuild tools
include $(TOP)/Make.config
include $(TOP)/mk/versions.mk

# On Linux, skip directories that require native compilation
ifdef IS_LINUX
SUBDIRS := $(filter-out runtime,$(SUBDIRS))
endif

SUBDIRS += dotnet

#
Expand Down
8 changes: 6 additions & 2 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
<clear />
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
<!-- Begin: Package sources from dotnet-dotnet -->
<add key="darc-pub-dotnet-dotnet-9441e5b" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-dotnet-9441e5bb/nuget/v3/index.json" />
<add key="darc-pub-dotnet-dotnet-455f135" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-dotnet-455f1358/nuget/v3/index.json" />
<!-- End: Package sources from dotnet-dotnet -->
<!-- Begin: Package sources from dotnet-macios -->
<add key="darc-pub-dotnet-macios-e6a0fb7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-macios-e6a0fb79/nuget/v3/index.json" />
<add key="darc-pub-dotnet-macios-6406450" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-macios-64064500/nuget/v3/index.json" />
<!-- End: Package sources from dotnet-macios -->
<!-- Begin: Package sources from xamarin-xamarin-macios -->
<!-- End: Package sources from xamarin-xamarin-macios -->
Expand All @@ -38,10 +38,14 @@
<add key="darc-pub-dotnet-runtime-ad2d4fbc" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-ad2d4fbc/nuget/v3/index.json" />
<!-- Add a 8.0.23 feed -->
<add key="darc-pub-dotnet-runtime-891f8976" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-891f8976/nuget/v3/index.json" />
<!-- Add a 8.0.24 feed -->
<add key="darc-pub-dotnet-runtime-b43df221" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-b43df221/nuget/v3/index.json" />
<!-- Add a 9.0.11 feed -->
<add key="darc-pub-dotnet-runtime-35fe9c61" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-35fe9c61/nuget/v3/index.json" />
<!-- Add a 9.0.12 feed -->
<add key="darc-pub-dotnet-runtime-9c2fb4b7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-9c2fb4b7/nuget/v3/index.json" />
<!-- Add a 9.0.13 feed -->
<add key="darc-pub-dotnet-runtime-7dd1559a" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-runtime-7dd1559a/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
Expand Down
3 changes: 2 additions & 1 deletion builds/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ downloads/$(DOTNET_INSTALL_NAME): dotnet-install.sh
tar -xzf $(DOTNET_CACHE_FILENAME) -C "$@.tmp"; \
else \
./dotnet-install.sh --install-dir "$@.tmp" --version "$(DOTNET_VERSION)" --architecture $(DOTNET_ARCH) --no-path --keep-zip --zip-path "downloads/$(DOTNET_FILENAME)" $$DOTNET_INSTALL_EXTRA_ARGS; \
cp -c downloads/$(DOTNET_FILENAME) $(DOTNET_CACHE_FILENAME); \
mkdir -p $$(dirname $(DOTNET_CACHE_FILENAME)); \
$(CP) downloads/$(DOTNET_FILENAME) $(DOTNET_CACHE_FILENAME); \
echo "Cached the download of $(DOTNET_FILENAME) in ~/Library/Caches/xamarin-macios"; \
fi
$(Q) rm -Rf "$@"
Expand Down
21 changes: 14 additions & 7 deletions builds/create-csproj-for-all-packagereferences.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ WHITE=$(tput setaf 7 || true)
RED=$(tput setaf 9 || true)
CLEAR=$(tput sgr0 || true)

# Detect the OS to use the right sed syntax
if [[ "$(uname -s)" == "Darwin" ]]; then
SED_INPLACE="sed -i ''"
else
SED_INPLACE="sed -i"
fi

OUTPUTPATH=
while [[ $# -gt 0 ]]; do
case $1 in
Expand Down Expand Up @@ -35,7 +42,7 @@ while [[ $# -gt 0 ]]; do
esac
done

TMPPATH=$(PWD)/packagereferences.tmp.csproj
TMPPATH="$PWD/packagereferences.tmp.csproj"

# Go to the root directory
cd "$(git rev-parse --show-toplevel)"
Expand All @@ -44,16 +51,16 @@ cd "$(git rev-parse --show-toplevel)"
git grep -e '<PackageReference.*Include="[a-zA-Z0-9._-]*".*Version="[a-zA-Z0-9._-]*".*>' -h > "$TMPPATH"

# Replace double double quotes with a single double quote. This happens in source code that generates project files (for tests).
sed -i '' 's/""/"/g' "$TMPPATH"
$SED_INPLACE 's/""/"/g' "$TMPPATH"

# Remove packages that we build locally
sed -i '' '/Xamarin.Tests.FrameworksInRuntimesNativeDirectory/d' "$TMPPATH"
sed -i '' '/Xamarin.Tests.DynamicLibrariesInRuntimesNativeDirectory/d' "$TMPPATH"
sed -i '' '/Xamarin.Tests.XCFrameworkWithStaticLibraryInRuntimesNativeDirectory/d' "$TMPPATH"
sed -i '' '/Xamarin.Tests.XCFrameworkWithSymlinks/d' "$TMPPATH"
$SED_INPLACE '/Xamarin.Tests.FrameworksInRuntimesNativeDirectory/d' "$TMPPATH"
$SED_INPLACE '/Xamarin.Tests.DynamicLibrariesInRuntimesNativeDirectory/d' "$TMPPATH"
$SED_INPLACE '/Xamarin.Tests.XCFrameworkWithStaticLibraryInRuntimesNativeDirectory/d' "$TMPPATH"
$SED_INPLACE '/Xamarin.Tests.XCFrameworkWithSymlinks/d' "$TMPPATH"

# Get only the name and version of each package, and write that back in a PackageDownload item
sed -i '' 's@.*<PackageReference.*Include="\([a-zA-Z0-9._-]*\)".*Version="\([a-zA-Z0-9._-]*\)".*>.*@\t\t<PackageDownload Include="\1" Version="[\2]" />@g' "$TMPPATH"
$SED_INPLACE 's@.*<PackageReference.*Include="\([a-zA-Z0-9._-]*\)".*Version="\([a-zA-Z0-9._-]*\)".*>.*@\t\t<PackageDownload Include="\1" Version="[\2]" />@g' "$TMPPATH"

# Sort the references and only list each once.
sort -u -o "$TMPPATH" "$TMPPATH"
Expand Down
4 changes: 2 additions & 2 deletions create-make-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export LANG
# Compute commit distances
for platform in $ALL_DOTNET_PLATFORMS; do
PLATFORM=$(echo "$platform" | tr '[:lower:]' '[:upper:]')
COMMIT=$(git blame -- ./Make.versions HEAD | grep "${PLATFORM}_NUGET_OS_VERSION=" | sed 's/ .*//')
COMMIT=$(git blame -- ./Make.versions HEAD | grep "${PLATFORM}_NUGET_OS_VERSION=" | sed 's/ .*//' | sed 's/^\^//')
COMMIT_DISTANCE=$(git log "$COMMIT..HEAD" --oneline | wc -l | sed -e 's/ //g')
TOTAL_DISTANCE=$((NUGET_VERSION_COMMIT_DISTANCE_START+COMMIT_DISTANCE))
printf "${PLATFORM}_NUGET_COMMIT_DISTANCE:=$TOTAL_DISTANCE\\n" >> "$OUTPUT_FILE"
done

STABLE_COMMIT=$(git blame -L '/^[#[:blank:]]*NUGET_RELEASE_BRANCH=/,+1' -- ./Make.config HEAD | sed 's/ .*//')
STABLE_COMMIT=$(git blame -L '/^[#[:blank:]]*NUGET_RELEASE_BRANCH=/,+1' -- ./Make.config HEAD | sed 's/ .*//' | sed 's/^\^//')
STABLE_COMMIT_DISTANCE=$(git log "$STABLE_COMMIT..HEAD" --oneline | wc -l | sed -e 's/ //g')
STABLE_TOTAL_DISTANCE=$((STABLE_COMMIT_DISTANCE+NUGET_VERSION_STABLE_COMMIT_DISTANCE_START))

Expand Down
14 changes: 14 additions & 0 deletions docs/building-apps/build-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,20 @@ Only applicable to macOS and Mac Catalyst projects.

See [BuildIpa](#buildipa) for iOS and tvOS projects.

## Device

Specifies which mobile device or emulator to target when using `dotnet run
--device <Device>` or MSBuild targets that interact with devices (such as
`Run`, `Install`, or `Uninstall`).

The value can be anything the command-line tools `simctl` or `devicectl`
accept for the device name; this is typically either the UDID or the name of
the device. For example, for the device `My iOS Device` with UDID `00001111-012301230123ABCD`, use
either `-p:Device="My iOS Device"` or `-p:Device=00001111-012301230123ABCD`.

For more information about device selection, see the
[.NET SDK device selection specification](https://github.com/dotnet/sdk/blob/2b9fc02a265c735f2132e4e3626e94962e48bdf5/documentation/specs/dotnet-run-for-maui.md).

## DeviceSpecificBuild

If the build should be specific to the selected device.
Expand Down
32 changes: 30 additions & 2 deletions docs/building-apps/build-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,39 @@ Builds the source code within a project and all dependencies.

Removes all files generated by the build process.

## ComputeAvailableDevices

Queries and returns a list of available iOS or tvOS devices and simulators that can be used with `dotnet run`.

This target is called automatically by the .NET SDK's `dotnet run` command to
support device selection via the `--device` option. It returns a `@(Devices)`
item group where each device has the following metadata:

- **Description**: The name of the device (e.g., "iPhone 16 - iOS 26.0" for simulators, "My iPhone 16" for physical devices)
- **Type**: Either "Device" or "Simulator"
- **OSVersion**: The OS version of the device
- **UDID**: The UDID of the device
- **RuntimeIdentifier**: The RuntimeIdentifier of the device

For example, to list all available devices:

```shell
$ dotnet build -t:ComputeAvailableDevices
```

This target is part of the [.NET SDK device selection specification](https://github.com/dotnet/sdk/blob/2b9fc02a265c735f2132e4e3626e94962e48bdf5/documentation/specs/dotnet-run-for-maui.md) and enables commands like:

```shell
$ dotnet run --device UDID
```

Added in .NET 11.

## Run

Builds the source code within a project and all dependencies, and then deploys and runs it
on a default simulator/device. A specific deployment target can be set by using the `$(_DeviceName)` property.
on a default simulator/device. A specific deployment target can be set by using the `$(Device)` property.

```dotnetcli
dotnet build -t:Run project.csproj -p:_DeviceName=$(MY_DEVICE_UDID)
dotnet build -t:Run project.csproj -p:Device=$(MY_DEVICE_UDID)
```
2 changes: 2 additions & 0 deletions dotnet/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ $(1)_NUGET_TARGETS = \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.$(1).Sdk.props \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.$(1).Sdk.Versions.props \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.$(1).Sdk.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.Sdk.Desktop.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.Sdk.Eol.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Microsoft.Sdk.Mobile.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.DefaultItems.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.Publish.targets \
$(DOTNET_DESTDIR)/$($(1)_NUGET_SDK_NAME)/targets/Xamarin.Shared.Sdk.TargetFrameworkInference.props \
Expand Down
28 changes: 28 additions & 0 deletions dotnet/targets/Microsoft.Sdk.Desktop.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target
Name="_PrepareRunDesktop"
BeforeTargets="ComputeRunArguments"
Condition="'$(_PlatformName)' == 'macOS' Or '$(_PlatformName)' == 'MacCatalyst'">

<PropertyGroup Condition="'$(RunWithOpen)' != 'false'">
<_OpenArguments Condition="'$(XamarinDebugMode)' != ''">$(_OpenArguments) --env __XAMARIN_DEBUG_MODE__=$(XamarinDebugMode)</_OpenArguments>
<_OpenArguments Condition="'$(XamarinDebugPort)' != ''">$(_OpenArguments) --env __XAMARIN_DEBUG_PORT__=$(XamarinDebugPort)</_OpenArguments>
<_OpenArguments Condition="'$(XamarinDebugHosts)' != ''">$(_OpenArguments) --env "__XAMARIN_DEBUG_HOSTS__=$(XamarinDebugHosts)"</_OpenArguments>
<_OpenArguments Condition="'$(XamarinDebugConnectTimeout)' != ''">$(_OpenArguments) --env __XAMARIN_DEBUG_CONNECT_TIMEOUT__=$(XamarinDebugConnectTimeout)</_OpenArguments>
<_OpenArguments Condition="'$(StandardOutputPath)' != ''">$(_OpenArguments) --stdout "$(StandardOutputPath)"</_OpenArguments>
<_OpenArguments Condition="'$(StandardErrorPath)' != ''">$(_OpenArguments) --stderr "$(StandardErrorPath)"</_OpenArguments>
<_OpenArguments Condition="'$(StandardInputPath)' != ''">$(_OpenArguments) --stdin "$(StandardInputPath)"</_OpenArguments>
<_OpenArgumentsPre Condition="'$(OpenNewInstance)' == 'true'">-n </_OpenArgumentsPre>
<_OpenArgumentsPre Condition="'$(OpenWaitForExit)' == 'true'">$(_OpenArgumentsPre) -W </_OpenArgumentsPre>
<_OpenArguments>$(_OpenArguments) $(RunEnvironment)</_OpenArguments>
<RunCommand>open</RunCommand>
<RunArguments>$(_OpenArgumentsPre) -a "$(TargetDir)/$(_AppBundleName).app" $(OpenArguments) $(_OpenArguments) --args</RunArguments>
</PropertyGroup>

<PropertyGroup Condition="'$(RunWithOpen)' == 'false'">
<RunCommand>$(TargetDir)/$(_AppBundleName).app/Contents/MacOS/$(_NativeExecutableName)</RunCommand>
<RunArguments />
</PropertyGroup>
</Target>
</Project>
Loading
Loading