[build] Xamarin.Android build preparation utility (#3051)
Fixes: https://github.com/xamarin/xamarin-android/issues/2562 The `make prepare` **make** target and `msbuild /t:Prepare` MSBuild target are used to "prepare" a `xamarin-android` checkout so that the subsequent `make all` or `msbuild /t:Build` invocation will work. The preparation step involves ensuring that all known required dependencies exist or are provisioned (54a7a029
), such as the build utilities (`autoconf`/etc.), cross-compilers (MinGW), the Android SDK and NDK, and building "enough" to allow `Xamarin.Android.sln` to build (see also7343965a0
). Unfortunately, the Glorious Idea™ of using MSBuild for significant portions of this process is "baroque", making it difficult to understand and maintain, and the requirement on `msbuild` means that things break in really bizarre and obscure ways on Linux and macOS if the installed `mono` version is "too old"...and the determination of "too old" was being done via `mono` & `msbuild`! Furthermore, there was duplication and repetition of various bits of build configuration on Linux and macOS between Makefile and the MSBuild project system, which made it easier to make mistakes. (Then there's the occasional bizarro failures that would result from attempting to evaluate `$(PRODUCT_VERSION)` within `make`; it would fail when `MONO_LOG_LEVEL=info` was set. Then there's...) Instead of having `make prepare` be implemented as an unholy mess of `make` and `msbuild`, introduce the new `build-tools/xaprepare` app. `xaprepare` will be built and executed as part of `make prepare`, and takes over responsibility for repo build preparation. See also: build-tools/xaprepare/README.md TODO: Windows support
This commit is contained in:
Родитель
ea6853a756
Коммит
9302d514a1
|
@ -20,6 +20,7 @@
|
|||
/build-tools/manifest-attribute-codegen @jonpryor
|
||||
/build-tools/scripts/PrepareWindows.targets @jonathanpeppers
|
||||
/build-tools/timing @jonathanpeppers @radekdoulik
|
||||
/build-tools/xaprepare @grendello
|
||||
|
||||
/src/OpenTK-1.0 @radekdoulik @jonpryor
|
||||
/src/Mono.Android.Export @jonpryor
|
||||
|
|
|
@ -38,12 +38,17 @@
|
|||
<AndroidUseLatestPlatformSdk Condition=" '$(AndroidFrameworkVersion)' == '' And '$(_IsRunningNuGetRestore)' == 'True' ">True</AndroidUseLatestPlatformSdk>
|
||||
<DebugType Condition=" '$(DebugType)' == '' ">portable</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(HostOS)' == '' ">
|
||||
<HostOS Condition="$([MSBuild]::IsOSPlatform('windows'))">Windows</HostOS>
|
||||
<HostOS Condition="$([MSBuild]::IsOSPlatform('linux'))">Linux</HostOS>
|
||||
<HostOS Condition="$([MSBuild]::IsOSPlatform('osx'))">Darwin</HostOS>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AutoProvision Condition=" '$(AutoProvision)' == '' ">False</AutoProvision>
|
||||
<AutoProvisionUsesSudo Condition=" '$(AutoProvisionUsesSudo)' == '' ">False</AutoProvisionUsesSudo>
|
||||
<XAInstallPrefix Condition=" '$(XAInstallPrefix)' == '' ">$(MSBuildThisFileDirectory)bin\$(Configuration)\lib\xamarin.android\</XAInstallPrefix>
|
||||
<_XABinRelativeInstallPrefix>lib\xamarin.android</_XABinRelativeInstallPrefix>
|
||||
<XAInstallPrefix Condition=" '$(XAInstallPrefix)' == '' ">$(MSBuildThisFileDirectory)bin\$(Configuration)\$(_XABinRelativeInstallPrefix)\</XAInstallPrefix>
|
||||
<MingwDependenciesRootDirectory Condition=" '$(MingwDependenciesRootDirectory)' == '' ">$(MSBuildThisFileDirectory)\bin\Build$(Configuration)\mingw-deps</MingwDependenciesRootDirectory>
|
||||
<HostOS Condition=" '$(HostOS)' == '' And '$(OS)' == 'Windows_NT' ">Windows</HostOS>
|
||||
<HostCc Condition=" '$(HostCc)' == '' ">$(HostCc64)</HostCc>
|
||||
<HostCxx Condition=" '$(HostCxx)' == '' ">$(HostCxx64)</HostCxx>
|
||||
<HostCc Condition=" '$(HostCc)' == '' ">$(HostCc32)</HostCc>
|
||||
|
@ -171,7 +176,8 @@
|
|||
<AndroidSupportedTargetAotAbisSplit>$(AndroidSupportedTargetAotAbis.Split(':'))</AndroidSupportedTargetAotAbisSplit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RemapAssemblyRefTool>$(ManagedRuntime) $(ManagedRuntimeArgs) "$(MSBuildThisFileDirectory)bin\Build$(Configuration)\remap-assembly-ref.exe"</RemapAssemblyRefTool>
|
||||
<RemapAssemblyRefToolExecutable>$(MSBuildThisFileDirectory)bin\Build$(Configuration)\remap-assembly-ref.exe</RemapAssemblyRefToolExecutable>
|
||||
<RemapAssemblyRefTool>$(ManagedRuntime) $(ManagedRuntimeArgs) "$(RemapAssemblyRefToolExecutable)"</RemapAssemblyRefTool>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Unit Test Properties -->
|
||||
|
|
268
Makefile
268
Makefile
|
@ -1,6 +1,3 @@
|
|||
export OS_NAME := $(shell uname)
|
||||
export OS_ARCH := $(shell uname -m)
|
||||
export NO_SUDO ?= false
|
||||
V ?= 0
|
||||
prefix = /usr/local
|
||||
CONFIGURATION = Debug
|
||||
|
@ -8,23 +5,74 @@ RUNTIME := $(shell which mono64 2> /dev/null && echo mono64 || echo mono)
|
|||
SOLUTION = Xamarin.Android.sln
|
||||
TEST_TARGETS = build-tools/scripts/RunTests.targets
|
||||
API_LEVEL ?=
|
||||
PREPARE_ARGS =
|
||||
PREPARE_BUILD_LOG = bin/Build$(CONFIGURATION)/bootstrap-build.binlog
|
||||
PREPARE_RESTORE_LOG = bin/Build$(CONFIGURATION)/bootstrap-restore.binlog
|
||||
PREPARE_SOURCE_DIR = build-tools/xaprepare
|
||||
PREPARE_SOLUTION = $(PREPARE_SOURCE_DIR)/xaprepare.sln
|
||||
PREPARE_EXE = $(PREPARE_SOURCE_DIR)/xaprepare/bin/$(CONFIGURATION)/xaprepare.exe
|
||||
PREPARE_COMMON_MSBUILD_FLAGS = /p:Configuration=$(CONFIGURATION) $(PREPARE_MSBUILD_ARGS) $(MSBUILD_ARGS)
|
||||
PREPARE_MSBUILD_FLAGS = /binaryLogger:"$(PREPARE_BUILD_LOG)" $(PREPARE_COMMON_MSBUILD_FLAGS)
|
||||
PREPARE_RESTORE_FLAGS = /binaryLogger:"$(PREPARE_RESTORE_LOG)" $(PREPARE_COMMON_MSBUILD_FLAGS)
|
||||
PREPARE_SCENARIO =
|
||||
PREPARE_CI ?= 0
|
||||
PREPARE_AUTOPROVISION ?= 0
|
||||
PREPARE_IGNORE_MONO_VERSION ?= 1
|
||||
|
||||
ifeq ($(OS_NAME),Darwin)
|
||||
export MACOSX_DEPLOYMENT_TARGET := 10.11
|
||||
HOMEBREW_PREFIX ?= $(shell brew --prefix)
|
||||
else
|
||||
HOMEBREW_PREFIX := $prefix
|
||||
_PREPARE_CI_MODE_ARGS = --no-emoji --run-mode=CI -a
|
||||
_PREPARE_ARGS =
|
||||
|
||||
all:
|
||||
$(call MSBUILD_BINLOG,all,$(_SLN_BUILD)) $(MSBUILD_FLAGS) $(SOLUTION)
|
||||
|
||||
-include bin/Build$(CONFIGURATION)/rules.mk
|
||||
|
||||
ifeq ($(OS_NAME),)
|
||||
export OS_NAME := $(shell uname)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),)
|
||||
export OS_ARCH := $(shell uname -m)
|
||||
endif
|
||||
|
||||
export NO_SUDO ?= false
|
||||
|
||||
ifneq ($(NO_SUDO),false)
|
||||
_PREPARE_ARGS += --auto-provisioning-uses-sudo=false
|
||||
endif
|
||||
|
||||
ifneq ($(V),0)
|
||||
MONO_OPTIONS += --debug
|
||||
NUGET_VERBOSITY = -Verbosity Detailed
|
||||
_PREPARE_ARGS += -v:d
|
||||
endif
|
||||
|
||||
ifneq ($(MONO_OPTIONS),)
|
||||
export MONO_OPTIONS
|
||||
ifneq ($(PREPARE_CI),0)
|
||||
_PREPARE_ARGS += $(_PREPARE_CI_MODE_ARGS)
|
||||
endif
|
||||
|
||||
ifneq ($(PREPARE_AUTOPROVISION),0)
|
||||
_PREPARE_ARGS += --auto-provision=yes --auto-provision-uses-sudo=yes
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),Darwin)
|
||||
ifeq ($(HOMEBREW_PREFIX),)
|
||||
HOMEBREW_PREFIX ?= $(shell brew --prefix)
|
||||
endif
|
||||
else
|
||||
HOMEBREW_PREFIX := $prefix
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard Configuration.OperatingSystem.props),)
|
||||
PREPARE_MSBUILD_FLAGS += "/p:HostHomebrewPrefix=$(HOMEBREW_PREFIX)"
|
||||
endif
|
||||
|
||||
ifneq ($(PREPARE_SCENARIO),)
|
||||
_PREPARE_ARGS += -s:"$(PREPARE_SCENARIO)"
|
||||
endif
|
||||
|
||||
_PREPARE_ARGS += $(PREPARE_ARGS)
|
||||
|
||||
include build-tools/scripts/msbuild.mk
|
||||
|
||||
ifeq ($(USE_MSBUILD),1)
|
||||
|
@ -34,12 +82,9 @@ _SLN_BUILD = MSBUILD="$(MSBUILD)" tools/scripts/xabuild
|
|||
endif # $(USE_MSBUILD) == 1
|
||||
|
||||
ifneq ($(API_LEVEL),)
|
||||
MSBUILD_FLAGS += /p:AndroidApiLevel=$(API_LEVEL) /p:AndroidFrameworkVersion=$(word $(API_LEVEL), $(ALL_FRAMEWORKS))
|
||||
MSBUILD_FLAGS += /p:AndroidApiLevel=$(API_LEVEL) /p:AndroidFrameworkVersion=$(word $(API_LEVEL), $(ALL_FRAMEWORKS)) /p:AndroidPlatformId=$(word $(a), $(ALL_PLATFORM_IDS))
|
||||
endif
|
||||
|
||||
all::
|
||||
$(call MSBUILD_BINLOG,all,$(_SLN_BUILD)) $(MSBUILD_FLAGS) $(SOLUTION)
|
||||
|
||||
all-tests::
|
||||
MSBUILD="$(MSBUILD)" $(call MSBUILD_BINLOG,all-tests,tools/scripts/xabuild) $(MSBUILD_FLAGS) Xamarin.Android-Tests.sln
|
||||
|
||||
|
@ -70,87 +115,6 @@ uninstall::
|
|||
rm -rf "$(prefix)/lib/mono/xbuild/Xamarin/Android"
|
||||
rm -rf "$(prefix)/lib/mono/xbuild-frameworks/MonoAndroid"
|
||||
|
||||
ifeq ($(OS_NAME),Linux)
|
||||
export LINUX_DISTRO := $(shell lsb_release -i -s || true)
|
||||
export LINUX_DISTRO_RELEASE := $(shell lsb_release -r -s || true)
|
||||
prepare:: linux-prepare
|
||||
endif # $(OS_NAME)=Linux
|
||||
|
||||
prepare:: prepare-paths prepare-msbuild
|
||||
|
||||
linux-prepare::
|
||||
BINFMT_MISC_TROUBLE="cli win" \
|
||||
BINFMT_WARN=no ; \
|
||||
for m in ${BINFMT_MISC_TROUBLE}; do \
|
||||
if [ -f "/proc/sys/fs/binfmt_misc/$$m" ]; then \
|
||||
BINFMT_WARN=yes ; \
|
||||
fi ; \
|
||||
done ; \
|
||||
if [ "x${BINFMT_WARN}" = "xyes" ]; then \
|
||||
cat Documentation/binfmt_misc-warning-Linux.txt ; \
|
||||
fi; \
|
||||
if [ -f build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO)-$(LINUX_DISTRO_RELEASE).sh ]; then \
|
||||
sh build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO)-$(LINUX_DISTRO_RELEASE).sh $(LINUX_DISTRO_RELEASE); \
|
||||
elif [ -f build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO).sh ]; then \
|
||||
sh build-tools/scripts/dependencies/linux-prepare-$(LINUX_DISTRO).sh $(LINUX_DISTRO_RELEASE); \
|
||||
fi
|
||||
|
||||
# $(call GetPath,path)
|
||||
GetPath = $(shell $(MSBUILD) $(MSBUILD_FLAGS) /p:DoNotLoadOSProperties=True /nologo /v:minimal /t:Get$(1)FullPath build-tools/scripts/Paths.targets | tr -d '[[:space:]]' )
|
||||
|
||||
MSBUILD_PREPARE_PROJS = \
|
||||
src/mono-runtimes/mono-runtimes.csproj \
|
||||
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
|
||||
|
||||
prepare-deps: prepare-cmake-mingw-toolchain
|
||||
git submodule update --init --recursive
|
||||
./build-tools/scripts/generate-os-info Configuration.OperatingSystem.props
|
||||
mkdir -p bin/Build$(CONFIGURATION)
|
||||
$(call MSBUILD_BINLOG,prepare-deps) build-tools/dependencies/dependencies.csproj
|
||||
|
||||
#
|
||||
# $(1): output file name
|
||||
#
|
||||
define create_cmake_toolchain
|
||||
prepare-cmake-mingw-toolchain:: bin/Build$(CONFIGURATION)/$(1)
|
||||
|
||||
bin/Build$(CONFIGURATION)/$(1): build-tools/scripts/$(1).in
|
||||
mkdir -p $$(dir $$@)
|
||||
sed -e 's;@HOMEBREW_PREFIX@;$$(HOMEBREW_PREFIX);g' < $$< > $$@
|
||||
endef
|
||||
|
||||
$(eval $(call create_cmake_toolchain,mingw-32.cmake))
|
||||
$(eval $(call create_cmake_toolchain,mingw-64.cmake))
|
||||
|
||||
prepare-external: prepare-deps
|
||||
nuget restore $(NUGET_VERBOSITY) $(SOLUTION)
|
||||
nuget restore $(NUGET_VERBOSITY) Xamarin.Android-Tests.sln
|
||||
(cd external/xamarin-android-tools && make prepare CONFIGURATION=$(CONFIGURATION))
|
||||
(cd $(call GetPath,JavaInterop) && make prepare CONFIGURATION=$(CONFIGURATION) JI_MAX_JDK=8)
|
||||
(cd $(call GetPath,JavaInterop) && make bin/Build$(CONFIGURATION)/JdkInfo.props CONFIGURATION=$(CONFIGURATION) JI_MAX_JDK=8)
|
||||
|
||||
prepare-bundle: prepare-external
|
||||
$(call MSBUILD_BINLOG,prepare-bundle) build-tools/download-bundle/download-bundle.csproj
|
||||
$(call MSBUILD_BINLOG,prepare-restore) $(MSBUILD_FLAGS) tests/Xamarin.Forms-Performance-Integration/Xamarin.Forms.Performance.Integration.csproj /t:Restore
|
||||
|
||||
prepare-props: prepare-bundle
|
||||
cp $(call GetPath,JavaInterop)/external/Mono.Cecil* "$(call GetPath,MonoSource)/external"
|
||||
cp "$(call GetPath,JavaInterop)/product.snk" "$(call GetPath,MonoSource)"
|
||||
cp build-tools/scripts/Configuration.Java.Interop.Override.props external/Java.Interop/Configuration.Override.props
|
||||
cp $(call GetPath,MonoSource)/mcs/class/msfinal.pub .
|
||||
|
||||
prepare-msbuild: prepare-props
|
||||
ifeq ($(USE_MSBUILD),1)
|
||||
for proj in $(MSBUILD_PREPARE_PROJS); do \
|
||||
$(call MSBUILD_BINLOG,prepare-msbuild) "$$proj" || exit 1; \
|
||||
done
|
||||
endif # msbuild
|
||||
|
||||
prepare-image-dependencies:
|
||||
$(call MSBUILD_BINLOG,prepare-image-deps) build-tools/scripts/PrepareImageDependencies.targets /t:PrepareImageDependencies \
|
||||
/p:AndroidSupportedHostJitAbis=mxe-Win32:mxe-Win64
|
||||
cat bin/Build$(CONFIGURATION)/prepare-image-dependencies.sh | tr -d '\r' > prepare-image-dependencies.sh
|
||||
|
||||
include build-tools/scripts/BuildEverything.mk
|
||||
|
||||
# Must be after BuildEverything.mk - it uses variables defined there
|
||||
|
@ -159,59 +123,10 @@ include tests/api-compatibility/api-compatibility.mk
|
|||
|
||||
topdir := $(shell pwd)
|
||||
|
||||
|
||||
XA_BUILD_PATHS_OUT = bin/Test$(CONFIGURATION)/XABuildPaths.cs
|
||||
|
||||
prepare-paths: $(XA_BUILD_PATHS_OUT)
|
||||
|
||||
$(XA_BUILD_PATHS_OUT): bin/Test%/XABuildPaths.cs: build-tools/scripts/XABuildPaths.cs.in
|
||||
mkdir -p $(shell dirname $@)
|
||||
sed -e 's;@CONFIGURATION@;$*;g' \
|
||||
-e 's;@TOP_DIRECTORY@;$(topdir);g' < $< > $@
|
||||
cat $@
|
||||
|
||||
|
||||
# Usage: $(call CALL_CREATE_THIRD_PARTY_NOTICES,path,licenseType,includeExternalDeps,includeBuildDeps)
|
||||
define CREATE_THIRD_PARTY_NOTICES
|
||||
$(call MSBUILD_BINLOG,create-tpn,$(MSBUILD)) $(_MSBUILD_ARGS) \
|
||||
$(topdir)/build-tools/ThirdPartyNotices/ThirdPartyNotices.csproj \
|
||||
/p:Configuration=$(CONFIGURATION) \
|
||||
/p:ThirdPartyNoticeFile=$(topdir)/$(1) \
|
||||
/p:ThirdPartyNoticeLicenseType=$(2) \
|
||||
/p:TpnIncludeExternalDependencies=$(3) \
|
||||
/p:TpnIncludeBuildDependencies=$(4)
|
||||
endef # CREATE_THIRD_PARTY_NOTICES
|
||||
|
||||
prepare:: prepare-tpn
|
||||
|
||||
TPN_LICENSE_FILES = $(shell grep -h '<LicenseFile>' external/*.tpnitems src/*.tpnitems \
|
||||
| sed -E 's,<LicenseFile>(.*)</LicenseFile>,\1,g;s,.\(MSBuildThisFileDirectory\),$(topdir)/external/,g' \
|
||||
| tr \\ / )
|
||||
|
||||
# Usage: $(call CREATE_THIRD_PARTY_NOTICES_RULE,path,licenseType,includeExternalDeps,includeBuildDeps)
|
||||
define CREATE_THIRD_PARTY_NOTICES_RULE
|
||||
prepare-tpn:: $(1)
|
||||
|
||||
$(1) $(topdir)/$(1): build-tools/ThirdPartyNotices/ThirdPartyNotices.csproj \
|
||||
$(wildcard external/*.tpnitems src/*.tpnitems build-tools/*.tpnitems) \
|
||||
$(TPN_LICENSE_FILES)
|
||||
$(call CREATE_THIRD_PARTY_NOTICES,$(1),$(2),$(3),$(4))
|
||||
endef # CREATE_THIRD_PARTY_NOTICES_RULE
|
||||
|
||||
THIRD_PARTY_NOTICE_LICENSE_TYPE = microsoft-oss
|
||||
|
||||
$(eval $(call CREATE_THIRD_PARTY_NOTICES_RULE,ThirdPartyNotices.txt,foundation,False,False))
|
||||
$(eval $(call CREATE_THIRD_PARTY_NOTICES_RULE,bin/$(CONFIGURATION)/lib/xamarin.android/ThirdPartyNotices.txt,$(THIRD_PARTY_NOTICE_LICENSE_TYPE),True,False))
|
||||
|
||||
# Used by External XA Build
|
||||
EXTERNAL_XA_PATH=$(topdir)
|
||||
EXTERNAL_GIT_PATH=$(topdir)/external
|
||||
|
||||
prepare-external-git-dependencies:
|
||||
msbuild build-tools/xa-prep-tasks/xa-prep-tasks.csproj /p:Configuration=$(CONFIGURATION)
|
||||
msbuild build-tools/xa-prep-tasks/xa-prep-tasks.csproj /p:Configuration=$(CONFIGURATION) \
|
||||
/t:CheckoutExternalGitSources /p:ExternalSourceDependencyDirectory='$(EXTERNAL_GIT_PATH)'
|
||||
|
||||
-include $(EXTERNAL_GIT_PATH)/monodroid/xa-integration.mk
|
||||
|
||||
run-all-tests:
|
||||
|
@ -257,3 +172,68 @@ list-nunit-tests:
|
|||
$(MSBUILD) $(MSBUILD_FLAGS) $(TEST_TARGETS) /t:ListNUnitTests
|
||||
|
||||
include build-tools/scripts/runtime-helpers.mk
|
||||
|
||||
.PHONY: prepare-build-init
|
||||
prepare-build-init:
|
||||
mkdir -p $(dir $(PREPARE_BUILD_LOG))
|
||||
msbuild $(PREPARE_RESTORE_FLAGS) $(PREPARE_SOLUTION) /t:Restore
|
||||
|
||||
.PHONY: prepare-build
|
||||
prepare-build: prepare-build-init
|
||||
msbuild $(PREPARE_MSBUILD_FLAGS) $(PREPARE_SOLUTION)
|
||||
|
||||
.PHONY: prepare-build-ci
|
||||
prepare-build-ci: prepare-build-init
|
||||
msbuild $(PREPARE_MSBUILD_FLAGS) $(PREPARE_SOLUTION) $(_MSBUILD_ARGS)
|
||||
|
||||
.PHONY: prepare
|
||||
prepare:: prepare-build
|
||||
mono --debug $(PREPARE_EXE) $(_PREPARE_ARGS)
|
||||
|
||||
.PHONY: prepare-help
|
||||
prepare-help: prepare-build
|
||||
mono --debug $(PREPARE_EXE) -h
|
||||
|
||||
# Hack: The current commercial pipeline doesn't pass all the required arguments when preparing the build, in particular it doesn't override the
|
||||
# ABI targets to build and so the prepare step configures only for the default set (armeabi-v7a, arm64-v8a, x86, $HOST_OS) which is not enough.
|
||||
# The `jenkins` rule in `BuildEverything.mk`, invoked by the commercial pipeline, now calls the rule below in which we rebuild the bootstrapper
|
||||
# with all the required properties set to include all the ABIs - it should fix the build. After the PR is merged, the commercial pipeline should
|
||||
# be modified to do the right thing instead.
|
||||
#
|
||||
# Commercial pipeline should also set PREPARE_CI=1 when calling targets. Since this is currently not done, we have to pass $(_PREPARE_CI_MODE_ARGS)
|
||||
# directly below
|
||||
#
|
||||
.PHONY: prepare-jenkins
|
||||
prepare-jenkins: prepare-build-ci prepare-commercial
|
||||
@echo preparing jenkins build
|
||||
mono --debug $(PREPARE_EXE) $(_PREPARE_ARGS) $(_PREPARE_CI_MODE_ARGS)
|
||||
|
||||
# This should go away once we can modify the commercial pipeline for the bootstrapper
|
||||
.PHONY: prepare-commercial
|
||||
ifeq ($(USE_COMMERCIAL_INSTALLER_NAME),true)
|
||||
prepare-commercial:
|
||||
cd $(TOP) && ./configure --with-xamarin-android='$(XAMARIN_ANDROID_PATH)'
|
||||
mkdir -p $(XA_MSBUILD_DIR)
|
||||
|
||||
else
|
||||
prepare-commercial:
|
||||
endif
|
||||
|
||||
.PHONY: prepare-update-mono
|
||||
|
||||
prepare-update-mono: prepare-build-ci
|
||||
mono --debug $(PREPARE_EXE) $(_PREPARE_ARGS) $(_PREPARE_CI_MODE_ARGS) /s:UpdateMono
|
||||
|
||||
# These targets exist only temporarily to satisfy requirements of the commercial build (since we can't modify the pipeline script in this PR)
|
||||
.PHONY: prepare-deps
|
||||
|
||||
# Commercial pipeline installs an older version of Mono and in effect we fail. `prepare-deps` is called after provisionator is ran and so we
|
||||
# can, temporarily, re-update Mono here. After the PR is merged and commercial pipeline updated, this step should be removed.
|
||||
prepare-deps: prepare-update-mono
|
||||
@echo prepare-deps is no-op, prepare-jenkins or prepare do the work instead
|
||||
|
||||
prepare-image-dependencies: prepare-build-ci
|
||||
mono --debug $(PREPARE_EXE) $(_PREPARE_ARGS) $(_PREPARE_CI_MODE_ARGS) -s:PrepareImageDependencies
|
||||
|
||||
prepare-external-git-dependencies: prepare-build-ci prepare-update-mono
|
||||
mono --debug $(PREPARE_EXE) $(_PREPARE_ARGS) $(_PREPARE_CI_MODE_ARGS) -s:PrepareExternalGitDependencies
|
||||
|
|
|
@ -16,9 +16,8 @@ The attached notices are provided for information only.
|
|||
3. nunit/nunitlite (https://github.com/nunit/nunitlite/)
|
||||
4. zLibDll/minizip (http://www.winimage.com/zLibDll/minizip.html)
|
||||
|
||||
|
||||
%% bazelbuild/bazel NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
======================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
@ -221,11 +220,12 @@ The attached notices are provided for information only.
|
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
=========================================
|
||||
|
||||
======================================================
|
||||
END OF bazelbuild/bazel NOTICES AND INFORMATION
|
||||
|
||||
%% google/desugar NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
====================================================
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
@ -428,12 +428,12 @@ END OF bazelbuild/bazel NOTICES AND INFORMATION
|
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
=========================================
|
||||
|
||||
====================================================
|
||||
END OF google/desugar NOTICES AND INFORMATION
|
||||
|
||||
%% nunit/nunitlite NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
|
||||
=====================================================
|
||||
Copyright (c) 2004-2013 Charlie Poole
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -454,12 +454,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
=========================================
|
||||
|
||||
|
||||
=====================================================
|
||||
END OF nunit/nunitlite NOTICES AND INFORMATION
|
||||
|
||||
%% zLibDll/minizip NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
|
||||
=====================================================
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
|
@ -478,5 +479,7 @@ appreciated but is not required.
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
=========================================
|
||||
|
||||
=====================================================
|
||||
END OF zLibDll/minizip NOTICES AND INFORMATION
|
||||
|
||||
|
|
|
@ -5,12 +5,8 @@ VisualStudioVersion = 15.0.27428.2037
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build-Tools", "Build-Tools", "{E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "android-toolchain", "build-tools\android-toolchain\android-toolchain.csproj", "{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Tools.BootstrapTasks", "build-tools\Xamarin.Android.Tools.BootstrapTasks\Xamarin.Android.Tools.BootstrapTasks.csproj", "{E8492EFB-D14A-4F32-AA28-88848322ECEA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mono-runtimes", "src\mono-runtimes\mono-runtimes.csproj", "{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "java-runtime", "src\java-runtime\java-runtime.csproj", "{1D4FC8F1-0DA4-4F38-BE68-11AEBA9A0EA4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libzip", "src\libzip\libzip.csproj", "{900A0F71-BAAD-417A-8D1A-8D330297CDD0}"
|
||||
|
@ -21,8 +17,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api-merge", "build-tools\ap
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "remap-assembly-ref", "build-tools\remap-assembly-ref\remap-assembly-ref.csproj", "{C876DA71-8573-4CEF-9149-716D72455ED4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "fetch-windows-assemblers", "build-tools\fetch-windows-assemblers\fetch-windows-assemblers.csproj", "{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{04E3E11E-B47D-4599-8AFC-50515A95E715}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop", "external\Java.Interop\src\Java.Interop\Java.Interop.csproj", "{94BD81F7-B06F-4295-9636-F8A3B6BDC762}"
|
||||
|
@ -83,8 +77,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libZipSharp", "external\Lib
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libzip-windows", "src\libzip-windows\libzip-windows.csproj", "{0DE278D6-000F-4001-BB98-187C0AF58A61}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mingw-dependencies", "build-tools\mingw-dependencies\mingw-dependencies.csproj", "{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "create-bundle", "build-tools\create-bundle\create-bundle.csproj", "{1640725C-4DB8-4D8D-BC96-74E688A06EEF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xa-prep-tasks", "build-tools\xa-prep-tasks\xa-prep-tasks.csproj", "{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}"
|
||||
|
@ -93,8 +85,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Cecil", "ex
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Cecil.Mdb", "external\Java.Interop\src\Xamarin.Android.Cecil\Xamarin.Android.Cecil.Mdb.csproj", "{C0487169-8F81-497F-919E-EB42B1D0243F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dependencies", "build-tools\dependencies\dependencies.csproj", "{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proguard", "src\proguard\proguard.csproj", "{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api-xml-adjuster", "build-tools\api-xml-adjuster\api-xml-adjuster.csproj", "{8A6CB07C-E493-4A4F-AB94-038645A27118}"
|
||||
|
@ -167,18 +157,10 @@ Global
|
|||
Release|AnyCPU = Release|AnyCPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{E8492EFB-D14A-4F32-AA28-88848322ECEA}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{E8492EFB-D14A-4F32-AA28-88848322ECEA}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{E8492EFB-D14A-4F32-AA28-88848322ECEA}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{E8492EFB-D14A-4F32-AA28-88848322ECEA}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{1D4FC8F1-0DA4-4F38-BE68-11AEBA9A0EA4}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{1D4FC8F1-0DA4-4F38-BE68-11AEBA9A0EA4}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{1D4FC8F1-0DA4-4F38-BE68-11AEBA9A0EA4}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -199,10 +181,6 @@ Global
|
|||
{C876DA71-8573-4CEF-9149-716D72455ED4}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{C876DA71-8573-4CEF-9149-716D72455ED4}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{C876DA71-8573-4CEF-9149-716D72455ED4}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -303,14 +281,6 @@ Global
|
|||
{0DE278D6-000F-4001-BB98-187C0AF58A61}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{0DE278D6-000F-4001-BB98-187C0AF58A61}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{0DE278D6-000F-4001-BB98-187C0AF58A61}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{1640725C-4DB8-4D8D-BC96-74E688A06EEF}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{1640725C-4DB8-4D8D-BC96-74E688A06EEF}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{1640725C-4DB8-4D8D-BC96-74E688A06EEF}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{1640725C-4DB8-4D8D-BC96-74E688A06EEF}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -323,10 +293,6 @@ Global
|
|||
{C0487169-8F81-497F-919E-EB42B1D0243F}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{C0487169-8F81-497F-919E-EB42B1D0243F}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{C0487169-8F81-497F-919E-EB42B1D0243F}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.Release|AnyCPU.Build.0 = Release|Any CPU
|
||||
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
|
||||
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Debug|AnyCPU.Build.0 = Debug|Any CPU
|
||||
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Release|AnyCPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -432,9 +398,7 @@ Global
|
|||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{E8492EFB-D14A-4F32-AA28-88848322ECEA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{1D4FC8F1-0DA4-4F38-BE68-11AEBA9A0EA4} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{900A0F71-BAAD-417A-8D1A-8D330297CDD0} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{AFB8F6D1-6EA9-42C3-950B-98F34C669AD2} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
|
@ -466,12 +430,9 @@ Global
|
|||
{5EB9E888-E357-417E-9F39-DDEC195CE47F} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{E248B2CA-303B-4645-ADDC-9D4459D550FD} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{0DE278D6-000F-4001-BB98-187C0AF58A61} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{1640725C-4DB8-4D8D-BC96-74E688A06EEF} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{15945D4B-FF56-4BCC-B598-2718D199DD08} = {864062D3-A415-4A6F-9324-5820237BA058}
|
||||
{C0487169-8F81-497F-919E-EB42B1D0243F} = {864062D3-A415-4A6F-9324-5820237BA058}
|
||||
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
|
||||
{8A6CB07C-E493-4A4F-AB94-038645A27118} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
|
||||
{E0890301-F75F-40E7-B008-54C28B3BA542} = {864062D3-A415-4A6F-9324-5820237BA058}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)Configuration.Override.props" Condition="Exists('$(XamarinAndroidSourcePath)Configuration.Override.props')" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Build$(Configuration)\XABuildConfig.cs" Condition="Exists('$(XamarinAndroidSourcePath)bin\Build$(Configuration)\XABuildConfig.cs')" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Build$(Configuration)\msbuild*.binlog" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Build$(Configuration)\prepare*.log" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)**\ThirdPartyNotices.txt" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)**\config.log" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)**\config.status" />
|
||||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)**\config.h" />
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Configuration.props" />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>$(AndroidToolchainDirectory)</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>$(AndroidToolchainDirectory)</OutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="android-toolchain.projitems" />
|
||||
<Import Project="..\scripts\RequiredPrograms.targets" />
|
||||
<Import Project="android-toolchain.targets" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\xa-prep-tasks\xa-prep-tasks.csproj">
|
||||
<Project>{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}</Project>
|
||||
<Name>xa-prep-tasks</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\dependencies\dependencies.csproj">
|
||||
<Project>{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}</Project>
|
||||
<Name>dependencies</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Xamarin.Android.Tools.BootstrapTasks\Xamarin.Android.Tools.BootstrapTasks.csproj">
|
||||
<Project>{E8492EFB-D14A-4F32-AA28-88848322ECEA}</Project>
|
||||
<Name>Xamarin.Android.Tools.BootstrapTasks</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,169 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AndroidUri Condition=" '$(AndroidUri)' == '' ">https://dl.google.com/android/repository</AndroidUri>
|
||||
<AntUri Condition=" '$(AntUri)' == '' ">https://archive.apache.org/dist/ant/binaries</AntUri>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AndroidNdkItem Include="android-ndk-r$(AndroidNdkVersion)-darwin-x86_64">
|
||||
<HostOS>Darwin</HostOS>
|
||||
</AndroidNdkItem>
|
||||
<AndroidNdkItem Include="android-ndk-r$(AndroidNdkVersion)-linux-x86_64">
|
||||
<HostOS>Linux</HostOS>
|
||||
</AndroidNdkItem>
|
||||
<AndroidNdkItem Include="android-ndk-r$(AndroidNdkVersion)-windows-x86_64">
|
||||
<HostOS>Windows</HostOS>
|
||||
</AndroidNdkItem>
|
||||
<!--
|
||||
$(XABuildToolsVersion) is defined in Configuration.props
|
||||
-->
|
||||
<AndroidSdkItem Include="build-tools_r$(XABuildToolsVersion)-linux">
|
||||
<HostOS>Linux</HostOS>
|
||||
<DestDir>build-tools\$(XABuildToolsFolder)</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-tools_r$(XAPlatformToolsVersion)-linux">
|
||||
<HostOS>Linux</HostOS>
|
||||
<DestDir>platform-tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="sdk-tools-linux-4333796">
|
||||
<HostOS>Linux</HostOS>
|
||||
<DestDir>tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="emulator-linux-$(EmulatorVersion)">
|
||||
<HostOS>Linux</HostOS>
|
||||
<DestDir>emulator</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="build-tools_r$(XABuildToolsVersion)-macosx">
|
||||
<HostOS>Darwin</HostOS>
|
||||
<DestDir>build-tools\$(XABuildToolsFolder)</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-tools_r$(XAPlatformToolsVersion)-darwin">
|
||||
<HostOS>Darwin</HostOS>
|
||||
<DestDir>platform-tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="sdk-tools-darwin-4333796">
|
||||
<HostOS>Darwin</HostOS>
|
||||
<DestDir>tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="emulator-darwin-$(EmulatorVersion)">
|
||||
<HostOS>Darwin</HostOS>
|
||||
<DestDir>emulator</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="build-tools_r$(XABuildToolsVersion)-windows">
|
||||
<HostOS>Windows</HostOS>
|
||||
<DestDir>build-tools\$(XABuildToolsFolder)</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-tools_r$(XAPlatformToolsVersion)-windows">
|
||||
<HostOS>Windows</HostOS>
|
||||
<DestDir>platform-tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="sdk-tools-windows-4333796">
|
||||
<HostOS>Windows</HostOS>
|
||||
<DestDir>tools</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="emulator-windows-$(EmulatorVersion)">
|
||||
<HostOS>Windows</HostOS>
|
||||
<DestDir>emulator</DestDir>
|
||||
</AndroidSdkItem>
|
||||
|
||||
<!-- Note: if the version is changed here (which forces the change of path), make sure to update Configuration.props! -->
|
||||
<AndroidSdkItem Include="cmake-$(AndroidCmakeVersion)-linux-x86_64">
|
||||
<HostOS>Linux</HostOS>
|
||||
<DestDir>cmake\$(AndroidCmakeVersionPath)</DestDir>
|
||||
<NoSubdirectory>True</NoSubdirectory>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="cmake-$(AndroidCmakeVersion)-darwin-x86_64">
|
||||
<HostOS>Darwin</HostOS>
|
||||
<DestDir>cmake\$(AndroidCmakeVersionPath)</DestDir>
|
||||
<NoSubdirectory>True</NoSubdirectory>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="cmake-$(AndroidCmakeVersion)-windows-x86_64">
|
||||
<HostOS>Windows</HostOS>
|
||||
<DestDir>cmake\$(AndroidCmakeVersionPath)</DestDir>
|
||||
<NoSubdirectory>True</NoSubdirectory>
|
||||
</AndroidSdkItem>
|
||||
|
||||
<AndroidSdkItem Include="android-2.3.3_r02-linux">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-10</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-15_r03">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-15</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-16_r04">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-16</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-17_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-17</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-18_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-18</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-19_r03">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-19</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-20_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-20</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-21_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-21</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android-22_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-22</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-23_r03">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-23</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-24_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-24</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-25_r03">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-25</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-26_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-26</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-27_r03">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-27</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-28_r04">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-28</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="platform-Q_r02">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>platforms\android-Q</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="docs-24_r01">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>docs</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="android_m2repository_r16">
|
||||
<HostOS></HostOS>
|
||||
<DestDir>extras\android\m2repository</DestDir>
|
||||
</AndroidSdkItem>
|
||||
<AndroidSdkItem Include="x86-28_r04">
|
||||
<HostOS></HostOS>
|
||||
<RelUrl>sys-img/android/</RelUrl>
|
||||
<DestDir>system-images\android-28\default\x86</DestDir>
|
||||
</AndroidSdkItem>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AntItem Include="apache-ant-1.9.9-bin">
|
||||
<HostOS></HostOS>
|
||||
</AntItem>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,111 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.AcceptAndroidSdkLicenses" />
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.GitCommitHash" />
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.SetEnvironmentVariable" />
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ReplaceFileContents" />
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>
|
||||
ResolveReferences;
|
||||
_DownloadItems;
|
||||
_UnzipFiles;
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.UnzipDirectoryChildren" />
|
||||
<Import Project="..\scripts\NDKVersionInfo.targets" />
|
||||
|
||||
<Target Name="_DetermineItems">
|
||||
<CreateItem
|
||||
Include="@(AndroidSdkItem)"
|
||||
Condition=" '%(HostOS)' == '$(HostOS)' Or '%(HostOS)' == '' ">
|
||||
<Output TaskParameter="Include" ItemName="_PlatformAndroidSdkItem"/>
|
||||
</CreateItem>
|
||||
<CreateItem
|
||||
Include="@(AndroidNdkItem)"
|
||||
Condition=" '%(HostOS)' == '$(HostOS)' Or '%(HostOS)' == '' ">
|
||||
<Output TaskParameter="Include" ItemName="_PlatformAndroidNdkItem"/>
|
||||
</CreateItem>
|
||||
<CreateItem
|
||||
Include="@(AntItem)"
|
||||
Condition=" '%(HostOS)' == '$(HostOS)' Or '%(HostOS)' == '' ">
|
||||
<Output TaskParameter="Include" ItemName="_PlatformAntItem"/>
|
||||
</CreateItem>
|
||||
<ItemGroup>
|
||||
<_SdkStampFiles Include="@(_PlatformAndroidSdkItem->'$(AndroidToolchainDirectory)\sdk\.stamp-%(Identity)')" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<_SdkStampFiles Include="@(_PlatformAntItem->'$(AntDirectory)\.stamp-%(Identity)')" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="_DownloadItems"
|
||||
DependsOnTargets="_DetermineItems"
|
||||
Outputs="@(_DownloadedItem)">
|
||||
<MakeDir Directories="$(AndroidToolchainCacheDirectory)" />
|
||||
<DownloadUri
|
||||
SourceUris="@(_PlatformAndroidSdkItem->'$(AndroidUri)/%(RelUrl)%(Identity).zip')"
|
||||
DestinationFiles="@(_PlatformAndroidSdkItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')">
|
||||
<Output TaskParameter="DestinationFiles" ItemName="_DownloadedItem" />
|
||||
</DownloadUri>
|
||||
<DownloadUri
|
||||
SourceUris="@(_PlatformAndroidNdkItem->'$(AndroidUri)/%(RelUrl)%(Identity).zip')"
|
||||
DestinationFiles="@(_PlatformAndroidNdkItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')">
|
||||
<Output TaskParameter="DestinationFiles" ItemName="_DownloadedItem" />
|
||||
</DownloadUri>
|
||||
<DownloadUri
|
||||
SourceUris="@(_PlatformAntItem->'$(AntUri)/%(RelUrl)%(Identity).zip')"
|
||||
DestinationFiles="@(_PlatformAntItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')">
|
||||
<Output TaskParameter="DestinationFiles" ItemName="_DownloadedItem" />
|
||||
</DownloadUri>
|
||||
</Target>
|
||||
<Target Name="_UnzipFiles"
|
||||
DependsOnTargets="_DetermineItems"
|
||||
Inputs="@(_DownloadedItem)"
|
||||
Outputs="@(_SdkStampFiles);$(AndroidToolchainDirectory)\ndk\.stamp-ndk-$(AndroidNdkVersion)">
|
||||
<PropertyGroup>
|
||||
<_OriginalPath>$(PATH)</_OriginalPath>
|
||||
</PropertyGroup>
|
||||
<CreateItem
|
||||
Include="@(_PlatformAndroidSdkItem->'$(AndroidToolchainCacheDirectory)\%(_PlatformAndroidSdkItem.Identity).zip'">
|
||||
<Output TaskParameter="Include" ItemName="_AndroidSdkItems"/>
|
||||
</CreateItem>
|
||||
<CreateItem
|
||||
Include="@(_PlatformAndroidNdkItem->'$(AndroidToolchainCacheDirectory)\%(_PlatformAndroidNdkItem.Identity).zip'"
|
||||
Condition=" '%(HostOS)' == '$(HostOS)' Or '%(HostOS)' == '' ">
|
||||
<Output TaskParameter="Include" ItemName="_AndroidNdkItems"/>
|
||||
</CreateItem>
|
||||
|
||||
<RemoveDir Directories="$(AndroidSdkDirectory);$(AndroidNdkDirectory);$(AntDirectory)" />
|
||||
<MakeDir Directories="$(AndroidSdkDirectory);$(AndroidNdkDirectory);$(AntDirectory)" />
|
||||
|
||||
<UnzipDirectoryChildren
|
||||
NoSubdirectory="%(_PlatformAndroidSdkItem.NoSubdirectory)"
|
||||
SourceFiles="@(_PlatformAndroidSdkItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')"
|
||||
DestinationFolder="$(AndroidToolchainDirectory)\sdk"
|
||||
/>
|
||||
<UnzipDirectoryChildren
|
||||
NoSubdirectory="%(_PlatformAndroidSdkItem.NoSubdirectory)"
|
||||
SourceFiles="@(_PlatformAndroidNdkItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')"
|
||||
DestinationFolder="$(AndroidToolchainDirectory)\ndk"
|
||||
/>
|
||||
<UnzipDirectoryChildren
|
||||
NoSubdirectory="%(_PlatformAndroidSdkItem.NoSubdirectory)"
|
||||
SourceFiles="@(_PlatformAntItem->'$(AndroidToolchainCacheDirectory)\%(Identity).zip')"
|
||||
DestinationFolder="$(AntDirectory)"
|
||||
/>
|
||||
<AcceptAndroidSdkLicenses AndroidSdkDirectory="$(AndroidSdkDirectory)" JavaSdkDirectory="$(JavaSdkDirectory)" />
|
||||
<Touch
|
||||
Files="@(_SdkStampFiles);$(AndroidToolchainDirectory)\ndk\.stamp-ndk-$(AndroidNdkVersion)"
|
||||
AlwaysCreate="True"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target Name="_CreateBuildConfig"
|
||||
DependsOnTargets="GetNDKVersionInfo"
|
||||
AfterTargets="Build">
|
||||
<ReplaceFileContents
|
||||
SourceFile="..\scripts\XABuildConfig.cs.in"
|
||||
DestinationFile="..\..\bin\Build$(Configuration)\XABuildConfig.cs"
|
||||
Replacements="@NDK_MINIMUM_API_AVAILABLE@=$(_NDKMinimumApiAvailable);@NDK_RELEASE@=$(AndroidNdkVersion);@NDK_REVISION@=$(_NDKRevision);@NDK_VERSION_MAJOR@=$(_NDKVersionMajor);@NDK_VERSION_MINOR@=$(_NDKVersionMinor);@NDK_VERSION_MICRO@=$(_NDKVersionMicro);@NDK_ARMEABI_V7_API@=$(AndroidNdkApiLevel_ArmV7a);@NDK_ARM64_V8A_API@=$(AndroidNdkApiLevel_ArmV8a);@NDK_X86_API@=$(AndroidNdkApiLevel_X86);@NDK_X86_64_API@=$(AndroidNdkApiLevel_X86_64);@XA_SUPPORTED_ABIS@=$(AndroidSupportedTargetJitAbis.Replace(':',';'))">
|
||||
</ReplaceFileContents>
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
</packages>
|
|
@ -8,16 +8,16 @@ trigger:
|
|||
variables:
|
||||
BundleArtifactName: bundle
|
||||
AutoProvisionArgs: /p:AutoProvision=True /p:AutoProvisionUsesSudo=True /p:IgnoreMaxMonoVersion=False
|
||||
AndroidTargetAbiArgs: >-
|
||||
/p:AndroidSupportedTargetJitAbis=armeabi-v7a:arm64-v8a:x86:x86_64
|
||||
/p:AndroidSupportedTargetAotAbis=armeabi-v7a:arm64:x86:x86_64:win-armeabi-v7a:win-arm64:win-x86:win-x86_64
|
||||
|
||||
# Stage and Job "display names" are shortened because they are combined to form the name of the corresponding GitHub check.
|
||||
stages:
|
||||
- stage: prepare
|
||||
displayName: Prepare
|
||||
variables:
|
||||
MSBuildAbiArgs: >-
|
||||
/p:AndroidSupportedTargetJitAbis=armeabi-v7a:arm64-v8a:x86:x86_64
|
||||
/p:AndroidSupportedHostJitAbis=Darwin:mxe-Win32:mxe-Win64
|
||||
/p:AndroidSupportedTargetAotAbis=armeabi-v7a:arm64:x86:x86_64:win-armeabi-v7a:win-arm64:win-x86:win-x86_64
|
||||
MSBuildAbiArgs: $(AndroidTargetAbiArgs) /p:AndroidSupportedHostJitAbis=Darwin:mxe-Win32:mxe-Win64
|
||||
jobs:
|
||||
- job: create_bundle
|
||||
displayName: Bundle
|
||||
|
@ -25,20 +25,17 @@ stages:
|
|||
timeoutInMinutes: 60
|
||||
cancelTimeoutInMinutes: 5
|
||||
steps:
|
||||
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: recursive
|
||||
|
||||
# Ensure the correct Mono.Cecil reference overrides are set before creating the bundle.
|
||||
- script: make prepare-props V=1 CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS="$(AutoProvisionArgs) $(MSBuildAbiArgs)"
|
||||
displayName: make prepare-props
|
||||
|
||||
- task: MSBuild@1
|
||||
# Update Mono in a separate step since xaprepare uses it as well and it will crash when Mono it runs with is updated
|
||||
# The 'prepare' step creates the bundle
|
||||
- script: |
|
||||
make prepare-update-mono PREPARE_CI=1 V=1 CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS="$(AutoProvisionArgs) $(MSBuildAbiArgs)"
|
||||
make prepare PREPARE_CI=1 V=1 CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS="$(AutoProvisionArgs) $(MSBuildAbiArgs)"
|
||||
displayName: create bundle
|
||||
inputs:
|
||||
solution: build-tools/create-bundle/create-bundle.csproj
|
||||
configuration: $(XA.Build.Configuration)
|
||||
msbuildArguments: /bl:$(System.DefaultWorkingDirectory)/bin/Build$(XA.Build.Configuration)/msbuild-createbundle.binlog $(MSBuildAbiArgs)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: copy bundle
|
||||
|
@ -58,7 +55,7 @@ stages:
|
|||
inputs:
|
||||
solution: build-tools/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks.csproj
|
||||
configuration: $(XA.Build.Configuration)
|
||||
msbuildArguments: /t:ZipBuildStatus /p:BuildStatusZipOutputPath=$(Build.ArtifactStagingDirectory)/results
|
||||
msbuildArguments: /t:Build,ZipBuildStatus /p:BuildStatusZipOutputPath=$(Build.ArtifactStagingDirectory)/results
|
||||
condition: always()
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
|
@ -89,7 +86,7 @@ stages:
|
|||
artifactName: $(BundleArtifactName)
|
||||
downloadPath: $(System.DefaultWorkingDirectory)
|
||||
|
||||
- script: make prepare-external-git-dependencies CONFIGURATION=$(XA.Build.Configuration)
|
||||
- script: make prepare-external-git-dependencies PREPARE_CI=1 CONFIGURATION=$(XA.Build.Configuration)
|
||||
displayName: make prepare-commercial
|
||||
condition: eq(variables['XA.Commercial.Build'], 'true')
|
||||
env:
|
||||
|
@ -103,11 +100,12 @@ stages:
|
|||
provisioning_script: $(System.DefaultWorkingDirectory)/external/monodroid/build-tools/provisionator/profile.csx
|
||||
provisioning_extra_args: -vv
|
||||
|
||||
- script: make prepare-deps V=1 CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS="$(AutoProvisionArgs)"
|
||||
displayName: make prepare-deps
|
||||
- script: make prepare-update-mono V=1 CONFIGURATION=$(XA.Build.Configuration) PREPARE_CI=1 PREPARE_ARGS="--bundle-path=$(System.DefaultWorkingDirectory)" MSBUILD_ARGS="$(AutoProvisionArgs) /p:BundleRootPath=$(System.DefaultWorkingDirectory)"
|
||||
displayName: make prepare-update-mono
|
||||
|
||||
- script: make prepare jenkins V=1 CONFIGURATION=$(XA.Build.Configuration) MSBUILD_ARGS="$(AutoProvisionArgs) /p:BundleRootPath=$(System.DefaultWorkingDirectory)"
|
||||
displayName: make prepare jenkins
|
||||
# No need to add `prepare` to the command line, the `jenkins` rule depends on `prepare-jenkins` which will run the bootstrapper
|
||||
- script: make jenkins V=1 CONFIGURATION=$(XA.Build.Configuration) PREPARE_CI=1 PREPARE_ARGS="--bundle-path=$(System.DefaultWorkingDirectory)" MSBUILD_ARGS="$(AutoProvisionArgs) /p:BundleRootPath=$(System.DefaultWorkingDirectory)"
|
||||
displayName: make jenkins
|
||||
|
||||
- script: make create-installers V=1 CONFIGURATION=$(XA.Build.Configuration)
|
||||
displayName: make create-installers
|
||||
|
@ -149,6 +147,8 @@ stages:
|
|||
pool: $(XA.Build.Win.Pool)
|
||||
timeoutInMinutes: 360
|
||||
cancelTimeoutInMinutes: 5
|
||||
variables:
|
||||
JAVA_HOME: '%HOMEDRIVE%%HOMEPATH%\android-toolchain\jdk'
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
@ -160,31 +160,34 @@ stages:
|
|||
downloadPath: $(System.DefaultWorkingDirectory)
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: msbuild Xamarin.Android /t:Prepare
|
||||
displayName: build xaprepare
|
||||
inputs:
|
||||
solution: Xamarin.Android.sln
|
||||
solution: build-tools\xaprepare\xaprepare.sln
|
||||
configuration: $(XA.Build.Configuration)
|
||||
msbuildArguments: /t:Prepare /bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\msbuild-prepare.binlog /p:BundleRootPath=$(System.DefaultWorkingDirectory)
|
||||
msbuildArguments: $(AutoProvisionArgs) $(AndroidTargetAbiArgs) /t:"Restore;Build"
|
||||
|
||||
- script: build-tools\xaprepare\xaprepare\bin\$(XA.Build.Configuration)\xaprepare.exe -v:d --no-emoji --run-mode=CI -a --bundle-path="$(System.DefaultWorkingDirectory)"
|
||||
displayName: run xaprepare
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: msbuild Xamarin.Android /t:Build
|
||||
inputs:
|
||||
solution: Xamarin.Android.sln
|
||||
configuration: $(XA.Build.Configuration)
|
||||
msbuildArguments: /t:Build /bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\msbuild-build.binlog /p:BundleRootPath=$(System.DefaultWorkingDirectory)
|
||||
msbuildArguments: /t:Build /bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\msbuild-build.binlog /p:BundleRootPath=$(System.DefaultWorkingDirectory) $(AndroidTargetAbiArgs)
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: msbuild create-vsix
|
||||
inputs:
|
||||
solution: build-tools\create-vsix\create-vsix.csproj
|
||||
configuration: $(XA.Build.Configuration)
|
||||
msbuildArguments: /p:CreateVsixContainer=True /p:ZipPackageCompressionLevel=Normal /bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\msbuild-create-vsix.binlog
|
||||
msbuildArguments: /p:CreateVsixContainer=True /p:ZipPackageCompressionLevel=Normal /bl:$(System.DefaultWorkingDirectory)\bin\Build$(XA.Build.Configuration)\msbuild-create-vsix.binlog $(AndroidTargetAbiArgs)
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: xabuild Xamarin.Android-Tests
|
||||
inputs:
|
||||
filename: bin\$(XA.Build.Configuration)\bin\xabuild.exe
|
||||
arguments: Xamarin.Android-Tests.sln /p:Configuration=$(XA.Build.Configuration) /p:XAIntegratedTests=False /bl:$(System.DefaultWorkingDirectory)\bin\Test$(XA.Build.Configuration)\msbuild-build-tests.binlog
|
||||
arguments: Xamarin.Android-Tests.sln /p:Configuration=$(XA.Build.Configuration) /p:XAIntegratedTests=False /bl:$(System.DefaultWorkingDirectory)\bin\Test$(XA.Build.Configuration)\msbuild-build-tests.binlog $(AndroidTargetAbiArgs)
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: nunit Xamarin.Android.Build.Tests
|
||||
|
|
|
@ -149,7 +149,7 @@ timestamps {
|
|||
|
||||
utils.stageWithTimeout('prepare deps', 30, 'MINUTES', XADir, true) { // Typically takes less than 2 minutes, but can take longer if any prereqs need to be provisioned
|
||||
if (isCommercial) {
|
||||
sh "make prepare-external-git-dependencies"
|
||||
sh "make prepare-external-git-dependencies PREPARE_CI=1 V=1 "
|
||||
|
||||
utils.stageWithTimeout('provisionator', 30, 'MINUTES', "${commercialPath}/build-tools/provisionator", true) {
|
||||
sh('./provisionator.sh profile.csx -v')
|
||||
|
@ -166,12 +166,11 @@ timestamps {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
sh "make prepare-deps CONFIGURATION=${env.BuildFlavor} V=1 MSBUILD_ARGS='$EXTRA_MSBUILD_ARGS'"
|
||||
}
|
||||
|
||||
utils.stageWithTimeout('build', 6, 'HOURS', XADir, true) { // Typically takes less than one hour except a build on a new bot to populate local caches can take several hours
|
||||
sh "make prepare ${buildTarget} CONFIGURATION=${env.BuildFlavor} V=1 MSBUILD_ARGS='$EXTRA_MSBUILD_ARGS'"
|
||||
sh "make prepare-update-mono CONFIGURATION=${env.BuildFlavor} V=1 PREPARE_CI=1 MSBUILD_ARGS='$EXTRA_MSBUILD_ARGS'"
|
||||
sh "make prepare ${buildTarget} CONFIGURATION=${env.BuildFlavor} V=1 PREPARE_CI=1 MSBUILD_ARGS='$EXTRA_MSBUILD_ARGS'"
|
||||
|
||||
if (isCommercial) {
|
||||
sh "cp bin/${env.BuildFlavor}/bundle-*.zip ${packagePath}"
|
||||
|
|
|
@ -167,7 +167,7 @@ timestamps {
|
|||
fi
|
||||
|
||||
echo 'STAGE: build'
|
||||
make prepare ${buildTarget} CONFIGURATION=${env.BuildFlavor} V=1 NO_SUDO=true MSBUILD_ARGS='/p:MonoRequiredMinimumVersion=5.12'
|
||||
make prepare ${buildTarget} CONFIGURATION=${env.BuildFlavor} V=1 NO_SUDO=true MSBUILD_ARGS='/p:MonoRequiredMinimumVersion=5.12' PREPARE_CI=1
|
||||
|
||||
if [[ "${isPr}" != "true" ]]; then
|
||||
echo 'STAGE: package deb'
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.GitCommitHash" />
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.HashFileContents" />
|
||||
<Target Name="_GetHashes">
|
||||
<GitCommitHash
|
||||
WorkingDirectory="$(LibZipSourceFullPath)"
|
||||
ToolPath="$(GitToolPath)"
|
||||
ToolExe="$(GitToolExe)">
|
||||
<Output TaskParameter="AbbreviatedCommitHash" PropertyName="_LibZipHash" />
|
||||
</GitCommitHash>
|
||||
<GitCommitHash
|
||||
WorkingDirectory="$(MonoSourceFullPath)"
|
||||
ToolPath="$(GitToolPath)"
|
||||
ToolExe="$(GitToolExe)">
|
||||
<Output TaskParameter="AbbreviatedCommitHash" PropertyName="_MonoHash" />
|
||||
</GitCommitHash>
|
||||
<!-- Files which contribute to the bundle "version" -->
|
||||
<ItemGroup>
|
||||
<VersionFile Include="..\..\src\mono-runtimes\mono-runtimes.*" />
|
||||
<VersionFile Include="..\..\src\mono-runtimes\ProfileAssemblies.projitems" />
|
||||
<VersionFile Include="..\scripts\BuildEverything.mk" />
|
||||
<VersionFile Include="..\scripts\Ndk.targets" />
|
||||
</ItemGroup>
|
||||
<HashFileContents
|
||||
Files="@(VersionFile)">
|
||||
<Output TaskParameter="AbbreviatedCompleteHash" PropertyName="_VersionHash"/>
|
||||
</HashFileContents>
|
||||
</Target>
|
||||
<Target Name="GetBundleFileName"
|
||||
DependsOnTargets="_GetHashes">
|
||||
<PropertyGroup>
|
||||
<XABundleVersion>v21</XABundleVersion>
|
||||
<XABundleFileName Condition=" '$(HostOS)' != 'Windows' AND '$(XABundleFileName)' == '' ">bundle-$(XABundleVersion)-h$(_VersionHash)-$(Configuration)-$(HostOS)-libzip=$(_LibZipHash),mono=$(_MonoHash).zip</XABundleFileName>
|
||||
<XABundleFileName Condition=" '$(HostOS)' == 'Windows' AND '$(XABundleFileName)' == '' ">bundle-$(XABundleVersion)-h$(_VersionHash)-$(Configuration)-Darwin-libzip=$(_LibZipHash),mono=$(_MonoHash).zip</XABundleFileName>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,52 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{1640725C-4DB8-4D8D-BC96-74E688A06EEF}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Configuration.props" />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>..\..\bin\Debug</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>..\..\bin\Release</OutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>
|
||||
ResolveReferences;
|
||||
CreateBundle
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
<Import Project="create-bundle.targets" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\xa-prep-tasks\xa-prep-tasks.csproj">
|
||||
<Project>{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}</Project>
|
||||
<Name>xa-prep-tasks</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\android-toolchain\android-toolchain.csproj">
|
||||
<Project>{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}</Project>
|
||||
<Name>android-toolchain</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\mono-runtimes\mono-runtimes.csproj">
|
||||
<Project>{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}</Project>
|
||||
<Name>mono-runtimes</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\libzip\libzip.csproj" Condition=" '$(HostOS)' != 'Windows' ">
|
||||
<Project>{900A0F71-BAAD-417A-8D1A-8D330297CDD0}</Project>
|
||||
<Name>libzip</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\libzip-windows\libzip-windows.csproj">
|
||||
<Project>{0DE278D6-000F-4001-BB98-187C0AF58A61}</Project>
|
||||
<Name>libzip-windows</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask AssemblyFile="$(_SourceTopDir)\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.Zip" />
|
||||
<Import Project="..\..\src\mono-runtimes\mono-runtimes.targets" />
|
||||
<Import Project="..\..\src\libzip\libzip.props" />
|
||||
<Import Project="..\..\src\libzip-windows\libzip-windows.props" />
|
||||
<Import Project="..\..\src\libzip\libzip.projitems" />
|
||||
<Import Project="..\..\src\libzip-windows\libzip-windows.projitems" />
|
||||
<Import Project="..\..\src\libzip\libzip.targets" />
|
||||
<Import Project="bundle-path.targets" />
|
||||
<Target Name="Clean"
|
||||
DependsOnTargets="GetBundleFileName">
|
||||
<Delete Files="$(OutputPath)$(XABundleFileName)" />
|
||||
</Target>
|
||||
<Target Name="_GetArchiveItems"
|
||||
DependsOnTargets="GetMonoBundleItems;GetLibZipBundleItems">
|
||||
</Target>
|
||||
<Target Name="CreateBundle"
|
||||
DependsOnTargets="GetBundleFileName;_GetArchiveItems"
|
||||
Inputs="@(BundleItem)"
|
||||
Outputs="$(OutputPath)$(XABundleFileName)">
|
||||
<Zip
|
||||
Entries="@(BundleItem)"
|
||||
File="$(OutputPath)$(XABundleFileName)"
|
||||
Prefix="$(OutputPath)"
|
||||
/>
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Configuration.props" />
|
||||
<Import Project="dependencies.targets" />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>.\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>.\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<BuildDependsOn>
|
||||
ResolveReferences;
|
||||
CheckForRequiredPrograms;
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\xa-prep-tasks\xa-prep-tasks.csproj">
|
||||
<Project>{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}</Project>
|
||||
<Name>xa-prep-tasks</Name>
|
||||
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_DarwinMonoFramework>MonoFramework-MDK-6.0.0.6.macos10.xamarin.universal.pkg</_DarwinMonoFramework>
|
||||
<_AptGetInstall>apt-get -f -u install</_AptGetInstall>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<RequiredProgram Include="$(HostCcName)" Condition=" '$(HostOS)' != 'Windows' " />
|
||||
<RequiredProgram Include="$(HostCxxName)" Condition=" '$(HostOS)' != 'Windows' " />
|
||||
<RequiredProgram Include="x86_64-w64-mingw32-g++" Condition=" '$(HostOS)' == 'Darwin' And ( $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:')) Or $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win32:')) )" >
|
||||
<Homebrew>mingw-w64</Homebrew>
|
||||
</RequiredProgram>
|
||||
<RequiredProgram Include="autoconf" Condition=" '$(HostOS)' == 'Darwin' ">
|
||||
<Homebrew>autoconf</Homebrew>
|
||||
</RequiredProgram>
|
||||
<RequiredProgram Include="automake" Condition=" '$(HostOS)' == 'Darwin' ">
|
||||
<Homebrew>automake</Homebrew>
|
||||
</RequiredProgram>
|
||||
<RequiredProgram Include="cmake" Condition=" '$(HostOS)' == 'Darwin' ">
|
||||
<Homebrew>cmake</Homebrew>
|
||||
</RequiredProgram>
|
||||
<RequiredProgram Include="ninja" Condition=" '$(HostOS)' == 'Darwin' ">
|
||||
<Homebrew>ninja</Homebrew>
|
||||
</RequiredProgram>
|
||||
<RequiredPackage Include="mingw-zlib" Condition=" '$(HostOS)' == 'Darwin' And ( $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:')) Or $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win32:')) )">
|
||||
<Homebrew>xamarin/xamarin-android-windeps/mingw-zlib</Homebrew>
|
||||
<HomebrewTap>xamarin/xamarin-android-windeps</HomebrewTap>
|
||||
</RequiredPackage>
|
||||
<RequiredProgram Include="$(JavaCPath)">
|
||||
<MinimumVersion>1.8</MinimumVersion>
|
||||
<CurrentVersionCommand Condition=" '$(HostOS)' != 'Windows' ">$(MSBuildThisFileDirectory)..\scripts\javac-version</CurrentVersionCommand>
|
||||
<CurrentVersionCommand Condition=" '$(HostOS)' == 'Windows' ">"$(JavaCPath)" -version 2>&1</CurrentVersionCommand>
|
||||
<UbuntuInstall>$(_AptGetInstall) openjdk-8-jdk</UbuntuInstall>
|
||||
</RequiredProgram>
|
||||
<RequiredProgram Include="make" Condition=" '$(HostOS)' != 'Windows' " />
|
||||
<RequiredProgram Include="$(ManagedRuntime)" Condition=" '$(ManagedRuntime)' != '' ">
|
||||
<MinimumVersion>$(MonoRequiredMinimumVersion)</MinimumVersion>
|
||||
<MaximumVersion Condition=" '$(IgnoreMaxMonoVersion)' == '' Or '$(IgnoreMaxMonoVersion)' == 'False' " >$(MonoRequiredMaximumVersion)</MaximumVersion>
|
||||
<DarwinMinimumVersion>$(MonoRequiredDarwinMinimumVersion)</DarwinMinimumVersion>
|
||||
<CurrentVersionCommand>$(MSBuildThisFileDirectory)..\scripts\mono-version</CurrentVersionCommand>
|
||||
<DarwinMinimumUrl>https://xamjenkinsartifact.azureedge.net/build-package-osx-mono/2019-02/7/12cadb2b21da7f1ad8f5999fd2c5ec8a127c5795/$(_DarwinMonoFramework)</DarwinMinimumUrl>
|
||||
<DarwinInstall>installer -pkg "$(AndroidToolchainCacheDirectory)\$(_DarwinMonoFramework)" -target /</DarwinInstall>
|
||||
</RequiredProgram>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="dependencies.projitems" />
|
||||
<Import Project="..\scripts\RequiredPrograms.targets" />
|
||||
</Project>
|
|
@ -2,14 +2,13 @@
|
|||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask AssemblyFile="$(OutputPath)xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.DownloadUri" />
|
||||
<UsingTask AssemblyFile="$(OutputPath)xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.SystemUnzip" />
|
||||
<Import Project="..\create-bundle\bundle-path.targets" />
|
||||
<Import Project="..\..\bin\Build$(Configuration)\bundle-path.targets" />
|
||||
<PropertyGroup>
|
||||
<_AzureBaseUri>https://xamjenkinsartifact.azureedge.net/mono-jenkins/</_AzureBaseUri>
|
||||
<_NuGetUri>https://dist.nuget.org/win-x86-commandline/v4.7.1/nuget.exe</_NuGetUri>
|
||||
<_NuGetPath>$(MSBuildThisFileDirectory)\..\..\.nuget</_NuGetPath>
|
||||
</PropertyGroup>
|
||||
<Target Name="_GetBundleOutputPath"
|
||||
DependsOnTargets="GetBundleFileName">
|
||||
<Target Name="_GetBundleOutputPath">
|
||||
<PropertyGroup>
|
||||
<BundleRootPath Condition=" '$(BundleRootPath)' == '' ">$(AndroidToolchainCacheDirectory)</BundleRootPath>
|
||||
<_BundlePath>$(BundleRootPath)\$(XABundleFileName)</_BundlePath>
|
||||
|
|
|
@ -1,738 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
//
|
||||
// Taken from:
|
||||
// https://github.com/force-net/Crc32.NET/blob/fbc1061b0cb53df2322d5aed33167a2e6335970b/Crc32.NET/SafeProxy.cs
|
||||
//
|
||||
// License: MIT
|
||||
// https://github.com/force-net/Crc32.NET/blob/fbc1061b0cb53df2322d5aed33167a2e6335970b/LICENSE
|
||||
//
|
||||
class CRC32
|
||||
{
|
||||
const uint Poly = 0xedb88320u;
|
||||
|
||||
readonly uint[] _table = new uint[16 * 256];
|
||||
|
||||
internal CRC32 ()
|
||||
{
|
||||
Init (Poly);
|
||||
}
|
||||
|
||||
protected void Init (uint poly)
|
||||
{
|
||||
var table = _table;
|
||||
for (uint i = 0; i < 256; i++) {
|
||||
uint res = i;
|
||||
for (int t = 0; t < 16; t++) {
|
||||
for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1);
|
||||
table[(t * 256) + i] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public uint Append (uint crc, byte[] input, int offset, int length)
|
||||
{
|
||||
uint crcLocal = uint.MaxValue ^ crc;
|
||||
|
||||
uint[] table = _table;
|
||||
while (length >= 16) {
|
||||
var a = table[(3 * 256) + input[offset + 12]]
|
||||
^ table[(2 * 256) + input[offset + 13]]
|
||||
^ table[(1 * 256) + input[offset + 14]]
|
||||
^ table[(0 * 256) + input[offset + 15]];
|
||||
|
||||
var b = table[(7 * 256) + input[offset + 8]]
|
||||
^ table[(6 * 256) + input[offset + 9]]
|
||||
^ table[(5 * 256) + input[offset + 10]]
|
||||
^ table[(4 * 256) + input[offset + 11]];
|
||||
|
||||
var c = table[(11 * 256) + input[offset + 4]]
|
||||
^ table[(10 * 256) + input[offset + 5]]
|
||||
^ table[(9 * 256) + input[offset + 6]]
|
||||
^ table[(8 * 256) + input[offset + 7]];
|
||||
|
||||
var d = table[(15 * 256) + ((byte)crcLocal ^ input[offset])]
|
||||
^ table[(14 * 256) + ((byte)(crcLocal >> 8) ^ input[offset + 1])]
|
||||
^ table[(13 * 256) + ((byte)(crcLocal >> 16) ^ input[offset + 2])]
|
||||
^ table[(12 * 256) + ((crcLocal >> 24) ^ input[offset + 3])];
|
||||
|
||||
crcLocal = d ^ c ^ b ^ a;
|
||||
offset += 16;
|
||||
length -= 16;
|
||||
}
|
||||
|
||||
while (--length >= 0)
|
||||
crcLocal = table[(byte)(crcLocal ^ input[offset++])] ^ crcLocal >> 8;
|
||||
|
||||
return crcLocal ^ uint.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
class app
|
||||
{
|
||||
const int EndFileChunkSize = 65535 + 22; // Maximum comment size + EOCD size
|
||||
const uint EOCDSignature = 0x06054b50;
|
||||
const uint CDHeaderSignature = 0x02014b50;
|
||||
const uint LFHeaderSignature = 0x04034b50;
|
||||
|
||||
class EOCD
|
||||
{
|
||||
public uint Signature; // Signature (0x06054b50)
|
||||
public ushort DiskNumber; // number of this disk
|
||||
public ushort CDStartDisk; // number of the disk with the start of the central directory
|
||||
public ushort TotalEntriesThisDisk; // total number of entries in the central directory on this disk
|
||||
public ushort TotalEntries; // total number of entries in the central directory
|
||||
public uint CDSize; // size of the central directory
|
||||
public uint CDOffset; // offset of start of central directory with respect to the starting disk number
|
||||
public ushort CommentLength; // .ZIP file comment length
|
||||
};
|
||||
|
||||
class CDHeader
|
||||
{
|
||||
public uint Signature; // 0x02014b50
|
||||
public ushort VersionMadeBy;
|
||||
public ushort VersionNeededToExtract;
|
||||
public ushort GeneralPurposeBitFlag;
|
||||
public ushort CompressionMethod;
|
||||
public ushort LastModFileTime;
|
||||
public ushort LastModFileDate;
|
||||
public uint CRC32;
|
||||
public uint CompressedSize;
|
||||
public uint UncompressedSize;
|
||||
public ushort FileNameLength;
|
||||
public ushort ExtraFieldLength;
|
||||
public ushort FileCommentLength;
|
||||
public ushort DiskNumberStart;
|
||||
public ushort InternalFileAttributes;
|
||||
public uint ExternalFileAttributes;
|
||||
public uint RelativeOffsetOfLocalHeader;
|
||||
public string FileName;
|
||||
public byte[] ExtraField;
|
||||
public string FileComment;
|
||||
};
|
||||
|
||||
class LFHeader
|
||||
{
|
||||
public uint Signature; // 0x04034b50
|
||||
public ushort VersionNeededToExtract;
|
||||
public ushort GeneralPurposeBitFlag;
|
||||
public ushort CompressionMethod;
|
||||
public ushort LastModFileTime;
|
||||
public ushort LastModFileDate;
|
||||
public uint CRC32;
|
||||
public uint CompressedSize;
|
||||
public uint UncompressedSize;
|
||||
public ushort FileNameLength;
|
||||
public ushort ExtraFieldLength;
|
||||
public string FileName;
|
||||
public byte[] ExtraField;
|
||||
};
|
||||
|
||||
static int Main (string[] args)
|
||||
{
|
||||
if (args.Length < 3) {
|
||||
Console.WriteLine ("Usage: fetch-windows-assemblers NDK_VERSION DESTINATION_DIRECTORY NDK_URL");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Task<bool> fetcher = FetchFiles (
|
||||
args [0],
|
||||
args [1],
|
||||
new Uri (args [2])
|
||||
);
|
||||
|
||||
fetcher.Wait ();
|
||||
|
||||
return fetcher.Result ? 0 : 1;
|
||||
}
|
||||
|
||||
static async Task<bool> FetchFiles (string ndkVersion, string destinationDirectory, Uri url)
|
||||
{
|
||||
var neededFiles = new HashSet<string> (StringComparer.OrdinalIgnoreCase) {
|
||||
$"android-ndk-r{ndkVersion}/toolchains/llvm/prebuilt/windows-x86_64/bin/i686-linux-android-as.exe",
|
||||
$"android-ndk-r{ndkVersion}/toolchains/llvm/prebuilt/windows-x86_64/bin/arm-linux-androideabi-as.exe",
|
||||
$"android-ndk-r{ndkVersion}/toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android-as.exe",
|
||||
$"android-ndk-r{ndkVersion}/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-as.exe",
|
||||
};
|
||||
|
||||
using (var httpClient = new HttpClient ()) {
|
||||
bool success;
|
||||
long size;
|
||||
|
||||
Console.WriteLine ($"Retrieving {url}");
|
||||
(success, size) = await GetFileSize (httpClient, url);
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
Console.WriteLine ($" File size: {size}");
|
||||
|
||||
EOCD eocd;
|
||||
(success, eocd) = await GetEOCD (httpClient, url, size);
|
||||
if (!success) {
|
||||
Console.Error.WriteLine ("Failed to find the End of Central Directory record");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eocd.DiskNumber != 0)
|
||||
throw new NotSupportedException ("Multi-disk ZIP archives not supported");
|
||||
|
||||
Console.WriteLine ($" Central Directory offset: {eocd.CDOffset} (0x{eocd.CDOffset:x})");
|
||||
Console.WriteLine ($" Central Directory size: {eocd.CDSize} (0x{eocd.CDSize})");
|
||||
Console.WriteLine ($" Total Entries: {eocd.TotalEntries}");
|
||||
|
||||
Stream cd;
|
||||
(success, cd) = await ReadCD (httpClient, url, eocd.CDOffset, eocd.CDSize, size);
|
||||
if (!success) {
|
||||
Console.Error.WriteLine ("Failed to read the Central Directory");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine ("Entries:");
|
||||
if (!await ProcessEntries (httpClient, url, eocd, cd, neededFiles, destinationDirectory))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static async Task<bool> ProcessEntries (HttpClient httpClient, Uri url, EOCD eocd, Stream centralDirectory, HashSet<string> neededFiles, string destinationDirectory)
|
||||
{
|
||||
long foundEntries = 0;
|
||||
|
||||
using (var br = new BinaryReader (centralDirectory)) {
|
||||
long nread = 0;
|
||||
long nentries = 1;
|
||||
|
||||
while (nread < centralDirectory.Length && nentries <= eocd.TotalEntries) {
|
||||
(bool success, CDHeader cdh) = ReadCDHeader (br, centralDirectory.Length, ref nread);
|
||||
nentries++;
|
||||
if (!success) {
|
||||
Console.Error.WriteLine ($"Failed to read a Central Directory file header for entry {nentries}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!neededFiles.Contains (cdh.FileName))
|
||||
continue;
|
||||
|
||||
if (!await ReadEntry (httpClient, url, cdh, br, destinationDirectory))
|
||||
return false;
|
||||
foundEntries++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundEntries < neededFiles.Count) {
|
||||
Console.WriteLine ($"Could not find all required binaries. Found {foundEntries} out of {neededFiles.Count}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static async Task<bool> ReadEntry (HttpClient httpClient, Uri url, CDHeader cdh, BinaryReader br, string destinationDirectory)
|
||||
{
|
||||
string compressedFilePath = Path.Combine (destinationDirectory, $"{Path.GetFileName (cdh.FileName)}.deflated");
|
||||
Console.WriteLine ($" {cdh.FileName} (offset: {cdh.RelativeOffsetOfLocalHeader})");
|
||||
|
||||
(bool success, Stream contentStream) = await ReadFileData (httpClient, url, cdh);
|
||||
if (!success) {
|
||||
Console.Error.WriteLine ("Failed to read file data");
|
||||
return false;
|
||||
}
|
||||
|
||||
using (var destFile = new BinaryWriter (File.OpenWrite (compressedFilePath))) {
|
||||
using (var fbr = new BinaryReader (contentStream)) {
|
||||
if (!await DownloadAndExtract (fbr, contentStream, destFile, compressedFilePath))
|
||||
return CleanupAndReturn (false);
|
||||
}
|
||||
}
|
||||
|
||||
return CleanupAndReturn (true);
|
||||
|
||||
bool CleanupAndReturn (bool retval)
|
||||
{
|
||||
if (File.Exists (compressedFilePath))
|
||||
File.Delete (compressedFilePath);
|
||||
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
static async Task<bool> DownloadAndExtract (BinaryReader fbr, Stream contentStream, BinaryWriter destFile, string destFileName)
|
||||
{
|
||||
long fread = 0;
|
||||
(bool success, LFHeader lfh) = ReadLFHeader (fbr, contentStream.Length, ref fread);
|
||||
if (!success) {
|
||||
Console.Error.WriteLine ("Failed to read local file header");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint dread = 0;
|
||||
var buffer = new byte [8192];
|
||||
while (fread <= contentStream.Length && dread < lfh.CompressedSize) {
|
||||
uint toRead;
|
||||
if (lfh.CompressedSize - dread < buffer.Length)
|
||||
toRead = lfh.CompressedSize - dread;
|
||||
else
|
||||
toRead = (uint)buffer.Length;
|
||||
|
||||
int bread = await contentStream.ReadAsync (buffer, 0, (int)toRead);
|
||||
if (bread == 0)
|
||||
break;
|
||||
destFile.Write (buffer, 0, bread);
|
||||
fread += bread;
|
||||
dread += (uint)bread;
|
||||
}
|
||||
|
||||
destFile.Flush ();
|
||||
destFile.Close ();
|
||||
destFile.Dispose ();
|
||||
Extract (destFileName, lfh.CRC32);
|
||||
|
||||
if (dread != lfh.CompressedSize)
|
||||
Console.Error.WriteLine ($" Invalid data size: expected {lfh.CompressedSize} bytes, read {dread} bytes");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Extract (string compressedFilePath, uint crc32FromHeader)
|
||||
{
|
||||
string outputFile = Path.GetFileNameWithoutExtension (compressedFilePath);
|
||||
using (var fs = File.OpenRead (compressedFilePath)) {
|
||||
using (var dfs = File.OpenWrite (outputFile)) {
|
||||
Extract (fs, dfs, crc32FromHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Extract (Stream src, Stream dest, uint crc32FromHeader)
|
||||
{
|
||||
uint fileCRC = 0;
|
||||
int fread = 0;
|
||||
var crc32 = new CRC32 ();
|
||||
var buffer = new byte [8192];
|
||||
|
||||
using (var iis = new DeflateStream (src, CompressionMode.Decompress)) {
|
||||
while (true) {
|
||||
fread = iis.Read(buffer, 0, buffer.Length);
|
||||
if (fread <= 0)
|
||||
break;
|
||||
|
||||
fileCRC = crc32.Append (fileCRC, buffer, 0, fread);
|
||||
dest.Write (buffer, 0, fread);
|
||||
}
|
||||
dest.Flush ();
|
||||
}
|
||||
|
||||
if (fileCRC != crc32FromHeader)
|
||||
Console.Error.WriteLine ($" Invalid CRC32: expected 0x{crc32FromHeader:x}, got 0x{fileCRC:x}");
|
||||
}
|
||||
|
||||
static async Task<(bool success, Stream data)> ReadFileData (HttpClient httpClient, Uri url, CDHeader cdh)
|
||||
{
|
||||
long fileOffset = cdh.RelativeOffsetOfLocalHeader;
|
||||
long dataSize =
|
||||
cdh.CompressedSize +
|
||||
30 + // local file header size, the static portion
|
||||
cdh.FileName.Length + // They're the same in both haders
|
||||
cdh.ExtraFieldLength + // This may differ between headers...
|
||||
16384; // ...so we add some extra padding
|
||||
|
||||
var req = new HttpRequestMessage (HttpMethod.Get, url);
|
||||
req.Headers.ConnectionClose = true;
|
||||
req.Headers.Range = new RangeHeaderValue (fileOffset, fileOffset + dataSize);
|
||||
|
||||
HttpResponseMessage resp = await httpClient.SendAsync (req).ConfigureAwait (false);
|
||||
|
||||
if (!resp.IsSuccessStatusCode) {
|
||||
Console.Error.WriteLine ($"Failed to read file data: HTTP error {resp.StatusCode}");
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
Stream s = await resp.Content.ReadAsStreamAsync ().ConfigureAwait (false);
|
||||
if (s.Length < dataSize) {
|
||||
Console.Error.WriteLine ($"Failed to read file data: invalid data length ({s.Length} < {dataSize})");
|
||||
s.Dispose ();
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
return (true, s);
|
||||
}
|
||||
|
||||
static (bool success, LFHeader lfh) ReadLFHeader (BinaryReader cdr, long dataLength, ref long nread)
|
||||
{
|
||||
var lfh = new LFHeader ();
|
||||
|
||||
bool worked;
|
||||
string whatFailed = null;
|
||||
lfh.Signature = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked || lfh.Signature != LFHeaderSignature) {
|
||||
whatFailed = $"Signature ({lfh.Signature:x} != {LFHeaderSignature:x})";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.VersionNeededToExtract = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "VersionNeededToExtract";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.GeneralPurposeBitFlag = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "GeneralPurposeBitFlag";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.CompressionMethod = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CompressionMethod";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.LastModFileTime = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "LastModFileTime";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.LastModFileDate = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "LastModFileDate";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.CRC32 = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CRC32";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.CompressedSize = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CompressedSize";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.UncompressedSize = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "UncompressedSize";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.FileNameLength = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileNameLength";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.ExtraFieldLength = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "ExtraFieldLength";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
byte[] bytes = ReadBytes (cdr, lfh.FileNameLength, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileName (bytes)";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lfh.FileName = Encoding.ASCII.GetString (bytes);
|
||||
if (!worked) {
|
||||
whatFailed = "FileName (ASCII decode)";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (lfh.ExtraFieldLength > 0) {
|
||||
lfh.ExtraField = ReadBytes (cdr, lfh.ExtraFieldLength, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "ExtraField";
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
return (true, lfh);
|
||||
|
||||
failed:
|
||||
if (!String.IsNullOrEmpty (whatFailed))
|
||||
Console.Error.WriteLine ($"Failed to read a local file header field: {whatFailed}");
|
||||
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
static (bool success, CDHeader cdh) ReadCDHeader (BinaryReader cdr, long dataLength, ref long nread)
|
||||
{
|
||||
var cdh = new CDHeader ();
|
||||
|
||||
bool worked;
|
||||
string whatFailed = null;
|
||||
cdh.Signature = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked || cdh.Signature != CDHeaderSignature) {
|
||||
whatFailed = "Signature ({cdh.Signature:x} != {CDHeaderSignature:x})";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.VersionMadeBy = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "VersionMadeBy";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.VersionNeededToExtract = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "VersionNeededToExtract";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.GeneralPurposeBitFlag = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "GeneralPurposeBitFlag";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.CompressionMethod = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CompressionMethod";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.LastModFileTime = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "LastModFileTime";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.LastModFileDate = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "LastModFileDate";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.CRC32 = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CRC32";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.CompressedSize = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "CompressedSize";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.UncompressedSize = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "UncompressedSize";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.FileNameLength = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileNameLength";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.ExtraFieldLength = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "ExtraFieldLength";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.FileCommentLength = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileCommentLength";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.DiskNumberStart = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "DiskNumberStart";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.InternalFileAttributes = ReadUShort (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "InternalFileAttributes";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.ExternalFileAttributes = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "ExternalFileAttributes";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.RelativeOffsetOfLocalHeader = ReadUInt (cdr, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "RelativeOffsetOfLocalHeader";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
byte[] bytes = ReadBytes (cdr, cdh.FileNameLength, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileName (bytes)";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cdh.FileName = Encoding.ASCII.GetString (bytes);
|
||||
if (!worked) {
|
||||
whatFailed = "FileName (ASCII decode)";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (cdh.ExtraFieldLength > 0) {
|
||||
cdh.ExtraField = ReadBytes (cdr, cdh.ExtraFieldLength, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "ExtraField";
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (cdh.FileCommentLength > 0) {
|
||||
bytes = ReadBytes (cdr, cdh.FileCommentLength, dataLength, ref nread, out worked);
|
||||
if (!worked) {
|
||||
whatFailed = "FileComment (bytes)";
|
||||
goto failed;
|
||||
}
|
||||
cdh.FileComment = Encoding.ASCII.GetString (bytes);
|
||||
}
|
||||
|
||||
return (true, cdh);
|
||||
|
||||
failed:
|
||||
if (!String.IsNullOrEmpty (whatFailed))
|
||||
Console.Error.WriteLine ($"Failed to read a central directory header field: {whatFailed}");
|
||||
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
static ushort ReadUShort (BinaryReader br, long dataLength, ref long nread, out bool success)
|
||||
{
|
||||
success = false;
|
||||
if (dataLength - nread < 2)
|
||||
return 0;
|
||||
|
||||
ushort ret = br.ReadUInt16 ();
|
||||
nread += 2;
|
||||
|
||||
success = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint ReadUInt (BinaryReader br, long dataLength, ref long nread, out bool success)
|
||||
{
|
||||
success = false;
|
||||
if (dataLength - nread < 4)
|
||||
return 0;
|
||||
|
||||
uint ret = br.ReadUInt32 ();
|
||||
nread += 4;
|
||||
|
||||
success = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static byte[] ReadBytes (BinaryReader br, int neededBytes, long dataLength, ref long nread, out bool success)
|
||||
{
|
||||
success = false;
|
||||
if (dataLength - nread < neededBytes)
|
||||
return null;
|
||||
|
||||
byte[] ret = br.ReadBytes (neededBytes);
|
||||
nread += neededBytes;
|
||||
|
||||
success = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static async Task<(bool success, Stream cd)> ReadCD (HttpClient httpClient, Uri url, uint cdOffset, uint cdSize, long fileSize)
|
||||
{
|
||||
long fileOffset = cdOffset;
|
||||
var req = new HttpRequestMessage (HttpMethod.Get, url);
|
||||
req.Headers.ConnectionClose = true;
|
||||
req.Headers.Range = new RangeHeaderValue (fileOffset, fileOffset + cdSize);
|
||||
|
||||
HttpResponseMessage resp = await httpClient.SendAsync (req).ConfigureAwait (false);
|
||||
if (!resp.IsSuccessStatusCode) {
|
||||
Console.Error.WriteLine ($"Failed to read Central Directory: HTTP error {resp.StatusCode}");
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
Stream s = await resp.Content.ReadAsStreamAsync ().ConfigureAwait (false);
|
||||
if (s.Length < cdSize) {
|
||||
Console.Error.WriteLine ($"Failed to read Central Directory: invalid data length ({s.Length} < {cdSize})");
|
||||
s.Dispose ();
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
return (true, s);
|
||||
}
|
||||
|
||||
static async Task<(bool success, EOCD eocd)> GetEOCD (HttpClient httpClient, Uri url, long fileSize)
|
||||
{
|
||||
long fileOffset = fileSize - EndFileChunkSize;
|
||||
var req = new HttpRequestMessage (HttpMethod.Get, url);
|
||||
req.Headers.ConnectionClose = true;
|
||||
req.Headers.Range = new RangeHeaderValue (fileOffset, fileSize);
|
||||
|
||||
HttpResponseMessage resp = await httpClient.SendAsync (req).ConfigureAwait (false);
|
||||
if (!resp.IsSuccessStatusCode)
|
||||
return (false, null);
|
||||
|
||||
using (var eocdStream = await resp.Content.ReadAsStreamAsync ().ConfigureAwait (false)) {
|
||||
using (var sr = new BinaryReader (eocdStream)) {
|
||||
byte[] expected = {0x50, 0x4b, 0x05, 0x06};
|
||||
int expectedPos = 0;
|
||||
|
||||
for (int i = 0; i < eocdStream.Length; i++) {
|
||||
byte b = sr.ReadByte ();
|
||||
if (b != expected [expectedPos]) {
|
||||
expectedPos = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expectedPos == expected.Length - 1) {
|
||||
// We've found the signature
|
||||
var eocd = new EOCD ();
|
||||
eocd.Signature = 0x06054b50;
|
||||
eocd.DiskNumber = sr.ReadUInt16 ();
|
||||
eocd.CDStartDisk = sr.ReadUInt16 ();
|
||||
eocd.TotalEntriesThisDisk = sr.ReadUInt16 ();
|
||||
eocd.TotalEntries = sr.ReadUInt16 ();
|
||||
eocd.CDSize = sr.ReadUInt32 ();
|
||||
eocd.CDOffset = sr.ReadUInt32 ();
|
||||
eocd.CommentLength = sr.ReadUInt16 ();
|
||||
|
||||
return (true, eocd);
|
||||
}
|
||||
|
||||
expectedPos++;
|
||||
if (expectedPos >= expected.Length)
|
||||
expectedPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
static async Task<(bool success, long size)> GetFileSize (HttpClient httpClient, Uri url)
|
||||
{
|
||||
var req = new HttpRequestMessage (HttpMethod.Head, url);
|
||||
req.Headers.ConnectionClose = true;
|
||||
|
||||
HttpResponseMessage resp = await httpClient.SendAsync (req).ConfigureAwait (false);
|
||||
if (!resp.IsSuccessStatusCode || !resp.Content.Headers.ContentLength.HasValue)
|
||||
return (false, 0);
|
||||
|
||||
return (true, resp.Content.Headers.ContentLength.Value);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{09518DF2-C7B1-4CDB-849A-9F91F4BEA925}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>fetchwindowsassemblers</RootNamespace>
|
||||
<AssemblyName>fetch-windows-assemblers</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Configuration.props" />
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\bin\BuildDebug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\bin\BuildRelease</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="fetch-windows-assemblers.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\scripts\XAVersionInfo.targets" />
|
||||
<Import Project="..\..\src\mono-runtimes\ProfileAssemblies.projitems" />
|
||||
<Import Project="..\..\bin\Build$(Configuration)\ProfileAssemblies.projitems" />
|
||||
<Import Project="..\..\src\Mono.Android\Mono.Android.projitems" />
|
||||
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ReplaceFileContents" />
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Mono Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the ""Software""), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2C1C68CD-CFED-4DEB-A2D3-61D6932F3E8E}</ProjectGuid>
|
||||
<ForceBuildProjectFilePath>$(MSBuildThisFileFullPath)</ForceBuildProjectFilePath>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Configuration.props" />
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>$(MingwDependenciesRootDirectory)</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>$(MingwDependenciesRootDirectory)</OutputPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
|
||||
<PropertyGroup>
|
||||
<BuildDependsOnLocal Condition=" '$(HostOS)' != 'Windows' And ($(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:')) Or $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win32:')))">
|
||||
ResolveReferences;
|
||||
_BuildUnlessCached
|
||||
</BuildDependsOnLocal>
|
||||
</PropertyGroup>
|
||||
<Import Project="mingw-dependencies.props" />
|
||||
<Import Project="mingw-dependencies.projitems" />
|
||||
<Import Project="mingw-dependencies.targets" />
|
||||
<Target Name="Build" DependsOnTargets="$(BuildDependsOnLocal)" />
|
||||
<Target Name="Clean" />
|
||||
</Project>
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CMake>cmake</CMake>
|
||||
<Ninja>ninja</Ninja>
|
||||
<_OutputSubdir32>x86</_OutputSubdir32>
|
||||
<_OutputSubdir64>x86_64</_OutputSubdir64>
|
||||
<_CommonCmakeProjectFlags>-DCMAKE_MAKE_PROGRAM=$(Ninja) -GNinja -DBUILD_TESTS=OFF</_CommonCmakeProjectFlags>
|
||||
<_CmakeNoSharedLibsFlags>-DBUILD_SHARED_LIBS=OFF</_CmakeNoSharedLibsFlags>
|
||||
<_CmakeWithSharedLibsFlags>-DBUILD_SHARED_LIBS=ON</_CmakeWithSharedLibsFlags>
|
||||
<_CMakeFlags32>-DCMAKE_INSTALL_PREFIX=$(MingwDependenciesRootDirectory)\$(_OutputSubdir32)</_CMakeFlags32>
|
||||
<_CMakeFlags64>-DCMAKE_INSTALL_PREFIX=$(MingwDependenciesRootDirectory)\$(_OutputSubdir64)</_CMakeFlags64>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<_CmakeMingwDependency Include="dlfcn-win32-64" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))">
|
||||
<CMake>$(CMake)</CMake>
|
||||
<Ninja>$(Ninja)</Ninja>
|
||||
<Submodule>dlfcn-win32</Submodule>
|
||||
<CMakeToolchainFile>..\..\bin\Build$(Configuration)\mingw-64.cmake</CMakeToolchainFile>
|
||||
<CMakeExtraFlags>$(_CommonCmakeProjectFlags) $(_CMakeFlags64) $(_CmakeNoSharedLibsFlags)</CMakeExtraFlags>
|
||||
<DestinationDirectory>$(MingwDependenciesRootDirectory)\$(_OutputSubdir64)\</DestinationDirectory>
|
||||
<OutputLibrary>lib\libdl.a</OutputLibrary>
|
||||
</_CmakeMingwDependency>
|
||||
|
||||
<_CmakeMingwDependency Include="dlfcn-win32-32" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win32:'))">
|
||||
<CMake>$(CMake)</CMake>
|
||||
<Ninja>$(Ninja)</Ninja>
|
||||
<Submodule>dlfcn-win32</Submodule>
|
||||
<CMakeToolchainFile>..\..\bin\Build$(Configuration)\mingw-32.cmake</CMakeToolchainFile>
|
||||
<CMakeExtraFlags>$(_CommonCmakeProjectFlags) $(_CMakeFlags32) $(_CmakeNoSharedLibsFlags)</CMakeExtraFlags>
|
||||
<DestinationDirectory>$(MingwDependenciesRootDirectory)\$(_OutputSubdir32)\</DestinationDirectory>
|
||||
<OutputLibrary>lib\libdl.a</OutputLibrary>
|
||||
</_CmakeMingwDependency>
|
||||
|
||||
<_CmakeMingwDependency Include="mman-win32-64" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))">
|
||||
<CMake>$(CMake)</CMake>
|
||||
<Ninja>$(Ninja)</Ninja>
|
||||
<Submodule>mman-win32</Submodule>
|
||||
<CMakeToolchainFile>..\..\bin\Build$(Configuration)\mingw-64.cmake</CMakeToolchainFile>
|
||||
<CMakeExtraFlags>$(_CommonCmakeProjectFlags) $(_CMakeFlags64) $(_CmakeNoSharedLibsFlags)</CMakeExtraFlags>
|
||||
<DestinationDirectory>$(MingwDependenciesRootDirectory)\$(_OutputSubdir64)\</DestinationDirectory>
|
||||
<OutputLibrary>lib\libmman.a</OutputLibrary>
|
||||
</_CmakeMingwDependency>
|
||||
|
||||
<_CmakeMingwDependency Include="mman-win32-32" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win32:'))">
|
||||
<CMake>$(CMake)</CMake>
|
||||
<Ninja>$(Ninja)</Ninja>
|
||||
<Submodule>mman-win32</Submodule>
|
||||
<CMakeToolchainFile>..\..\bin\Build$(Configuration)\mingw-32.cmake</CMakeToolchainFile>
|
||||
<CMakeExtraFlags>$(_CommonCmakeProjectFlags) $(_CMakeFlags32) $(_CmakeNoSharedLibsFlags)</CMakeExtraFlags>
|
||||
<DestinationDirectory>$(MingwDependenciesRootDirectory)\$(_OutputSubdir32)\</DestinationDirectory>
|
||||
<OutputLibrary>lib\libmman.a</OutputLibrary>
|
||||
</_CmakeMingwDependency>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,89 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\build-tools\scripts\RequiredPrograms.targets" />
|
||||
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.CreateFilePaths" />
|
||||
<PropertyGroup>
|
||||
<ForceBuildDependsOn>
|
||||
CheckForRequiredPrograms;
|
||||
_Configure;
|
||||
_Make
|
||||
</ForceBuildDependsOn>
|
||||
<_LibZipOutputPath>$(XAInstallPrefix)xbuild\Xamarin\Android\</_LibZipOutputPath>
|
||||
</PropertyGroup>
|
||||
<Target Name="Build" DependsOnTargets="$(BuildDependsOn)" />
|
||||
<Target Name="Clean" />
|
||||
|
||||
<Target Name="_SetCMakeListsTxtTimeToLastCommitTimestamp">
|
||||
<GitCommitTime
|
||||
WorkingDirectory="$(_SubmoduleTopDir)\%(_CmakeMingwDependency.Submodule)"
|
||||
ToolPath="$(GitToolPath)"
|
||||
ToolExe="$(GitToolExe)">
|
||||
<Output TaskParameter="Time" PropertyName="_MingwDepCommitTime" />
|
||||
</GitCommitTime>
|
||||
<Touch Files="@(_CmakeMingwDependency->'$(_SubmoduleTopDir)\%(Submodule)\CMakeLists.txt')" Time="$(_MingwDepCommitTime)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_Configure"
|
||||
Condition=" '@(_CmakeMingwDependency)' != '' "
|
||||
DependsOnTargets="_SetCMakeListsTxtTimeToLastCommitTimestamp"
|
||||
Inputs="@(_CmakeMingwDependency->'$(_SubmoduleTopDir)\%(Submodule)\CMakeLists.txt')"
|
||||
Outputs="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)\build.ninja">
|
||||
<MakeDir Directories="@(_CmakeMingwDependency->'$(IntermediateOutputPath)\%(Identity)')" />
|
||||
<Exec
|
||||
Command="%(_CmakeMingwDependency.CMake) -DCMAKE_TOOLCHAIN_FILE=$(MSBuildThisFileDirectory)\%(_CmakeMingwDependency.CMakeToolchainFile) %(_CmakeMingwDependency.CMakeExtraFlags) $(_SubmoduleTopDir)\%(_CmakeMingwDependency.Submodule)"
|
||||
WorkingDirectory="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target Name="_Make"
|
||||
Condition=" '@(_CmakeMingwDependency)' != '' "
|
||||
Inputs="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)\build.ninja"
|
||||
Outputs="@(_CmakeMingwDependency->'%(DestinationDirectory)\%(OutputLibrary)')">
|
||||
<Exec
|
||||
Command="%(_CmakeMingwDependency.Ninja) -v $(MakeConcurrency)"
|
||||
WorkingDirectory="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)"
|
||||
/>
|
||||
<Exec
|
||||
Command="%(_CmakeMingwDependency.Ninja) -v install"
|
||||
WorkingDirectory="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)"
|
||||
/>
|
||||
<Touch Files="@(_CmakeMingwDependency->'%(DestinationDirectory)\%(OutputLibrary)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GetMingwDepsBundleItems">
|
||||
<ItemGroup>
|
||||
<BundleItem Include="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)\build.ninja">
|
||||
<Submodule>%(_CmakeMingwDependency.Submodule)</Submodule>
|
||||
</BundleItem>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="ForceBuild"
|
||||
DependsOnTargets="GetMingwDepsBundleItems;$(ForceBuildDependsOn)"
|
||||
Inputs="@(_CmakeMingwDependency->'$(_SubmoduleTopDir)\%(Submodule)\CMakeLists.txt"
|
||||
Outputs="@(BundleItem)">
|
||||
</Target>
|
||||
|
||||
<Target Name="_BuildUnlessCached"
|
||||
DependsOnTargets="_SetCMakeListsTxtTimeToLastCommitTimestamp;GetMingwDepsBundleItems"
|
||||
Inputs="@(_CmakeMingwDependency->'$(_SubmoduleTopDir)\%(Submodule)\CMakeLists.txt"
|
||||
Outputs="@(BundleItem)">
|
||||
<PropertyGroup>
|
||||
<_Now>$([System.DateTime]::Now.Ticks)</_Now>
|
||||
</PropertyGroup>
|
||||
<MSBuild
|
||||
Projects="$(ForceBuildProjectFilePath)"
|
||||
Properties="_ForceXbuildToNotCacheTargets=$(_Now)"
|
||||
Targets="ForceBuild"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target Name="_CleanBinaries"
|
||||
AfterTargets="Clean">
|
||||
<RemoveDir Directories="$(IntermediateOutputPath)\%(_CmakeMingwDependency.Identity)" />
|
||||
<Delete Files="@(_CmakeMingwDependency->'$(MingwDependenciesRootDirectory)\%(OutputLibrary)')" />
|
||||
</Target>
|
||||
<Target Name="CoreCompile"
|
||||
DependsOnTargets="_BuildUnlessCached">
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,130 +1,26 @@
|
|||
PRODUCT_VERSION = $(shell $(MSBUILD) $(MSBUILD_FLAGS) /p:DoNotLoadOSProperties=True /nologo /v:minimal /t:GetProductVersion build-tools/scripts/Info.targets | tr -d '[[:space:]]')
|
||||
|
||||
GIT_BRANCH = $(shell LANG=C build-tools/scripts/get-git-branch.sh | tr -d '[[:space:]]' | tr -C a-zA-Z0-9- _)
|
||||
GIT_COMMIT = $(shell LANG=C git log --no-color --first-parent -n1 --pretty=format:%h)
|
||||
|
||||
# In which commit did $(PRODUCT_VERSION) change? 00000000 if uncommitted
|
||||
-commit-of-last-version-change = $(shell LANG=C git blame Configuration.props | grep '<ProductVersion>' | grep -v grep | sed 's/ .*//')
|
||||
|
||||
# How many commits have passed since $(-commit-of-last-version-change)?
|
||||
# "0" when commit hash is invalid (e.g. 00000000)
|
||||
-num-commits-since-version-change = $(shell LANG=C git log $(-commit-of-last-version-change)..HEAD --oneline 2>/dev/null | wc -l | sed 's/ //g')
|
||||
|
||||
ifeq ($(OS_NAME),Linux)
|
||||
ZIP_EXTENSION = tar.bz2
|
||||
else
|
||||
ZIP_EXTENSION = zip
|
||||
endif
|
||||
|
||||
ZIP_OUTPUT_BASENAME = xamarin.android-oss_v$(PRODUCT_VERSION).$(-num-commits-since-version-change)_$(OS_NAME)-$(OS_ARCH)_$(GIT_BRANCH)_$(GIT_COMMIT)-$(CONFIGURATION)
|
||||
ZIP_OUTPUT = $(ZIP_OUTPUT_BASENAME).$(ZIP_EXTENSION)
|
||||
|
||||
|
||||
## The following values *must* use SPACE, **not** TAB, to separate values.
|
||||
|
||||
# $(ALL_API_LEVELS) and $(ALL_FRAMEWORKS) must be kept in sync w/ each other
|
||||
ALL_API_LEVELS = 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
|
||||
# this was different from ALL_API_LEVELS when API Level 26 was "O". Same could happen in the future.
|
||||
ALL_PLATFORM_IDS = 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 Q
|
||||
# supported api levels
|
||||
ALL_FRAMEWORKS = _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ v4.4 v4.4.87 v5.0 v5.1 v6.0 v7.0 v7.1 v8.0 v8.1 v9.0 v9.0.99
|
||||
API_LEVELS = 19 20 21 22 23 24 25 26 27 28 29
|
||||
STABLE_API_LEVELS = 19 20 21 22 23 24 25 26 27 28
|
||||
|
||||
## The preceding values *must* use SPACE, **not** TAB, to separate values.
|
||||
|
||||
|
||||
FRAMEWORKS = $(foreach a, $(API_LEVELS), $(word $(a),$(ALL_FRAMEWORKS)))
|
||||
STABLE_FRAMEWORKS = $(foreach a, $(STABLE_API_LEVELS), $(word $(a),$(ALL_FRAMEWORKS)))
|
||||
PLATFORM_IDS = $(foreach a, $(API_LEVELS), $(word $(a),$(ALL_PLATFORM_IDS)))
|
||||
|
||||
ALL_JIT_ABIS = \
|
||||
armeabi-v7a \
|
||||
arm64-v8a \
|
||||
x86 \
|
||||
x86_64
|
||||
|
||||
ALL_HOST_ABIS = \
|
||||
$(shell uname)
|
||||
|
||||
ALL_AOT_ABIS = \
|
||||
armeabi-v7a \
|
||||
arm64 \
|
||||
x86 \
|
||||
x86_64 \
|
||||
win-armeabi-v7a \
|
||||
win-arm64 \
|
||||
win-x86 \
|
||||
win-x86_64
|
||||
|
||||
ifneq ($(OS_NAME),Linux)
|
||||
ALL_HOST_ABIS += \
|
||||
mxe-Win32 \
|
||||
mxe-Win64
|
||||
endif
|
||||
|
||||
ifneq ($(OS_NAME),Linux)
|
||||
MONO_OPTIONS += --arch=64
|
||||
endif
|
||||
|
||||
_space :=
|
||||
_space +=
|
||||
|
||||
# usage: $(call join-with,SEPARATOR,LIST)
|
||||
# Joins elements of LISt with SEPARATOR.
|
||||
join-with = $(subst $(_space),$(1),$(strip $(2)))
|
||||
|
||||
|
||||
_MSBUILD_ARGS = \
|
||||
/p:AndroidSupportedTargetJitAbis=$(call join-with,:,$(ALL_JIT_ABIS)) \
|
||||
/p:AndroidSupportedHostJitAbis=$(call join-with,:,$(ALL_HOST_ABIS)) \
|
||||
/p:AndroidSupportedTargetAotAbis=$(call join-with,:,$(ALL_AOT_ABIS))
|
||||
|
||||
.PHONY: leeroy jenkins leeroy-all opentk-jcw framework-assemblies
|
||||
.PHONY: leeroy jenkins leeroy-all opentk-jcw
|
||||
.PHONY: create-vsix
|
||||
|
||||
jenkins:: prepare leeroy $(ZIP_OUTPUT)
|
||||
#
|
||||
# framework-assemblies lives in bin/Build$(CONFIGURATION)/rules.mk generated by `make prepare`
|
||||
#
|
||||
# It has to be invoked with $(MAKE) because otherwise rules.mk would not be included and we'd
|
||||
# get a build failure.
|
||||
#
|
||||
# The other targets depended upon by leeroy also require rules.mk to be present and thus they
|
||||
# are invoked in the same way framework-assemblies is
|
||||
#
|
||||
jenkins:: prepare-jenkins
|
||||
$(MAKE) leeroy $(ZIP_OUTPUT)
|
||||
|
||||
leeroy: leeroy-all framework-assemblies opentk-jcw
|
||||
|
||||
leeroy-all:
|
||||
$(call MSBUILD_BINLOG,leeroy-all,$(_SLN_BUILD)) $(SOLUTION) /p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) && \
|
||||
$(call CREATE_THIRD_PARTY_NOTICES,bin/$(CONFIGURATION)/lib/xamarin.android/ThirdPartyNotices.txt,$(THIRD_PARTY_NOTICE_LICENSE_TYPE),True,False)
|
||||
|
||||
framework-assemblies:
|
||||
PREV_VERSION="v1.0"; \
|
||||
$(foreach a, $(API_LEVELS), \
|
||||
CUR_VERSION=`echo "$(ALL_FRAMEWORKS)"|tr -s " "|cut -d " " -s -f $(a)`; \
|
||||
REDIST_FILE=bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/$${CUR_VERSION}/RedistList/FrameworkList.xml; \
|
||||
grep -q $${PREV_VERSION} $${REDIST_FILE}; \
|
||||
if [ $$? -ne 0 ] ; then \
|
||||
rm -f bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/$${CUR_VERSION}/RedistList/FrameworkList.xml; \
|
||||
fi; \
|
||||
$(call MSBUILD_BINLOG,Mono.Android,$(_SLN_BUILD)) src/Mono.Android/Mono.Android.csproj \
|
||||
/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \
|
||||
/p:AndroidApiLevel=$(a) /p:AndroidPlatformId=$(word $(a), $(ALL_PLATFORM_IDS)) /p:AndroidFrameworkVersion=$${CUR_VERSION} \
|
||||
/p:AndroidPreviousFrameworkVersion=$${PREV_VERSION} || exit 1; \
|
||||
PREV_VERSION=$${CUR_VERSION}; )
|
||||
rm -f bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/Xamarin.Android.NUnitLite.dll; \
|
||||
$(call MSBUILD_BINLOG,NUnitLite,$(_SLN_BUILD)) $(MSBUILD_FLAGS) src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj \
|
||||
/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \
|
||||
/p:AndroidApiLevel=$(firstword $(API_LEVELS)) /p:AndroidPlatformId=$(word $(firstword $(API_LEVELS)), $(ALL_PLATFORM_IDS)) \
|
||||
/p:AndroidFrameworkVersion=$(firstword $(FRAMEWORKS)) || exit 1;
|
||||
_latest_stable_framework=$$($(MSBUILD) /p:DoNotLoadOSProperties=True /nologo /v:minimal /t:GetAndroidLatestStableFrameworkVersion build-tools/scripts/Info.targets | tr -d '[[:space:]]') ; \
|
||||
rm -f "bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/$$_latest_stable_framework"/Mono.Android.Export.* ; \
|
||||
$(call MSBUILD_BINLOG,Mono.Android.Export,$(_SLN_BUILD)) $(MSBUILD_FLAGS) src/Mono.Android.Export/Mono.Android.Export.csproj \
|
||||
/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \
|
||||
/p:AndroidApiLevel=$(firstword $(API_LEVELS)) /p:AndroidPlatformId=$(word $(firstword $(API_LEVELS)), $(ALL_PLATFORM_IDS)) \
|
||||
/p:AndroidFrameworkVersion=$(firstword $(FRAMEWORKS)) || exit 1; \
|
||||
rm -f "bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/$$_latest_stable_framework"/OpenTK-1.0.* ; \
|
||||
$(call MSBUILD_BINLOG,OpenTK,$(_SLN_BUILD)) $(MSBUILD_FLAGS) src/OpenTK-1.0/OpenTK.csproj \
|
||||
/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \
|
||||
/p:AndroidApiLevel=$(firstword $(API_LEVELS)) /p:AndroidPlatformId=$(word $(firstword $(API_LEVELS)), $(ALL_PLATFORM_IDS)) \
|
||||
/p:AndroidFrameworkVersion=$(firstword $(FRAMEWORKS)) || exit 1;
|
||||
$(call MSBUILD_BINLOG,leeroy-all,$(_SLN_BUILD)) $(SOLUTION) /p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS)
|
||||
|
||||
opentk-jcw:
|
||||
$(foreach a, $(API_LEVELS), \
|
||||
$(foreach api_level, $(API_LEVELS), \
|
||||
touch bin/$(CONFIGURATION)/lib/xamarin.android/xbuild-frameworks/MonoAndroid/*/OpenTK-1.0.dll; \
|
||||
$(call MSBUILD_BINLOG,OpenTK-JCW,$(_SLN_BUILD)) $(MSBUILD_FLAGS) src/OpenTK-1.0/OpenTK.csproj \
|
||||
/t:GenerateJavaCallableWrappers /p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \
|
||||
/p:AndroidApiLevel=$(a) /p:AndroidPlatformId=$(word $(a), $(ALL_PLATFORM_IDS)) /p:AndroidFrameworkVersion=$(word $(a), $(ALL_FRAMEWORKS)) || exit 1; )
|
||||
/p:AndroidApiLevel=$(api_level) /p:AndroidPlatformId=$(word $(api_level), $(ALL_PLATFORM_IDS)) /p:AndroidFrameworkVersion=$(word $(api_level), $(ALL_FRAMEWORKS)) || exit 1; )
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AndroidNdkVersion Condition=" '$(AndroidNdkVersion)' == '' ">@NDK_RELEASE@</AndroidNdkVersion>
|
||||
<AndroidNdkApiLevel_ArmV7a Condition=" '$(AndroidNdkApiLevel_ArmV7a)' == '' ">@NDK_ARMEABI_V7_API@</AndroidNdkApiLevel_ArmV7a>
|
||||
<AndroidNdkApiLevel_ArmV8a Condition=" '$(AndroidNdkApiLevel_ArmV8a)' == '' ">@NDK_ARM64_V8A_API@</AndroidNdkApiLevel_ArmV8a>
|
||||
<AndroidNdkApiLevel_X86 Condition=" '$(AndroidNdkApiLevel_X86)' == '' ">@NDK_X86_API@</AndroidNdkApiLevel_X86>
|
||||
<AndroidNdkApiLevel_X86_64 Condition=" '$(AndroidNdkApiLevel_X86_64)' == '' ">@NDK_X86_64_API@</AndroidNdkApiLevel_X86_64>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="armeabi-v7a"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':armeabi-v7a:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_ArmV7a)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="arm64-v8a"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':arm64-v8a:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_ArmV8a)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="x86"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':x86:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_X86)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="x86_64"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':x86_64:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_X86_64)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,38 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AndroidNdkVersion Condition=" '$(AndroidNdkVersion)' == '' ">19c</AndroidNdkVersion>
|
||||
<AndroidNdkApiLevel_ArmV7a Condition=" '$(AndroidNdkApiLevel_ArmV7a)' == '' ">16</AndroidNdkApiLevel_ArmV7a>
|
||||
<AndroidNdkApiLevel_ArmV8a Condition=" '$(AndroidNdkApiLevel_ArmV8a)' == '' ">21</AndroidNdkApiLevel_ArmV8a>
|
||||
<AndroidNdkApiLevel_X86 Condition=" '$(AndroidNdkApiLevel_X86)' == '' ">16</AndroidNdkApiLevel_X86>
|
||||
<AndroidNdkApiLevel_X86_64 Condition=" '$(AndroidNdkApiLevel_X86_64)' == '' ">21</AndroidNdkApiLevel_X86_64>
|
||||
<ProjitemsFile>$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\Ndk.projitems</ProjitemsFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- It appears we cannot use batching outside a <Target> so we cannot use a set of items specifying the necessary API level to generate the
|
||||
AndroidSupportedTargetJitAbi items with appropriate metadata. Thus we need to do it manually as below -->
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="armeabi-v7a"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':armeabi-v7a:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_ArmV7a)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="arm64-v8a"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':arm64-v8a:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_ArmV8a)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="x86"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':x86:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_X86)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
|
||||
<AndroidSupportedTargetJitAbi
|
||||
Include="x86_64"
|
||||
Condition=" $(AndroidSupportedTargetJitAbisForConditionalChecks.Contains (':x86_64:')) ">
|
||||
<ApiLevel>$(AndroidNdkApiLevel_X86_64)</ApiLevel>
|
||||
</AndroidSupportedTargetJitAbi>
|
||||
</ItemGroup>
|
||||
<Import
|
||||
Project="$(ProjitemsFile)"
|
||||
Condition="Exists('$(ProjitemsFile)')"/>
|
||||
</Project>
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
_BUNDLE_ZIPS_INCLUDE = \
|
||||
$(ZIP_OUTPUT_BASENAME)/ThirdPartyNotices.txt \
|
||||
$(ZIP_OUTPUT_BASENAME)/bin/Debug \
|
||||
$(ZIP_OUTPUT_BASENAME)/bin/Release
|
||||
|
||||
_BUNDLE_ZIPS_EXCLUDE = \
|
||||
$(ZIP_OUTPUT_BASENAME)/bin/*/bundle-*.zip
|
||||
|
||||
create-installers: create-pkg create-vsix
|
||||
|
||||
create-pkg:
|
||||
|
|
|
@ -3,97 +3,24 @@
|
|||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<_TopDir>$(MSBuildThisFileDirectory)..\..</_TopDir>
|
||||
<_NuGet>.nuget\NuGet.exe</_NuGet>
|
||||
<_NuGetVerbosity>-Verbosity Detailed</_NuGetVerbosity>
|
||||
<_XAPrepareExe>$(MSBuildThisFileDirectory)..\xaprepare\xaprepare\bin\$(Configuration)\xaprepare.exe</_XAPrepareExe>
|
||||
<_XAPrepareStandardArgs>--no-emoji --run-mode=CI</_XAPrepareStandardArgs>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(_TopDir)\Configuration.props" />
|
||||
<UsingTask AssemblyFile="$(_TopDir)\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.JdkInfo" />
|
||||
<UsingTask AssemblyFile="$(_TopDir)\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ReplaceFileContents" />
|
||||
<Target Name="PrepareExternal">
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\xa-prep-tasks\xa-prep-tasks.csproj" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\xa-prep-tasks\xa-prep-tasks.csproj" Targets="CheckoutExternalGitSources"/>
|
||||
<Target Name="_BuildXAPrepare">
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\xaprepare\xaprepare.sln" Targets="Restore" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\xaprepare\xaprepare.sln" />
|
||||
</Target>
|
||||
<Target Name="Prepare">
|
||||
<Target Name="PrepareExternal"
|
||||
DependsOnTargets="_BuildXAPrepare">
|
||||
<Exec Command="$(_XAPrepareExe) -s:PrepareExternalGitDependencies $(_XAPrepareStandardArgs)" />
|
||||
</Target>
|
||||
<Target Name="Prepare"
|
||||
DependsOnTargets="_BuildXAPrepare">
|
||||
<Error
|
||||
Text="The specified `%24(AndroidToolchainDirectory)` '$(AndroidToolchainDirectory)' contains a space. Android NDK commands do not support this. Please create a Configuration.Override.props file that sets the AndroidToolchainDirectory property to a different path."
|
||||
Condition="$(AndroidToolchainDirectory.Contains (' '))"
|
||||
/>
|
||||
<Exec Command="git submodule update --init --recursive" WorkingDirectory="$(_TopDir)" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\xa-prep-tasks\xa-prep-tasks.csproj" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\download-bundle\download-bundle.csproj" />
|
||||
<Exec
|
||||
Command="$(_NuGet) restore $(_NuGetVerbosity) Xamarin.Android.sln"
|
||||
WorkingDirectory="$(_TopDir)"
|
||||
IgnoreStandardErrorWarningFormat="True"
|
||||
/>
|
||||
<Exec
|
||||
Command="$(_NuGet) restore $(_NuGetVerbosity) external\Java.Interop\Java.Interop.sln"
|
||||
WorkingDirectory="$(_TopDir)"
|
||||
IgnoreStandardErrorWarningFormat="True"
|
||||
/>
|
||||
<Exec
|
||||
Command="$(_NuGet) restore $(_NuGetVerbosity) external\LibZipSharp\libZipSharp.sln"
|
||||
WorkingDirectory="$(_TopDir)"
|
||||
IgnoreStandardErrorWarningFormat="True"
|
||||
/>
|
||||
<Exec
|
||||
Command="$(_NuGet) restore $(_NuGetVerbosity) external\xamarin-android-tools\Xamarin.Android.Tools.sln"
|
||||
WorkingDirectory="$(_TopDir)"
|
||||
IgnoreStandardErrorWarningFormat="True"
|
||||
/>
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\Xamarin.Android.Tools.BootstrapTasks\Xamarin.Android.Tools.BootstrapTasks.csproj" />
|
||||
<MSBuild Projects="tests\Xamarin.Forms-Performance-Integration\Xamarin.Forms.Performance.Integration.csproj" Targets="Restore" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)..\android-toolchain\android-toolchain.csproj" />
|
||||
<!--NOTE: need to restore test sln *after* android-toolchain has the Android SDK in place-->
|
||||
<Exec
|
||||
Command="$(_NuGet) restore $(_NuGetVerbosity) Xamarin.Android-Tests.sln"
|
||||
WorkingDirectory="$(_TopDir)"
|
||||
IgnoreStandardErrorWarningFormat="True"
|
||||
/>
|
||||
<JdkInfo
|
||||
AndroidSdkPath="$(AndroidSdkDirectory)"
|
||||
AndroidNdkPath="$(AndroidNdkDirectory)"
|
||||
JavaSdkPath="$(JavaSdkDirectory)"
|
||||
MaxJdkVersion="$(MaxJdkVersion)"
|
||||
Output="$(_TopDir)\external\Java.Interop\bin\Build$(Configuration)\JdkInfo.props">
|
||||
<Output TaskParameter="JavaSdkDirectory" PropertyName="_JavaSdkDirectory" />
|
||||
</JdkInfo>
|
||||
<Copy
|
||||
SourceFiles="$(MSBuildThisFileDirectory)Configuration.Java.Interop.Override.props"
|
||||
DestinationFiles="$(_TopDir)\external\Java.Interop\Configuration.Override.props"
|
||||
SkipUnchangedFiles="True"
|
||||
/>
|
||||
<ReplaceFileContents
|
||||
SourceFile="$(MSBuildThisFileDirectory)Windows-Configuration.OperatingSystem.props.in"
|
||||
DestinationFile="$(_TopDir)\Configuration.OperatingSystem.props"
|
||||
Replacements="@JAVA_HOME@=$(_JavaSdkDirectory)"
|
||||
/>
|
||||
<ItemGroup>
|
||||
<_CecilFiles Include="$(_TopDir)\external\Java.Interop\external\Mono.Cecil*" />
|
||||
</ItemGroup>
|
||||
<Copy
|
||||
SourceFiles="@(_CecilFiles)"
|
||||
DestinationFolder="$(_TopDir)\external\mono\external"
|
||||
SkipUnchangedFiles="True"
|
||||
/>
|
||||
<Copy
|
||||
SourceFiles="$(_TopDir)\external\Java.Interop\product.snk"
|
||||
DestinationFolder="$(_TopDir)\external\mono"
|
||||
SkipUnchangedFiles="True"
|
||||
/>
|
||||
<MakeDir Directories="$(_TopDir)\bin\Test$(Configuration)" />
|
||||
<ReplaceFileContents
|
||||
SourceFile="$(MSBuildThisFileDirectory)XABuildPaths.cs.in"
|
||||
DestinationFile="$(_TopDir)\bin\Test$(Configuration)\XABuildPaths.cs"
|
||||
Replacements="@TOP_DIRECTORY@=$(_TopDir);@CONFIGURATION@=$(Configuration)"
|
||||
/>
|
||||
<MSBuild
|
||||
Projects="$(_TopDir)\build-tools\ThirdPartyNotices\ThirdPartyNotices.csproj"
|
||||
Properties="ThirdPartyNoticeFile=$(_TopDir)\ThirdPartyNotices.txt;ThirdPartyNoticeLicenseType=foundation"
|
||||
/>
|
||||
<MSBuild
|
||||
Projects="$(_TopDir)\build-tools\ThirdPartyNotices\ThirdPartyNotices.csproj"
|
||||
Properties="ThirdPartyNoticeFile=$(_TopDir)\bin\$(Configuration)\lib\xamarin.android\ThirdPartyNotices.txt;ThirdPartyNoticeLicenseType=microsoft-oss;TpnIncludeExternalDependencies=True"
|
||||
/>
|
||||
<Exec Command="$(_XAPrepareExe) $(_XAPrepareStandardArgs)" WorkingDirectory="$(_TopDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_SubmoduleTopDir>$(XamarinAndroidSourcePath)\external</_SubmoduleTopDir>
|
||||
<XABundleVersion>@XA_BUNDLE_VERSION@</XABundleVersion>
|
||||
<XABundleFileName Condition=" '$(XABundleFileName)' == '' ">@XA_BUNDLE_FILE_NAME@</XABundleFileName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,46 +0,0 @@
|
|||
DEBIAN_COMMON_DEPS="autoconf
|
||||
autotools-dev
|
||||
automake
|
||||
curl
|
||||
g++-mingw-w64
|
||||
gcc-mingw-w64
|
||||
git
|
||||
libtool
|
||||
libncurses-dev
|
||||
libz-mingw-w64-dev
|
||||
libzip-dev
|
||||
linux-libc-dev
|
||||
make
|
||||
unzip
|
||||
vim-common
|
||||
sqlite3
|
||||
zlib1g-dev
|
||||
"
|
||||
|
||||
if [ "$OS_ARCH" = "x86_64" ]; then
|
||||
DEBIAN_COMMON_DEPS="$DEBIAN_COMMON_DEPS
|
||||
lib32stdc++6
|
||||
lib32z1
|
||||
"
|
||||
fi
|
||||
|
||||
debian_install()
|
||||
{
|
||||
if [ "$NO_SUDO" = "true" ]; then
|
||||
for p in $DISTRO_DEPS; do
|
||||
if dpkg -l $p > /dev/null 2>&1 ; then
|
||||
echo "[INSTALLED] $p"
|
||||
else
|
||||
echo "[ MISSING ] $p"
|
||||
PACKAGES_MISSING=yes
|
||||
fi
|
||||
done
|
||||
if [ "x$PACKAGES_MISSING" = "xyes" ]; then
|
||||
echo Some packages are missing, cannot continue
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
sudo apt-get -f -u -y install $DISTRO_DEPS
|
||||
fi
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
ARCH_DEPS="autoconf
|
||||
automake
|
||||
binutils
|
||||
bison
|
||||
curl
|
||||
fakeroot
|
||||
file
|
||||
findutils
|
||||
flex
|
||||
gawk
|
||||
gcc
|
||||
gettext
|
||||
git
|
||||
grep
|
||||
groff
|
||||
gtk-sharp-2
|
||||
gzip
|
||||
jdk8-openjdk
|
||||
libtool
|
||||
libzip
|
||||
m4
|
||||
make
|
||||
nuget
|
||||
patch
|
||||
pkg-config
|
||||
pkg-config
|
||||
referenceassemblies-pcl
|
||||
sed
|
||||
texinfo
|
||||
unzip
|
||||
which
|
||||
zip
|
||||
"
|
||||
all_installed=yes
|
||||
for pkg in $ARCH_DEPS
|
||||
do
|
||||
if ! pacman -Qq "$pkg" > /dev/null 2>&1
|
||||
then
|
||||
all_installed=no
|
||||
missing_pkgs+=("$pkg")
|
||||
fi
|
||||
done
|
||||
if [ "$NO_SUDO" = "false" ]
|
||||
then
|
||||
[ "$all_installed" = "yes" ] && exit
|
||||
if ! sudo pacman -S --noconfirm --needed $ARCH_DEPS
|
||||
then
|
||||
echo "Failed to install required packages"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ "$all_installed" = "no" ]
|
||||
then
|
||||
echo "Missing package(s): '${missing_pkgs[@]}'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
|
@ -1,8 +0,0 @@
|
|||
. "`dirname $0`"/debian-common.sh
|
||||
|
||||
DISTRO_DEPS="$DEBIAN_COMMON_DEPS $DISTRO_DEPS \
|
||||
zulu-8
|
||||
zlib1g-dev
|
||||
"
|
||||
|
||||
debian_install
|
|
@ -1,16 +0,0 @@
|
|||
. "`dirname $0`"/debian-common.sh
|
||||
|
||||
DISTRO_DEPS="$DEBIAN_COMMON_DEPS"
|
||||
|
||||
MAJOR=$(echo $1 | cut -d '.' -f 1)
|
||||
MINOR=$(echo $1 | cut -d '.' -f 2)
|
||||
|
||||
if [ $MAJOR -ge 19 ]; then
|
||||
NEED_LIBTOOL=yes
|
||||
else
|
||||
NEED_LIBTOOL=no
|
||||
fi
|
||||
|
||||
. "`dirname $0`"/ubuntu-common.sh
|
||||
|
||||
debian_install
|
|
@ -1,17 +0,0 @@
|
|||
. "`dirname $0`"/debian-common.sh
|
||||
|
||||
MAJOR=$(echo $1 | cut -d '.' -f 1)
|
||||
MINOR=$(echo $1 | cut -d '.' -f 2)
|
||||
|
||||
if [ $MAJOR -eq 17 -a $MINOR -eq 10 ] || [ $MAJOR -ge 18 ]; then
|
||||
NEED_LIBTOOL=yes
|
||||
if [ $MAJOR -lt 19 ]; then
|
||||
DISTRO_DEPS="$DEBIAN_COMMON_DEPS openjdk-8-jdk"
|
||||
fi
|
||||
else
|
||||
NEED_LIBTOOL=no
|
||||
fi
|
||||
|
||||
. "`dirname $0`"/ubuntu-common.sh
|
||||
|
||||
debian_install
|
|
@ -1,11 +0,0 @@
|
|||
if [ "$OS_ARCH" = "x86_64" ]; then
|
||||
DISTRO_DEPS="$DISTRO_DEPS
|
||||
libx32tinfo-dev
|
||||
linux-libc-dev:i386
|
||||
zlib1g-dev:i386
|
||||
"
|
||||
fi
|
||||
|
||||
if [ "$NEED_LIBTOOL" = "yes" ]; then
|
||||
DISTRO_DEPS="$DISTRO_DEPS libtool-bin"
|
||||
fi
|
|
@ -2,7 +2,6 @@
|
|||
# Various helper/shortcut targets
|
||||
#
|
||||
MONO_RUNTIMES_DIR = src/mono-runtimes
|
||||
MONO_RUNTIMES_PROJECT = $(MONO_RUNTIMES_DIR)/mono-runtimes.csproj
|
||||
MONO_RUNTIMES_BUILD_DIR = $(MONO_RUNTIMES_DIR)/obj/$(CONFIGURATION)
|
||||
|
||||
# $(1) - architecture name
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Xamarin.Android.BuildTools.PrepTasks
|
|||
public ITaskItem DestinationFile { get; set; }
|
||||
|
||||
public string[] Replacements { get; set; }
|
||||
public string ReplacementFilePath { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
|
@ -25,13 +26,20 @@ namespace Xamarin.Android.BuildTools.PrepTasks
|
|||
Log.LogMessage (MessageImportance.Low, $" {nameof (SourceFile)}: {SourceFile.ItemSpec}");
|
||||
Log.LogMessage (MessageImportance.Low, $" {nameof (DestinationFile)}: {DestinationFile.ItemSpec}");
|
||||
Log.LogMessage (MessageImportance.Low, $" {nameof (Replacements)}:");
|
||||
foreach (var replacement in Replacements) {
|
||||
Log.LogMessage (MessageImportance.Low, $" {replacement}");
|
||||
if (Replacements != null) {
|
||||
foreach (var replacement in Replacements) {
|
||||
Log.LogMessage (MessageImportance.Low, $" {replacement}");
|
||||
}
|
||||
}
|
||||
|
||||
File.Delete (DestinationFile.ItemSpec);
|
||||
|
||||
var r = GetReplacementInfo (Replacements);
|
||||
string[] replacements;
|
||||
if (!String.IsNullOrEmpty (ReplacementFilePath))
|
||||
replacements = File.ReadAllLines (ReplacementFilePath);
|
||||
else
|
||||
replacements = Replacements;
|
||||
var r = GetReplacementInfo (replacements);
|
||||
using (var i = File.OpenText (SourceFile.ItemSpec))
|
||||
using (var o = File.CreateText (DestinationFile.ItemSpec)) {
|
||||
string line;
|
||||
|
|
|
@ -0,0 +1,405 @@
|
|||
# globs
|
||||
Makefile.in
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
|
@ -0,0 +1,173 @@
|
|||
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
|
||||
**Table of Contents**
|
||||
|
||||
- [Xamarin.Android build preparation utility](#xamarinandroid-build-preparation-utility)
|
||||
- [Introduction](#introduction)
|
||||
- [Why?](#why)
|
||||
- [Supported operating systems](#supported-operating-systems)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [All systems](#all-systems)
|
||||
- [macOS and Linux](#macos-and-linux)
|
||||
- [macOS](#macos)
|
||||
- [Build configuration](#build-configuration)
|
||||
- [File naming convention](#file-naming-convention)
|
||||
- [Configuration directory](#configuration-directory)
|
||||
- [Running](#running)
|
||||
- [Scenarios](#scenarios)
|
||||
- [Invocation](#invocation)
|
||||
- [Log files](#log-files)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
# Xamarin.Android build preparation utility
|
||||
|
||||
## Introduction
|
||||
|
||||
The task and purpose of this utility is to prepare the `Xamarin.Android` source tree for build by
|
||||
performing a number of steps which need to be done only once (or very few and far between) mostly after
|
||||
the repository is freshly cloned.
|
||||
|
||||
The utility is written in C# as a .NET 4.7 console app and does not depend on any other code within the
|
||||
`xamarin-android` repository.
|
||||
|
||||
## Why?
|
||||
|
||||
The utility replaces older system which was implemented using a vast collection of MSBuild projects,
|
||||
target files, property files distributed around the `Xamarin.Android` source tree which caused the following,
|
||||
but not limited to, problems:
|
||||
|
||||
- MSBuild doesn't very well interface with 3rd party build systems, which caused the need to employ a number
|
||||
of workarounds/hacks in order to make things work. The workarounds made the code confusing and not very
|
||||
friendly to occasional contributors.
|
||||
- Settings, configurations etc were often duplicated between makefiles and msbuild (and even between different
|
||||
MSBuild projects) which made it easy to make mistakes. It also made the whole setup hard to navigate.
|
||||
- Due to the way MSBuild works, we had to build some projects twice in order to get things working - once during
|
||||
preparation phase, second time during "normal" builds
|
||||
- Retrieval of settings/property values from makefiles used MSBuild to invoke its targets which then printed
|
||||
values to standard output to be captured by shell code inside the makefile. While it worked **most** of the time,
|
||||
it caused mysterious and hard to track errors when it did not work (e.g. the shell invoking msbuild to get some
|
||||
value would interpret "garbage" output and produce nonsensical errors)
|
||||
|
||||
All of the above problems (and a few more) are addressed by this utility by putting all the configuration and code in
|
||||
one place as well as the entire process using a real programming language which allows for more expressive and readable
|
||||
implementation.
|
||||
|
||||
## Supported operating systems
|
||||
|
||||
Currently the utility supports `macOS`, ``Linux`` (``Debian`` and derivatives, `Arch` is to be implemented)
|
||||
with `Windows` support in the works.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The utility requires that the following is present on the host system:
|
||||
|
||||
### All systems
|
||||
- [NuGet](https://www.nuget.org/downloads)
|
||||
|
||||
### macOS and Linux
|
||||
- [Mono runtime](https://www.mono-project.com/download/stable/)
|
||||
|
||||
### macOS
|
||||
- [Homebrew](https://brew.sh/)
|
||||
- Xcode with command line utilities (for GNU Make as well as the compilers)
|
||||
|
||||
## Build configuration
|
||||
|
||||
The utility is designed to make it easy(-ier) to change all aspects of `Xamarin.Android` build preparation process including,
|
||||
but not limited to:
|
||||
|
||||
- Android API levels
|
||||
- Mono runtimes/compilers/cross compilers
|
||||
- Location of output files/logs/etc
|
||||
- Contents of various "bundles" created by the build
|
||||
- URLs to download Mono archive, installers etc from
|
||||
- Build system dependencies and required program versions
|
||||
|
||||
The idea here is to put all of the above, and more, in a single location (in a small number of C# source files) which contain
|
||||
everyting that is required by other parts of the code, so that anyone (even with limited knowledge of the source tree or build
|
||||
process) can make any necessary changes. The files are laid out in a way that the information found in them, albeit sometimes
|
||||
voluminous, is self-explanatory and should not require much effort to understand and modify.
|
||||
|
||||
### File naming convention
|
||||
|
||||
Some files have the operating system embeded before their `.cs` extension. Such files are built and used only when the preparation
|
||||
utility is built on that particular operating system.
|
||||
|
||||
### Configuration directory
|
||||
|
||||
The files mentioned above are found in the [ConfigAndData](xaprepare/ConfigAndData) directory and are briefly described below.
|
||||
|
||||
- [AbiNames.cs](xaprepare/ConfigAndData/AbiNames.cs)
|
||||
Rarely modified, contains all the target ABI names as used throughout the `Xamarin.Android` source as well as a number of
|
||||
helper methods used throughout the preparation utility code. **Be very careful** when modifying the names there as it may
|
||||
break the build!
|
||||
- [BuildAndroidPlatforms.cs](xaprepare/ConfigAndData/BuildAndroidPlatforms.cs)
|
||||
Modified whenever a new Android platform is added, this file names all of the Android API levels along with platform/API
|
||||
identifiers and `Xamarin.Android` framework names corresponding to specific API levels. The file also contains specification
|
||||
of minimum NDK API levels used for all the Android device targets.
|
||||
- [CommonLicenses.cs](xaprepare/ConfigAndData/CommonLicenses.cs)
|
||||
A file with constants containing paths to licenses commonly used by software `Xamarin.Android` uses. The licenses are used
|
||||
when generating Third Party Notices.
|
||||
- [Configurables](xaprepare/ConfigAndData/Configurables.cs)
|
||||
The file (and its OS-specific companions) contain all of the tunable bits and pieces of configuration that affect various
|
||||
aspects of the build. There are three subclasses with self-explanatory names: `Configurables.Paths`, `Configurables.Urls` and
|
||||
`Configurables.Defaults`
|
||||
- [Runtimes.cs](xaprepare/ConfigAndData/Runtimes.cs)
|
||||
This file defines **all** of the Mono runtimes, BCL (Base Class Library) assemblies, utilities and components used by
|
||||
`Xamarin.Android` in the build as well as generated as part of the build for inclusion in bundles and installers.
|
||||
- [Dependencies/*.cs](xaprepare/ConfigAndData/Dependencies)
|
||||
Files in this directory contain dependencies (program and package names + versions) for all the supported operating systems.
|
||||
|
||||
## Running
|
||||
|
||||
### Scenarios
|
||||
|
||||
The utility employs the abstraction of "scenarios" which are collections of various steps to perform in order to achieve a
|
||||
specific goal. The main scenario is named `Standard` and is the default one if no other scenario is named on the command line
|
||||
(by using the `-s NAME` parameter). You can list all the scenarios by issuing the following command from the root of `Xamarin.Android`
|
||||
source tree:
|
||||
|
||||
```
|
||||
make PREPARE_ARGS=--ls
|
||||
```
|
||||
|
||||
### Invocation
|
||||
|
||||
In order to run the preparation utility on your development machine, all you need to do is to invoke the following command from
|
||||
the root of the `Xamarin.Android` source tree:
|
||||
|
||||
```
|
||||
make prepare
|
||||
```
|
||||
|
||||
To get list of all command line parameters accepted by the utility, issue the following command:
|
||||
|
||||
```
|
||||
make prepare-help
|
||||
```
|
||||
|
||||
You can append the following parameters to the command line:
|
||||
|
||||
- `PREPARE_ARGS=""`
|
||||
All and any command line parameters accepted by the utility
|
||||
- `PREPARE_SCENARIO=""`
|
||||
Name of the "scenario" to run
|
||||
- `PREPARE_AUTOPROVISION=0|1`
|
||||
If set to `0` (the default), the utility will take notice of missing/outdated software the build depends on and exit with an error
|
||||
should any such condition is detected. Setting the property to `1` will let the utility install the software (installation **may**
|
||||
use `sudo` on Unix so you will need administrator/root credentials for it to work)
|
||||
- `PREPARE_IGNORE_MONO_VERSION=0|1`
|
||||
If set to `1` (the default), the utility will not enforce Mono version but rather will use any Mono version you have installed.
|
||||
- `V=1`
|
||||
Causes the run to output much more information (making output much more messy in the process) to the console. Normally this additional
|
||||
information is placed only in the log files generated by the utility.
|
||||
|
||||
### Log files
|
||||
|
||||
Log files are generated in the `bin/Build*/` directory (where the part indicated by asterisk here is either `Debug` or `Release` depending
|
||||
on the chosen configuration) in files named using the following format: `prepare-TIMESTAMP.TAGS.log` where the components in capital letters
|
||||
have the following format:
|
||||
|
||||
- `TIMESTAMP`
|
||||
yyyymmddThhmmss (``yyyy`` - year, `mm` - month, `dd` - day, `hh` - hour, `mm` - minute, `ss` - second)
|
||||
- `TAGS`
|
||||
Arbitrary set of strings as set by various steps/tasks, usually self-explanatory
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xaprepare", "xaprepare\xaprepare.csproj", "{965D4281-1668-498C-86C4-264D7A44DAE7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{965D4281-1668-498C-86C4-264D7A44DAE7}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{965D4281-1668-498C-86C4-264D7A44DAE7}.Debug|x86.Build.0 = Debug|x86
|
||||
{965D4281-1668-498C-86C4-264D7A44DAE7}.Release|x86.ActiveCfg = Release|x86
|
||||
{965D4281-1668-498C-86C4-264D7A44DAE7}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
|
@ -0,0 +1,12 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Abi
|
||||
{
|
||||
public enum Bitness
|
||||
{
|
||||
Any,
|
||||
ThirtyTwo,
|
||||
SixtyFour,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Abi
|
||||
{
|
||||
public enum OS
|
||||
{
|
||||
Any,
|
||||
Windows,
|
||||
NotWindows
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Abi
|
||||
{
|
||||
static readonly List<Abi> KnownAbis = new List<Abi> {
|
||||
new Abi { Name = AbiNames.TargetJit.AndroidArmV7a, Type = AbiType.TargetJit, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetJit.AndroidArmV8a, Type = AbiType.TargetJit, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetJit.AndroidX86, Type = AbiType.TargetJit, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetJit.AndroidX86_64, Type = AbiType.TargetJit, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
|
||||
new Abi { Name = AbiNames.TargetAot.ArmV7a, Type = AbiType.TargetAot, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetAot.WinArmV7a, Type = AbiType.TargetAot, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.TargetAot.ArmV8a, Type = AbiType.TargetAot, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetAot.WinArmV8a, Type = AbiType.TargetAot, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.TargetAot.X86, Type = AbiType.TargetAot, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetAot.WinX86, Type = AbiType.TargetAot, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.TargetAot.X86_64, Type = AbiType.TargetAot, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.TargetAot.WinX86_64, Type = AbiType.TargetAot, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
|
||||
new Abi { Name = AbiNames.HostJit.Linux, Type = AbiType.HostJit, Is64Bit = false, IsCross = false, IsHost = true, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.HostJit.Darwin, Type = AbiType.HostJit, Is64Bit = false, IsCross = false, IsHost = true, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.HostJit.Win32, Type = AbiType.HostJit, Is64Bit = false, IsCross = false, IsHost = true, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.HostJit.Win64, Type = AbiType.HostJit, Is64Bit = true, IsCross = false, IsHost = true, IsLlvm = false, IsWindows = true },
|
||||
|
||||
new Abi { Name = AbiNames.CrossAot.ArmV7a, Type = AbiType.CrossAot, Is64Bit = false, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.CrossAot.WinArmV7a, Type = AbiType.CrossAot, Is64Bit = false, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.CrossAot.ArmV8a, Type = AbiType.CrossAot, Is64Bit = true, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.CrossAot.WinArmV8a, Type = AbiType.CrossAot, Is64Bit = true, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.CrossAot.X86, Type = AbiType.CrossAot, Is64Bit = false, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.CrossAot.WinX86, Type = AbiType.CrossAot, Is64Bit = false, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
new Abi { Name = AbiNames.CrossAot.X86_64, Type = AbiType.CrossAot, Is64Bit = true, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = false },
|
||||
new Abi { Name = AbiNames.CrossAot.WinX86_64, Type = AbiType.CrossAot, Is64Bit = true, IsCross = true, IsHost = false, IsLlvm = false, IsWindows = true },
|
||||
|
||||
new Abi { Name = AbiNames.Llvm.Host32Bit, Type = AbiType.Llvm, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = true, IsWindows = false },
|
||||
new Abi { Name = AbiNames.Llvm.Host64Bit, Type = AbiType.Llvm, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = true, IsWindows = false },
|
||||
new Abi { Name = AbiNames.Llvm.Windows32Bit, Type = AbiType.Llvm, Is64Bit = false, IsCross = false, IsHost = false, IsLlvm = true, IsWindows = true },
|
||||
new Abi { Name = AbiNames.Llvm.Windows64Bit, Type = AbiType.Llvm, Is64Bit = true, IsCross = false, IsHost = false, IsLlvm = true, IsWindows = true },
|
||||
};
|
||||
|
||||
public bool Is64Bit { get; private set; }
|
||||
public bool IsCross { get; private set; }
|
||||
public bool IsHost { get; private set; }
|
||||
public bool IsLlvm { get; private set; }
|
||||
public bool IsWindows { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public AbiType Type { get; private set; }
|
||||
|
||||
public static HashSet<string> GetHostAbis (OS osType = OS.Any, Bitness bitness = Bitness.Any, bool includeAllHostOSes = true)
|
||||
{
|
||||
IEnumerable<string> abis = KnownAbis.Where
|
||||
(a =>
|
||||
a.Type == AbiType.HostJit &&
|
||||
OSMatches(a, osType) &&
|
||||
BitnessMatches (a, bitness) &&
|
||||
(includeAllHostOSes || IsCurrentHostOS (a))).Select (a => a.Name);
|
||||
|
||||
return MakeHashSet (abis);
|
||||
}
|
||||
|
||||
public static HashSet<string> GetLlvmAbis (OS osType = OS.Any, Bitness bitness = Bitness.Any)
|
||||
{
|
||||
return MakeHashSet (KnownAbis.Where (a => a.Type == AbiType.Llvm && OSMatches (a, osType) && BitnessMatches (a, bitness)).Select (a => a.Name));
|
||||
}
|
||||
|
||||
public static HashSet<string> GetTargetJitAbis (Bitness bitness = Bitness.Any)
|
||||
{
|
||||
return MakeHashSet (KnownAbis.Where (a => a.Type == AbiType.TargetJit && BitnessMatches (a, bitness)).Select (a => a.Name));
|
||||
}
|
||||
|
||||
public static HashSet<string> GetHostAotAbis (OS osType = OS.Any, Bitness bitness = Bitness.Any)
|
||||
{
|
||||
return MakeHashSet (KnownAbis.Where (a => a.Type == AbiType.TargetAot && OSMatches (a, osType) && BitnessMatches (a, bitness)).Select (a => a.Name));
|
||||
}
|
||||
|
||||
public static HashSet<string> GetCrossAbis (OS osType = OS.Any, Bitness bitness = Bitness.Any)
|
||||
{
|
||||
return MakeHashSet (KnownAbis.Where (a => a.Type == AbiType.CrossAot && OSMatches (a, osType) && BitnessMatches (a, bitness)).Select (a => a.Name));
|
||||
}
|
||||
|
||||
static bool IsCurrentHostOS (Abi abi)
|
||||
{
|
||||
if (abi.IsWindows)
|
||||
return true; // Cross-build ABIs should be included in this case
|
||||
|
||||
return String.Compare (abi.Name, Context.Instance.OS.Type, StringComparison.Ordinal) == 0;
|
||||
}
|
||||
|
||||
static bool OSMatches (Abi abi, OS osType)
|
||||
{
|
||||
if (osType == OS.Any)
|
||||
return true;
|
||||
|
||||
if (osType == OS.Windows)
|
||||
return abi.IsWindows;
|
||||
|
||||
return !abi.IsWindows;
|
||||
}
|
||||
|
||||
static bool BitnessMatches (Abi abi, Bitness bitness)
|
||||
{
|
||||
if (bitness == Bitness.Any)
|
||||
return true;
|
||||
|
||||
if (bitness == Bitness.ThirtyTwo)
|
||||
return !abi.Is64Bit;
|
||||
|
||||
return abi.Is64Bit;
|
||||
}
|
||||
|
||||
static HashSet<string> MakeHashSet (IEnumerable<string> entries)
|
||||
{
|
||||
return new HashSet<string> (entries, StringComparer.Ordinal);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
enum AbiType
|
||||
{
|
||||
CrossAot,
|
||||
HostJit,
|
||||
Llvm,
|
||||
TargetJit,
|
||||
TargetAot,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class AndroidPlatform
|
||||
{
|
||||
public uint ApiLevel { get; }
|
||||
public string PlatformID { get; }
|
||||
public string Framework { get; }
|
||||
public bool Stable { get; }
|
||||
public bool Supported { get; }
|
||||
|
||||
public AndroidPlatform (uint apiLevel, string platformID, string framework = null, bool stable = true)
|
||||
{
|
||||
if (String.IsNullOrEmpty (platformID))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (platformID));
|
||||
|
||||
ApiLevel = apiLevel;
|
||||
PlatformID = platformID;
|
||||
Framework = framework ?? String.Empty;
|
||||
Stable = stable;
|
||||
Supported = !String.IsNullOrEmpty (framework);
|
||||
}
|
||||
}
|
||||
|
||||
static class AndroidPlatformExtensions
|
||||
{
|
||||
public static void Add (this List<AndroidPlatform> list, uint apiLevel, string platformID, string framework, bool stable)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
if (list.Any (p => p.ApiLevel == apiLevel))
|
||||
throw new InvalidOperationException ($"Duplicate Android platform, API level {apiLevel}");
|
||||
|
||||
list.Add (new AndroidPlatform (apiLevel, platformID, framework, stable));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class AndroidToolchainComponent : AppObject
|
||||
{
|
||||
public string Name { get; }
|
||||
public string DestDir { get; }
|
||||
public Uri RelativeUrl { get; }
|
||||
public bool IsMultiVersion { get; }
|
||||
public bool NoSubdirectory { get; }
|
||||
public string ExpectedPkgRevision { get; }
|
||||
|
||||
public AndroidToolchainComponent (string name, string destDir, Uri relativeUrl = null, bool isMultiVersion = false, bool noSubdirectory = false, string expectedPkgRevision = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (name));
|
||||
if (String.IsNullOrEmpty (destDir))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (destDir));
|
||||
|
||||
Name = name;
|
||||
DestDir = destDir;
|
||||
RelativeUrl = relativeUrl;
|
||||
IsMultiVersion = isMultiVersion;
|
||||
NoSubdirectory = noSubdirectory;
|
||||
ExpectedPkgRevision = expectedPkgRevision;
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidPlatformComponent : AndroidToolchainComponent
|
||||
{
|
||||
public AndroidPlatformComponent (string name, string apiLevel)
|
||||
: base (name, Path.Combine ("platforms", $"android-{apiLevel}"))
|
||||
{}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class AppObject
|
||||
{
|
||||
Log log;
|
||||
|
||||
public Log Log {
|
||||
get => log ?? Log.Instance;
|
||||
protected set => log = value;
|
||||
}
|
||||
|
||||
protected AppObject (Log log = null)
|
||||
{
|
||||
this.log = log;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
sealed class BclFile
|
||||
{
|
||||
readonly Dictionary<BclFileTarget, string> bclProfileSourceDirs = new Dictionary<BclFileTarget, string> () {
|
||||
{ BclFileTarget.Android, Configurables.Paths.BCLAssembliesSourceDir },
|
||||
{ BclFileTarget.DesignerHost, Configurables.Paths.BCLHostAssembliesSourceDir },
|
||||
{ BclFileTarget.DesignerWindows, Configurables.Paths.BCLWindowsAssembliesSourceDir },
|
||||
};
|
||||
|
||||
readonly Dictionary<BclFileTarget, string> bclFacadeSourceDirs = new Dictionary<BclFileTarget, string> () {
|
||||
{ BclFileTarget.Android, Configurables.Paths.BCLFacadeAssembliesSourceDir },
|
||||
{ BclFileTarget.DesignerHost, Configurables.Paths.BCLHostFacadeAssembliesSourceDir },
|
||||
{ BclFileTarget.DesignerWindows, Configurables.Paths.BCLWindowsFacadeAssembliesSourceDir },
|
||||
};
|
||||
|
||||
public string Name { get; }
|
||||
public BclFileType Type { get; }
|
||||
public BclFileTarget Target { get; }
|
||||
public bool ExcludeDebugSymbols { get; }
|
||||
public string SourcePath { get; }
|
||||
public string Version { get; }
|
||||
public string DebugSymbolsPath {
|
||||
get {
|
||||
if (ExcludeDebugSymbols)
|
||||
return null;
|
||||
|
||||
return Utilities.GetDebugSymbolsPath (SourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
public BclFile (string name, BclFileType type, bool excludeDebugSymbols = false, string version = null, BclFileTarget target = BclFileTarget.Android)
|
||||
{
|
||||
name = name?.Trim ();
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (name));
|
||||
|
||||
Name = name;
|
||||
Type = type;
|
||||
ExcludeDebugSymbols = excludeDebugSymbols;
|
||||
Version = version;
|
||||
Target = target;
|
||||
|
||||
string sourceDir;
|
||||
switch (type) {
|
||||
case BclFileType.ProfileAssembly:
|
||||
sourceDir = bclProfileSourceDirs [target];
|
||||
break;
|
||||
|
||||
case BclFileType.FacadeAssembly:
|
||||
sourceDir = bclFacadeSourceDirs [target];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException ($"Unsupported BCL file type {Type} for file {Name}");
|
||||
}
|
||||
|
||||
SourcePath = Path.GetFullPath (Path.Combine (sourceDir, name));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
/// <summary>
|
||||
/// Installation target of the BCL file. <seealso cref="BclFile"/>
|
||||
/// </summary>
|
||||
enum BclFileTarget
|
||||
{
|
||||
/// <summary>
|
||||
/// Install for Android
|
||||
/// </summary>
|
||||
Android,
|
||||
|
||||
/// <summary>
|
||||
/// Install for Android Designer on the current host operating system
|
||||
/// </summary>
|
||||
DesignerHost,
|
||||
|
||||
/// <summary>
|
||||
/// Install for Android Designer on Windows
|
||||
/// </summary>
|
||||
DesignerWindows,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
enum BclFileType
|
||||
{
|
||||
FacadeAssembly,
|
||||
ProfileAssembly,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class BuildInfo : AppObject
|
||||
{
|
||||
static readonly char[] NDKPropertySeparator = new [] { '=' };
|
||||
static readonly char[] NDKPlatformDirectorySeparator = new [] { '-' };
|
||||
|
||||
public string CommitOfLastVersionChange { get; private set; }
|
||||
|
||||
// Not available from the start, only after NDK is installed
|
||||
public string NDKRevision { get; private set; } = String.Empty;
|
||||
public string NDKVersionMajor { get; private set; } = String.Empty;
|
||||
public string NDKVersionMinor { get; private set; } = String.Empty;
|
||||
public string NDKVersionMicro { get; private set; } = String.Empty;
|
||||
public string NDKMinimumApiAvailable { get; private set; } = String.Empty;
|
||||
|
||||
public string VersionHash { get; private set; } = String.Empty;
|
||||
public string LibZipHash { get; private set; } = String.Empty;
|
||||
public string FullLibZipHash { get; private set; } = String.Empty;
|
||||
public string MonoHash { get; private set; } = String.Empty;
|
||||
public string FullMonoHash { get; private set; } = String.Empty;
|
||||
|
||||
public async Task GatherGitInfo (Context context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
|
||||
Log.StatusLine ();
|
||||
Log.StatusLine ("Determining basic build information", ConsoleColor.DarkGreen);
|
||||
await DetermineLastVersionChangeCommit (context);
|
||||
Log.StatusLine ();
|
||||
DetermineBundleHashes (context);
|
||||
Log.StatusLine ();
|
||||
}
|
||||
|
||||
public bool GatherNDKInfo (Context context, string ndkRoot)
|
||||
{
|
||||
string props = Path.Combine (ndkRoot, "source.properties");
|
||||
if (!File.Exists (props)) {
|
||||
Log.ErrorLine ("NDK properties file does not exist: ", props, tailColor: Log.DestinationColor);
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] lines = File.ReadAllLines (props);
|
||||
foreach (string l in lines) {
|
||||
string line = l.Trim ();
|
||||
string[] parts = line.Split (NDKPropertySeparator, 2);
|
||||
if (parts.Length != 2)
|
||||
continue;
|
||||
|
||||
if (String.Compare ("Pkg.Revision", parts [0].Trim (), StringComparison.Ordinal) != 0)
|
||||
continue;
|
||||
|
||||
string rev = parts [1].Trim ();
|
||||
NDKRevision = rev;
|
||||
|
||||
Version ver;
|
||||
if (!Version.TryParse (rev, out ver)) {
|
||||
Log.ErrorLine ($"Unable to parse NDK revision '{rev}' as a valid version string");
|
||||
return false;
|
||||
}
|
||||
|
||||
NDKVersionMajor = ver.Major.ToString ();
|
||||
NDKVersionMinor = ver.Minor.ToString ();
|
||||
NDKVersionMicro = ver.Build.ToString ();
|
||||
break;
|
||||
}
|
||||
|
||||
int minimumApi = Int32.MaxValue;
|
||||
string platforms = Path.Combine (ndkRoot, "platforms");
|
||||
foreach (string p in Directory.EnumerateDirectories (platforms, "android-*", SearchOption.TopDirectoryOnly)) {
|
||||
string pdir = Path.GetFileName (p);
|
||||
string[] parts = pdir.Split (NDKPlatformDirectorySeparator, 2);
|
||||
if (parts.Length != 2)
|
||||
continue;
|
||||
|
||||
int api;
|
||||
if (!Int32.TryParse (parts [1].Trim (), out api))
|
||||
continue;
|
||||
|
||||
if (api >= minimumApi)
|
||||
continue;
|
||||
|
||||
minimumApi = api;
|
||||
}
|
||||
|
||||
NDKMinimumApiAvailable = minimumApi.ToString ();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DetermineBundleHashes (Context context)
|
||||
{
|
||||
GitRunner git = CreateGitRunner (context);
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} LibZip commit hash", ConsoleColor.Gray);
|
||||
FullLibZipHash = git.GetTopCommitHash (context.Properties.GetRequiredValue (KnownProperties.LibZipSourceFullPath), shortHash: false);
|
||||
LibZipHash = EnsureHash ("LibZip", Utilities.ShortenGitHash (FullLibZipHash));
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} Mono commit hash", ConsoleColor.Gray);
|
||||
FullMonoHash = git.GetTopCommitHash (context.Properties.GetRequiredValue (KnownProperties.MonoSourceFullPath), shortHash: false);
|
||||
MonoHash = EnsureHash ("Mono", Utilities.ShortenGitHash (FullMonoHash));
|
||||
|
||||
if (Configurables.Paths.BundleVersionHashFiles == null || Configurables.Paths.BundleVersionHashFiles.Count == 0) {
|
||||
Log.WarningLine ("Bundle version hash files not specified");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} Generating bundle version hash", ConsoleColor.Gray);
|
||||
using (var ha = HashAlgorithm.Create (context.HashAlgorithm)) {
|
||||
HashFiles (ha, Configurables.Paths.BundleVersionHashFiles);
|
||||
VersionHash = FormatHash (ha.Hash).Substring (0, (int)Configurables.Defaults.AbbreviatedHashLength);
|
||||
Log.StatusLine (" Hash: ", VersionHash, tailColor: ConsoleColor.Cyan);
|
||||
}
|
||||
|
||||
string EnsureHash (string name, string hash)
|
||||
{
|
||||
if (String.IsNullOrEmpty (hash))
|
||||
throw new InvalidOperationException ($"Unable to determine {name} commit hash");
|
||||
Log.StatusLine (" Commit: ", hash, tailColor: ConsoleColor.Cyan);
|
||||
Log.StatusLine ();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
void HashFiles (HashAlgorithm ha, List<string> globPatterns)
|
||||
{
|
||||
var block = new byte [4096];
|
||||
foreach (string glob in globPatterns) {
|
||||
string pattern = glob?.Trim ();
|
||||
if (String.IsNullOrEmpty (pattern))
|
||||
continue;
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles (Path.GetDirectoryName (pattern), Path.GetFileName (pattern))) {
|
||||
Log.StatusLine (" file: ", Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, file), tailColor: ConsoleColor.Cyan);
|
||||
HashFile (ha, file, block);
|
||||
}
|
||||
}
|
||||
ha.TransformFinalBlock (block, 0, 0);
|
||||
}
|
||||
|
||||
void HashFile (HashAlgorithm ha, string filePath, byte[] block)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream ()) {
|
||||
//Read the file into a MemoryStream, ignoring newlines
|
||||
using (var file = File.OpenRead (filePath)) {
|
||||
int readByte;
|
||||
while ((readByte = file.ReadByte ()) != -1) {
|
||||
byte b = (byte)readByte;
|
||||
if (b != '\r' && b != '\n') {
|
||||
memoryStream.WriteByte (b);
|
||||
}
|
||||
}
|
||||
}
|
||||
memoryStream.Seek (0, SeekOrigin.Begin);
|
||||
|
||||
int read;
|
||||
while ((read = memoryStream.Read (block, 0, block.Length)) > 0) {
|
||||
ha.TransformBlock (block, 0, read, block, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string FormatHash (byte[] hash)
|
||||
{
|
||||
return string.Join (String.Empty, hash.Select (b => b.ToString ("x2")));
|
||||
}
|
||||
|
||||
async Task DetermineLastVersionChangeCommit (Context context)
|
||||
{
|
||||
Log.StatusLine ($" {context.Characters.Bullet} Commit of last version change", ConsoleColor.Gray);
|
||||
GitRunner git = CreateGitRunner (context);
|
||||
IList <GitRunner.BlamePorcelainEntry> blameEntries;
|
||||
|
||||
blameEntries = await git.Blame ("Configuration.props");
|
||||
if (blameEntries == null || blameEntries.Count == 0)
|
||||
throw new InvalidOperationException ("Unable to determine the last version change commit");
|
||||
|
||||
foreach (GitRunner.BlamePorcelainEntry be in blameEntries) {
|
||||
if (be == null || String.IsNullOrEmpty (be.Line))
|
||||
continue;
|
||||
|
||||
if (be.Line.IndexOf ("<ProductVersion>") >= 0) {
|
||||
Log.DebugLine ($"Last version change on {GetCommitDate (be)} by {be.Author}");
|
||||
CommitOfLastVersionChange = be.Commit;
|
||||
Log.StatusLine (" Commit: ", be.Commit, tailColor: ConsoleColor.Cyan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string GetCommitDate (GitRunner.BlamePorcelainEntry be)
|
||||
{
|
||||
int tzOffset = GetTZOffset (be.CommitterTZ, be);
|
||||
int committerTimeUTC = (int)be.CommitterTime + tzOffset;
|
||||
var unixEpoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
DateTime dt = unixEpoch.AddSeconds (committerTimeUTC);
|
||||
|
||||
return dt.ToString ("R", DateTimeFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
||||
int GetTZOffset (string tz, GitRunner.BlamePorcelainEntry be)
|
||||
{
|
||||
if (String.IsNullOrEmpty (tz)) {
|
||||
Log.DebugLine ($"No timezone information from `git blame` for commit {be.Commit}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tz.Length != 5) {
|
||||
LogUnexpectedFormat ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tzSign;
|
||||
switch (tz [0]) {
|
||||
case '-':
|
||||
tzSign = 1;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
tzSign = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
LogUnexpectedFormat ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Int32.TryParse (tz.Substring (1, 2), out int hours)) {
|
||||
LogUnexpectedFormat ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Int32.TryParse (tz.Substring (3, 2), out int minutes)) {
|
||||
LogUnexpectedFormat ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tzSign * ((hours * 3600) + (minutes * 60));
|
||||
|
||||
void LogUnexpectedFormat ()
|
||||
{
|
||||
Log.DebugLine ($"Unexpected timezone format from `git blame` for commit {be.Commit}: {tz}");
|
||||
}
|
||||
}
|
||||
|
||||
GitRunner CreateGitRunner (Context context)
|
||||
{
|
||||
return new GitRunner (context, Log) {
|
||||
LogMessageIndent = " Running: "
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class BundleItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Optional path of the item in the destination archive
|
||||
/// </summary>
|
||||
public string ArchivePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional functor to determine whether or not to include the item in the archive.
|
||||
/// </summary>
|
||||
public Func<Context, bool> ShouldInclude { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Required source path of the item.
|
||||
/// </summary>
|
||||
public string SourcePath { get; }
|
||||
|
||||
public BundleItem (string sourcePath, string archivePath = null, Func<Context, bool> shouldInclude = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty (sourcePath))
|
||||
throw new ArgumentNullException (nameof (sourcePath));
|
||||
|
||||
ArchivePath = archivePath;
|
||||
ShouldInclude = shouldInclude;
|
||||
SourcePath = sourcePath;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
abstract class Characters
|
||||
{
|
||||
public abstract string Bullet { get; }
|
||||
public abstract string Link { get; }
|
||||
public abstract string Package { get; }
|
||||
public abstract string LeftArrow { get; }
|
||||
public abstract string RightArrow { get; }
|
||||
public abstract string[] Twiddler { get; }
|
||||
|
||||
protected Characters ()
|
||||
{}
|
||||
|
||||
public static Characters Create (Context context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
|
||||
if (!context.NoEmoji && !context.DullMode && context.CanConsoleUseUnicode)
|
||||
return new UnicodeChars ();
|
||||
|
||||
return new PlainChars ();
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PlainChars : Characters
|
||||
{
|
||||
static readonly string[] twiddler = new [] {"-", "\\", "|", "/", "-", "\\", "|", "/"};
|
||||
|
||||
public override string Bullet => "*";
|
||||
public override string Link => "->";
|
||||
public override string Package => "#";
|
||||
public override string LeftArrow => "<-";
|
||||
public override string RightArrow => "->";
|
||||
public override string[] Twiddler => twiddler;
|
||||
}
|
||||
|
||||
sealed class UnicodeChars : Characters
|
||||
{
|
||||
readonly string[] twiddler;
|
||||
|
||||
public override string Bullet => "•";
|
||||
public override string Link => Char.ConvertFromUtf32 (0x1f517); // 🔗
|
||||
public override string Package => Char.ConvertFromUtf32 (0x1f4e6); // 📦
|
||||
public override string LeftArrow => "←";
|
||||
public override string RightArrow => "→";
|
||||
public override string[] Twiddler => twiddler;
|
||||
|
||||
public UnicodeChars ()
|
||||
{
|
||||
twiddler = new string [12];
|
||||
|
||||
for (int i = 0 ; i < 12; i++) {
|
||||
twiddler [i] = Char.ConvertFromUtf32 (0x1F550 + i); // 🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class CompressionFormat
|
||||
{
|
||||
public string Description { get; }
|
||||
public string Extension { get; }
|
||||
public string Name { get; }
|
||||
|
||||
public CompressionFormat (string name, string description, string extension)
|
||||
{
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentNullException (nameof (name));
|
||||
|
||||
if (String.IsNullOrEmpty (description))
|
||||
throw new ArgumentNullException (nameof (description));
|
||||
|
||||
if (String.IsNullOrEmpty (extension))
|
||||
throw new ArgumentNullException (nameof (extension));
|
||||
|
||||
Description = description;
|
||||
Extension = extension;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Context
|
||||
{
|
||||
void InitOS ()
|
||||
{
|
||||
OS = Linux.DetectAndCreate (this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Context
|
||||
{
|
||||
void InitOS ()
|
||||
{
|
||||
OS = new MacOS (this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Context
|
||||
{
|
||||
void InitOS ()
|
||||
{
|
||||
OS = new Windows (Context.Instance);
|
||||
|
||||
// Windows console (cmd.exe) is rather... antiquated and doesn't behave well with our output so turn off all
|
||||
// the nice stuff until Windows Terminal is in and we can enjoy the full console goodness.
|
||||
UseColor = false;
|
||||
NoEmoji = true;
|
||||
DullMode = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,845 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
/// <summary>
|
||||
/// Shared application contet.
|
||||
/// </summary>
|
||||
partial class Context : AppObject
|
||||
{
|
||||
const ConsoleColor BannerColor = ConsoleColor.DarkGreen;
|
||||
|
||||
public const ConsoleColor SuccessColor = ConsoleColor.Green;
|
||||
public const ConsoleColor FailureColor = ConsoleColor.Red;
|
||||
public const ConsoleColor WarningColor = ConsoleColor.Yellow;
|
||||
|
||||
static readonly string XASolutionFilePath = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "Xamarin.Android.sln");
|
||||
static readonly string XATestsSolutionFilePath = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "Xamarin.Android-Tests.sln");
|
||||
|
||||
string logDirectory;
|
||||
string mainLogFilePath;
|
||||
string xaInstallPrefix;
|
||||
string overridenLogDirectory;
|
||||
string configuration;
|
||||
string productVersion;
|
||||
string androidLatestStableFrameworkVersion;
|
||||
string hashAlgorithm;
|
||||
bool canOutputColor;
|
||||
bool canConsoleUseUnicode;
|
||||
Characters characters;
|
||||
bool? useColor;
|
||||
bool? dullMode;
|
||||
Scenario defaultScenario;
|
||||
HashSet<string> hostJitAbis;
|
||||
HashSet<string> targetAotAbis;
|
||||
HashSet<string> targetJitAbis;
|
||||
List<RuleGenerator> ruleGenerators;
|
||||
string debugFileExtension;
|
||||
CompressionFormat compressionFormat;
|
||||
Dictionary<KnownConditions, bool> conditions = new Dictionary<KnownConditions, bool> ();
|
||||
|
||||
/// <summary>
|
||||
/// Access the only instance of the Context class
|
||||
/// </summary>
|
||||
public static Context Instance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Information about the operating system we're currently running on. See <see cref="OS" />
|
||||
/// </summary>
|
||||
public OS OS { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A shortcut to access a small set of essential tools used by the bootstrapper. See <see cref="EssentialTools" />
|
||||
/// </summary>
|
||||
public EssentialTools Tools { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Information about the current build. <see cref="BuildInfo" />
|
||||
/// </summary>
|
||||
public BuildInfo BuildInfo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All the scenarios known to the bootstrapper
|
||||
/// </summary>
|
||||
public IDictionary<string, Scenario> Scenarios { get; } = new SortedDictionary<string, Scenario> (StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Default scenario to execute if none was specified by the user on the command line
|
||||
/// </summary>
|
||||
public Scenario DefaultScenario => defaultScenario;
|
||||
|
||||
/// <summary>
|
||||
/// Scenario selected for the current session
|
||||
/// </summary>
|
||||
public Scenario SelectedScenario { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the current run of the bootstrapper can interact with the user or not
|
||||
/// </summary>
|
||||
public bool InteractiveSession { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Set of properties available in this instance of the bootstrapper. See <see cref="KnownProperties" /> and <see
|
||||
/// cref="Properties" />
|
||||
/// </summary>
|
||||
public Properties Properties { get; } = new Properties ();
|
||||
|
||||
/// <summary>
|
||||
/// Time stamp of the current build
|
||||
/// </summary>
|
||||
public string BuildTimeStamp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A collection of all the methods to obtain version numbers from programs. See <see cref="t:VersionFetchers" />
|
||||
/// </summary>
|
||||
public VersionFetchers VersionFetchers { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Logging verbosity/level of the current session.
|
||||
/// </summary>
|
||||
public LoggingVerbosity LoggingVerbosity { get; set; } = Configurables.Defaults.LoggingVerbosity;
|
||||
|
||||
/// <summary>
|
||||
/// How many make/ninja jobs to run when building software
|
||||
/// </summary>
|
||||
public uint MakeConcurrency { get; set; } = Configurables.Defaults.MakeConcurrency;
|
||||
|
||||
/// <summary>
|
||||
/// Do not use emoji characters
|
||||
/// </summary>
|
||||
public bool NoEmoji { get; set; } = !Configurables.Defaults.UseEmoji;
|
||||
|
||||
/// <summary>
|
||||
/// Force a rebuild of the Mono runtimes
|
||||
/// </summary>
|
||||
public bool ForceRuntimesBuild { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Automatically provision all the missing programs
|
||||
/// </summary>
|
||||
public bool AutoProvision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If a program being provisioned automatically requires administrative rights to install, use sudo
|
||||
/// </summary>
|
||||
public bool AutoProvisionUsesSudo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Do not terminate session when Mono is newer than specified in the dependencies
|
||||
/// </summary>
|
||||
public bool IgnoreMaxMonoVersion { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Current session execution mode. See <see cref="t:ExecutionMode" />
|
||||
/// </summary>
|
||||
public ExecutionMode ExecutionMode { get; set; } = Configurables.Defaults.ExecutionMode;
|
||||
|
||||
/// <summary>
|
||||
/// Set of Mono command line options to be placed in the `MONO_OPTIOS` environment variable
|
||||
/// </summary>
|
||||
public List<string> MonoOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable all supported targets, runtimes etc. Takes effect only if set before <see cref="Init"/> is called
|
||||
/// </summary>
|
||||
public bool EnableAllTargets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to the current session's main log file
|
||||
/// </summary>
|
||||
public string MainLogFilePath => mainLogFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// Path to the Xamarin.Android solution file
|
||||
/// </summary>
|
||||
public string XASolutionFile => XASolutionFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// Path to the Xamarin.Android tests solution file
|
||||
/// </summary>
|
||||
public string XATestsSolutionFile => XATestsSolutionFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// If <c>true</c>, the current console is capable of displayig UTF-8 characters
|
||||
/// </summary>
|
||||
public bool CanConsoleUseUnicode => canConsoleUseUnicode;
|
||||
|
||||
/// <summary>
|
||||
/// A set of various special characters used in progress messages. See <see cref="t:Characters" />
|
||||
/// </summary>
|
||||
public Characters Characters => characters;
|
||||
|
||||
/// <summary>
|
||||
/// Xamarin.Android version
|
||||
/// </summary>
|
||||
public string ProductVersion => productVersion;
|
||||
|
||||
/// <summary>
|
||||
/// If <c>true</c> make messages logged to console not use colors, do not use "fancy" progress indicators etc
|
||||
/// </summary>
|
||||
public bool DullMode {
|
||||
get => dullMode.HasValue ? dullMode.Value : ExecutionMode == ExecutionMode.CI;
|
||||
set => dullMode = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compression format to use for the archives we create
|
||||
/// </summary>
|
||||
public CompressionFormat CompressionFormat {
|
||||
get => compressionFormat ?? Configurables.Defaults.DefaultCompressionFormat;
|
||||
set => compressionFormat = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current session buuld configuration
|
||||
/// </summary>
|
||||
public string Configuration {
|
||||
get => configuration ?? Properties.GetRequiredValue (KnownProperties.Configuration);
|
||||
set {
|
||||
if (String.IsNullOrEmpty (value))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (value));
|
||||
if (!String.IsNullOrEmpty (configuration))
|
||||
throw new InvalidOperationException ("Configuration can be set only once");
|
||||
|
||||
logDirectory = null;
|
||||
configuration = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not current build is a debug one.
|
||||
/// </summary>
|
||||
public bool IsDebugBuild => String.Compare (Configuration, "Debug", StringComparison.OrdinalIgnoreCase) == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Hash algorithm to use when calculating various hashes.
|
||||
/// </summary>
|
||||
public string HashAlgorithm {
|
||||
get => String.IsNullOrEmpty (hashAlgorithm) ? Configurables.Defaults.HashAlgorithm : HashAlgorithm;
|
||||
set {
|
||||
value = value?.Trim ();
|
||||
if (String.IsNullOrEmpty (value))
|
||||
throw new ArgumentException ("must not be null or empty", "value");
|
||||
hashAlgorithm = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directoruy containing all the session logs
|
||||
/// </summary>
|
||||
public string LogDirectory {
|
||||
get => GetLogDirectory ();
|
||||
set {
|
||||
if (String.IsNullOrEmpty (value))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (value));
|
||||
|
||||
overridenLogDirectory = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not log messages should use color
|
||||
/// </summary>
|
||||
public bool UseColor {
|
||||
get => canOutputColor && (!useColor.HasValue || useColor.Value);
|
||||
set => useColor = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prefix where Xamarin.Android is installed
|
||||
/// </summary>
|
||||
public string XAInstallPrefix {
|
||||
get {
|
||||
if (String.IsNullOrEmpty (xaInstallPrefix))
|
||||
xaInstallPrefix = Properties.GetRequiredValue (KnownProperties.XAInstallPrefix);
|
||||
return xaInstallPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>true</c> if any Windows ABI targets are enabled
|
||||
/// </summary>
|
||||
public bool WindowsJitAbisEnabled {
|
||||
get => IsHostJitAbiEnabled (AbiNames.HostJit.Win32) || IsHostJitAbiEnabled (AbiNames.HostJit.Win64);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>true</c> if any Android device AOT targets are enabled
|
||||
/// </summary>
|
||||
public bool TargetAotAbisEnabled {
|
||||
get => AbiNames.AllTargetAotAbis.Any (abi => IsTargetAotAbiEnabled (abi));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A collection of delegates which can add rules to the `rules.mk` file generated at the end of
|
||||
/// bootstrapper's run
|
||||
/// </summary>
|
||||
public List<RuleGenerator> RuleGenerators {
|
||||
get {
|
||||
if (ruleGenerators == null)
|
||||
ruleGenerators = new List<RuleGenerator> ();
|
||||
return ruleGenerators;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extensions of files with debug information
|
||||
/// </summary>
|
||||
public string DebugFileExtension {
|
||||
get => debugFileExtension ?? Configurables.Defaults.DebugFileExtension;
|
||||
set {
|
||||
value = value?.Trim ();
|
||||
if (String.IsNullOrEmpty (value))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (value));
|
||||
if (value [0] != '.')
|
||||
debugFileExtension = $".{value}";
|
||||
else
|
||||
debugFileExtension = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full filesystem path to the Xamarin.Android bundle *if* defined on the command line by the user, otherwise
|
||||
/// <c>null</c>
|
||||
/// </summary>
|
||||
public string XABundlePath { get; set; }
|
||||
|
||||
static Context ()
|
||||
{
|
||||
Instance = new Context ();
|
||||
}
|
||||
|
||||
Context ()
|
||||
{
|
||||
try {
|
||||
// This may throw on Windows
|
||||
Console.CursorVisible = false;
|
||||
} catch (IOException) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Standard Console class offers no way to detect if the terminal can use color, so we use this rather poor
|
||||
// way to detect it
|
||||
canOutputColor = true;
|
||||
try {
|
||||
ConsoleColor color = Console.ForegroundColor;
|
||||
} catch (IOException) {
|
||||
canOutputColor = false;
|
||||
}
|
||||
|
||||
Properties.PropertiesChanged += PropertiesChanged;
|
||||
canConsoleUseUnicode =
|
||||
Console.OutputEncoding is UTF7Encoding ||
|
||||
Console.OutputEncoding is UTF8Encoding ||
|
||||
Console.OutputEncoding is UTF32Encoding ||
|
||||
Console.OutputEncoding is UnicodeEncoding;
|
||||
|
||||
Log.Todo ("better checks for interactive session (isatty?)");
|
||||
InteractiveSession = !Console.IsOutputRedirected;
|
||||
|
||||
var now = DateTime.Now;
|
||||
BuildTimeStamp = $"{now.Year}{now.Month:00}{now.Day:00}T{now.Hour:00}{now.Minute:00}{now.Second:00}";
|
||||
mainLogFilePath = GetLogFilePath (null, true);
|
||||
Log.Instance.SetLogFile (mainLogFilePath);
|
||||
|
||||
productVersion = Properties.GetRequiredValue (KnownProperties.ProductVersion);
|
||||
androidLatestStableFrameworkVersion = Properties.GetRequiredValue (KnownProperties.AndroidLatestStableFrameworkVersion);
|
||||
|
||||
Log.Instance.DebugLine ("All defined properties:");
|
||||
foreach (KeyValuePair<string, string> prop in Properties) {
|
||||
Log.Instance.DebugLine ($" {prop.Key} = {prop.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertiesChanged (object sender, PropertiesChangedEventArgs args)
|
||||
{
|
||||
if (String.Compare (KnownProperties.AndroidSupportedTargetJitAbis, args.Name, StringComparison.Ordinal) == 0) {
|
||||
targetJitAbis = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.Compare (KnownProperties.AndroidSupportedHostJitAbis, args.Name, StringComparison.Ordinal) == 0) {
|
||||
hostJitAbis = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.Compare (KnownProperties.AndroidSupportedTargetAotAbis, args.Name, StringComparison.Ordinal) == 0) {
|
||||
targetAotAbis = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> names an enabled Android device ABI target.
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetJit"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsTargetJitAbiEnabled (string abiName)
|
||||
{
|
||||
PopulateTargetJitAbis ();
|
||||
return IsAbiEnabled (abiName, targetJitAbis);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> names an enabled host OS ABI target.
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.HostJit"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsHostJitAbiEnabled (string abiName)
|
||||
{
|
||||
PopulateHostJitAbis ();
|
||||
return IsAbiEnabled (abiName, hostJitAbis);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> names an enabled AOT cross-compieler target.
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsTargetAotAbiEnabled (string abiName)
|
||||
{
|
||||
PopulateTargetAotAbis ();
|
||||
return IsAbiEnabled (abiName, targetAotAbis);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS AOT cross compiler ABI
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsHostAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllHostAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a Windows AOT cross compiler ABI
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsWindowsAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllWindowsAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 64-bit Android JIT ABI target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is64BitTargetJitAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All64BitTargetJitAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 32-bit Android JIT ABI target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is32BitTargetJitAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All32BitTargetJitAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 64-bit AOT cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is64BitTargetAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All64BitTargetAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 32-bit AOT cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is32BitTargetAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All32BitTargetAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsMingwHostAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllMingwHostAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows 32-bit cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is32BitMingwHostAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All32BitMingwHostAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows 64-bit cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is64BitMingwHostAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All64BitMingwHostAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsNativeHostAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllNativeHostAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows AOT cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsCrossAotWindowsAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllCrossWindowsAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS AOT 64-bit cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is64BitCrossAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All64BitCrossAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows 32-bit cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is32BitCrossAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All32BitCrossAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS AOT cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsHostCrossAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllCrossHostAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS Windows AOT cross-compiler target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsWindowsCrossAotAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllCrossWindowsAotAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a Windows LLVM target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsLlvmWindowsAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllLlvmWindowsAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a host OS LLVM target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool IsLlvmHostAbi (string abiName)
|
||||
{
|
||||
return AbiNames.AllLlvmHostAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 32-bit LLVM target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is32BitLlvmAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All32BitLlvmAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether <paramref name="abiName"/> refers to a 64-bit LLVM target
|
||||
/// <seealso cref="Xamarin.Android.Prepare.AbiNames.TargetAot"/>
|
||||
/// <seealso cref="Xamarin.Android.Prepare.Abi"/>
|
||||
/// </summary>
|
||||
public bool Is64BitLlvmAbi (string abiName)
|
||||
{
|
||||
return AbiNames.All64BitLlvmAbis.Contains (abiName);
|
||||
}
|
||||
|
||||
bool IsAbiEnabled (string abiName, HashSet<string> collection)
|
||||
{
|
||||
if (String.IsNullOrEmpty (abiName))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (abiName));
|
||||
|
||||
return collection.Contains (abiName);
|
||||
}
|
||||
|
||||
void PopulateTargetJitAbis ()
|
||||
{
|
||||
if (targetJitAbis != null)
|
||||
return;
|
||||
|
||||
Utilities.AddAbis (Properties.GetRequiredValue (KnownProperties.AndroidSupportedTargetJitAbis).Trim (), ref targetJitAbis);
|
||||
}
|
||||
|
||||
void PopulateTargetAotAbis ()
|
||||
{
|
||||
if (targetAotAbis != null)
|
||||
return;
|
||||
|
||||
Utilities.AddAbis (Properties.GetRequiredValue (KnownProperties.AndroidSupportedTargetAotAbis).Trim (), ref targetAotAbis);
|
||||
}
|
||||
|
||||
void PopulateHostJitAbis ()
|
||||
{
|
||||
if (hostJitAbis != null) {
|
||||
return;
|
||||
}
|
||||
Utilities.AddAbis (Properties.GetRequiredValue (KnownProperties.AndroidSupportedHostJitAbis).Trim (), ref hostJitAbis);
|
||||
}
|
||||
|
||||
void OnPropertiesChanged (object sender, EventArgs args)
|
||||
{
|
||||
hostJitAbis = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct and return path to a log file other than the main log file. The <paramref name="tags"/> parameter
|
||||
/// is a string appended to the log name - it MUST consist only of characters valid for file/path names.
|
||||
/// </summary>
|
||||
public string GetLogFilePath (string tags)
|
||||
{
|
||||
return GetLogFilePath (tags, false);
|
||||
}
|
||||
|
||||
string GetLogFilePath (string tags, bool mainLogFile)
|
||||
{
|
||||
string logFileName;
|
||||
if (String.IsNullOrEmpty (tags)) {
|
||||
if (!mainLogFile)
|
||||
throw new ArgumentException ("must not be null or empty", nameof (tags));
|
||||
logFileName = $"{Configurables.Defaults.LogFilePrefix}-{BuildTimeStamp}.log";
|
||||
} else {
|
||||
logFileName = $"{Configurables.Defaults.LogFilePrefix}-{BuildTimeStamp}.{tags}.log";
|
||||
}
|
||||
|
||||
return Path.Combine (LogDirectory, logFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check value of a condition flag. If the flag was never set, it will return <c>false</c>
|
||||
/// </summary>
|
||||
public bool CheckCondition (KnownConditions knownCondition)
|
||||
{
|
||||
if (!conditions.TryGetValue (knownCondition, out bool v))
|
||||
return false;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a condition flag that can be used by any part of the program for its own purposes. <see cref="KnownConditions"/>
|
||||
/// </summary>
|
||||
public void SetCondition (KnownConditions knownCondition, bool v)
|
||||
{
|
||||
Log.DebugLine ($"Setting condition {knownCondition} to '{v}'");
|
||||
conditions [knownCondition] = v;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the execution context. Called only once from Main.
|
||||
/// </summary>
|
||||
public async Task<bool> Init (string scenarioName = null)
|
||||
{
|
||||
SetCondition (KnownConditions.AllowProgramInstallation, true);
|
||||
|
||||
characters = Characters.Create (this);
|
||||
|
||||
Log.StatusLine ("Main log file: ", MainLogFilePath, ConsoleColor.Gray, Log.DestinationColor);
|
||||
|
||||
MonoOptions = new List<string> {
|
||||
"--debug", // Doesn't hurt to have line numbers in stack traces...
|
||||
};
|
||||
|
||||
Banner ("Detecting operating system");
|
||||
InitOS ();
|
||||
|
||||
Log.StatusLine ();
|
||||
Log.StatusLine (" OS type: ", OS.Type, tailColor: Log.InfoColor);
|
||||
Log.StatusLine (" OS name: ", OS.Name, tailColor: Log.InfoColor);
|
||||
Log.StatusLine ("OS release: ", OS.Release, tailColor: Log.InfoColor);
|
||||
Log.StatusLine (" OS bits: ", OS.Architecture, tailColor: Log.InfoColor);
|
||||
Log.StatusLine (" CPU count: ", OS.CPUCount.ToString (), tailColor: Log.InfoColor);
|
||||
Log.StatusLine ();
|
||||
|
||||
if (EnableAllTargets) {
|
||||
Properties.Set (KnownProperties.AndroidSupportedTargetJitAbis, Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllJitAbis));
|
||||
Properties.Set (KnownProperties.AndroidSupportedHostJitAbis, Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllHostAbis));
|
||||
Properties.Set (KnownProperties.AndroidSupportedTargetAotAbis, Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllAotAbis));
|
||||
}
|
||||
|
||||
VersionFetchers = new VersionFetchers ();
|
||||
Tools = new EssentialTools ();
|
||||
DiscoverScenarios (scenarioName);
|
||||
|
||||
if (!await OS.Init ()) {
|
||||
Log.ErrorLine ("Failed to initialize OS support");
|
||||
return false;
|
||||
}
|
||||
|
||||
Tools.Init (this);
|
||||
|
||||
Banner ("Updating Git submodules");
|
||||
|
||||
var git = new GitRunner (this);
|
||||
if (!await git.SubmoduleUpdate ())
|
||||
Log.WarningLine ("Failed to update Git submodules");
|
||||
|
||||
BuildInfo = new BuildInfo ();
|
||||
await BuildInfo.GatherGitInfo (this);
|
||||
AbiNames.LogAllNames (this);
|
||||
|
||||
if (MakeConcurrency == 0)
|
||||
MakeConcurrency = OS.CPUCount + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute the selected scenario (either the default one or one chosen by using the <c>-s</c> command line parameter)
|
||||
/// </summary>
|
||||
public async Task<bool> Execute ()
|
||||
{
|
||||
Scenario scenario = SelectedScenario;
|
||||
Banner ($"Running scenario: {scenario.Description}");
|
||||
|
||||
string logFilePath = scenario.LogFilePath ?? mainLogFilePath;
|
||||
Log scenarioLog = null;
|
||||
|
||||
if (!String.IsNullOrEmpty (scenario.LogFilePath)) {
|
||||
Log.StatusLine ("Log file: ", scenario.LogFilePath, ConsoleColor.Gray, Log.DestinationColor);
|
||||
scenarioLog = new Log (logFilePath);
|
||||
} else {
|
||||
Log.StatusLine ("Logging to main log file");
|
||||
}
|
||||
|
||||
try {
|
||||
await scenario.Run (this, scenarioLog);
|
||||
} finally {
|
||||
scenarioLog?.Dispose ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiscoverScenarios (string scenarioName)
|
||||
{
|
||||
List<Type> types = Utilities.GetTypesWithCustomAttribute<ScenarioAttribute> ();
|
||||
|
||||
bool haveScenarioName = !String.IsNullOrEmpty (scenarioName);
|
||||
SelectedScenario = null;
|
||||
defaultScenario = null;
|
||||
foreach (Type type in types) {
|
||||
var scenario = Activator.CreateInstance (type) as Scenario;
|
||||
Scenarios.Add (scenario.Name, scenario);
|
||||
if (IsDefaultScenario (type)) {
|
||||
if (defaultScenario != null)
|
||||
throw new InvalidOperationException ($"Only one default scenario is allowed. {defaultScenario} was previously declared as one, {type} is also marked as deafult");
|
||||
defaultScenario = scenario;
|
||||
}
|
||||
|
||||
if (!haveScenarioName || SelectedScenario != null)
|
||||
continue;
|
||||
|
||||
if (String.Compare (scenarioName, scenario.Name, StringComparison.OrdinalIgnoreCase) != 0)
|
||||
continue;
|
||||
|
||||
SelectedScenario = scenario;
|
||||
}
|
||||
|
||||
if (haveScenarioName && SelectedScenario == null)
|
||||
throw new InvalidOperationException ($"Unknown scenario '{scenarioName}'");
|
||||
|
||||
if (SelectedScenario == null)
|
||||
SelectedScenario = defaultScenario;
|
||||
|
||||
if (SelectedScenario == null)
|
||||
throw new InvalidOperationException ("No specific scenario named and no default scenario found");
|
||||
|
||||
Log.DebugLine ($"Initializing scenario {SelectedScenario.Name}");
|
||||
SelectedScenario.Init (this);
|
||||
}
|
||||
|
||||
bool IsDefaultScenario (Type type)
|
||||
{
|
||||
foreach (ScenarioAttribute attr in type.GetCustomAttributes (typeof(ScenarioAttribute), true)) {
|
||||
if (attr.IsDefault)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print a "banner" to the output stream - will not show anything only if logging verbosity is set to <see
|
||||
/// cref="LoggingVerbosity.Quiet"/>
|
||||
/// </summary>
|
||||
public void Banner (string text)
|
||||
{
|
||||
if (LoggingVerbosity <= LoggingVerbosity.Quiet)
|
||||
return;
|
||||
|
||||
Log.StatusLine ();
|
||||
Log.StatusLine ("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", BannerColor);
|
||||
Log.StatusLine (text, BannerColor);
|
||||
Log.StatusLine ("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", BannerColor);
|
||||
Log.StatusLine ();
|
||||
}
|
||||
|
||||
string GetLogDirectory ()
|
||||
{
|
||||
if (!String.IsNullOrEmpty (overridenLogDirectory))
|
||||
return overridenLogDirectory;
|
||||
|
||||
if (!String.IsNullOrEmpty (logDirectory))
|
||||
return logDirectory;
|
||||
|
||||
logDirectory = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "bin", $"Build{Configuration}");
|
||||
if (!Directory.Exists (logDirectory))
|
||||
Directory.CreateDirectory (logDirectory);
|
||||
|
||||
return logDirectory;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
using System;
|
||||
|
||||
// Based on code from https://code.msdn.microsoft.com/windowsapps/How-to-determine-the-263b1850
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class OSVersionInfo
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public int Minor { get; private set; }
|
||||
public int Major { get; private set; }
|
||||
public int Build { get; private set; }
|
||||
|
||||
public string FullName => $"Microsoft {Name} [Version {Major}.{Minor}.{Build}]";
|
||||
|
||||
OSVersionInfo ()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Init OSVersionInfo object by current windows environment
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static OSVersionInfo GetOSVersionInfo ()
|
||||
{
|
||||
OperatingSystem osVersionObj = Environment.OSVersion;
|
||||
OSVersionInfo osVersionInfo = new OSVersionInfo () {
|
||||
Name = GetOSName (osVersionObj),
|
||||
Major = osVersionObj.Version.Major,
|
||||
Minor = osVersionObj.Version.Minor,
|
||||
Build = osVersionObj.Version.Build
|
||||
};
|
||||
|
||||
return osVersionInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get current windows name
|
||||
/// </summary>
|
||||
/// <param name="osInfo"></param>
|
||||
/// <returns></returns>
|
||||
static string GetOSName (OperatingSystem osInfo)
|
||||
{
|
||||
string osName = "unknown";
|
||||
switch (osInfo.Platform) {
|
||||
//for old windows kernel
|
||||
case PlatformID.Win32Windows:
|
||||
osName = ForWin32Windows (osInfo);
|
||||
break;
|
||||
|
||||
//fow NT kernel
|
||||
case PlatformID.Win32NT:
|
||||
osName = ForWin32NT (osInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
return osName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// for old windows kernel
|
||||
/// this function is the child function for method GetOSName
|
||||
/// </summary>
|
||||
/// <param name="osInfo"></param>
|
||||
/// <returns></returns>
|
||||
static string ForWin32Windows (OperatingSystem osInfo)
|
||||
{
|
||||
string osVersion = "Unknown";
|
||||
|
||||
//Code to determine specific version of Windows 95,
|
||||
//Windows 98, Windows 98 Second Edition, or Windows Me.
|
||||
switch (osInfo.Version.Minor) {
|
||||
case 0:
|
||||
osVersion = "Windows 95";
|
||||
break;
|
||||
|
||||
case 10:
|
||||
switch (osInfo.Version.Revision.ToString ()) {
|
||||
case "2222A":
|
||||
osVersion = "Windows 98 Second Edition";
|
||||
break;
|
||||
|
||||
default:
|
||||
osVersion = "Windows 98";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 90:
|
||||
osVersion = "Windows Me";
|
||||
break;
|
||||
}
|
||||
|
||||
return osVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fow NT kernel
|
||||
/// this function is the child function for method GetOSName
|
||||
/// </summary>
|
||||
/// <param name="osInfo"></param>
|
||||
/// <returns></returns>
|
||||
static string ForWin32NT (OperatingSystem osInfo)
|
||||
{
|
||||
string osVersion = "Unknown";
|
||||
|
||||
//Code to determine specific version of Windows NT 3.51,
|
||||
//Windows NT 4.0, Windows 2000, or Windows XP.
|
||||
switch (osInfo.Version.Major) {
|
||||
case 3:
|
||||
osVersion = "Windows NT 3.51";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
osVersion = "Windows NT 4.0";
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switch (osInfo.Version.Minor) {
|
||||
case 0:
|
||||
osVersion = "Windows 2000";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
osVersion = "Windows XP";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
osVersion = "Windows 2003";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
switch (osInfo.Version.Minor) {
|
||||
case 0:
|
||||
osVersion = "Windows Vista";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
osVersion = "Windows 7";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
osVersion = "Windows 8";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
osVersion = "Windows 8.1";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
osVersion = "Windows 10";
|
||||
break;
|
||||
}
|
||||
|
||||
return osVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class DownloadStatus
|
||||
{
|
||||
const uint DefaultUpdateInterval = 1000;
|
||||
readonly object updateLock = new object ();
|
||||
|
||||
ConcurrentQueue<ulong> byteSnapshots;
|
||||
Stopwatch watch;
|
||||
Action<DownloadStatus> updater;
|
||||
|
||||
public ulong TotalSize { get; }
|
||||
public ulong DownloadedSoFar { get; set; }
|
||||
public ulong BytesPerSecond { get; set; }
|
||||
public uint UpdateIntervalMS { get; set; } = DefaultUpdateInterval;
|
||||
|
||||
public DownloadStatus (ulong totalSize, Action<DownloadStatus> updaterCallback)
|
||||
{
|
||||
if (updaterCallback == null)
|
||||
throw new ArgumentNullException (nameof (updaterCallback));
|
||||
|
||||
TotalSize = totalSize;
|
||||
DownloadedSoFar = 0;
|
||||
BytesPerSecond = 0;
|
||||
byteSnapshots = new ConcurrentQueue<ulong> ();
|
||||
watch = new Stopwatch ();
|
||||
updater = updaterCallback;
|
||||
}
|
||||
|
||||
public void Start ()
|
||||
{
|
||||
watch.Start ();
|
||||
}
|
||||
|
||||
public void Update (ulong bytesRead)
|
||||
{
|
||||
if (bytesRead == 0)
|
||||
return;
|
||||
|
||||
bool timeForUpdate = watch.ElapsedMilliseconds >= UpdateIntervalMS;
|
||||
if (timeForUpdate) {
|
||||
lock (updateLock) {
|
||||
StoreAndUpdate (bytesRead, timeForUpdate);
|
||||
}
|
||||
} else {
|
||||
StoreAndUpdate (bytesRead, timeForUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
void StoreAndUpdate (ulong bytesRead, bool timeForUpdate)
|
||||
{
|
||||
byteSnapshots.Enqueue (bytesRead);
|
||||
if (!timeForUpdate)
|
||||
return;
|
||||
|
||||
ulong[] snapshots = byteSnapshots.ToArray ();
|
||||
while (!byteSnapshots.IsEmpty)
|
||||
byteSnapshots.TryDequeue (out ulong _);
|
||||
|
||||
// LINQ has no overloads for UInt64 (!?), so we do it by hand...
|
||||
ulong bytesPerSecond = 0;
|
||||
foreach (ulong u in snapshots) {
|
||||
DownloadedSoFar += u;
|
||||
bytesPerSecond += u;
|
||||
}
|
||||
BytesPerSecond = bytesPerSecond;
|
||||
|
||||
updater (this);
|
||||
watch.Restart ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class EssentialTools : AppObject
|
||||
{
|
||||
partial void InitOS (Context context)
|
||||
{
|
||||
InitSharedUnixOS (context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class EssentialTools : AppObject
|
||||
{
|
||||
public string BrewPath { get; set; }
|
||||
public string PkgutilPath { get; set; }
|
||||
|
||||
partial void InitOS (Context context)
|
||||
{
|
||||
Log.StatusLine ($" {context.Characters.Bullet} homebrew", ConsoleColor.White);
|
||||
if (String.IsNullOrEmpty (BrewPath))
|
||||
BrewPath = context.OS.Which ("brew", required: true);
|
||||
Log.StatusLine (" Found: ", BrewPath, tailColor: Log.DestinationColor);
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} pkgutil", ConsoleColor.White);
|
||||
if (String.IsNullOrEmpty (PkgutilPath))
|
||||
PkgutilPath = context.OS.Which ("/usr/sbin/pkgutil", required: true);
|
||||
Log.StatusLine ($" Found: ", PkgutilPath, tailColor: Log.DestinationColor);
|
||||
|
||||
InitSharedUnixOS (context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class EssentialTools
|
||||
{
|
||||
void InitSharedUnixOS (Context context)
|
||||
{}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class EssentialTools : AppObject
|
||||
{
|
||||
public string GitPath { get; set; }
|
||||
public string SevenZipPath { get; set; }
|
||||
|
||||
public EssentialTools ()
|
||||
{}
|
||||
|
||||
public void Init (Context context)
|
||||
{
|
||||
Log.StatusLine ();
|
||||
Log.StatusLine ("Locating essential tool binaries", ConsoleColor.DarkGreen);
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} git", ConsoleColor.White);
|
||||
GitPath = context.OS.Which ("git", required: true);
|
||||
Log.StatusLine (" Found: ", GitPath, tailColor: Log.DestinationColor);
|
||||
|
||||
Log.StatusLine ($" {context.Characters.Bullet} 7za", ConsoleColor.White);
|
||||
SevenZipPath = context.OS.Which ("7za", required: true);
|
||||
Log.StatusLine (" Found: ", SevenZipPath, tailColor: Log.DestinationColor);
|
||||
|
||||
InitOS (context);
|
||||
}
|
||||
|
||||
partial void InitOS (Context context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
enum ExecutionMode
|
||||
{
|
||||
CI,
|
||||
Standard,
|
||||
Interactive
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
static class DictionaryOfProgramVersionParser_Extensions
|
||||
{
|
||||
public static void Add (this Dictionary<string, ProgramVersionParser> dict, string programName, string versionArguments, Regex regex, uint versionOutputLine = 0, Log log = null)
|
||||
{
|
||||
if (dict == null)
|
||||
throw new ArgumentNullException (nameof (dict));
|
||||
|
||||
if (dict.ContainsKey (programName)) {
|
||||
Log.Instance.WarningLine ($"Entry for {programName} version matcher already defined. Ignoring the new entry ({regex})");
|
||||
return;
|
||||
}
|
||||
|
||||
dict [programName] = new RegexProgramVersionParser (programName, versionArguments, regex, versionOutputLine, log);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
static class BundleItem_List_Extensions
|
||||
{
|
||||
public static void Add (this List<BundleItem> list, string sourcePath)
|
||||
{
|
||||
list.Add (sourcePath, archivePath: null, shouldInclude: null);
|
||||
}
|
||||
|
||||
public static void Add (this List<BundleItem> list, string sourcePath, string archivePath)
|
||||
{
|
||||
list.Add (sourcePath, archivePath, shouldInclude: null);
|
||||
}
|
||||
|
||||
public static void Add (this List<BundleItem> list, string sourcePath, Func<Context, bool> shouldInclude)
|
||||
{
|
||||
list.Add (sourcePath, archivePath: null, shouldInclude: shouldInclude);
|
||||
}
|
||||
|
||||
public static void Add (this List<BundleItem> list, string sourcePath, string archivePath, Func<Context, bool> shouldInclude)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
list.Add (new BundleItem (sourcePath, archivePath, shouldInclude));
|
||||
}
|
||||
|
||||
public static void AddRange (this List<BundleItem> list, List<BclFile> bclFiles)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
if (bclFiles == null)
|
||||
throw new ArgumentNullException (nameof (bclFiles));
|
||||
|
||||
foreach (BclFile bf in bclFiles) {
|
||||
if (bf == null)
|
||||
continue;
|
||||
|
||||
// BCL file's *destination* location is our *source* path
|
||||
(string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths (bf);
|
||||
list.Add (destFilePath);
|
||||
if (bf.ExcludeDebugSymbols || !File.Exists (debugSymbolsDestPath))
|
||||
continue;
|
||||
list.Add (debugSymbolsDestPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRange (this List<BundleItem> list, List<MonoUtilityFile> muFiles)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
if (muFiles == null)
|
||||
throw new ArgumentNullException (nameof (muFiles));
|
||||
|
||||
foreach (MonoUtilityFile muf in muFiles) {
|
||||
if (muf == null)
|
||||
continue;
|
||||
|
||||
// MU file's *destination* location is our *source* path
|
||||
(string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths (muf);
|
||||
list.Add (destFilePath);
|
||||
if (muf.IgnoreDebugInfo || String.IsNullOrEmpty (debugSymbolsDestPath))
|
||||
continue;
|
||||
list.Add (debugSymbolsDestPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRange (this List<BundleItem> list, List<RuntimeFile> runtimeFiles)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
if (runtimeFiles == null)
|
||||
throw new ArgumentNullException (nameof (runtimeFiles));
|
||||
|
||||
var sharedFiles = new HashSet <string> (StringComparer.Ordinal);
|
||||
foreach (Runtime runtime in MonoRuntimesHelpers.GetEnabledRuntimes (new Runtimes (), false)) {
|
||||
foreach (RuntimeFile rtf in runtimeFiles) {
|
||||
if (rtf == null)
|
||||
continue;
|
||||
|
||||
// Runtime file's *destination* location is our *source* path
|
||||
(bool skipFile, string _, string destFilePath) = MonoRuntimesHelpers.GetRuntimeFilePaths (runtime, rtf);
|
||||
if (rtf.Shared && sharedFiles.Contains (destFilePath))
|
||||
continue;
|
||||
|
||||
if (skipFile)
|
||||
continue;
|
||||
list.Add (destFilePath);
|
||||
|
||||
if (rtf.Shared)
|
||||
sharedFiles.Add (destFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRange (this List<BundleItem> list, List<TestAssembly> testAssemblies)
|
||||
{
|
||||
if (list == null)
|
||||
throw new ArgumentNullException (nameof (list));
|
||||
|
||||
if (testAssemblies == null)
|
||||
throw new ArgumentNullException (nameof (testAssemblies));
|
||||
|
||||
foreach (TestAssembly tasm in testAssemblies) {
|
||||
if (tasm == null)
|
||||
continue;
|
||||
|
||||
// Test assembly's *destination* location is our *source* path
|
||||
(string destFilePath, string debugSymbolsDestPath) = MonoRuntimesHelpers.GetDestinationPaths (tasm);
|
||||
list.Add (destFilePath);
|
||||
if (String.IsNullOrEmpty (debugSymbolsDestPath))
|
||||
continue;
|
||||
list.Add (debugSymbolsDestPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
static class Runtime_Extensions
|
||||
{
|
||||
public static T As <T> (this Runtime runtime) where T: Runtime
|
||||
{
|
||||
return runtime as T;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
sealed class ExternalGitDependency : AppObject
|
||||
{
|
||||
const string GitHubServer = "github.com";
|
||||
|
||||
static readonly Regex externalRegex = new Regex (@"
|
||||
^
|
||||
\s*
|
||||
(?<comment>\#.*)
|
||||
|
|
||||
(
|
||||
\s*
|
||||
(?<owner>[^/]+)
|
||||
/
|
||||
(?<repo>[^:]+)
|
||||
:
|
||||
(?<branch>[^@]+)
|
||||
@
|
||||
(?<commit>.*)
|
||||
)
|
||||
$
|
||||
", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
public string Branch { get; private set; }
|
||||
public string Commit { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Owner { get; private set; }
|
||||
|
||||
public static List<ExternalGitDependency> GetDependencies (Context context, string externalFilePath)
|
||||
{
|
||||
Log.Instance.StatusLine ($" {context.Characters.Bullet} Reading external dependencies from {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, externalFilePath)}");
|
||||
string[] unparsedExternals = File.ReadAllLines (externalFilePath);
|
||||
var externals = new List<ExternalGitDependency> (unparsedExternals.Length);
|
||||
|
||||
foreach (string external in unparsedExternals) {
|
||||
Match match = externalRegex.Match (external);
|
||||
if (match != null && match.Success) {
|
||||
if (match.Groups["comment"].Success) {
|
||||
// Ignore matching lines which start with '#'.
|
||||
continue;
|
||||
}
|
||||
|
||||
var e = new ExternalGitDependency {
|
||||
Branch = match.Groups["branch"].Value,
|
||||
Commit = match.Groups["commit"].Value,
|
||||
Name = match.Groups["repo"].Value,
|
||||
Owner = match.Groups["owner"].Value,
|
||||
};
|
||||
externals.Add (e);
|
||||
Log.Instance.StatusLine ($" {context.Characters.Bullet} {e.Owner}/{e.Name} ({e.Commit})");
|
||||
}
|
||||
}
|
||||
|
||||
return externals;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
abstract class GeneratedFile : AppObject
|
||||
{
|
||||
public string InputPath { get; }
|
||||
public string OutputPath { get; }
|
||||
public bool EchoOutput { get; set; }
|
||||
|
||||
protected GeneratedFile (string outputPath)
|
||||
{
|
||||
OutputPath = outputPath?.Trim ();
|
||||
if (String.IsNullOrEmpty (OutputPath))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (outputPath));
|
||||
}
|
||||
|
||||
protected GeneratedFile (string inputPath, string outputPath)
|
||||
: this (outputPath)
|
||||
{
|
||||
InputPath = inputPath?.Trim ();
|
||||
if (String.IsNullOrEmpty (InputPath))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (inputPath));
|
||||
|
||||
if (!File.Exists (InputPath))
|
||||
throw new InvalidOperationException ($"Input file {InputPath} must exist");
|
||||
}
|
||||
|
||||
public abstract void Generate (Context context);
|
||||
|
||||
protected void EnsureOutputDir ()
|
||||
{
|
||||
Utilities.CreateDirectory (Path.GetDirectoryName (OutputPath));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class GeneratedMakeRulesFile
|
||||
{
|
||||
partial void OutputOSVariables (Context context, StreamWriter sw)
|
||||
{
|
||||
sw.WriteLine ($"export MACOSX_DEPLOYMENT_TARGET := {Configurables.Defaults.MacOSDeploymentTarget}");
|
||||
sw.WriteLine ($"HOMEBREW_PREFIX := {context.OS.HomebrewPrefix}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class GeneratedMakeRulesFile : GeneratedFile
|
||||
{
|
||||
public GeneratedMakeRulesFile (string outputPath)
|
||||
: base (outputPath)
|
||||
{}
|
||||
|
||||
public override void Generate (Context context)
|
||||
{
|
||||
Log.Todo ("Generate some help for `make help`");
|
||||
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
|
||||
using (StreamWriter sw = Utilities.OpenStreamWriter (OutputPath)) {
|
||||
Generate (context, sw);
|
||||
sw.Flush ();
|
||||
}
|
||||
}
|
||||
|
||||
string GetOutputFileName (Context context, string namePrefix)
|
||||
{
|
||||
return $"{namePrefix}-v{BuildInfo.XAVersion}.$(-num-commits-since-version-change)_{context.OS.Type}-{context.OS.Architecture}_$(GIT_BRANCH)_$(GIT_COMMIT)-$(CONFIGURATION)";
|
||||
}
|
||||
|
||||
void Generate (Context context, StreamWriter sw)
|
||||
{
|
||||
string myPath = Path.Combine (BuildPaths.XAPrepareSourceDir, "Application", "GeneratedMakeRulesFile.cs");
|
||||
sw.WriteLine ( "#");
|
||||
sw.WriteLine ($"# Generated by {myPath}");
|
||||
sw.WriteLine ( "#");
|
||||
sw.WriteLine ();
|
||||
|
||||
WriteVariable ("export OS_NAME", context.OS.Type);
|
||||
WriteVariable ("export OS_ARCH", context.OS.Architecture);
|
||||
WriteVariable ("PRODUCT_VERSION", context.ProductVersion);
|
||||
WriteVariable ("MONO_SOURCE_FULL_PATH", Configurables.Paths.MonoSourceFullPath);
|
||||
|
||||
// These must remain dynamic since the developer may change branches without re-running `prepare`
|
||||
string getGitBranchScript = Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, Path.Combine (Configurables.Paths.BuildToolsScriptsDir, "get-git-branch.sh"));
|
||||
WriteVariable ("GIT_BRANCH", $"$(shell LANG=C \"{getGitBranchScript}\" | tr -d '[[:space:]]' | tr -C a-zA-Z0-9- _)");
|
||||
WriteVariable ("GIT_COMMIT", $"$(shell LANG=C git log --no-color --first-parent -n1 --pretty=format:%h)");
|
||||
WriteVariable ("-num-commits-since-version-change", $"$(shell LANG=C git log {context.BuildInfo.CommitOfLastVersionChange}..HEAD --oneline 2>/dev/null | wc -l | sed 's/ //g')");
|
||||
|
||||
WriteVariable ("ZIP_EXTENSION", context.OS.ZipExtension);
|
||||
WriteVariable ("ZIP_OUTPUT_BASENAME", GetOutputFileName (context, "xamarin.android-oss"));
|
||||
WriteVariable ("_TEST_RESULTS_BASENAME", GetOutputFileName (context, "xa-test-results"));
|
||||
WriteVariable ("_BUILD_STATUS_BASENAME", GetOutputFileName (context, "xa-build-status"));
|
||||
|
||||
WriteVariable ("ZIP_OUTPUT", "$(ZIP_OUTPUT_BASENAME).$(ZIP_EXTENSION)");
|
||||
WriteVariable ("_BUILD_STATUS_ZIP_OUTPUT", "$(_BUILD_STATUS_BASENAME).$(ZIP_EXTENSION)");
|
||||
WriteVariable ("_TEST_RESULTS_ZIP_OUTPUT", "$(_TEST_RESULTS_BASENAME).$(ZIP_EXTENSION)");
|
||||
|
||||
var allApiLevels = new List <string> ();
|
||||
var allPlatformIDs = new List <string> ();
|
||||
var allFrameworks = new List <string> ();
|
||||
var apiLevels = new List <string> ();
|
||||
var stableApiLevels = new List <string> ();
|
||||
var frameworks = new List <string> ();
|
||||
var stableFrameworks = new List <string> ();
|
||||
var platformIds = new List <string> ();
|
||||
|
||||
foreach (AndroidPlatform ap in BuildAndroidPlatforms.AllPlatforms) {
|
||||
string api = ap.ApiLevel.ToString ();
|
||||
|
||||
allApiLevels.Add (api);
|
||||
allPlatformIDs.Add (ap.PlatformID);
|
||||
if (!String.IsNullOrEmpty (ap.Framework)) {
|
||||
allFrameworks.Add (ap.Framework);
|
||||
frameworks.Add (ap.Framework);
|
||||
if (ap.Stable)
|
||||
stableFrameworks.Add (ap.Framework);
|
||||
} else
|
||||
allFrameworks.Add ("-");
|
||||
|
||||
if (!ap.Supported)
|
||||
continue;
|
||||
|
||||
apiLevels.Add (api);
|
||||
platformIds.Add (ap.PlatformID);
|
||||
if (ap.Stable)
|
||||
stableApiLevels.Add (api);
|
||||
}
|
||||
|
||||
WriteVariable ("ALL_API_LEVELS", ToValue (allApiLevels));
|
||||
WriteVariable ("ALL_PLATFORM_IDS", ToValue (allPlatformIDs));
|
||||
WriteVariable ("ALL_FRAMEWORKS", ToValue (allFrameworks));
|
||||
WriteVariable ("API_LEVELS", ToValue (apiLevels));
|
||||
WriteVariable ("STABLE_API_LEVELS", ToValue (stableApiLevels));
|
||||
WriteVariable ("FRAMEWORKS", ToValue (frameworks));
|
||||
WriteVariable ("STABLE_FRAMEWORKS", ToValue (stableFrameworks));
|
||||
WriteVariable ("ALL_JIT_ABIS", ToValue (AbiNames.AllJitAbis));
|
||||
WriteVariable ("ALL_HOST_ABIS", ToValue (AbiNames.AllHostAbis));
|
||||
WriteVariable ("ALL_AOT_ABIS", ToValue (AbiNames.AllAotAbis));
|
||||
if (context.MonoOptions != null && context.MonoOptions.Count > 0) {
|
||||
WriteVariable ("MONO_OPTIONS", ToValue (context.MonoOptions));
|
||||
sw.WriteLine ("export MONO_OPTIONS");
|
||||
}
|
||||
|
||||
sw.WriteLine ("_MSBUILD_ARGS = \\");
|
||||
sw.WriteLine ($"\t/p:{KnownProperties.AndroidSupportedTargetJitAbis}={Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllJitAbis)} \\");
|
||||
sw.WriteLine ($"\t/p:{KnownProperties.AndroidSupportedHostJitAbis}={Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllHostAbis)} \\");
|
||||
sw.WriteLine ($"\t/p:{KnownProperties.AndroidSupportedTargetAotAbis}={Utilities.ToXamarinAndroidPropertyValue (AbiNames.AllAotAbis)}");
|
||||
|
||||
OutputOSVariables (context, sw);
|
||||
|
||||
WriteListVariable ("_BUNDLE_ZIPS_INCLUDE", Configurables.Defaults.BundleZipsInclude);
|
||||
WriteListVariable ("_BUNDLE_ZIPS_EXCLUDE", Configurables.Defaults.BundleZipsExclude);
|
||||
WriteListVariable ("_TEST_RESULTS_BUNDLE_INCLUDE", Configurables.Defaults.TestResultsBundleInclude);
|
||||
WriteListVariable ("_TEST_RESULTS_BUNDLE_EXCLUDE", Configurables.Defaults.TestResultsBundleExclude);
|
||||
WriteListVariable ("_BUILD_STATUS_BUNDLE_INCLUDE", Configurables.Defaults.BuildStatusBundleInclude);
|
||||
WriteListVariable ("_BUILD_STATUS_BUNDLE_INCLUDE", Configurables.Defaults.BuildStatusBundleIncludeConditional, true);
|
||||
WriteListVariable ("_BUILD_STATUS_BUNDLE_EXCLUDE", Configurables.Defaults.BuildStatusBundleExclude);
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine (".PHONY: framework-assemblies");
|
||||
sw.WriteLine ("framework-assemblies:");
|
||||
|
||||
string prevVersion = "v1.0";
|
||||
string monoFrameworksRoot = Path.Combine ("bin", "$(CONFIGURATION)", context.Properties.GetRequiredValue (KnownProperties.XABinRelativeInstallPrefix), Configurables.Paths.MonoAndroidFrameworksSubDir);
|
||||
for (int i = 0; i < apiLevels.Count; i++) {
|
||||
string curVersion = frameworks [i];
|
||||
string apiLevel = apiLevels [i];
|
||||
string platformId = platformIds [i];
|
||||
string redistFile = Path.Combine (monoFrameworksRoot, curVersion, "RedistList", "FrameworkList.xml");
|
||||
WriteRuleLine ($"grep -q {prevVersion} {redistFile}; \\");
|
||||
WriteRuleLine ( "if [ $$? -ne 0 ] ; then \\");
|
||||
WriteRuleLine ($"\trm -f {redistFile}; \\");
|
||||
WriteRuleLine ( "fi; \\");
|
||||
WriteRuleLine ( "$(call MSBUILD_BINLOG,Mono.Android,$(_SLN_BUILD)) src/Mono.Android/Mono.Android.csproj \\");
|
||||
WriteRuleLine ( "\t/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \\");
|
||||
WriteRuleLine ($"\t/p:AndroidApiLevel={apiLevel} /p:AndroidPlatformId={platformId} /p:AndroidFrameworkVersion={curVersion} \\");
|
||||
WriteRuleLine ($"\t/p:AndroidPreviousFrameworkVersion={prevVersion} || exit 1;");
|
||||
|
||||
prevVersion = curVersion;
|
||||
}
|
||||
|
||||
string firstApiLevel = apiLevels [0];
|
||||
string firstPlatformId = platformIds [0];
|
||||
string firstFramework = frameworks [0];
|
||||
string latestStableFramework = stableFrameworks [stableFrameworks.Count - 1];
|
||||
|
||||
WriteMSBuildCall (
|
||||
fileToRemovePath: Path.Combine (monoFrameworksRoot, "v1.0", "Xamarin.Android.NUnitLite.dll"),
|
||||
projectPath: "src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj"
|
||||
);
|
||||
|
||||
WriteMSBuildCall (
|
||||
fileToRemovePath: $"{monoFrameworksRoot}/{latestStableFramework}/Mono.Android.Export.*",
|
||||
projectPath: "src/Mono.Android.Export/Mono.Android.Export.csproj"
|
||||
);
|
||||
|
||||
WriteMSBuildCall (
|
||||
fileToRemovePath: $"{monoFrameworksRoot}/{latestStableFramework}/OpenTK-1.0.*",
|
||||
projectPath: "src/OpenTK-1.0/OpenTK.csproj"
|
||||
);
|
||||
sw.WriteLine ();
|
||||
|
||||
if (context.RuleGenerators == null || context.RuleGenerators.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (RuleGenerator rg in context.RuleGenerators) {
|
||||
if (rg == null)
|
||||
continue;
|
||||
rg (this, sw);
|
||||
}
|
||||
|
||||
void WriteMSBuildCall (string fileToRemovePath, string projectPath)
|
||||
{
|
||||
WriteRuleLine ($"rm -f {fileToRemovePath}");
|
||||
WriteRuleLine ($"$(call MSBUILD_BINLOG,NUnitLite,$(_SLN_BUILD)) $(MSBUILD_FLAGS) {projectPath} \\");
|
||||
WriteRuleLine ( "\t/p:Configuration=$(CONFIGURATION) $(_MSBUILD_ARGS) \\");
|
||||
WriteRuleLine ($"\t/p:AndroidApiLevel={firstApiLevel} /p:AndroidPlatformId={firstPlatformId} \\");
|
||||
WriteRuleLine ($"\t/p:AndroidFrameworkVersion={firstFramework} || exit 1;");
|
||||
}
|
||||
|
||||
string ToValue (ICollection<string> list, string separator = null)
|
||||
{
|
||||
return String.Join (separator ?? " ", list);
|
||||
}
|
||||
|
||||
void WriteRuleLine (string line = null)
|
||||
{
|
||||
sw.Write ('\t');
|
||||
sw.WriteLine (line);
|
||||
}
|
||||
|
||||
void WriteVariable (string name, string value)
|
||||
{
|
||||
sw.WriteLine ($"{name} = {value}");
|
||||
}
|
||||
|
||||
void WriteListVariable (string name, ICollection <string> list, bool conditional = false)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
return;
|
||||
|
||||
if (!conditional)
|
||||
sw.Write ($"{name} =");
|
||||
|
||||
foreach (string i in list) {
|
||||
string item = i?.Trim ();
|
||||
if (String.IsNullOrEmpty (item))
|
||||
continue;
|
||||
|
||||
if (conditional) {
|
||||
sw.WriteLine ($"ifneq ($(wildcard {item}),)");
|
||||
sw.WriteLine ($"{name} += {item}");
|
||||
sw.WriteLine ("endif");
|
||||
continue;
|
||||
}
|
||||
|
||||
sw.WriteLine (" \\");
|
||||
sw.Write ($"\t{item}");
|
||||
}
|
||||
|
||||
if (!conditional)
|
||||
sw.WriteLine ();
|
||||
}
|
||||
}
|
||||
|
||||
partial void OutputOSVariables (Context context, StreamWriter sw);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class GeneratedPlaceholdersFile : GeneratedFile
|
||||
{
|
||||
IDictionary<string, string> replacements;
|
||||
|
||||
public GeneratedPlaceholdersFile (IDictionary<string, string> replacements, string inputPath, string outputPath)
|
||||
: base (inputPath, outputPath)
|
||||
{
|
||||
if (replacements == null)
|
||||
throw new ArgumentNullException (nameof (replacements));
|
||||
this.replacements = replacements;
|
||||
}
|
||||
|
||||
public override void Generate (Context context)
|
||||
{
|
||||
var inputData = new StringBuilder (File.ReadAllText (InputPath, Encoding.UTF8));
|
||||
|
||||
foreach (var kvp in replacements) {
|
||||
string placeholder = kvp.Key?.Trim ();
|
||||
if (String.IsNullOrEmpty (placeholder))
|
||||
continue;
|
||||
|
||||
inputData.Replace (placeholder, kvp.Value ?? String.Empty);
|
||||
}
|
||||
|
||||
EnsureOutputDir ();
|
||||
string outputData = inputData.ToString ();
|
||||
File.WriteAllText (OutputPath, outputData, Encoding.UTF8);
|
||||
|
||||
if (!EchoOutput)
|
||||
return;
|
||||
|
||||
Log.DebugLine ();
|
||||
Log.DebugLine ("--------------------------------------------");
|
||||
Log.DebugLine (outputData);
|
||||
Log.DebugLine ("--------------------------------------------");
|
||||
Log.DebugLine ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class GeneratedProfileAssembliesProjitemsFile : GeneratedFile
|
||||
{
|
||||
const string FileTop = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!-- This is a GENERATED FILE -->
|
||||
<!-- See build-tools/xaprepare/xaprepare/Application/GeneratedProfileAssembliesProjitemsFile.cs -->
|
||||
<Project DefaultTargets=""Build"" ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
|
||||
";
|
||||
|
||||
const string FileBottom = @"
|
||||
</Project>
|
||||
";
|
||||
|
||||
public GeneratedProfileAssembliesProjitemsFile (string outputPath)
|
||||
: base (outputPath)
|
||||
{}
|
||||
|
||||
public override void Generate (Context context)
|
||||
{
|
||||
var runtimes = new Runtimes ();
|
||||
|
||||
IEnumerable<BclFile> facadeAssemblies = runtimes.BclFilesToInstall.Where (f => f.Type == BclFileType.FacadeAssembly);
|
||||
IEnumerable<BclFile> profileAssemblies = runtimes.BclFilesToInstall.Where (f => f.Type == BclFileType.ProfileAssembly);
|
||||
IEnumerable<TestAssembly> testAssemblies = Runtimes.TestAssemblies;
|
||||
|
||||
EnsureNoDiscrepancies (facadeAssemblies, profileAssemblies, testAssemblies.Where (ta => ta.TestType != TestAssemblyType.Reference && ta.TestType != TestAssemblyType.TestRunner));
|
||||
|
||||
using (var fs = File.Open (OutputPath, FileMode.Create)) {
|
||||
using (var sw = new StreamWriter (fs)) {
|
||||
GenerateFile (sw, facadeAssemblies, profileAssemblies, testAssemblies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureNoDiscrepancies (IEnumerable<BclFile> facadeAssemblies, IEnumerable<BclFile> profileAssemblies, IEnumerable<TestAssembly> testAssemblies)
|
||||
{
|
||||
bool failed = false;
|
||||
|
||||
// We compare against the *installed* locations since we will not always need to download and/or build the
|
||||
// Mono Archive (when the XA bundle is present) so we can't rely on the *source* locations of those
|
||||
// assemblies to be present.
|
||||
failed |= FileSetsDiffer (facadeAssemblies, Configurables.Paths.InstallBCLFrameworkFacadesDir, "Façade", new HashSet<string> (StringComparer.OrdinalIgnoreCase) { "nunitlite.dll" });
|
||||
failed |= FileSetsDiffer (profileAssemblies, Configurables.Paths.InstallBCLFrameworkDir, "Profile");
|
||||
failed |= FileSetsDiffer (testAssemblies, Configurables.Paths.BCLTestsDestDir, "Test");
|
||||
|
||||
if (failed)
|
||||
throw new InvalidOperationException ("Profile assembly discrepancies found. Please examine 'build-tools/xaprepare/xaprepare/ConfigAndData/Runtimes.cs' to make sure all assemblies listed above are included");
|
||||
}
|
||||
|
||||
bool FileSetsDiffer (IEnumerable<TestAssembly> assemblies, string directoryPath, string batchName, HashSet<string> ignoreFiles = null)
|
||||
{
|
||||
List<string> tests = FilesFromDir (directoryPath, ignoreFiles).ToList ();
|
||||
tests.AddRange (
|
||||
FilesFromDir (
|
||||
directoryPath,
|
||||
globPattern: "*.resources.dll",
|
||||
stripPath: false,
|
||||
searchSubdirs: true
|
||||
).Select (f => Utilities.GetRelativePath (directoryPath, f))
|
||||
);
|
||||
|
||||
return FileSetsDiffer (ToStringSet (assemblies), tests, batchName);
|
||||
}
|
||||
|
||||
bool FileSetsDiffer (IEnumerable<BclFile> assemblies, string directoryPath, string batchName, HashSet<string> ignoreFiles = null)
|
||||
{
|
||||
return FileSetsDiffer (ToStringSet (assemblies), FilesFromDir (directoryPath, ignoreFiles), batchName);
|
||||
}
|
||||
|
||||
bool FileSetsDiffer (IEnumerable<string> set1, IEnumerable<string> set2, string batchName)
|
||||
{
|
||||
List<string> diff = set1.Except (set2).ToList ();
|
||||
|
||||
if (diff.Count == 0)
|
||||
return false;
|
||||
|
||||
Log.ErrorLine ($"{batchName} assemblies found on disk but missing from xaprepare:");
|
||||
foreach (string asm in diff) {
|
||||
Log.StatusLine ($" {Context.Instance.Characters.Bullet} {asm}", ConsoleColor.Cyan);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
IEnumerable<string> FilesFromDir (string directoryPath, HashSet<string> ignoreFiles = null, string globPattern = "*.dll", bool stripPath = true, bool searchSubdirs = false)
|
||||
{
|
||||
IEnumerable<string> files = Directory.EnumerateFiles (
|
||||
directoryPath,
|
||||
globPattern,
|
||||
searchSubdirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly
|
||||
).Select (f => stripPath ? Path.GetFileName (f) : f);
|
||||
|
||||
if (ignoreFiles == null || ignoreFiles.Count == 0)
|
||||
return files;
|
||||
|
||||
return files.Where (f => !ignoreFiles.Contains (f));
|
||||
}
|
||||
|
||||
IEnumerable<string> ToStringSet (IEnumerable<BclFile> files)
|
||||
{
|
||||
return files.Select (bcf => bcf.Name);
|
||||
}
|
||||
|
||||
IEnumerable<string> ToStringSet (IEnumerable<TestAssembly> files)
|
||||
{
|
||||
return files.Select (ta => ta.Name);
|
||||
}
|
||||
|
||||
void GenerateFile (StreamWriter sw, IEnumerable<BclFile> facadeAssemblies, IEnumerable<BclFile> profileAssemblies, IEnumerable<TestAssembly> testAssemblies)
|
||||
{
|
||||
sw.Write (FileTop);
|
||||
|
||||
WriteGroup (sw, "MonoFacadeAssembly", facadeAssemblies);
|
||||
WriteGroup (sw, "MonoProfileAssembly", profileAssemblies);
|
||||
WriteGroup (sw, testAssemblies);
|
||||
|
||||
sw.Write (FileBottom);
|
||||
}
|
||||
|
||||
void WriteGroup (StreamWriter sw, string itemName, IEnumerable<BclFile> files)
|
||||
{
|
||||
StartGroup (sw);
|
||||
foreach (BclFile bcf in files) {
|
||||
sw.WriteLine ($" <{itemName} Include=\"{bcf.Name}\" />");
|
||||
}
|
||||
EndGroup (sw);
|
||||
}
|
||||
|
||||
void WriteGroup (StreamWriter sw, IEnumerable<TestAssembly> files)
|
||||
{
|
||||
sw.WriteLine ("<!-- Manual fixups -->");
|
||||
StartGroup (sw);
|
||||
foreach (TestAssembly taf in files) {
|
||||
string itemName = "MonoTestAssembly";
|
||||
string testType = null;
|
||||
|
||||
switch (taf.TestType) {
|
||||
case TestAssemblyType.Satellite:
|
||||
itemName = "MonoTestSatelliteAssembly";
|
||||
break;
|
||||
|
||||
case TestAssemblyType.XUnit:
|
||||
testType = "xunit";
|
||||
break;
|
||||
|
||||
case TestAssemblyType.Reference:
|
||||
testType = "reference";
|
||||
break;
|
||||
|
||||
case TestAssemblyType.TestRunner:
|
||||
itemName = "MonoTestRunner";
|
||||
break;
|
||||
}
|
||||
|
||||
sw.Write ($" <{itemName} Include=\"{taf.Name}\"");
|
||||
if (String.IsNullOrEmpty (testType))
|
||||
sw.WriteLine (" />");
|
||||
else {
|
||||
sw.WriteLine (" >");
|
||||
sw.WriteLine ($" <TestType>{testType}</TestType>");
|
||||
sw.WriteLine ($" </{itemName}>");
|
||||
}
|
||||
}
|
||||
EndGroup (sw);
|
||||
}
|
||||
|
||||
void StartGroup (StreamWriter sw)
|
||||
{
|
||||
sw.WriteLine (" <ItemGroup>");
|
||||
}
|
||||
|
||||
void EndGroup (StreamWriter sw)
|
||||
{
|
||||
sw.WriteLine (" </ItemGroup>");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class HomebrewProgram : Program
|
||||
{
|
||||
string cachedVersionOutput;
|
||||
bool brewNeedsSudo;
|
||||
|
||||
public override bool NeedsSudoToInstall => brewNeedsSudo;
|
||||
public string HomebrewTapName { get; }
|
||||
public Uri HomebrewFormulaUrl { get; }
|
||||
public bool Pin { get; set; }
|
||||
|
||||
public HomebrewProgram (string homebrewPackageName, string executableName = null)
|
||||
: this (homebrewPackageName, homebrewTap: null, executableName: executableName)
|
||||
{}
|
||||
|
||||
public HomebrewProgram (string homebrewPackageName, Uri homebrewFormulaUrl, string executableName = null)
|
||||
: this (homebrewPackageName, homebrewTap: null, executableName: executableName)
|
||||
{
|
||||
HomebrewFormulaUrl = homebrewFormulaUrl ?? throw new ArgumentNullException (nameof (homebrewFormulaUrl));
|
||||
}
|
||||
|
||||
public HomebrewProgram (string homebrewPackageName, string homebrewTap, string executableName)
|
||||
{
|
||||
if (String.IsNullOrEmpty (homebrewPackageName))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (homebrewPackageName));
|
||||
Name = homebrewPackageName;
|
||||
HomebrewTapName = homebrewTap?.Trim ();
|
||||
ExecutableName = executableName?.Trim ();
|
||||
}
|
||||
|
||||
public override async Task<bool> Install ()
|
||||
{
|
||||
var runner = new BrewRunner (Context.Instance);
|
||||
if (!String.IsNullOrEmpty (HomebrewTapName)) {
|
||||
if (!await runner.Tap (HomebrewTapName))
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success;
|
||||
if (InstalledButWrongVersion) {
|
||||
if (HomebrewFormulaUrl != null)
|
||||
success = await runner.Upgrade (HomebrewFormulaUrl.ToString ());
|
||||
else
|
||||
success = await runner.Upgrade (Name);
|
||||
} else
|
||||
success = await runner.Install (Name);
|
||||
|
||||
if (!success || !Pin)
|
||||
return success;
|
||||
|
||||
return await runner.Pin (Name);
|
||||
}
|
||||
|
||||
protected override bool CheckWhetherInstalled ()
|
||||
{
|
||||
if (String.IsNullOrEmpty (Name)) {
|
||||
Log.DebugLine ("Homebrew package name not specified, unable to check installation state");
|
||||
return false;
|
||||
}
|
||||
|
||||
cachedVersionOutput = GetPackageVersion ();
|
||||
return !String.IsNullOrEmpty (cachedVersionOutput);
|
||||
}
|
||||
|
||||
protected override bool ParseVersion (string version, out Version ver)
|
||||
{
|
||||
if (base.ParseVersion (version, out ver))
|
||||
return true;
|
||||
|
||||
ver = null;
|
||||
if (String.IsNullOrEmpty (version))
|
||||
return false;
|
||||
|
||||
// Some brew packages (e.g. mingw-w64) have "weird" version formats, we'll handle them here on the
|
||||
// case-by-case basis. First we should try some general rules to handle the weird versions, checking package
|
||||
// name should be the very last resort.
|
||||
int pos = version.IndexOf ('_');
|
||||
if (pos > 0) {
|
||||
// e.g. 6.0.0_1
|
||||
string v = version.Replace ('_', '.');
|
||||
if (Version.TryParse (v, out ver))
|
||||
return true;
|
||||
|
||||
Log.DebugLine ($"Failed to parse {Name} version {version} as {v}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override async Task<bool> DetermineCurrentVersion ()
|
||||
{
|
||||
bool result = await base.DetermineCurrentVersion ();
|
||||
if (result)
|
||||
return true;
|
||||
|
||||
if (String.IsNullOrEmpty (cachedVersionOutput)) {
|
||||
cachedVersionOutput = GetPackageVersion ();
|
||||
if (String.IsNullOrEmpty (cachedVersionOutput))
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] parts = cachedVersionOutput.Split (new [] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length != 2) {
|
||||
Log.DebugLine ($"Unable to parse {Name} version from Homebrew output: '{cachedVersionOutput}'");
|
||||
return false;
|
||||
}
|
||||
|
||||
string currentVersion = parts [1];
|
||||
if (String.IsNullOrEmpty (currentVersion)) {
|
||||
Log.DebugLine ($"Missing Homebrew version info for package {Name}");
|
||||
return false;
|
||||
}
|
||||
|
||||
CurrentVersion = currentVersion;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override async Task AfterDetect (bool installed)
|
||||
{
|
||||
if (!installed)
|
||||
return;
|
||||
|
||||
var runner = new BrewRunner (Context.Instance);
|
||||
if (InstalledButWrongVersion) {
|
||||
Log.DebugLine ($"Unpinning {Name} as wrong version installed (may show warnings if package isn't pinned)");
|
||||
await runner.UnPin (Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Pin)
|
||||
return;
|
||||
|
||||
Log.DebugLine ($"Pinning {Name} to version {CurrentVersion}");
|
||||
await runner.Pin (Name);
|
||||
}
|
||||
|
||||
string GetPackageVersion ()
|
||||
{
|
||||
return Utilities.GetStringFromStdout (
|
||||
Context.Instance.Tools.BrewPath,
|
||||
false, // throwOnErrors
|
||||
true, // trimTrailingWhitespace
|
||||
true, // quietErrors
|
||||
"ls", "--versions", "-1", Name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
public enum KnownConditions
|
||||
{
|
||||
/// <summary>
|
||||
/// If this condition is set, then Mono upgrade will be performed. It is unset by default because Mono upgrade
|
||||
/// requires application restart or we may crash. Default: unset. <see cref="Scenario_UpdateMono" />
|
||||
/// </summary>
|
||||
AllowMonoUpdate,
|
||||
|
||||
/// <summary>
|
||||
/// If set, the outdated or missing programs will be installed. Default: set.
|
||||
/// </summary>
|
||||
AllowProgramInstallation,
|
||||
|
||||
/// <summary>
|
||||
/// Ignore missing programs and do not signal an error. This is useful in scenarios when we want to update
|
||||
/// only a single program (e.g. the UpdateMono scenario) but not the rest. Default: unset. <see cref="Scenario_UpdateMono" />
|
||||
/// </summary>
|
||||
IgnoreMissingPrograms,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
static class KnownProperties
|
||||
{
|
||||
public const string AndroidCmakeVersion = "AndroidCmakeVersion";
|
||||
public const string AndroidCmakeVersionPath = "AndroidCmakeVersionPath";
|
||||
public const string AndroidLatestStableFrameworkVersion = "AndroidLatestStableFrameworkVersion";
|
||||
public const string AndroidMxeFullPath = "AndroidMxeFullPath";
|
||||
public const string AndroidNdkDirectory = "AndroidNdkDirectory";
|
||||
public const string AndroidSdkDirectory = "AndroidSdkDirectory";
|
||||
public const string AndroidSupportedHostJitAbis = "AndroidSupportedHostJitAbis";
|
||||
public const string AndroidSupportedTargetAotAbis = "AndroidSupportedTargetAotAbis";
|
||||
public const string AndroidSupportedTargetJitAbis = "AndroidSupportedTargetJitAbis";
|
||||
public const string AndroidToolchainCacheDirectory = "AndroidToolchainCacheDirectory";
|
||||
public const string AndroidToolchainDirectory = "AndroidToolchainDirectory";
|
||||
public const string AutoProvision = "AutoProvision";
|
||||
public const string AutoProvisionUsesSudo = "AutoProvisionUsesSudo";
|
||||
public const string Configuration = "Configuration";
|
||||
public const string EmulatorVersion = "EmulatorVersion";
|
||||
public const string IgnoreMaxMonoVersion = "IgnoreMaxMonoVersion";
|
||||
public const string JavaInteropFullPath = "JavaInteropFullPath";
|
||||
public const string JavaSdkDirectory = "JavaSdkDirectory";
|
||||
public const string LibZipSourceFullPath = "LibZipSourceFullPath";
|
||||
public const string ManagedRuntime = "ManagedRuntime";
|
||||
public const string MingwCommandPrefix32 = "MingwCommandPrefix32";
|
||||
public const string MingwCommandPrefix64 = "MingwCommandPrefix64";
|
||||
public const string MingwDependenciesRootDirectory = "MingwDependenciesRootDirectory";
|
||||
public const string MingwZlibLibraryName = "MingwZlibLibraryName";
|
||||
public const string MingwZlibRootDirectory32 = "MingwZlibRootDirectory32";
|
||||
public const string MingwZlibRootDirectory64 = "MingwZlibRootDirectory64";
|
||||
public const string MonoRequiredMinimumVersion = "MonoRequiredMinimumVersion";
|
||||
public const string MonoSourceFullPath = "MonoSourceFullPath";
|
||||
public const string ProductVersion = "ProductVersion";
|
||||
public const string RemapAssemblyRefToolExecutable = "RemapAssemblyRefToolExecutable";
|
||||
public const string XABuildToolsFolder = "XABuildToolsFolder";
|
||||
public const string XABuildToolsVersion = "XABuildToolsVersion";
|
||||
public const string XABinRelativeInstallPrefix = "XABinRelativeInstallPrefix";
|
||||
public const string XAInstallPrefix = "XAInstallPrefix";
|
||||
public const string XAPlatformToolsVersion = "XAPlatformToolsVersion";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class LlvmRuntime
|
||||
{
|
||||
const string OSInstallPath = "Linux";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class LlvmRuntime
|
||||
{
|
||||
const string OSInstallPath = "Darwin";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class LlvmRuntime
|
||||
{
|
||||
const string OSInstallPath = "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class LlvmRuntime : Runtime
|
||||
{
|
||||
public override string Flavor => "LLVM";
|
||||
public bool InstallBinaries { get; protected set; }
|
||||
|
||||
public LlvmRuntime (string name, Func<Context, bool> enabledCheck)
|
||||
: base (name, enabledCheck)
|
||||
{}
|
||||
|
||||
public override void Init (Context context)
|
||||
{
|
||||
InstallBinaries = String.Compare (Name, AbiNames.Llvm.Windows64Bit, StringComparison.Ordinal) != 0;
|
||||
if (Context.IsLlvmWindowsAbi (Name)) {
|
||||
ExeSuffix = Configurables.Defaults.WindowsExecutableSuffix;
|
||||
InstallPath = Configurables.Paths.InstallMSBuildDir;
|
||||
} else
|
||||
InstallPath = OSInstallPath;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Log
|
||||
{
|
||||
void InitOS ()
|
||||
{}
|
||||
|
||||
void ShutdownOS ()
|
||||
{}
|
||||
|
||||
void DoConsoleWrite (string message)
|
||||
{
|
||||
Console.Write (message);
|
||||
}
|
||||
|
||||
void DoConsoleWriteLine (string message)
|
||||
{
|
||||
Console.WriteLine (message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Log
|
||||
{
|
||||
sealed class LogMessage
|
||||
{
|
||||
public bool IsLine;
|
||||
public string Message;
|
||||
}
|
||||
|
||||
BlockingCollection<LogMessage> lineQueue = new BlockingCollection<LogMessage> (new ConcurrentQueue<LogMessage> ());
|
||||
Task loggerTask;
|
||||
CancellationTokenSource cts;
|
||||
CancellationToken token;
|
||||
|
||||
void InitOS ()
|
||||
{
|
||||
cts = new CancellationTokenSource ();
|
||||
token = cts.Token;
|
||||
loggerTask = Task.Run (() => LogWorker (), token);
|
||||
}
|
||||
|
||||
void ShutdownOS ()
|
||||
{
|
||||
try {
|
||||
cts.Cancel ();
|
||||
loggerTask.Wait (500);
|
||||
} catch (AggregateException ex) {
|
||||
if (ex.InnerException is TaskCanceledException)
|
||||
return;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void DoConsoleWrite (string message)
|
||||
{
|
||||
lineQueue.Add (new LogMessage { IsLine = false, Message = message });
|
||||
}
|
||||
|
||||
void DoConsoleWriteLine (string message)
|
||||
{
|
||||
lineQueue.Add (new LogMessage { IsLine = true, Message = message });
|
||||
}
|
||||
|
||||
void LogWorker ()
|
||||
{
|
||||
while (!token.IsCancellationRequested) {
|
||||
LogMessage message = lineQueue.Take ();
|
||||
if (message == null)
|
||||
continue;
|
||||
|
||||
if (message.IsLine) {
|
||||
Console.WriteLine (message.Message);
|
||||
} else {
|
||||
Console.Write (message.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,354 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class Log : IDisposable
|
||||
{
|
||||
static readonly char[] lineSplit = new [] { '\n' };
|
||||
|
||||
static Log instance;
|
||||
static readonly object writeLock = new object ();
|
||||
|
||||
public const ConsoleColor ErrorColor = ConsoleColor.Red;
|
||||
public const ConsoleColor ErrorLeadColor = ErrorColor;
|
||||
public const ConsoleColor ErrorTailColor = ErrorColor;
|
||||
public const ConsoleColor WarningColor = ConsoleColor.Yellow;
|
||||
public const ConsoleColor InfoColor = ConsoleColor.Green;
|
||||
public const ConsoleColor InfoLeadColor = ConsoleColor.White;
|
||||
public const ConsoleColor InfoTailColor = InfoColor;
|
||||
public const ConsoleColor MessageColor = ConsoleColor.Gray;
|
||||
public const ConsoleColor DebugColor = ConsoleColor.DarkGray;
|
||||
public const ConsoleColor DestinationColor = ConsoleColor.Cyan;
|
||||
public const ConsoleColor StatusColor = ConsoleColor.Gray;
|
||||
public const ConsoleColor StatusLeadColor = StatusColor;
|
||||
public const ConsoleColor StatusTailColor = ConsoleColor.White;
|
||||
|
||||
public const bool DefaultErrorShowSeverity = true;
|
||||
public const bool DefaultWarningShowSeverity = true;
|
||||
public const bool DefaultInfoShowSeverity = false;
|
||||
public const bool DefaultMessageShowSeverity = false;
|
||||
public const bool DefaultDebugShowSeverity = false;
|
||||
|
||||
const LoggingVerbosity ErrorMinimumVerbosity = LoggingVerbosity.Quiet;
|
||||
const LoggingVerbosity WarningMinimumVerbosity = LoggingVerbosity.Quiet;
|
||||
const LoggingVerbosity InfoMinimumVerbosity = LoggingVerbosity.Quiet;
|
||||
const LoggingVerbosity MessageMinimumVerbosity = LoggingVerbosity.Normal;
|
||||
const LoggingVerbosity DebugMinimumVerbosity = LoggingVerbosity.Verbose;
|
||||
|
||||
const string ErrorSeverity = " Error: ";
|
||||
const string WarningSeverity = "Warning: ";
|
||||
const string InfoSeverity = " Info: ";
|
||||
const string MessageSeverity = "Message: ";
|
||||
const string DebugSeverity = " Debug: ";
|
||||
|
||||
static Context ctx;
|
||||
static LoggingVerbosity Verbosity => ctx != null ? ctx.LoggingVerbosity : Configurables.Defaults.LoggingVerbosity;
|
||||
|
||||
public static Log Instance => instance;
|
||||
|
||||
static bool UseColor => ctx?.UseColor ?? true;
|
||||
|
||||
TextWriter logFileWriter;
|
||||
bool alreadyDisposed;
|
||||
Stopwatch watch;
|
||||
|
||||
static Log ()
|
||||
{
|
||||
instance = new Log ();
|
||||
}
|
||||
|
||||
public Log (string logFilePath = null)
|
||||
{
|
||||
InitOS ();
|
||||
SetLogFile (logFilePath);
|
||||
watch = new Stopwatch ();
|
||||
watch.Start ();
|
||||
}
|
||||
|
||||
public static void SetContext (Context context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
ctx = context;
|
||||
}
|
||||
|
||||
public void SetLogFile (string logFilePath)
|
||||
{
|
||||
CloseLogFile ();
|
||||
if (String.IsNullOrEmpty (logFilePath))
|
||||
return;
|
||||
|
||||
logFileWriter = new StreamWriter (File.Open (logFilePath, FileMode.Create));
|
||||
}
|
||||
|
||||
public void Todo (string text)
|
||||
{
|
||||
var caller = new StackFrame (1, true);
|
||||
MethodBase method = caller.GetMethod ();
|
||||
|
||||
var sb = new StringBuilder ();
|
||||
sb.Append (method.DeclaringType.FullName);
|
||||
sb.Append ('.');
|
||||
sb.Append (method.Name);
|
||||
|
||||
if (!String.IsNullOrEmpty (caller.GetFileName ())) {
|
||||
int lineNumber = caller.GetFileLineNumber ();
|
||||
int columnNumber = caller.GetFileColumnNumber ();
|
||||
bool haveLocation = false;
|
||||
|
||||
if (lineNumber > 0 || columnNumber > 0) {
|
||||
haveLocation = true;
|
||||
sb.Append (" at ");
|
||||
} else
|
||||
sb.Append (" in ");
|
||||
|
||||
sb.Append (caller.GetFileName ());
|
||||
|
||||
if (haveLocation)
|
||||
sb.Append ($"({lineNumber},{columnNumber})");
|
||||
}
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, "TODO:", ConsoleColor.Red);
|
||||
|
||||
string message = $" {text}\n From: {sb.ToString()}";
|
||||
DoWrite (WriteLineToConsole, ErrorMinimumVerbosity, String.Empty, message, ConsoleColor.Blue);
|
||||
}
|
||||
|
||||
public void Status (string text, ConsoleColor color = StatusColor, bool skipLogFile = false)
|
||||
{
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, text, color, skipLogFile);
|
||||
}
|
||||
|
||||
public void Status (string lead, string tail, ConsoleColor leadColor = StatusLeadColor, ConsoleColor tailColor = StatusTailColor, bool skipLogFile = false)
|
||||
{
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, lead, leadColor, skipLogFile);
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, tail, tailColor, skipLogFile);
|
||||
}
|
||||
|
||||
public void StatusLine (string line = null, ConsoleColor color = StatusColor, bool skipLogFile = false)
|
||||
{
|
||||
DoWrite (WriteLineToConsole, ErrorMinimumVerbosity, String.Empty, line, color, skipLogFile);
|
||||
}
|
||||
|
||||
public void StatusLine (string lead, string tail, ConsoleColor leadColor = StatusLeadColor, ConsoleColor tailColor = StatusTailColor, bool skipLogFile = false)
|
||||
{
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, lead, leadColor, skipLogFile);
|
||||
DoWrite (WriteLineToConsole, ErrorMinimumVerbosity, String.Empty, tail, tailColor, skipLogFile);
|
||||
}
|
||||
|
||||
public void Error (string text, ConsoleColor color = ErrorColor, bool showSeverity = DefaultErrorShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? ErrorSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, severity, text, color);
|
||||
}
|
||||
|
||||
public void Error (string lead, string tail, ConsoleColor leadColor = ErrorLeadColor, ConsoleColor tailColor = ErrorTailColor, bool showSeverity = DefaultErrorShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? ErrorSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, severity, lead, leadColor);
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, String.Empty, tail, tailColor);
|
||||
}
|
||||
|
||||
public void ErrorLine (string line = null, ConsoleColor color = ErrorColor, bool showSeverity = DefaultErrorShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? ErrorSeverity) : String.Empty;
|
||||
DoWrite (WriteLineToConsole, ErrorMinimumVerbosity, severity, line, color);
|
||||
}
|
||||
|
||||
public void ErrorLine (string lead, string tail, ConsoleColor leadColor = ErrorLeadColor, ConsoleColor tailColor = ErrorTailColor, bool showSeverity = DefaultErrorShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? ErrorSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, ErrorMinimumVerbosity, severity, lead, leadColor);
|
||||
DoWrite (WriteLineToConsole, ErrorMinimumVerbosity, String.Empty, tail, tailColor);
|
||||
}
|
||||
|
||||
public void Warning (string text, ConsoleColor color = WarningColor, bool showSeverity = DefaultWarningShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? WarningSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, WarningMinimumVerbosity, severity, text, color);
|
||||
}
|
||||
|
||||
public void WarningLine (string line = null, ConsoleColor color = WarningColor, bool showSeverity = DefaultWarningShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? WarningSeverity) : String.Empty;
|
||||
DoWrite (WriteLineToConsole, WarningMinimumVerbosity, severity, line, color);
|
||||
}
|
||||
|
||||
public void Info (string text, ConsoleColor color = InfoColor, bool showSeverity = DefaultInfoShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? InfoSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, InfoMinimumVerbosity, severity, text, color);
|
||||
}
|
||||
|
||||
public void Info (string lead, string tail, ConsoleColor leadColor = InfoLeadColor, ConsoleColor tailColor = InfoTailColor, bool showSeverity = DefaultInfoShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? InfoSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, InfoMinimumVerbosity, severity, lead, leadColor);
|
||||
DoWrite (WriteToConsole, InfoMinimumVerbosity, String.Empty, tail, tailColor);
|
||||
}
|
||||
|
||||
public void InfoLine (string line = null, ConsoleColor color = InfoColor, bool showSeverity = DefaultInfoShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? InfoSeverity) : String.Empty;
|
||||
DoWrite (WriteLineToConsole, InfoMinimumVerbosity, severity, line, color);
|
||||
}
|
||||
|
||||
public void InfoLine (string lead, string tail, ConsoleColor leadColor = InfoLeadColor, ConsoleColor tailColor = InfoTailColor, bool showSeverity = DefaultInfoShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? InfoSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, InfoMinimumVerbosity, severity, lead, leadColor);
|
||||
DoWrite (WriteLineToConsole, InfoMinimumVerbosity, String.Empty, tail, tailColor);
|
||||
}
|
||||
|
||||
public void Message (string text, ConsoleColor color = MessageColor, bool showSeverity = DefaultMessageShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? MessageSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, MessageMinimumVerbosity, severity, text, color);
|
||||
}
|
||||
|
||||
public void MessageLine (string line = null, ConsoleColor color = MessageColor, bool showSeverity = DefaultMessageShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? MessageSeverity) : String.Empty;
|
||||
DoWrite (WriteLineToConsole, MessageMinimumVerbosity, showSeverity ? MessageSeverity : String.Empty, line, color);
|
||||
}
|
||||
|
||||
public void Debug (string text, ConsoleColor color = DebugColor, bool showSeverity = DefaultDebugShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? DebugSeverity) : String.Empty;
|
||||
DoWrite (WriteToConsole, DebugMinimumVerbosity, severity, text, color);
|
||||
}
|
||||
|
||||
public void DebugLine (string line = null, ConsoleColor color = DebugColor, bool showSeverity = DefaultDebugShowSeverity, string customSeverityName = null)
|
||||
{
|
||||
string severity = showSeverity ? (customSeverityName ?? DebugSeverity) : String.Empty;
|
||||
DoWrite (WriteLineToConsole, DebugMinimumVerbosity, severity, line, color);
|
||||
}
|
||||
|
||||
void DoWrite (Action<LoggingVerbosity, string, ConsoleColor, bool> writer, LoggingVerbosity minimumVerbosity, string prefix, string message, ConsoleColor color, bool skipLogFile = false)
|
||||
{
|
||||
writer (minimumVerbosity, $"{prefix}{message}", color, skipLogFile);
|
||||
}
|
||||
|
||||
void WriteLineToConsole (LoggingVerbosity minimumVerbosity, string message, ConsoleColor color, bool skipLogFile = false)
|
||||
{
|
||||
ConsoleColor fg = ConsoleColor.Gray;
|
||||
try {
|
||||
lock (writeLock) {
|
||||
if (UseColor && Verbosity >= minimumVerbosity) {
|
||||
fg = Console.ForegroundColor;
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
|
||||
WriteLineToConsole (minimumVerbosity, message, skipLogFile);
|
||||
}
|
||||
} finally {
|
||||
if (UseColor && Verbosity >= minimumVerbosity) {
|
||||
Console.ForegroundColor = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteLineToConsole (LoggingVerbosity minimumVerbosity, string message = null, bool skipLogFile = false)
|
||||
{
|
||||
lock (writeLock) {
|
||||
if (Verbosity >= minimumVerbosity) {
|
||||
Console.WriteLine (message ?? String.Empty);
|
||||
}
|
||||
|
||||
if (skipLogFile)
|
||||
return;
|
||||
LogToFile (message ?? String.Empty, addNewLine: true);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteToConsole (LoggingVerbosity minimumVerbosity, string message, ConsoleColor color, bool skipLogFile = false)
|
||||
{
|
||||
ConsoleColor fg = ConsoleColor.Gray;
|
||||
try {
|
||||
lock (writeLock) {
|
||||
if (UseColor && Verbosity >= minimumVerbosity) {
|
||||
fg = Console.ForegroundColor;
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
|
||||
WriteToConsole (minimumVerbosity, message, skipLogFile);
|
||||
}
|
||||
} finally {
|
||||
if (UseColor && Verbosity >= minimumVerbosity) {
|
||||
Console.ForegroundColor = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteToConsole (LoggingVerbosity minimumVerbosity, string message = null, bool skipLogFile = false)
|
||||
{
|
||||
if (message == null)
|
||||
return;
|
||||
|
||||
lock (writeLock) {
|
||||
if (Verbosity >= minimumVerbosity) {
|
||||
Console.Write (message);
|
||||
}
|
||||
|
||||
if (skipLogFile)
|
||||
return;
|
||||
LogToFile (message, addNewLine: false);
|
||||
}
|
||||
}
|
||||
|
||||
void LogToFile (string message, bool addNewLine)
|
||||
{
|
||||
if (logFileWriter == null)
|
||||
return;
|
||||
|
||||
string stamp = watch.Elapsed.ToString ();
|
||||
string[] lines = message.Split (lineSplit);
|
||||
if (lines.Length > 1) {
|
||||
for (int i = 0; i < lines.Length - 1; i++) {
|
||||
logFileWriter.WriteLine (FormatMessage (lines [i]));
|
||||
}
|
||||
}
|
||||
logFileWriter.Write (FormatMessage (lines [lines.Length - 1]));
|
||||
|
||||
if (addNewLine)
|
||||
logFileWriter.WriteLine ();
|
||||
|
||||
string FormatMessage (string msg)
|
||||
{
|
||||
return $"[{stamp}] {msg}";
|
||||
}
|
||||
}
|
||||
|
||||
void CloseLogFile ()
|
||||
{
|
||||
if (logFileWriter == null)
|
||||
return;
|
||||
|
||||
logFileWriter.Flush ();
|
||||
logFileWriter.Dispose ();
|
||||
logFileWriter = null;
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
protected void Dispose (bool disposing)
|
||||
{
|
||||
if (!alreadyDisposed) {
|
||||
if (disposing) {
|
||||
CloseLogFile ();
|
||||
ShutdownOS ();
|
||||
}
|
||||
|
||||
alreadyDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
enum LoggingVerbosity
|
||||
{
|
||||
Silent,
|
||||
Quiet,
|
||||
Normal,
|
||||
Verbose,
|
||||
Diagnostic,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class MonoCrossRuntime : MonoRuntime
|
||||
{
|
||||
public override string Flavor => "cross compilation";
|
||||
|
||||
public MonoCrossRuntime (string name, Func<Context, bool> enabledCheck)
|
||||
: base (name, enabledCheck)
|
||||
{}
|
||||
|
||||
public override void Init (Context context)
|
||||
{
|
||||
if (context.IsHostCrossAotAbi (Name)) {
|
||||
InstallPath = context.OS.Type; // Linux | Darwin | Windows
|
||||
Strip = "strip";
|
||||
StripFlags = "-S";
|
||||
} else if (Context.IsWindowsCrossAotAbi (Name)) {
|
||||
string mingwPrefix;
|
||||
|
||||
if (Context.Is32BitCrossAbi (Name))
|
||||
mingwPrefix = Path.Combine (Configurables.Paths.MingwBinDir, Context.Properties.GetRequiredValue (KnownProperties.MingwCommandPrefix32));
|
||||
else
|
||||
mingwPrefix = Path.Combine (Configurables.Paths.MingwBinDir, Context.Properties.GetRequiredValue (KnownProperties.MingwCommandPrefix64));
|
||||
|
||||
Strip = $"{mingwPrefix}-strip";
|
||||
ExeSuffix = Configurables.Defaults.WindowsExecutableSuffix;
|
||||
} else
|
||||
throw new InvalidOperationException ($"Unsupported cross compiler abi {Name}");
|
||||
|
||||
CrossMonoName = Configurables.Defaults.CrossRuntimeNames [Name];
|
||||
ExePrefix = Configurables.Defaults.CrossRuntimeExePrefixes [Name];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class MonoHostRuntime
|
||||
{
|
||||
partial void InitOS ()
|
||||
{
|
||||
if (Context.Is32BitMingwHostAbi (Name))
|
||||
CanStripNativeLibrary = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
partial class MonoHostRuntime : MonoRuntime
|
||||
{
|
||||
public override string Flavor => "host";
|
||||
public bool MinGW { get; }
|
||||
|
||||
public MonoHostRuntime (string name, bool mingw, Func<Context, bool> enabledCheck)
|
||||
: base (name, enabledCheck)
|
||||
{
|
||||
MinGW = mingw;
|
||||
CanStripNativeLibrary = true;
|
||||
MonoSdksPrefix = "host-";
|
||||
}
|
||||
|
||||
public override void Init (Context context)
|
||||
{
|
||||
if (MinGW) {
|
||||
NativeLibraryExtension = Configurables.Defaults.MonoHostMingwRuntimeNativeLibraryExtension;
|
||||
NativeLibraryDirPrefix = Configurables.Paths.MonoRuntimeHostMingwNativeLibraryPrefix;
|
||||
} else
|
||||
NativeLibraryExtension = Configurables.Defaults.NativeLibraryExtension;
|
||||
|
||||
if (Context.IsNativeHostAbi (Name)) {
|
||||
OutputAotProfilerFilename = Configurables.Defaults.MonoRuntimeOutputAotProfilerFilename;
|
||||
OutputProfilerFilename = Configurables.Defaults.MonoRuntimeOutputProfilerFilename;
|
||||
} else {
|
||||
OutputAotProfilerFilename = String.Empty;
|
||||
OutputProfilerFilename = String.Empty;
|
||||
}
|
||||
OutputMonoBtlsFilename = String.Empty;
|
||||
OutputMonoPosixHelperFilename = Configurables.Defaults.MonoRuntimeOutputMonoPosixHelperFilename;
|
||||
|
||||
if (Context.IsMingwHostAbi (Name)) {
|
||||
string prefix;
|
||||
if (Context.Is32BitMingwHostAbi (Name)) {
|
||||
prefix = Context.Properties.GetRequiredValue (KnownProperties.MingwCommandPrefix32);
|
||||
} else if (Context.Is64BitMingwHostAbi (Name)) {
|
||||
prefix = Context.Properties.GetRequiredValue (KnownProperties.MingwCommandPrefix64);
|
||||
} else
|
||||
throw new InvalidOperationException($"MinGW host ABI {Name} is neither 32 nor 64-bit (?!)");
|
||||
Strip = Path.Combine (Configurables.Paths.MingwBinDir, $"{prefix}-strip");
|
||||
} else {
|
||||
Strip = "strip";
|
||||
StripFlags = "-S";
|
||||
}
|
||||
|
||||
InitOS ();
|
||||
}
|
||||
|
||||
partial void InitOS ();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class MonoJitRuntime : MonoRuntime
|
||||
{
|
||||
public override string Flavor => "Android JIT";
|
||||
|
||||
public MonoJitRuntime (string abiName, Func<Context, bool> enabledCheck)
|
||||
: base (abiName, enabledCheck)
|
||||
{}
|
||||
|
||||
public override void Init (Context context)
|
||||
{
|
||||
InstallPath = "lib";
|
||||
NativeLibraryExtension = Configurables.Defaults.MonoJitRuntimeNativeLibraryExtension;
|
||||
OutputAotProfilerFilename = Configurables.Defaults.MonoRuntimeOutputAotProfilerFilename;
|
||||
OutputMonoBtlsFilename = Configurables.Defaults.MonoRuntimeOutputMonoBtlsFilename;
|
||||
OutputMonoPosixHelperFilename = Configurables.Defaults.MonoRuntimeOutputMonoPosixHelperFilename;
|
||||
OutputProfilerFilename = Configurables.Defaults.MonoRuntimeOutputProfilerFilename;
|
||||
Strip = Path.Combine (Configurables.Paths.AndroidToolchainBinDirectory, $"{Configurables.Defaults.AndroidToolchainPrefixes [Name]}-strip");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class MonoPkgProgram : PkgProgram
|
||||
{
|
||||
public MonoPkgProgram (string name, string packageId, Uri packageUrl = null)
|
||||
: base (name, packageId, packageUrl)
|
||||
{
|
||||
ExecutableName = "mono";
|
||||
}
|
||||
|
||||
public override bool CanInstall ()
|
||||
{
|
||||
// We do not want to return `false` here if Mono updates are disallowed - we want Install to be called to
|
||||
// show the error message as returning `false` here might prevent other programs from updating, and there's
|
||||
// no good reason for this.
|
||||
if (!Context.Instance.CheckCondition (KnownConditions.AllowMonoUpdate))
|
||||
return base.CanInstall ();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async Task<bool> Install ()
|
||||
{
|
||||
if (Context.Instance.CheckCondition (KnownConditions.AllowMonoUpdate))
|
||||
return await base.Install ();
|
||||
|
||||
Log.ErrorLine ($"Mono needs to be updated but updates are disallowed in this scenario. Please run prepare with the '/s:{Scenario_UpdateMono.MyName}' parameter to update Mono.");
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool CheckWhetherInstalled ()
|
||||
{
|
||||
IgnoreMaximumVersion = Context.Instance.IgnoreMaxMonoVersion;
|
||||
return base.CheckWhetherInstalled ();
|
||||
}
|
||||
|
||||
protected override async Task<bool> DetermineCurrentVersion ()
|
||||
{
|
||||
// Mono is special in that its package does not contain the full version, so we have to get it from the
|
||||
// --version output instead.
|
||||
SkipPkgUtilVersionCheck = true;
|
||||
return await base.DetermineCurrentVersion ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
abstract class MonoRuntime : Runtime
|
||||
{
|
||||
string nativeLibraryDirPrefix;
|
||||
|
||||
public bool CanStripNativeLibrary { get; set; } = true;
|
||||
public string CrossMonoName { get; set; }
|
||||
public string ExePrefix { get; set; }
|
||||
public bool IsCrossRuntime { get; set; }
|
||||
public string NativeLibraryExtension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional directory prefix for native library source. This should be a path relative to runtime's library
|
||||
/// output dir and it exists because MinGW builds will put the runtime .dll in the bin directory instead of in
|
||||
/// the lib one.
|
||||
/// </summary>
|
||||
public string NativeLibraryDirPrefix {
|
||||
get => nativeLibraryDirPrefix ?? String.Empty;
|
||||
set => nativeLibraryDirPrefix = value;
|
||||
}
|
||||
|
||||
public string OutputAotProfilerFilename { get; set; }
|
||||
public string OutputMonoBtlsFilename { get; set; }
|
||||
public string OutputMonoPosixHelperFilename { get; set; }
|
||||
public string OutputProfilerFilename { get; set; }
|
||||
public string OutputRuntimeFilename { get; set; } = Configurables.Defaults.MonoRuntimeOutputFileName;
|
||||
public string Strip { get; set; }
|
||||
public string StripFlags { get; set; }
|
||||
|
||||
protected MonoRuntime (string name, Func<Context, bool> enabledCheck)
|
||||
: base (name, enabledCheck)
|
||||
{}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
sealed class MonoUtilityFile
|
||||
{
|
||||
public string SourcePath { get; }
|
||||
public string TargetName { get; }
|
||||
public bool RemapCecil { get; }
|
||||
public bool IgnoreDebugInfo { get; }
|
||||
|
||||
public string DebugSymbolsPath => Utilities.GetDebugSymbolsPath (SourcePath);
|
||||
|
||||
public MonoUtilityFile (string name, bool remap = false, string targetName = null, bool ignoreDebugInfo = false)
|
||||
{
|
||||
name = name?.Trim ();
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (name));
|
||||
|
||||
SourcePath = Path.GetFullPath (Path.Combine (Configurables.Paths.MonoProfileToolsDir, name));
|
||||
RemapCecil = remap;
|
||||
TargetName = targetName;
|
||||
IgnoreDebugInfo = ignoreDebugInfo;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class PkgProgram : Program
|
||||
{
|
||||
public override bool NeedsSudoToInstall => false;
|
||||
public string PackageId { get; }
|
||||
public Uri PackageUrl { get; set; }
|
||||
protected bool SkipPkgUtilVersionCheck { get; set; }
|
||||
|
||||
public PkgProgram (string name, string packageId, Uri packageUrl = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (name));
|
||||
|
||||
if (String.IsNullOrEmpty(packageId))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (packageId));
|
||||
|
||||
Name = name;
|
||||
PackageId = packageId;
|
||||
PackageUrl = packageUrl;
|
||||
}
|
||||
|
||||
public override async Task<bool> Install ()
|
||||
{
|
||||
Context context = Context.Instance;
|
||||
|
||||
if (!context.AutoProvisionUsesSudo) {
|
||||
Log.ErrorLine ("Installation of macOS packages requires sudo to be enabled (pass `--auto-provision-uses-sudo=yes` to the bootstrapper)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PackageUrl == null) {
|
||||
Log.ErrorLine ($"{Name} is not installed but no URL is provided to download it from. Please make sure to install it before continuing");
|
||||
return false;
|
||||
}
|
||||
|
||||
(bool success, ulong size) = await Utilities.GetDownloadSize (PackageUrl);
|
||||
if (!success) {
|
||||
Log.ErrorLine ($"Failed to get download size of {PackageUrl}");
|
||||
return false;
|
||||
}
|
||||
|
||||
DownloadStatus downloadStatus = Utilities.SetupDownloadStatus (context, size, context.InteractiveSession);
|
||||
Log.StatusLine ($" {context.Characters.Link} {PackageUrl}", ConsoleColor.White);
|
||||
|
||||
string localPath = Path.Combine (context.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory), Path.GetFileName (PackageUrl.LocalPath));
|
||||
success = await Utilities.Download (PackageUrl, localPath, downloadStatus);
|
||||
if (!success) {
|
||||
Log.ErrorLine ($"Failed to download {PackageUrl}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var runner = new ProcessRunner ("sudo") {
|
||||
EchoStandardError = true,
|
||||
EchoStandardOutput = true,
|
||||
ProcessTimeout = TimeSpan.FromMinutes (10)
|
||||
};
|
||||
|
||||
runner.AddArgument ("/usr/sbin/installer");
|
||||
runner.AddArgument ("-verbose");
|
||||
runner.AddArgument ("-pkg");
|
||||
runner.AddQuotedArgument (localPath);
|
||||
runner.AddArgument ("-target");
|
||||
runner.AddArgument ("/");
|
||||
|
||||
return await Task.Run (() => runner.Run ());
|
||||
}
|
||||
|
||||
protected override bool CheckWhetherInstalled ()
|
||||
{
|
||||
return GetVersion (echoError: false).Result != null;
|
||||
}
|
||||
|
||||
protected override async Task<bool> DetermineCurrentVersion ()
|
||||
{
|
||||
if (SkipPkgUtilVersionCheck)
|
||||
return await base.DetermineCurrentVersion ();
|
||||
|
||||
var runner = new PkgutilRunner (Context.Instance);
|
||||
|
||||
Version ver = await GetVersion (echoError: true);
|
||||
if (ver == null)
|
||||
return false;
|
||||
|
||||
CurrentVersion = ver.ToString ();
|
||||
return true;
|
||||
}
|
||||
|
||||
async Task<Version> GetVersion (bool echoError)
|
||||
{
|
||||
var runner = new PkgutilRunner (Context.Instance);
|
||||
return await runner.GetPackageVersion (PackageId, echoError: echoError);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class ProcessRunner : AppObject
|
||||
{
|
||||
public enum ErrorReasonCode
|
||||
{
|
||||
NotExecutedYet,
|
||||
NoError,
|
||||
CommandNotFound,
|
||||
ExecutionTimedOut,
|
||||
ExitCodeNotZero,
|
||||
};
|
||||
|
||||
static readonly TimeSpan DefaultProcessTimeout = TimeSpan.FromMinutes (5);
|
||||
static readonly TimeSpan DefaultOutputTimeout = TimeSpan.FromSeconds (10);
|
||||
|
||||
sealed class WriterGuard
|
||||
{
|
||||
public readonly object WriteLock = new object ();
|
||||
public readonly TextWriter Writer;
|
||||
|
||||
public WriterGuard (TextWriter writer)
|
||||
{
|
||||
Writer = writer;
|
||||
}
|
||||
}
|
||||
|
||||
string command;
|
||||
List<string> arguments;
|
||||
List<WriterGuard> stderrSinks;
|
||||
List<WriterGuard> stdoutSinks;
|
||||
Dictionary<TextWriter, WriterGuard> guardCache;
|
||||
bool defaultStdoutEchoWrapperAdded;
|
||||
ProcessStandardStreamWrapper defaultStderrEchoWrapper;
|
||||
|
||||
public string Command => command;
|
||||
|
||||
public string Arguments {
|
||||
get {
|
||||
if (arguments == null)
|
||||
return String.Empty;
|
||||
return String.Join (" ", arguments);
|
||||
}
|
||||
}
|
||||
|
||||
public string FullCommandLine {
|
||||
get {
|
||||
string args = Arguments;
|
||||
if (String.IsNullOrEmpty (args))
|
||||
return command;
|
||||
return $"{command} {args}";
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary <string, string> Environment { get; } = new Dictionary <string, string> (StringComparer.Ordinal);
|
||||
public int ExitCode { get; private set; } = -1;
|
||||
public ErrorReasonCode ErrorReason { get; private set; } = ErrorReasonCode.NotExecutedYet;
|
||||
public bool EchoCmdAndArguments { get; set; } = true;
|
||||
public bool EchoStandardOutput { get; set; }
|
||||
public ProcessStandardStreamWrapper.LogLevel EchoStandardOutputLevel { get; set; } = ProcessStandardStreamWrapper.LogLevel.Message;
|
||||
public bool EchoStandardError { get; set; }
|
||||
public ProcessStandardStreamWrapper.LogLevel EchoStandardErrorLevel { get; set; } = ProcessStandardStreamWrapper.LogLevel.Error;
|
||||
public ProcessStandardStreamWrapper StandardOutputEchoWrapper { get; set; }
|
||||
public ProcessStandardStreamWrapper StandardErrorEchoWrapper { get; set; }
|
||||
public Encoding StandardOutputEncoding { get; set; } = Encoding.Default;
|
||||
public Encoding StandardErrorEncoding { get; set; } = Encoding.Default;
|
||||
public TimeSpan StandardOutputTimeout { get; set; } = DefaultOutputTimeout;
|
||||
public TimeSpan StandardErrorTimeout { get; set; } = DefaultOutputTimeout;
|
||||
public TimeSpan ProcessTimeout { get; set; } = DefaultProcessTimeout;
|
||||
public string WorkingDirectory { get; set; }
|
||||
public Action<ProcessStartInfo> StartInfoCallback { get; set; }
|
||||
|
||||
public ProcessRunner (string command, params string[] arguments)
|
||||
: this (command, false, arguments)
|
||||
{}
|
||||
|
||||
public ProcessRunner (string command, bool ignoreEmptyArguments, params string[] arguments)
|
||||
{
|
||||
if (String.IsNullOrEmpty (command))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (command));
|
||||
|
||||
this.command = command;
|
||||
if (arguments == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < arguments.Length; i++) {
|
||||
string argument = arguments [i]?.Trim ();
|
||||
if (String.IsNullOrEmpty (argument)) {
|
||||
if (ignoreEmptyArguments)
|
||||
continue;
|
||||
throw new InvalidOperationException ($"Argument {i} is null or empty");
|
||||
}
|
||||
|
||||
AddQuotedArgument (argument);
|
||||
}
|
||||
}
|
||||
|
||||
public ProcessRunner AddArgument (string argument)
|
||||
{
|
||||
if (String.IsNullOrEmpty (argument))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (argument));
|
||||
|
||||
AddToList (argument, ref arguments);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProcessRunner AddQuotedArgument (string argument)
|
||||
{
|
||||
if (String.IsNullOrEmpty (argument))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (argument));
|
||||
|
||||
return AddArgument (QuoteArgument (argument));
|
||||
}
|
||||
|
||||
public static string QuoteArgument (string argument)
|
||||
{
|
||||
if (String.IsNullOrEmpty (argument))
|
||||
return String.Empty;
|
||||
|
||||
if (argument.IndexOf ('"') >= 0)
|
||||
argument = argument.Replace ("\"", "\\\"");
|
||||
|
||||
return $"\"{argument}\"";
|
||||
}
|
||||
|
||||
public ProcessRunner AddStandardErrorSink (TextWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw new ArgumentNullException (nameof (writer));
|
||||
|
||||
AddToList (GetGuard (writer), ref stderrSinks);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProcessRunner AddStandardOutputSink (TextWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw new ArgumentNullException (nameof (writer));
|
||||
|
||||
AddToList (GetGuard (writer), ref stdoutSinks);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some programs will not write errors to stderr but we might want to "redirect" them to the error stream for
|
||||
/// console reporting, this is the purpose of this method. Not that this method bypassess stderr sinks other
|
||||
/// than the default one (created when <see cref="EchoStandardOutput"/> is set to <c>true</c>) or the one
|
||||
/// specified by the caller by setting the <see cref="StandardErrorEchoWrapper" />.
|
||||
/// </summary>
|
||||
public void WriteStderrLine (string line)
|
||||
{
|
||||
if (StandardErrorEchoWrapper != null) {
|
||||
StandardErrorEchoWrapper.WriteLine (line);
|
||||
return;
|
||||
}
|
||||
|
||||
defaultStderrEchoWrapper?.WriteLine (line ?? String.Empty, stderrSinks);
|
||||
}
|
||||
|
||||
WriterGuard GetGuard (TextWriter writer)
|
||||
{
|
||||
if (guardCache == null)
|
||||
guardCache = new Dictionary<TextWriter, WriterGuard> ();
|
||||
|
||||
if (guardCache.TryGetValue (writer, out WriterGuard ret) && ret != null)
|
||||
return ret;
|
||||
|
||||
ret = new WriterGuard (writer);
|
||||
guardCache.Add (writer, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool Run ()
|
||||
{
|
||||
if (EchoStandardOutput) {
|
||||
if (StandardOutputEchoWrapper != null) {
|
||||
AddStandardOutputSink (StandardOutputEchoWrapper);
|
||||
} else if (!defaultStdoutEchoWrapperAdded) {
|
||||
AddStandardOutputSink (new ProcessStandardStreamWrapper { LoggingLevel = EchoStandardOutputLevel, CustomSeverityName = "stdout" });
|
||||
defaultStdoutEchoWrapperAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (EchoStandardError) {
|
||||
if (StandardErrorEchoWrapper != null) {
|
||||
AddStandardErrorSink (StandardErrorEchoWrapper);
|
||||
} else if (defaultStderrEchoWrapper == null) {
|
||||
defaultStderrEchoWrapper = new ProcessStandardStreamWrapper { LoggingLevel = EchoStandardErrorLevel, CustomSeverityName = "stderr" };
|
||||
AddStandardErrorSink (defaultStderrEchoWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
ManualResetEventSlim stdout_done = null;
|
||||
ManualResetEventSlim stderr_done = null;
|
||||
|
||||
if (stderrSinks != null && stderrSinks.Count > 0)
|
||||
stderr_done = new ManualResetEventSlim (false);
|
||||
|
||||
if (stdoutSinks != null && stdoutSinks.Count > 0)
|
||||
stdout_done = new ManualResetEventSlim (false);
|
||||
|
||||
var psi = new ProcessStartInfo (command) {
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
RedirectStandardError = stderr_done != null,
|
||||
RedirectStandardOutput = stdout_done != null,
|
||||
};
|
||||
|
||||
if (arguments != null)
|
||||
psi.Arguments = String.Join (" ", arguments);
|
||||
|
||||
if (!String.IsNullOrEmpty (WorkingDirectory))
|
||||
psi.WorkingDirectory = WorkingDirectory;
|
||||
|
||||
if (psi.RedirectStandardError)
|
||||
StandardErrorEncoding = StandardErrorEncoding;
|
||||
|
||||
if (psi.RedirectStandardOutput)
|
||||
StandardOutputEncoding = StandardOutputEncoding;
|
||||
|
||||
if (StartInfoCallback != null)
|
||||
StartInfoCallback (psi);
|
||||
|
||||
var process = new Process {
|
||||
StartInfo = psi
|
||||
};
|
||||
|
||||
if (EchoCmdAndArguments)
|
||||
Log.DebugLine ($"Running: {FullCommandLine}");
|
||||
|
||||
try {
|
||||
process.Start ();
|
||||
} catch (System.ComponentModel.Win32Exception ex) {
|
||||
Log.ErrorLine ($"Process failed to start: {ex.Message}");
|
||||
Log.DebugLine (ex.ToString ());
|
||||
|
||||
Log.Todo ("need to check NativeErrorCode to make sure it's command not found");
|
||||
ErrorReason = ErrorReasonCode.CommandNotFound;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (psi.RedirectStandardError) {
|
||||
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => {
|
||||
if (e.Data != null)
|
||||
WriteOutput (e.Data, stderrSinks);
|
||||
else
|
||||
stderr_done.Set ();
|
||||
};
|
||||
process.BeginErrorReadLine ();
|
||||
}
|
||||
|
||||
if (psi.RedirectStandardOutput) {
|
||||
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => {
|
||||
if (e.Data != null)
|
||||
WriteOutput (e.Data, stdoutSinks);
|
||||
else
|
||||
stdout_done.Set ();
|
||||
};
|
||||
process.BeginOutputReadLine ();
|
||||
}
|
||||
|
||||
bool exited = process.WaitForExit ((int)ProcessTimeout.TotalMilliseconds);
|
||||
if (!exited) {
|
||||
Log.ErrorLine ($"Process '{FullCommandLine}' timed out after {ProcessTimeout}");
|
||||
ErrorReason = ErrorReasonCode.ExecutionTimedOut;
|
||||
process.Kill ();
|
||||
}
|
||||
|
||||
// See: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexit?view=netframework-4.7.2#System_Diagnostics_Process_WaitForExit)
|
||||
if (psi.RedirectStandardError || psi.RedirectStandardOutput)
|
||||
process.WaitForExit ();
|
||||
|
||||
if (stderr_done != null)
|
||||
stderr_done.Wait (StandardErrorTimeout);
|
||||
|
||||
if (stdout_done != null)
|
||||
stdout_done.Wait (StandardOutputTimeout);
|
||||
|
||||
ExitCode = process.ExitCode;
|
||||
if (ExitCode != 0 && ErrorReason == ErrorReasonCode.NotExecutedYet) {
|
||||
ErrorReason = ErrorReasonCode.ExitCodeNotZero;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exited)
|
||||
ErrorReason = ErrorReasonCode.NoError;
|
||||
|
||||
return exited;
|
||||
}
|
||||
|
||||
void WriteOutput (string data, List<WriterGuard> sinks)
|
||||
{
|
||||
foreach (WriterGuard wg in sinks) {
|
||||
if (wg == null || wg.Writer == null)
|
||||
continue;
|
||||
|
||||
lock (wg.WriteLock) {
|
||||
wg.Writer.WriteLine (data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddToList <T> (T item, ref List<T> list)
|
||||
{
|
||||
if (list == null)
|
||||
list = new List <T> ();
|
||||
list.Add (item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Android.Prepare
|
||||
{
|
||||
class ProcessStandardStreamWrapper : TextWriter
|
||||
{
|
||||
public enum LogLevel
|
||||
{
|
||||
Error,
|
||||
Warning,
|
||||
Info,
|
||||
Message,
|
||||
Debug,
|
||||
}
|
||||
|
||||
Log Log = Log.Instance;
|
||||
string indentString = " | ";
|
||||
|
||||
public bool IndentOutput { get; set; } = true;
|
||||
public LogLevel LoggingLevel { get; set; } = LogLevel.Debug;
|
||||
public string CustomSeverityName { get; set; }
|
||||
|
||||
public string IndentString {
|
||||
get => indentString;
|
||||
set {
|
||||
indentString = value ?? String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override Encoding Encoding => Encoding.Default;
|
||||
|
||||
public ProcessStandardStreamWrapper ()
|
||||
{}
|
||||
|
||||
public ProcessStandardStreamWrapper (IFormatProvider formatProvider)
|
||||
: base (formatProvider)
|
||||
{}
|
||||
|
||||
public override void WriteLine (string value)
|
||||
{
|
||||
DoWrite (value, true);
|
||||
}
|
||||
|
||||
protected virtual string PreprocessMessage (string message, ref bool writeLine)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
void DoWrite (string message, bool writeLine)
|
||||
{
|
||||
Action<string, ConsoleColor, bool, string> writer;
|
||||
ConsoleColor color;
|
||||
bool showSeverity;
|
||||
|
||||
message = PreprocessMessage (message, ref writeLine) ?? String.Empty;
|
||||
switch (LoggingLevel) {
|
||||
case LogLevel.Error:
|
||||
color = Log.ErrorColor;
|
||||
showSeverity = Log.DefaultErrorShowSeverity;
|
||||
if (writeLine)
|
||||
writer = Log.ErrorLine;
|
||||
else
|
||||
writer = Log.Error;
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
color = Log.WarningColor;
|
||||
showSeverity = Log.DefaultWarningShowSeverity;
|
||||
if (writeLine)
|
||||
writer = Log.WarningLine;
|
||||
else
|
||||
writer = Log.Warning;
|
||||
break;
|
||||
|
||||
case LogLevel.Info:
|
||||
color = Log.InfoColor;
|
||||
showSeverity = Log.DefaultInfoShowSeverity;
|
||||
if (writeLine)
|
||||
writer = Log.InfoLine;
|
||||
else
|
||||
writer = Log.Info;
|
||||
break;
|
||||
|
||||
case LogLevel.Message:
|
||||
color = Log.MessageColor;
|
||||
showSeverity = Log.DefaultMessageShowSeverity;
|
||||
if (writeLine)
|
||||
writer = Log.MessageLine;
|
||||
else
|
||||
writer = Log.Message;
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
color = Log.DebugColor;
|
||||
showSeverity = Log.DefaultDebugShowSeverity;
|
||||
if (writeLine)
|
||||
writer = Log.DebugLine;
|
||||
else
|
||||
writer = Log.Debug;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException ($"Unsupported log level {LoggingLevel}");
|
||||
}
|
||||
|
||||
if (IndentOutput)
|
||||
writer ($"{IndentString}{message}", color, showSeverity, CustomSeverityName);
|
||||
else
|
||||
writer (message, color, showSeverity, CustomSeverityName);
|
||||
}
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче