Merge remote-tracking branch 'origin/master' into mono-2018-10
This commit is contained in:
Коммит
aa6fefb1c9
14
Make.config
14
Make.config
|
@ -326,5 +326,19 @@ JENKINS_RESULTS_DIRECTORY ?= $(abspath $(TOP)/jenkins-results)
|
|||
# Clone files instead of copying them on APFS file systems. Much faster.
|
||||
CP:=$(shell df -t apfs / >/dev/null 2>&1 && echo "cp -c" || echo "cp")
|
||||
|
||||
# Setup various variables depending on whether mono is downloaded or built from source
|
||||
ifeq ($(MONO_BUILD_FROM_SOURCE),)
|
||||
MONO_HASH:=$(shell git --git-dir=$(abspath $(TOP)/.git) --work-tree=$(abspath $(TOP)) ls-tree HEAD --full-tree -- external/mono | awk -F' ' '{printf "%s",$$3}')
|
||||
MONO_FILENAME:=ios-release-Darwin-$(MONO_HASH).zip
|
||||
MONO_URL:=https://xamjenkinsartifact.azureedge.net/mono-sdks/$(MONO_FILENAME)
|
||||
MONO_SDK_BUILDDIR:=$(abspath $(TOP)/builds/downloads/$(basename $(MONO_FILENAME)))
|
||||
MONO_SDK_DESTDIR:=$(abspath $(TOP)/builds/downloads/$(basename $(MONO_FILENAME)))
|
||||
MONO_BUILD_MODE=download
|
||||
else
|
||||
MONO_SDK_BUILDDIR:=$(abspath $(MONO_PATH)/sdks/builds)
|
||||
MONO_SDK_DESTDIR:=$(abspath $(MONO_PATH)/sdks/out)
|
||||
MONO_BUILD_MODE=compile
|
||||
endif
|
||||
|
||||
.SUFFIXES:
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
|
|
@ -43,5 +43,5 @@
|
|||
# line changed in git).
|
||||
#
|
||||
|
||||
IOS_PACKAGE_VERSION=12.5.1.$(IOS_COMMIT_DISTANCE)
|
||||
MAC_PACKAGE_VERSION=5.5.1.$(MAC_COMMIT_DISTANCE)
|
||||
IOS_PACKAGE_VERSION=12.6.0.$(IOS_COMMIT_DISTANCE)
|
||||
MAC_PACKAGE_VERSION=5.6.0.$(MAC_COMMIT_DISTANCE)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
downloads
|
||||
.stamp*
|
||||
.deps.*.mk
|
||||
*.config.cache
|
||||
|
|
|
@ -3,6 +3,32 @@ include $(TOP)/Make.config
|
|||
|
||||
PREFIX=$(abspath $(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/)
|
||||
|
||||
download: downloads/$(basename $(MONO_FILENAME))
|
||||
|
||||
downloads/$(MONO_FILENAME):
|
||||
$(Q) mkdir -p downloads
|
||||
$(Q) echo "Downloading $(MONO_URL)..."
|
||||
$(Q) curl -f -L $(if $(V),-v,-s) $(MONO_URL) --output $@.tmp
|
||||
$(Q) mv $@.tmp $@
|
||||
$(Q) echo "Downloaded $(MONO_URL)"
|
||||
|
||||
downloads/$(basename $(MONO_FILENAME)): downloads/$(MONO_FILENAME)
|
||||
$(Q) echo "Unzipping $(MONO_FILENAME)..."
|
||||
$(Q) rm -Rf $@.tmp
|
||||
$(Q) unzip -q -d $@.tmp $<
|
||||
$(Q) mv $@.tmp $@
|
||||
$(Q) echo "Unzipped $(MONO_FILENAME)"
|
||||
|
||||
clean-locals::
|
||||
$(Q) rm -Rf downloads
|
||||
|
||||
.stamp-download-%: downloads/$(basename $(MONO_FILENAME))
|
||||
$(Q) touch $@
|
||||
|
||||
ifeq ($(MONO_BUILD_FROM_SOURCE),)
|
||||
all-local:: download
|
||||
endif
|
||||
|
||||
IPHONESIMULATOR_SDK=$(MONOTOUCH_PREFIX)/SDKs/MonoTouch.iphonesimulator.sdk
|
||||
IPHONESIMULATOR_PREFIX=$(MONOTOUCH_PREFIX)/SDKs/MonoTouch.iphonesimulator.sdk/usr
|
||||
IPHONEOS_SDK=$(MONOTOUCH_PREFIX)/SDKs/MonoTouch.iphoneos.sdk
|
||||
|
@ -1577,48 +1603,53 @@ ifdef INCLUDE_DEVICE
|
|||
clean-local:: clean-llvm
|
||||
endif
|
||||
|
||||
build-llvm32: .stamp-build-llvm .stamp-build-llvm32
|
||||
build-llvm64: .stamp-build-llvm .stamp-build-llvm32
|
||||
build-llvm32: .stamp-build-llvm32
|
||||
build-llvm64: .stamp-build-llvm64
|
||||
|
||||
.stamp-build-llvm: $(SDK_CONFIG)
|
||||
$(MAKE) -C $(SDK_BUILDDIR) provision-llvm-llvm64 $(SDK_ARGS)
|
||||
.stamp-compile-llvm64: $(SDK_CONFIG)
|
||||
$(MAKE) -C $(MONO_SDK_BUILDDIR) provision-llvm-llvm64 $(SDK_ARGS)
|
||||
$(Q) touch $@
|
||||
|
||||
.stamp-build-llvm32: $(SDK_CONFIG)
|
||||
$(MAKE) -C $(SDK_BUILDDIR) provision-llvm36-llvm32 $(SDK32_ARGS)
|
||||
.stamp-compile-llvm32: $(SDK_CONFIG)
|
||||
$(MAKE) -C $(MONO_SDK_BUILDDIR) provision-llvm36-llvm32 $(SDK32_ARGS)
|
||||
$(Q) touch $@
|
||||
|
||||
.stamp-build-llvm64: .stamp-$(MONO_BUILD_MODE)-llvm64
|
||||
.stamp-build-llvm32: .stamp-$(MONO_BUILD_MODE)-llvm32
|
||||
|
||||
clean-llvm: $(SDK_CONFIG)
|
||||
$(MAKE) -C $(SDK_BUILDDIR) clean-llvm36-llvm32 clean-llvm-llvm64 $(SDK_ARGS)
|
||||
$(MAKE) -C $(MONO_SDK_BUILDDIR) clean-llvm36-llvm32 clean-llvm-llvm64 $(SDK_ARGS)
|
||||
$(RM) .stamp-*-llvm*
|
||||
|
||||
.PHONY: install-llvm64 llvm llvm64
|
||||
.PHONY: install-llvm64 install-llvm32 llvm32 llvm64
|
||||
|
||||
install-llvm: install-llvm32 install-llvm64
|
||||
|
||||
LLVM_TARGETS = \
|
||||
LLVM64_TARGETS = \
|
||||
$(PREFIX)/LLVM/bin/opt \
|
||||
$(PREFIX)/LLVM/bin/llc \
|
||||
|
||||
LLVM32_TARGETS = \
|
||||
$(PREFIX)/LLVM36/bin/opt \
|
||||
$(PREFIX)/LLVM36/bin/llc
|
||||
$(PREFIX)/LLVM36/bin/llc \
|
||||
|
||||
$(PREFIX)/LLVM/bin/%: $(SDK_DESTDIR)/llvm-llvm64/bin/% | $(PREFIX)/LLVM/bin
|
||||
$(MONO_SDK_DESTDIR)/llvm-llvm64/bin/%: .stamp-build-llvm64; @true
|
||||
$(MONO_SDK_DESTDIR)/llvm36-llvm32/bin/%: .stamp-build-llvm32; @true
|
||||
|
||||
$(PREFIX)/LLVM/bin/%: $(MONO_SDK_DESTDIR)/llvm-llvm64/bin/% | $(PREFIX)/LLVM/bin
|
||||
$(call Q_2,INSTALL ,[LLVM64]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@
|
||||
|
||||
$(PREFIX)/LLVM36/bin/%: $(SDK_DESTDIR)/llvm36-llvm32/bin/% | $(PREFIX)/LLVM36/bin
|
||||
$(call Q_2,INSTALL ,[LLVM64]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@
|
||||
$(PREFIX)/LLVM36/bin/%: $(MONO_SDK_DESTDIR)/llvm36-llvm32/bin/% | $(PREFIX)/LLVM36/bin
|
||||
$(call Q_2,INSTALL ,[LLVM32]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $^ $@
|
||||
|
||||
$(PREFIX)/LLVM/bin:
|
||||
$(PREFIX)/LLVM/bin $(PREFIX)/LLVM36/bin:
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
$(PREFIX)/LLVM36/bin:
|
||||
$(Q) mkdir -p $@
|
||||
install-llvm: install-llvm32 install-llvm64
|
||||
install-llvm32: $(LLVM32_TARGETS)
|
||||
install-llvm64: $(LLVM64_TARGETS)
|
||||
|
||||
install-llvm32:.stamp-build-llvm .stamp-build-llvm32 $(LLVM_TARGETS)
|
||||
install-llvm64: .stamp-build-llvm .stamp-build-llvm32 $(LLVM_TARGETS)
|
||||
|
||||
llvm: build-llvm64 install-llvm
|
||||
llvm: install-llvm
|
||||
llvm64: install-llvm64
|
||||
llvm32: install-llvm32
|
||||
|
||||
$(MONO_PATH)/tools/offsets-tool/MonoAotOffsetsDumper.exe: $(MONO_PATH)/configure $(wildcard $(MONO_PATH)/tools/offsets-tool/*.cs)
|
||||
$(Q) $(MAKE) -C $(dir $@) MonoAotOffsetsDumper.exe
|
||||
|
@ -1652,10 +1683,12 @@ build:: build-$(1)
|
|||
install-local:: install-$(1)
|
||||
clean-local:: clean-$(1)
|
||||
|
||||
.stamp-build-$(1): .stamp-build-llvm .stamp-build-llvm32 $(MONO_PATH)/configure $(MONO_PATH)/tools/offsets-tool/MonoAotOffsetsDumper.exe $(MONO_DEPENDENCIES) $(SDK_CONFIG)
|
||||
$(MAKE) -C $(SDK_BUILDDIR) package-ios-$(1) $(SDK_ARGS) $(if $(5), XCODE_DIR=$(5))
|
||||
.stamp-compile-$(1): .stamp-build-llvm64 .stamp-build-llvm32 $(MONO_PATH)/configure $(MONO_PATH)/tools/offsets-tool/MonoAotOffsetsDumper.exe $(MONO_DEPENDENCIES) $(SDK_CONFIG)
|
||||
$(MAKE) -C $(MONO_SDK_BUILDDIR) package-ios-$(1) $(SDK_ARGS) $(if $(5), XCODE_DIR=$(5))
|
||||
$(Q) touch $$@
|
||||
|
||||
.stamp-build-$(1): .stamp-$(MONO_BUILD_MODE)-$(1)
|
||||
|
||||
build-$(1): .stamp-build-$(1)
|
||||
|
||||
_$(1)_CROSS_TARGETS = \
|
||||
|
@ -1663,14 +1696,14 @@ _$(1)_CROSS_TARGETS = \
|
|||
|
||||
$(SDK_DESTDIR)/ios-$(1)/bin/$(4): .stamp-build-$(1)
|
||||
|
||||
$(PREFIX)/bin/$(3): $(SDK_DESTDIR)/ios-$(1)-release/bin/$(4) | $(PREFIX)/bin
|
||||
$(PREFIX)/bin/$(3): $(MONO_SDK_DESTDIR)/ios-$(1)-release/bin/$(4) | $(PREFIX)/bin
|
||||
$(call Q_2,INSTALL ,[CROSS]) install -c -m 0755 $(INSTALL_STRIP_FLAG) $$< $$@
|
||||
|
||||
install-$(1): install-$(2) $$(_$(1)_CROSS_TARGETS)
|
||||
|
||||
clean-$(1): $(SDK_CONFIG)
|
||||
$(MAKE) -C $(SDK_BUILDDIR) clean-ios-$(1) $(SDK_ARGS)
|
||||
-rm -rf $(SDK_DESTDIR)/$(1) .stamp-build-$(1)
|
||||
$(MAKE) -C $(MONO_SDK_BUILDDIR) clean-ios-$(1) $(SDK_ARGS)
|
||||
-rm -rf $(MONO_SDK_DESTDIR)/$(1) .stamp-build-$(1)
|
||||
|
||||
endef
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ Usage: configure [options]
|
|||
--enable-xamarin Enable additional Xamarin-specific parts of the build.
|
||||
|
||||
--disable-packaged-llvm Compile LLVM instead of downloading a precompiled version.
|
||||
|
||||
--disable-packaged-mono Compile Mono from source instead of downloading a precompiled version.
|
||||
EOL
|
||||
}
|
||||
|
||||
|
@ -88,6 +90,10 @@ while test x$1 != x; do
|
|||
echo "DISABLE_DOWNLOAD_LLVM=1" >> $CONFIGURED_FILE
|
||||
shift
|
||||
;;
|
||||
--disable-packaged-mono)
|
||||
echo "MONO_BUILD_FROM_SOURCE=1" >> "$CONFIGURED_FILE"
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
show_help
|
||||
exit 0
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit a0ac40a1a5494829a24c752bb0439a75e182545b
|
||||
Subproject commit 4ad781f981ebc1f34f09b7877bcb52009e4dbea2
|
|
@ -395,6 +395,7 @@ timestamps {
|
|||
stage ('Checkout') {
|
||||
currentStage = "${STAGE_NAME}"
|
||||
echo ("Building on ${env.NODE_NAME}")
|
||||
sh ("env | sort") // Print out environment for debug purposes
|
||||
scmVars = checkout scm
|
||||
isPr = (env.CHANGE_ID && !env.CHANGE_ID.empty ? true : false)
|
||||
branchName = env.BRANCH_NAME
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
# Script to add a comment to a commit on GitHub.
|
||||
#
|
||||
# Arguments (all required):
|
||||
# --token=<pat>: The GitHub Personal Access Token used to authenticate with GitHub.
|
||||
# --file=<path>: The file to add as the comment.
|
||||
# --hash=<hash>: The hash to add the comment to.
|
||||
#
|
||||
|
||||
TOKEN=
|
||||
FILE=
|
||||
HASH=
|
||||
VERBOSE=
|
||||
|
||||
while ! test -z "${1:-}"; do
|
||||
case "$1" in
|
||||
--token=*)
|
||||
TOKEN="${1:8}"
|
||||
shift
|
||||
;;
|
||||
--token)
|
||||
TOKEN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--file=*)
|
||||
FILE="${1:7}"
|
||||
shift
|
||||
;;
|
||||
--file)
|
||||
FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--hash=*)
|
||||
HASH="${1:7}"
|
||||
shift
|
||||
;;
|
||||
--hash)
|
||||
HASH="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v | --verbose)
|
||||
VERBOSE=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$TOKEN"; then
|
||||
echo "The GitHub token is required (--token=<TOKEN>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$FILE"; then
|
||||
echo "The file to add as a comment is required (--file=<path>)"
|
||||
exit 1
|
||||
elif ! test -f "$FILE"; then
|
||||
echo "The file $FILE does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$HASH"; then
|
||||
echo "The commit hash is required (--hash=<hash>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JSONFILE=$(mktemp)
|
||||
LOGFILE=$(mktemp)
|
||||
cleanup ()
|
||||
{
|
||||
rm -f "$JSONFILE" "$LOGFILE"
|
||||
}
|
||||
trap cleanup ERR
|
||||
trap cleanup EXIT
|
||||
|
||||
printf '{\n"body": ' > "$JSONFILE"
|
||||
python -c 'import json,sys; print(json.dumps(sys.stdin.read()))' < "$FILE" >> "$JSONFILE"
|
||||
printf '}\n' >> "$JSONFILE"
|
||||
|
||||
if test -n "$VERBOSE"; then
|
||||
echo "JSON file:"
|
||||
sed 's/^/ /' "$JSONFILE";
|
||||
fi
|
||||
|
||||
if ! curl -f -v -H "Authorization: token $TOKEN" -H "User-Agent: command line tool" -d "@$JSONFILE" "https://api.github.com/repos/xamarin/xamarin-macios/commits/$HASH/comments" > "$LOGFILE" 2>&1; then
|
||||
echo "Failed to add commit message."
|
||||
echo "curl output:"
|
||||
sed 's/^/ /' "$LOGFILE"
|
||||
echo "Json body:"
|
||||
sed 's/^/ /' "$JSONFILE"
|
||||
exit 1
|
||||
else
|
||||
if test -n "$VERBOSE"; then sed 's/^/ /' "$LOGFILE"; fi
|
||||
echo "Successfully added commit message to https://github.com/xamarin/xamarin-macios/commit/$HASH"
|
||||
fi
|
|
@ -0,0 +1,146 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
# Script to add a status to a commit on GitHub.
|
||||
#
|
||||
# Arguments (all required):
|
||||
# --token=<pat>: The GitHub Personal Access Token used to authenticate with GitHub.
|
||||
# --hash=<hash>: The hash to add the comment to.
|
||||
# --state=<success|pending|error|failure>: The status state.
|
||||
# --target-url=<url>: The status url.
|
||||
# --description=<description>: The status description.
|
||||
# --context=<context>: The status context.
|
||||
#
|
||||
|
||||
TOKEN=
|
||||
HASH=
|
||||
STATE=
|
||||
TARGET_URL=
|
||||
DESCRIPTION=
|
||||
CONTEXT=
|
||||
VERBOSE=
|
||||
|
||||
while ! test -z "${1:-}"; do
|
||||
case "$1" in
|
||||
--token=*)
|
||||
TOKEN="${1:8}"
|
||||
shift
|
||||
;;
|
||||
--token)
|
||||
TOKEN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--hash=*)
|
||||
HASH="${1:7}"
|
||||
shift
|
||||
;;
|
||||
--hash)
|
||||
HASH="$2"
|
||||
shift 2
|
||||
;;
|
||||
--state=*)
|
||||
STATE="${1:8}"
|
||||
shift
|
||||
;;
|
||||
--state)
|
||||
STATE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--target-url=*)
|
||||
TARGET_URL="${1:13}"
|
||||
shift
|
||||
;;
|
||||
--target-url)
|
||||
TARGET_URL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--description=*)
|
||||
DESCRIPTION="${1:14}"
|
||||
shift
|
||||
;;
|
||||
--description)
|
||||
DESCRIPTION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--context=*)
|
||||
CONTEXT="${1:10}"
|
||||
shift
|
||||
;;
|
||||
--context)
|
||||
CONTEXT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v | --verbose)
|
||||
VERBOSE=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$TOKEN"; then
|
||||
echo "The GitHub token is required (--token=<TOKEN>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$HASH"; then
|
||||
echo "The commit hash is required (--hash=<hash>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$STATE"; then
|
||||
echo "The state of the status is required (--state=<STATE>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$TARGET_URL"; then
|
||||
echo "The target url of the status is required (--target-url=<TARGET URL>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$DESCRIPTION"; then
|
||||
echo "The description of the status is required (--description=<DESCRIPTION>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$CONTEXT"; then
|
||||
echo "The context of the status is required (--context=<CONTEXT>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JSONFILE=$(mktemp)
|
||||
LOGFILE=$(mktemp)
|
||||
cleanup ()
|
||||
{
|
||||
rm -f "$JSONFILE" "$LOGFILE"
|
||||
}
|
||||
trap cleanup ERR
|
||||
trap cleanup EXIT
|
||||
|
||||
(
|
||||
printf '{\n'
|
||||
printf "\t\"state\": \"%s\",\n" "$STATE"
|
||||
printf "\t\"target_url\": \"%s\",\n" "$TARGET_URL"
|
||||
printf "\t\"description\": %s,\n" "$(echo -n "$DESCRIPTION" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))')"
|
||||
printf "\t\"context\": \"%s\"\n" "$CONTEXT"
|
||||
printf "}\n"
|
||||
) > "$JSONFILE"
|
||||
|
||||
if test -n "$VERBOSE"; then
|
||||
echo "JSON file:"
|
||||
sed 's/^/ /' "$JSONFILE";
|
||||
fi
|
||||
|
||||
if ! curl -f -v -H "Authorization: token $TOKEN" -H "User-Agent: command line tool" -d "@$JSONFILE" "https://api.github.com/repos/xamarin/xamarin-macios/statuses/$HASH" > "$LOGFILE" 2>&1; then
|
||||
echo "Failed to add status."
|
||||
echo "curl output:"
|
||||
sed 's/^/ /' "$LOGFILE"
|
||||
echo "Json body:"
|
||||
sed 's/^/ /' "$JSONFILE"
|
||||
exit 1
|
||||
else
|
||||
if test -n "$VERBOSE"; then sed 's/^/ /' "$LOGFILE"; fi
|
||||
echo "Successfully added status to https://github.com/xamarin/xamarin-macios/commit/$HASH"
|
||||
fi
|
|
@ -3,6 +3,9 @@
|
|||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
WORKSPACE=$(pwd)
|
||||
|
||||
# Print out environment for debug purposes
|
||||
env | sort
|
||||
|
||||
report_error ()
|
||||
{
|
||||
printf "🔥 [Test run failed](%s) 🔥\\n" "$URL" >> "$WORKSPACE/jenkins/pr-comments.md"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
def reportGitHubStatus(commitHash, context, backref, statusResult, statusResultMessage) {
|
||||
step([
|
||||
$class: 'GitHubCommitStatusSetter',
|
||||
reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/xamarin/xamarin-macios"],
|
||||
commitShaSource: [$class: "ManuallyEnteredShaSource", sha: commitHash],
|
||||
contextSource: [$class: 'ManuallyEnteredCommitContextSource', context: context],
|
||||
statusBackrefSource: [$class: 'ManuallyEnteredBackrefSource', backref: backref],
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash -eux
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
|
||||
TOKEN=
|
||||
START=
|
||||
while ! test -z "$1"; do
|
||||
case "$1" in
|
||||
--token=*)
|
||||
TOKEN="${1:8}"
|
||||
shift
|
||||
;;
|
||||
--token)
|
||||
TOKEN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--start)
|
||||
START=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$TOKEN"; then
|
||||
echo "The GitHub token is required (--token=<TOKEN>)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
P=$(cat tmp.p)
|
||||
|
||||
VSTS_BUILD_URL="${SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${SYSTEM_TEAMPROJECT}/_build/index?buildId=${BUILD_BUILDID}"
|
||||
|
||||
# Add a GitHub status to the commit we're testing
|
||||
GH_STATE=failure
|
||||
DESCRIPTION="Running device tests"
|
||||
RESULT_EMOJII=
|
||||
if test -n "$START"; then
|
||||
GH_STATE=pending
|
||||
DESCRIPTION="Running device tests"
|
||||
else
|
||||
case "$(echo "$AGENT_JOBSTATUS" | tr '[:upper:]' '[:lower:]')" in
|
||||
succeeded)
|
||||
GH_STATE=success
|
||||
DESCRIPTION="Device tests passed"
|
||||
RESULT_EMOJII="✅ "
|
||||
;;
|
||||
failed | canceled | succeededwithissues | *)
|
||||
GH_STATE=error
|
||||
DESCRIPTION="Device tests completed ($AGENT_JOBSTATUS)"
|
||||
RESULT_EMOJII="🔥 "
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
./jenkins/add-commit-status.sh --token="$TOKEN" --hash="$BUILD_REVISION" --state="$GH_STATE" --target-url="$VSTS_BUILD_URL" --description="$DESCRIPTION" --context="VSTS: device tests"
|
||||
|
||||
if test -z "$START"; then
|
||||
# When we're done, add a GitHub comment to the commit we're testing
|
||||
MESSAGE_FILE=commit-message.txt
|
||||
cleanup ()
|
||||
{
|
||||
rm -f "$MESSAGE_FILE"
|
||||
}
|
||||
trap cleanup ERR
|
||||
trap cleanup EXIT
|
||||
|
||||
printf "%s%s on [Azure DevOps](%s): [Html Report](http://xamarin-storage/%s/jenkins-results/tests/index.html) %s\\n\\n" "$RESULT_EMOJII" "$DESCRIPTION" "$VSTS_BUILD_URL" "$P" "$RESULT_EMOJII" > "$MESSAGE_FILE"
|
||||
|
||||
FILE=$PWD/tests/TestSummary.md
|
||||
if ! test -f "$FILE"; then
|
||||
printf "🔥 Tests failed catastrophically (no summary found)\\n" >> "$MESSAGE_FILE"
|
||||
else
|
||||
cat "$FILE" >> "$MESSAGE_FILE"
|
||||
fi
|
||||
|
||||
./jenkins/add-commit-comment.sh --token="$TOKEN" --file="$MESSAGE_FILE" "--hash=$BUILD_REVISION"
|
||||
fi
|
|
@ -31,6 +31,7 @@ IOS_TARGETS = \
|
|||
$(wildcard Xamarin.iOS.Tasks.Core/Xamarin.MonoTouch.*.targets) \
|
||||
$(wildcard Xamarin.iOS.Tasks.Core/Xamarin.iOS.*.props) \
|
||||
$(wildcard Xamarin.iOS.Tasks.Core/Xamarin.iOS.*.targets) \
|
||||
$(wildcard Xamarin.Shared/Xamarin.*.targets) \
|
||||
|
||||
IOS_BINDING_TARGETS = $(wildcard Xamarin.ObjcBinding.Tasks/*.targets)
|
||||
|
||||
|
@ -142,7 +143,7 @@ endif
|
|||
## XM definitions
|
||||
##
|
||||
|
||||
MAC_TARGETS = $(wildcard Xamarin.Mac.Tasks/*.props) $(wildcard Xamarin.Mac.Tasks/*.targets)
|
||||
MAC_TARGETS = $(wildcard Xamarin.Mac.Tasks/*.props) $(wildcard Xamarin.Mac.Tasks/*.targets) $(wildcard Xamarin.Shared/Xamarin.*.targets)
|
||||
MAC_BINDING_TARGETS =
|
||||
|
||||
MAC_TASK_ASSEMBLIES = Xamarin.Mac.Tasks
|
||||
|
@ -216,6 +217,9 @@ $(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS/%: Xamarin.ObjcBinding.Tasks/%
|
|||
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS/%: Xamarin.iOS.Tasks.Core/% | $(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS/%: Xamarin.Shared/% | $(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS/%.dll: build/%.dll | $(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/msbuild/iOS
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
|
@ -283,6 +287,9 @@ $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/etc/mono/4.5/machine.config: $(TOP)/t
|
|||
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild/%: Xamarin.Mac.Tasks/% | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild/%: Xamarin.Shared/% | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild/%.dll: build/%.dll | $(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/msbuild
|
||||
$(Q) install -m 644 $< $@
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.MacDev.Tasks;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Xamarin.Mac.Tasks
|
||||
{
|
||||
public class CreateBindingResourcePackage : CreateBindingResourcePackageBase
|
||||
{
|
||||
}
|
||||
}
|
|
@ -61,6 +61,8 @@ Copyright (C) 2014 Xamarin. All rights reserved.
|
|||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Mac.Common.props"
|
||||
Condition="'$(_XamarinCommonPropsHasBeenImported)' != 'true'" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Shared.targets"/>
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets"
|
||||
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets')"/>
|
||||
|
@ -482,9 +484,21 @@ Copyright (C) 2014 Xamarin. All rights reserved.
|
|||
IsAppExtension="$(IsAppExtension)"
|
||||
PartialAppManifests="@(_PartialAppManifest)" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<CompileToNativeDependsOn>
|
||||
_DetectAppManifest;
|
||||
_DetectSdkLocations;
|
||||
_GenerateBundleName;
|
||||
ResolveReferences;
|
||||
_CompileEntitlements;
|
||||
_CompileAppManifest;
|
||||
_ExpandNativeReferences;
|
||||
</CompileToNativeDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="_CompileToNative" DependsOnTargets="_DetectAppManifest;_DetectSdkLocations;_GenerateBundleName;ResolveReferences;_CompileEntitlements;_CompileAppManifest"
|
||||
Inputs="$(TargetDir)$(TargetFileName)"
|
||||
<Target Name="_CompileToNative" DependsOnTargets="$(CompileToNativeDependsOn)"
|
||||
Inputs="$(TargetDir)$(TargetFileName);@(_FrameworkNativeReference);@(_FileNativeReference);@(BundleDependentFiles)"
|
||||
Outputs="$(_AppBundlePath)Contents\MacOS\$(_AppBundleName)">
|
||||
<ItemGroup>
|
||||
<!-- Skip the reference assemblies. 'mmp' will fail to AOT them if passed 'aot:all'. Similar to: https://github.com/xamarin/xamarin-macios/issues/3199 -->
|
||||
|
|
|
@ -16,6 +16,7 @@ Copyright (C) 2014 Xamarin Inc. All rights reserved.
|
|||
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Xamarin.Mac.Tasks.BTouch" AssemblyFile="Xamarin.Mac.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.Mac.Tasks.CreateBindingResourcePackage" AssemblyFile="Xamarin.Mac.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Zip" AssemblyFile="Xamarin.Mac.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.Mac.Tasks.PrepareNativeReferences" AssemblyFile="Xamarin.Mac.Tasks.dll" />
|
||||
|
||||
|
@ -56,15 +57,18 @@ Copyright (C) 2014 Xamarin Inc. All rights reserved.
|
|||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Mac.ObjCBinding.Common.targets" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Shared.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_GeneratedSourcesFileList>$(GeneratedSourcesDir)sources.list</_GeneratedSourcesFileList>
|
||||
|
||||
<!-- Add our own pre-build steps -->
|
||||
<!-- Add our own pre and post build steps -->
|
||||
<CompileDependsOn>
|
||||
_GenerateBindings;
|
||||
_PrepareNativeReferences;
|
||||
_CollectGeneratedSources;
|
||||
$(CompileDependsOn)
|
||||
_CreateBindingResourcePackage;
|
||||
</CompileDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -119,8 +123,8 @@ Copyright (C) 2014 Xamarin Inc. All rights reserved.
|
|||
IntermediateOutputPath="$(IntermediateOutputPath)"
|
||||
NativeReferences="@(NativeReference)"
|
||||
>
|
||||
<Output ItemName="ManifestResourceWithNoCulture" TaskParameter="EmbeddedResources" />
|
||||
<Output ItemName="_NativeFramework" TaskParameter="NativeFrameworks" />
|
||||
<Output ItemName="ManifestResourceWithNoCulture" TaskParameter="EmbeddedResources" Condition="'$(NoBindingEmbedding)' != 'true'"/>
|
||||
<Output ItemName="_NativeFramework" TaskParameter="NativeFrameworks" Condition="'$(NoBindingEmbedding)' != 'true'"/>
|
||||
<Output ItemName="Compile" TaskParameter="LinkWithAttributes" />
|
||||
</PrepareNativeReferences>
|
||||
</Target>
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Tasks\ACTool.cs" />
|
||||
<Compile Include="Tasks\BTouch.cs" />
|
||||
<Compile Include="Tasks\CreateBindingResourcePackage.cs" />
|
||||
<Compile Include="Tasks\CodesignVerify.cs" />
|
||||
<Compile Include="Tasks\CompileAppManifest.cs" />
|
||||
<Compile Include="Tasks\CompileEntitlements.cs" />
|
||||
|
@ -118,6 +119,9 @@
|
|||
<None Include="Xamarin.Mac.AppExtension.Common.targets">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="../Xamarin.Shared/Xamarin.Shared.targets">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Xamarin.MacDev.Tasks {
|
||||
public abstract class CreateBindingResourcePackageBase : Task {
|
||||
public string SessionId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] NativeReferences { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ProjectDir { get; set; }
|
||||
|
||||
[Required]
|
||||
public string BindingAssembly { get; set; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem Manifest { get; set; }
|
||||
|
||||
public override bool Execute ()
|
||||
{
|
||||
// LinkWith must be migrated for NoBindingEmbedding styled binding projects
|
||||
if (NativeReferences.Length == 0) {
|
||||
Log.LogError (7068, null, $"Can't create a binding resource package unless there are native references in the binding project.");
|
||||
return false;
|
||||
}
|
||||
|
||||
string bindingResourcePath = Path.Combine (ProjectDir, OutputPath, Path.ChangeExtension (Path.GetFileName (BindingAssembly), ".resources"));
|
||||
Log.LogMessage ($"Creating binding resource package: {bindingResourcePath}");
|
||||
|
||||
Directory.CreateDirectory (bindingResourcePath);
|
||||
foreach (var nativeRef in NativeReferences)
|
||||
Xamarin.Bundler.FileCopier.UpdateDirectory (nativeRef.ItemSpec, bindingResourcePath);
|
||||
|
||||
string manifestPath = CreateManifest (bindingResourcePath);
|
||||
|
||||
Manifest = new TaskItem ("Manifest") { ItemSpec = manifestPath };
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string [] NativeReferenceAttributeNames = new string [] { "Kind", "ForceLoad", "SmartLink", "Frameworks", "WeakFrameworks", "LinkerFlags", "NeedsGccExceptionHandling", "IsCxx"};
|
||||
|
||||
string CreateManifest (string resourcePath)
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings() {
|
||||
OmitXmlDeclaration = true,
|
||||
Indent = true,
|
||||
IndentChars = "\t",
|
||||
};
|
||||
|
||||
string manifestPath = Path.Combine (resourcePath, "manifest");
|
||||
using (var writer = XmlWriter.Create (manifestPath, settings)) {
|
||||
writer.WriteStartElement ("BindingAssembly");
|
||||
|
||||
foreach (var nativeRef in NativeReferences) {
|
||||
writer.WriteStartElement ("NativeReference");
|
||||
writer.WriteAttributeString ("Name", Path.GetFileName (nativeRef.ItemSpec));
|
||||
|
||||
foreach (string attribute in NativeReferenceAttributeNames) {
|
||||
writer.WriteStartElement (attribute);
|
||||
writer.WriteString (nativeRef.GetMetadata (attribute));
|
||||
writer.WriteEndElement ();
|
||||
}
|
||||
|
||||
writer.WriteEndElement ();
|
||||
}
|
||||
writer.WriteEndElement ();
|
||||
}
|
||||
return manifestPath;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,6 +67,7 @@
|
|||
<Compile Include="Tasks\ArchiveTaskBase.cs" />
|
||||
<Compile Include="Tasks\ArToolTaskBase.cs" />
|
||||
<Compile Include="Tasks\BTouchTaskBase.cs" />
|
||||
<Compile Include="Tasks\CreateBindingResourcePackageBase.cs" />
|
||||
<Compile Include="Tasks\CodesignTaskBase.cs" />
|
||||
<Compile Include="Tasks\CodesignVerifyTaskBase.cs" />
|
||||
<Compile Include="Tasks\CollectBundleResourcesTaskBase.cs" />
|
||||
|
@ -116,6 +117,7 @@
|
|||
<Compile Include="PlatformFramework.cs" />
|
||||
<Compile Include="ProcessUtils.cs" />
|
||||
<Compile Include="StringParserService.cs" />
|
||||
<Compile Include="../../tools/common/FileCopier.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<!--
|
||||
***********************************************************************************************
|
||||
Xamarin.Shared.targets
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
This file imports the version- and platform-specific targets for the project importing
|
||||
this file. This file also defines targets to produce an error if the specified targets
|
||||
file does not exist, but the project is built anyway (command-line or IDE build).
|
||||
|
||||
Copyright (C) 2018 Microsoft. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
|
||||
<!-- This is shared between Xamarin.iOS and Xamarin.Mac -->
|
||||
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets"
|
||||
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets')"/>
|
||||
|
||||
<!--
|
||||
@(NativeReference) are not safe to use as an Input to a task, as frameworks are a directory and will appears unbuilt every time.
|
||||
So we split it into two camps as a prebuild step
|
||||
-->
|
||||
<Target Name="_ExpandNativeReferences" Condition="'$(DesignTimeBuild)' != 'true'">
|
||||
<ItemGroup>
|
||||
<_FrameworkNativeReference Include="@(NativeReference -> '%(Identity)/%(Filename)')" Condition="'%(Extension)' == '.framework'" />
|
||||
<_FileNativeReference Include="@(NativeReference)" Condition="'%(Extension)' != '.framework'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<BindingResourcePath>$(ProjectDir)$(OutputPath)$(AssemblyName).resources</BindingResourcePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="_CreateBindingResourcePackage" Condition="'$(DesignTimeBuild)' != 'true'"
|
||||
DependsOnTargets="_ExpandNativeReferences"
|
||||
Inputs="$(MSBuildAllProjects);@(ObjcBindingApiDefinition);@(ObjcBindingCoreSource);@(ReferencePath);@(ObjcBindingNativeLibrary);@(_FrameworkNativeReference);@(_FileNativeReference)"
|
||||
Outputs="$(BindingResourcePath)/manifest">
|
||||
<CreateBindingResourcePackage Condition="'$(IsMacEnabled)' == 'true' And '$(NoBindingEmbedding)' == 'true' And '$(SkipBindingResourcePackage)' != 'true'"
|
||||
SessionId="$(BuildSessionId)"
|
||||
OutputPath="$(OutputPath)"
|
||||
NativeReferences="@(NativeReference)"
|
||||
ProjectDir="$(MSBuildProjectDirectory)"
|
||||
BindingAssembly="@(IntermediateAssembly)">
|
||||
<Output TaskParameter="Manifest" ItemName="_BundleResourceManifest" />
|
||||
</CreateBindingResourcePackage>
|
||||
</Target>
|
||||
|
||||
<!-- Cleaning via FileWrites leaves empty framework directories on disk, so nuke via RemoveDir -->
|
||||
<PropertyGroup>
|
||||
<CleanDependsOn>
|
||||
$(CleanDependsOn);
|
||||
_CleanBindingResourcePackage
|
||||
</CleanDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="_CleanBindingResourcePackage">
|
||||
<RemoveDir Directories="$(BindingResourcePath);" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).After.targets"
|
||||
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).After.targets')"/>
|
||||
</Project>
|
||||
|
|
@ -102,6 +102,8 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
|
|||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Analysis.targets"
|
||||
Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.Analysis.targets') And '$(OutputType)' == 'Exe'" />
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Shared.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Switching to a new property allows us to potentially switch from iPhone to simulator builds
|
||||
dynamically based on the user's selection when starting the project. This allows us to
|
||||
|
@ -767,7 +769,8 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
|
|||
_CompileAppManifest;
|
||||
_ResolveAppExtensionReferences;
|
||||
_GetNativeExecutableName;
|
||||
_GetCompileToNativeInputs
|
||||
_GetCompileToNativeInputs;
|
||||
_ExpandNativeReferences;
|
||||
</_CompileToNativeDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -779,7 +782,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
|
|||
</Target>
|
||||
|
||||
<Target Name="_CompileToNative" DependsOnTargets="$(_CompileToNativeDependsOn)"
|
||||
Inputs="@(_CompileToNativeInput)"
|
||||
Inputs="@(_CompileToNativeInput);@(_FrameworkNativeReference);@(_FileNativeReference);@(BundleDependentFiles)"
|
||||
Outputs="$(_NativeExecutable);$(DeviceSpecificOutputPath)mtouch.stamp">
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,6 +17,7 @@ Copyright (C) 2013-2016 Xamarin Inc. All rights reserved.
|
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.PrepareNativeReferences" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.BTouch" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.iOS.Tasks.CreateBindingResourcePackage" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
<UsingTask TaskName="Xamarin.MacDev.Tasks.Zip" AssemblyFile="Xamarin.iOS.Tasks.dll" />
|
||||
|
||||
<UsingTask TaskName="Microsoft.Build.Tasks.Delete" AssemblyFile="Xamarin.iOS.Tasks.dll"/>
|
||||
|
@ -28,6 +29,7 @@ Copyright (C) 2013-2016 Xamarin Inc. All rights reserved.
|
|||
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="Xamarin.iOS.ObjCBinding.Common.targets" />
|
||||
<Import Project="Xamarin.Shared.targets"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<_GeneratedSourcesFileList>$(GeneratedSourcesDir)sources.list</_GeneratedSourcesFileList>
|
||||
|
@ -35,12 +37,13 @@ Copyright (C) 2013-2016 Xamarin Inc. All rights reserved.
|
|||
<XamarinDefineConstants Condition="'$(XamarinDefineConstants)' == ''">__UNIFIED__;__MOBILE__;__IOS__</XamarinDefineConstants>
|
||||
<DefineConstants>$(XamarinDefineConstants);$(DefineConstants)</DefineConstants>
|
||||
|
||||
<!-- Add our own pre-build steps -->
|
||||
<!-- Add our own pre and post build steps -->
|
||||
<CompileDependsOn>
|
||||
_GenerateBindings;
|
||||
_PrepareNativeReferences;
|
||||
_CollectGeneratedSources;
|
||||
$(CompileDependsOn)
|
||||
_CreateBindingResourcePackage;
|
||||
</CompileDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -87,8 +90,8 @@ Copyright (C) 2013-2016 Xamarin Inc. All rights reserved.
|
|||
SessionId="$(BuildSessionId)"
|
||||
IntermediateOutputPath="$(IntermediateOutputPath)"
|
||||
NativeReferences="@(NativeReference)">
|
||||
<Output ItemName="ManifestResourceWithNoCulture" TaskParameter="EmbeddedResources" />
|
||||
<Output ItemName="_NativeFramework" TaskParameter="NativeFrameworks" />
|
||||
<Output ItemName="ManifestResourceWithNoCulture" TaskParameter="EmbeddedResources" Condition="'$(NoBindingEmbedding)' != 'true'"/>
|
||||
<Output ItemName="_NativeFramework" TaskParameter="NativeFrameworks" Condition="'$(NoBindingEmbedding)' != 'true'"/>
|
||||
<Output ItemName="Compile" TaskParameter="LinkWithAttributes" />
|
||||
</PrepareNativeReferences>
|
||||
</Target>
|
||||
|
|
|
@ -214,5 +214,8 @@
|
|||
<None Include="Xamarin.WatchOS.ObjCBinding.CSharp.targets">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="../Xamarin.Shared/Xamarin.Shared.targets">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.MacDev.Tasks;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
namespace Xamarin.iOS.Tasks
|
||||
{
|
||||
public class CreateBindingResourcePackage : CreateBindingResourcePackageBase
|
||||
{
|
||||
}
|
||||
}
|
|
@ -74,6 +74,7 @@
|
|||
<Compile Include="Tasks\FindWatchOS2AppBundle.cs" />
|
||||
<Compile Include="Tasks\DetectDebugNetworkConfiguration.cs" />
|
||||
<Compile Include="Tasks\CodesignNativeLibraries.cs" />
|
||||
<Compile Include="Tasks\CreateBindingResourcePackage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
using System;
|
||||
|
||||
using UIKit;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
using CoreGraphics;
|
||||
|
||||
namespace MyiOSBinding
|
||||
{
|
||||
// The first step to creating a binding is to add your native library ("libNativeLibrary.a")
|
||||
// to the project by right-clicking (or Control-clicking) the folder containing this source
|
||||
// file and clicking "Add files..." and then simply select the native library (or libraries)
|
||||
// that you want to bind.
|
||||
//
|
||||
// When you do that, you'll notice that MonoDevelop generates a code-behind file for each
|
||||
// native library which will contain a [LinkWith] attribute. MonoDevelop auto-detects the
|
||||
// architectures that the native library supports and fills in that information for you,
|
||||
// however, it cannot auto-detect any Frameworks or other system libraries that the
|
||||
// native library may depend on, so you'll need to fill in that information yourself.
|
||||
//
|
||||
// Once you've done that, you're ready to move on to binding the API...
|
||||
//
|
||||
//
|
||||
// Here is where you'd define your API definition for the native Objective-C library.
|
||||
//
|
||||
// For example, to bind the following Objective-C class:
|
||||
//
|
||||
// @interface Widget : NSObject {
|
||||
// }
|
||||
//
|
||||
// The C# binding would look like this:
|
||||
//
|
||||
// [BaseType (typeof (NSObject))]
|
||||
// interface Widget {
|
||||
// }
|
||||
//
|
||||
// To bind Objective-C properties, such as:
|
||||
//
|
||||
// @property (nonatomic, readwrite, assign) CGPoint center;
|
||||
//
|
||||
// You would add a property definition in the C# interface like so:
|
||||
//
|
||||
// [Export ("center")]
|
||||
// CGPoint Center { get; set; }
|
||||
//
|
||||
// To bind an Objective-C method, such as:
|
||||
//
|
||||
// -(void) doSomething:(NSObject *)object atIndex:(NSInteger)index;
|
||||
//
|
||||
// You would add a method definition to the C# interface like so:
|
||||
//
|
||||
// [Export ("doSomething:atIndex:")]
|
||||
// void DoSomething (NSObject object, int index);
|
||||
//
|
||||
// Objective-C "constructors" such as:
|
||||
//
|
||||
// -(id)initWithElmo:(ElmoMuppet *)elmo;
|
||||
//
|
||||
// Can be bound as:
|
||||
//
|
||||
// [Export ("initWithElmo:")]
|
||||
// IntPtr Constructor (ElmoMuppet elmo);
|
||||
//
|
||||
// For more information, see http://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/
|
||||
//
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace MyiOSBinding
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Tests;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace Xamarin.iOS.Tasks
|
||||
{
|
||||
[TestFixture ("iPhone")]
|
||||
[TestFixture ("iPhoneSimulator")]
|
||||
public class NativeReferencesNoEmbedding : ProjectTest {
|
||||
|
||||
public NativeReferencesNoEmbedding (string platform) : base (platform)
|
||||
{
|
||||
}
|
||||
|
||||
void SetNoBindingEmbedding ()
|
||||
{
|
||||
// TODO - This is a hack. We should be setting it only on the binding project, but
|
||||
// the iOS msbuild test system doesn't have an easy way to access since it's just a project reference
|
||||
// and not loaded up here...
|
||||
Engine.ProjectCollection.SetGlobalProperty ("NoBindingEmbedding", "true");
|
||||
}
|
||||
|
||||
void BuildProjectNoEmbedding (ProjectPaths project, bool clean = true)
|
||||
{
|
||||
Engine.ProjectCollection.SetGlobalProperty ("Platform", Platform);
|
||||
var proj = SetupProject (Engine, project.ProjectCSProjPath);
|
||||
|
||||
SetNoBindingEmbedding ();
|
||||
|
||||
if (clean)
|
||||
RunTarget (proj, "Clean", 0);
|
||||
RunTarget (proj, "Build", 0);
|
||||
}
|
||||
|
||||
string GetMessages () => string.Join ("\n", Engine.Logger.MessageEvents.Select (x => x.Message));
|
||||
|
||||
void ClearMessages () => Engine.Logger.MessageEvents.Clear ();
|
||||
|
||||
// [TestCase (true)] MISSING_TEST - Tests are framework only
|
||||
// [TestCase (false)] MISSING_TEST - Also, project reference only
|
||||
public void LibrariesEmbeddedProperly (bool useProjectReference)
|
||||
{
|
||||
Assert.Fail ();
|
||||
}
|
||||
|
||||
// [TestCase (false)] MISSING_TEST - Project reference only
|
||||
[TestCase (true)]
|
||||
public void FrameworksEmbeddedProperly (bool useProjectReference)
|
||||
{
|
||||
// TODO - Checked in projects are project reference only...
|
||||
Assert.True (useProjectReference);
|
||||
|
||||
var bindingApp = SetupProjectPaths ("MyiOSAppWithBinding", "../", true, Platform);
|
||||
|
||||
BuildProjectNoEmbedding (bindingApp);
|
||||
|
||||
string libPath = Path.Combine (Directory.GetCurrentDirectory (), bindingApp.ProjectBinPath, "MyiOSBinding.dll");
|
||||
Assert.True (File.Exists (libPath), $"Did not find expected library: {libPath}");
|
||||
|
||||
int returnValue = ExecutionHelper.Execute ("/Library/Frameworks/Mono.framework/Commands/monodis", "--presources " + libPath, out string monoDisResults);
|
||||
Assert.AreEqual (0, returnValue);
|
||||
Assert.IsFalse (monoDisResults.Contains ("XTest.framework"), $"Binding Library contained embedded resource: {monoDisResults}");
|
||||
|
||||
string finalFrameworkPath = Path.Combine (bindingApp.AppBundlePath, "Frameworks/XTest.framework/XTest");
|
||||
Assert.True (File.Exists (finalFrameworkPath), $"{finalFrameworkPath} file was not part of bundle?");
|
||||
}
|
||||
|
||||
// [Test] MISSING_TEST - No LinkWith only projects
|
||||
public void DoesNotSupportLinkWith ()
|
||||
{
|
||||
Assert.Fail ();
|
||||
}
|
||||
|
||||
[TestCase (true)]
|
||||
// [TestCase (false)] MISSING_TEST - Framework only tests
|
||||
public void ShouldNotUnnecessarilyRebuildBindingProject (bool framework)
|
||||
{
|
||||
Assert.True (framework);
|
||||
|
||||
var bindingLib = SetupProjectPaths ("MyiOSFrameworkBinding", "../", true, "");
|
||||
|
||||
const string CreatePackageString = "Creating binding resource package";
|
||||
|
||||
// First build should create a package
|
||||
BuildProjectNoEmbedding (bindingLib);
|
||||
Assert.True (GetMessages ().Contains (CreatePackageString), "First build did not create package?");
|
||||
ClearMessages ();
|
||||
|
||||
// No change build should not
|
||||
BuildProjectNoEmbedding (bindingLib, clean : false);
|
||||
Assert.False (GetMessages ().Contains (CreatePackageString), "Rebuild build did create package?");
|
||||
ClearMessages ();
|
||||
|
||||
// Touching the binding project should
|
||||
Touch (bindingLib.ProjectCSProjPath);
|
||||
BuildProjectNoEmbedding (bindingLib, clean: false);
|
||||
Assert.True (GetMessages ().Contains (CreatePackageString), "Bindng project build did not create package?");
|
||||
ClearMessages ();
|
||||
|
||||
// Touching the binding file should
|
||||
Touch (Path.Combine (Path.GetDirectoryName (bindingLib.ProjectCSProjPath), @"../../../tests/bindings-framework-test/ApiDefinition.cs"));
|
||||
BuildProjectNoEmbedding (bindingLib, clean: false);
|
||||
Assert.True (GetMessages ().Contains (CreatePackageString), "Bindng file build did not create package?");
|
||||
ClearMessages ();
|
||||
|
||||
// No change build should not
|
||||
BuildProjectNoEmbedding (bindingLib, clean: false);
|
||||
Assert.False (GetMessages ().Contains (CreatePackageString), "Second rebuild build did create package?");
|
||||
ClearMessages ();
|
||||
|
||||
// Touching native library should
|
||||
Touch (Path.Combine (Path.GetDirectoryName (bindingLib.ProjectCSProjPath), @"../../../tests/test-libraries/.libs/ios/XTest.framework/XTest"));
|
||||
BuildProjectNoEmbedding (bindingLib, clean: false);
|
||||
Assert.True (GetMessages ().Contains (CreatePackageString), "Bindng build did not create package?");
|
||||
}
|
||||
|
||||
[TestCase (true)]
|
||||
// [TestCase (false)] MISSING_TEST - Project reference only
|
||||
public void ShouldNotUnnecessarilyRebuildFinalProject (bool useProjectReference)
|
||||
{
|
||||
Assert.True (useProjectReference);
|
||||
|
||||
var appProject = SetupProjectPaths ("MyiOSAppWithBinding", "../", true, "");
|
||||
|
||||
const string BuildString = "/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin/mtouch";
|
||||
|
||||
// First build should create run mtouch
|
||||
BuildProjectNoEmbedding (appProject);
|
||||
Assert.True (GetMessages ().Contains (BuildString), "First build did not run mtouch?");
|
||||
ClearMessages ();
|
||||
|
||||
// But not a rebuild
|
||||
BuildProjectNoEmbedding (appProject, clean: false);
|
||||
Assert.False (GetMessages ().Contains (BuildString), "Rebuild build did run mtouch?");
|
||||
ClearMessages ();
|
||||
|
||||
if (!useProjectReference) {
|
||||
Assert.Fail (); // TODO - Checked in projects are project reference only...
|
||||
} else {
|
||||
var libProject = SetupProjectPaths ("MyiOSFrameworkBinding", "../", true, "");
|
||||
|
||||
Touch (libProject.ProjectCSProjPath);
|
||||
BuildProjectNoEmbedding (appProject, clean: false);
|
||||
Assert.True (GetMessages ().Contains (BuildString), "Binding binary build did not run mtouch?");
|
||||
}
|
||||
}
|
||||
|
||||
// [TestCase (true)] - MISSING_TEST - Requires special "chain" project that is not checked in
|
||||
// [TestCase (false)] - MISSING_TEST - Requires special "chain" project that is not checked in
|
||||
public void MultipleDependencyChain (bool useProjectReference)
|
||||
{
|
||||
Assert.Fail ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -331,8 +331,7 @@ namespace Xamarin.iOS.Tasks
|
|||
{
|
||||
if (!File.Exists (file))
|
||||
Assert.Fail ("Expected file '{0}' did not exist", file);
|
||||
File.SetLastWriteTimeUtc (file, DateTime.UtcNow.AddDays (1));
|
||||
System.Threading.Thread.Sleep (1000);
|
||||
File.SetLastWriteTimeUtc (file, DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public void RunTarget (Project project, string target, int expectedErrorCount = 0)
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
<Compile Include="ProjectsTests\ProjectReference.cs" />
|
||||
<Compile Include="ProjectsTests\ResponseFileArguments.cs" />
|
||||
<Compile Include="ProjectsTests\CompileSceneKitAssetsTest.cs" />
|
||||
<Compile Include="ProjectsTests\NativeReferencesNoEmbedding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
|
|
|
@ -736,6 +736,25 @@ namespace AudioUnit
|
|||
return MusicDeviceMIDIEvent (handle, status, data1, data2, offsetSampleFrame);
|
||||
}
|
||||
|
||||
public AudioUnitStatus SetLatency (double latency)
|
||||
{
|
||||
// ElementCount: Float64, AudioUnitScopeType.Global is the only valid scope for Latency.
|
||||
return AudioUnitSetProperty (handle, AudioUnitPropertyIDType.Latency, AudioUnitScopeType.Global, 0, ref latency, sizeof (double));
|
||||
}
|
||||
|
||||
[DllImport (Constants.AudioUnitLibrary)]
|
||||
static extern AudioUnitStatus AudioUnitGetProperty (IntPtr inUnit, AudioUnitPropertyIDType inID, AudioUnitScopeType inScope, uint inElement, ref double outData, ref uint ioDataSize);
|
||||
|
||||
public double GetLatency ()
|
||||
{
|
||||
uint size = sizeof (double);
|
||||
double latency = 0;
|
||||
var err = AudioUnitGetProperty (handle, AudioUnitPropertyIDType.Latency, AudioUnitScopeType.Global, 0, ref latency, ref size);
|
||||
if (err != 0)
|
||||
throw new AudioUnitException ((int) err);
|
||||
return latency;
|
||||
}
|
||||
|
||||
#region SetRenderCallback
|
||||
|
||||
public AudioUnitStatus SetRenderCallback (RenderDelegate renderDelegate, AudioUnitScopeType scope = AudioUnitScopeType.Global, uint audioUnitElement = 0)
|
||||
|
|
|
@ -41,6 +41,7 @@ using Foundation;
|
|||
|
||||
namespace CFNetwork {
|
||||
|
||||
[Obsolete ("Use 'System.Net.Http.CFNetworkHandler' or the more recent 'Foundation.NSUrlSessionHandler' instead.")]
|
||||
public class MessageHandler : HttpClientHandler {
|
||||
public MessageHandler ()
|
||||
{
|
||||
|
@ -86,19 +87,19 @@ namespace CFNetwork {
|
|||
if (!request.RequestUri.IsAbsoluteUri)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
using (var message = CreateRequest (request)) {
|
||||
using (var message = CreateRequest (request, true)) {
|
||||
var body = await CreateBody (request, message, cancellationToken);
|
||||
return await ProcessRequest (request, message, body, true, cancellationToken);
|
||||
return await ProcessRequest (request, message, body, true, cancellationToken, true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
CFHTTPMessage CreateRequest (HttpRequestMessage request)
|
||||
CFHTTPMessage CreateRequest (HttpRequestMessage request, bool isFirstRequest)
|
||||
{
|
||||
var message = CFHTTPMessage.CreateRequest (
|
||||
request.RequestUri, request.Method.Method, request.Version);
|
||||
|
||||
SetupRequest (request, message);
|
||||
SetupRequest (request, message, isFirstRequest);
|
||||
|
||||
if ((auth == null) || (Credentials == null) || !PreAuthenticate)
|
||||
return message;
|
||||
|
@ -111,11 +112,12 @@ namespace CFNetwork {
|
|||
if (credential == null)
|
||||
return message;
|
||||
|
||||
message.ApplyCredentials (auth, credential);
|
||||
if (isFirstRequest)
|
||||
message.ApplyCredentials (auth, credential);
|
||||
return message;
|
||||
}
|
||||
|
||||
void SetupRequest (HttpRequestMessage request, CFHTTPMessage message)
|
||||
void SetupRequest (HttpRequestMessage request, CFHTTPMessage message, bool isFirstRequest)
|
||||
{
|
||||
string accept_encoding = null;
|
||||
if ((AutomaticDecompression & DecompressionMethods.GZip) != 0)
|
||||
|
@ -127,6 +129,8 @@ namespace CFNetwork {
|
|||
|
||||
if (request.Content != null) {
|
||||
foreach (var header in request.Content.Headers) {
|
||||
if (!isFirstRequest && header.Key == "Authorization")
|
||||
continue;
|
||||
var value = string.Join (",", header.Value);
|
||||
message.SetHeaderFieldValue (header.Key, value);
|
||||
}
|
||||
|
@ -190,12 +194,23 @@ namespace CFNetwork {
|
|||
|
||||
return request.Headers.Contains ("Keep-Alive");
|
||||
}
|
||||
|
||||
// Decide if we redirect or not, similar to what is done in the managed handler
|
||||
// https://github.com/mono/mono/blob/eca15996c7163f331c9f2cd0a17b63e8f92b1d55/mcs/class/referencesource/System/net/System/Net/HttpWebRequest.cs#L5681
|
||||
static bool IsRedirect (HttpStatusCode status)
|
||||
{
|
||||
return status == HttpStatusCode.Ambiguous || // 300
|
||||
status == HttpStatusCode.Moved || // 301
|
||||
status == HttpStatusCode.Redirect || // 302
|
||||
status == HttpStatusCode.RedirectMethod || // 303
|
||||
status == HttpStatusCode.RedirectKeepVerb; // 307
|
||||
}
|
||||
|
||||
async Task<HttpResponseMessage> ProcessRequest (HttpRequestMessage request,
|
||||
CFHTTPMessage message,
|
||||
WebRequestStream body,
|
||||
bool retryWithCredentials,
|
||||
CancellationToken cancellationToken)
|
||||
CancellationToken cancellationToken, bool isFirstRequest)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested ();
|
||||
|
||||
|
@ -210,21 +225,35 @@ namespace CFNetwork {
|
|||
request.RequestUri)
|
||||
);
|
||||
|
||||
stream.Stream.ShouldAutoredirect = AllowAutoRedirect;
|
||||
if (!isFirstRequest)
|
||||
stream.Stream.ShouldAutoredirect = AllowAutoRedirect;
|
||||
stream.Stream.AttemptPersistentConnection = GetKeepAlive (request);
|
||||
|
||||
var response = await stream.Open (
|
||||
WorkerThread, cancellationToken).ConfigureAwait (false);
|
||||
WorkerThread, cancellationToken).ConfigureAwait (true); // with false, we will have a deadlock.
|
||||
|
||||
var status = (HttpStatusCode)response.ResponseStatusCode;
|
||||
|
||||
if ( IsRedirect (status)) {
|
||||
request.Headers.Authorization = null;
|
||||
stream.Dispose ();
|
||||
// we cannot reuse the message, will deadlock and also the message.ApplyCredentials (auth, credential);
|
||||
// was called the first time
|
||||
using (var retryMsg = CreateRequest (request, false)) {
|
||||
return await ProcessRequest (
|
||||
request, retryMsg, null, false, cancellationToken, false);
|
||||
}
|
||||
|
||||
}
|
||||
if (retryWithCredentials && (body == null) &&
|
||||
(status == HttpStatusCode.Unauthorized) ||
|
||||
(status == HttpStatusCode.ProxyAuthenticationRequired)) {
|
||||
if (HandleAuthentication (request.RequestUri, message, response)) {
|
||||
stream.Dispose ();
|
||||
return await ProcessRequest (
|
||||
request, message, null, false, cancellationToken);
|
||||
using (var retryMsg = CreateRequest (request, true)) { // behave as if it was the first attempt
|
||||
return await ProcessRequest (
|
||||
request, message, null, false, cancellationToken, true); // behave as if it was the first attempt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,12 +118,6 @@ namespace Foundation {
|
|||
public static readonly Assembly MonoMacAssembly = typeof (NSObject).Assembly;
|
||||
#endif
|
||||
|
||||
static internal void OverrideRetainAndRelease (IntPtr @class)
|
||||
{
|
||||
Class.class_addMethod (@class, Selector.RetainHandle, Method.RetainTrampoline, "@@:");
|
||||
Class.class_addMethod (@class, Selector.ReleaseHandle, Method.ReleaseTrampoline, "v@:");
|
||||
}
|
||||
|
||||
internal void SetAsProxy () {
|
||||
IsDirectBinding = true;
|
||||
}
|
||||
|
|
|
@ -27,13 +27,16 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
|
||||
#if UNIFIED
|
||||
using CoreFoundation;
|
||||
|
@ -53,8 +56,62 @@ namespace System.Net.Http {
|
|||
#else
|
||||
namespace Foundation {
|
||||
#endif
|
||||
|
||||
// useful extensions for the class in order to set it in a header
|
||||
static class NSHttpCookieExtensions
|
||||
{
|
||||
static void AppendSegment(StringBuilder builder, string name, string value)
|
||||
{
|
||||
if (builder.Length > 0)
|
||||
builder.Append ("; ");
|
||||
|
||||
builder.Append (name);
|
||||
if (value != null)
|
||||
builder.Append ("=").Append (value);
|
||||
}
|
||||
|
||||
// returns the header for a cookie
|
||||
public static string GetHeaderValue (this NSHttpCookie cookie)
|
||||
{
|
||||
var header = new StringBuilder();
|
||||
AppendSegment (header, cookie.Name, cookie.Value);
|
||||
AppendSegment (header, NSHttpCookie.KeyPath.ToString (), cookie.Path.ToString ());
|
||||
AppendSegment (header, NSHttpCookie.KeyDomain.ToString (), cookie.Domain.ToString ());
|
||||
AppendSegment (header, NSHttpCookie.KeyVersion.ToString (), cookie.Version.ToString ());
|
||||
|
||||
if (cookie.Comment != null)
|
||||
AppendSegment (header, NSHttpCookie.KeyComment.ToString (), cookie.Comment.ToString());
|
||||
|
||||
if (cookie.CommentUrl != null)
|
||||
AppendSegment (header, NSHttpCookie.KeyCommentUrl.ToString (), cookie.CommentUrl.ToString());
|
||||
|
||||
if (cookie.Properties.ContainsKey (NSHttpCookie.KeyDiscard))
|
||||
AppendSegment (header, NSHttpCookie.KeyDiscard.ToString (), null);
|
||||
|
||||
if (cookie.ExpiresDate != null) {
|
||||
// Format according to RFC1123; 'r' uses invariant info (DateTimeFormatInfo.InvariantInfo)
|
||||
var dateStr = ((DateTime) cookie.ExpiresDate).ToUniversalTime ().ToString("r", CultureInfo.InvariantCulture);
|
||||
AppendSegment (header, NSHttpCookie.KeyExpires.ToString (), dateStr);
|
||||
}
|
||||
|
||||
if (cookie.Properties.ContainsKey (NSHttpCookie.KeyMaximumAge)) {
|
||||
var timeStampString = (NSString) cookie.Properties[NSHttpCookie.KeyMaximumAge];
|
||||
AppendSegment (header, NSHttpCookie.KeyMaximumAge.ToString (), timeStampString);
|
||||
}
|
||||
|
||||
if (cookie.IsSecure)
|
||||
AppendSegment (header, NSHttpCookie.KeySecure.ToString(), null);
|
||||
|
||||
if (cookie.IsHttpOnly)
|
||||
AppendSegment (header, "httponly", null); // Apple does not show the key for the httponly
|
||||
|
||||
return header.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class NSUrlSessionHandler : HttpMessageHandler
|
||||
{
|
||||
private const string SetCookie = "Set-Cookie";
|
||||
readonly Dictionary<string, string> headerSeparators = new Dictionary<string, string> {
|
||||
["User-Agent"] = " ",
|
||||
["Server"] = " "
|
||||
|
@ -265,11 +322,18 @@ namespace Foundation {
|
|||
foreach (var v in urlResponse.AllHeaderFields) {
|
||||
// NB: Cocoa trolling us so hard by giving us back dummy dictionary entries
|
||||
if (v.Key == null || v.Value == null) continue;
|
||||
// NSUrlSession tries to be smart with cookies, we will not use the raw value but the ones provided by the cookie storage
|
||||
if (v.Key.ToString () == SetCookie) continue;
|
||||
|
||||
httpResponse.Headers.TryAddWithoutValidation (v.Key.ToString (), v.Value.ToString ());
|
||||
httpResponse.Content.Headers.TryAddWithoutValidation (v.Key.ToString (), v.Value.ToString ());
|
||||
}
|
||||
|
||||
var cookies = session.Configuration.HttpCookieStorage.CookiesForUrl (response.Url);
|
||||
for (var index = 0; index < cookies.Length; index++) {
|
||||
httpResponse.Headers.TryAddWithoutValidation (SetCookie, cookies [index].GetHeaderValue ());
|
||||
}
|
||||
|
||||
inflight.Response = httpResponse;
|
||||
|
||||
// We don't want to send the response back to the task just yet. Because we want to mimic .NET behavior
|
||||
|
|
|
@ -91,7 +91,6 @@ $(IOS_BUILD_DIR)/AssemblyInfo.cs: $(TOP)/src/AssemblyInfo.cs.in
|
|||
$(IOS_BUILD_DIR)/native/core.dll: $(IOS_CORE_SOURCES) frameworks.sources
|
||||
$(Q) mkdir -p $(IOS_BUILD_DIR)native
|
||||
$(call Q_PROF_CSC,ios) $(IOS_CSC) -nologo -out:$@ -target:library -debug -unsafe \
|
||||
-r:$(IOS_LIBDIR)/Mono.Security.dll \
|
||||
-nowarn:219,618,114,414,1635,3021,$(IOS_WARNINGS_THAT_YOU_SHOULD_FIX) \
|
||||
-define:COREBUILD $(IOS_DEFINES) \
|
||||
$(IOS_native_DEFINES) \
|
||||
|
@ -126,7 +125,6 @@ $(IOS_BUILD_DIR)/native-$(1)%Xamarin.iOS.dll $(IOS_BUILD_DIR)/native-$(1)%Xamari
|
|||
@mkdir -p $(IOS_BUILD_DIR)/native-$(1)
|
||||
$$(call Q_PROF_CSC,ios/$(1) bit) $$(IOS_CSC) -nologo -out:$$@ -target:library -debug -unsafe -optimize \
|
||||
-deterministic \
|
||||
-r:$(IOS_LIBDIR)/Mono.Security.dll \
|
||||
$$(ARGS_$(1)) \
|
||||
-publicsign -keyfile:$(PRODUCT_KEY_PATH) $$(IOS_DEFINES) \
|
||||
$$(IOS_native_DEFINES) \
|
||||
|
@ -480,7 +478,6 @@ $(MAC_BUILD_DIR)/$(1)/$(2): $(MAC_BUILD_DIR)/$(3)/generated-sources $(MAC_SOURCE
|
|||
$$(MAC_$(3)_CSC) -nologo -out:$$@ -target:library -debug -unsafe \
|
||||
-deterministic \
|
||||
$$(MAC_COMMON_DEFINES),OBJECT_REF_TRACKING \
|
||||
-r:Mono.Security.dll \
|
||||
$$(MAC_$(3)_ARGS) \
|
||||
$$(ARGS_$(6)) \
|
||||
-publicsign -keyfile:$(SN_KEY) \
|
||||
|
@ -955,7 +952,6 @@ $(TVOS_BUILD_DIR)/tvos-64/Xamarin.TVOS%dll $(TVOS_BUILD_DIR)/tvos-64/Xamarin.TVO
|
|||
$(call Q_PROF_CSC,tvos) $(TV_CSC) -nologo -out:$(basename $@).dll -target:library -debug -unsafe -optimize \
|
||||
-publicsign -keyfile:$(PRODUCT_KEY_PATH) $(TVOS_DEFINES) \
|
||||
-deterministic \
|
||||
-r:$(TVOS_LIBDIR)/Mono.Security.dll \
|
||||
$(ARGS_64) \
|
||||
-nowarn:219,618,114,414,1635,3021,$(IOS_WARNINGS_THAT_YOU_SHOULD_FIX) \
|
||||
$(TVOS_SOURCES) @$(TVOS_BUILD_DIR)/tvos/generated_sources
|
||||
|
|
|
@ -22,12 +22,6 @@ using Registrar;
|
|||
using AppKit;
|
||||
#endif
|
||||
|
||||
#if !COREBUILD && (XAMARIN_APPLETLS || XAMARIN_NO_TLS)
|
||||
#if !MMP && !MTOUCH && !MTOUCH_TEST
|
||||
using Mono.Security.Interface;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ObjCRuntime {
|
||||
|
||||
public partial class Runtime {
|
||||
|
|
|
@ -20,12 +20,6 @@ using MonoTouch.Foundation;
|
|||
using MonoTouch.ObjCRuntime;
|
||||
#endif
|
||||
|
||||
#if !COREBUILD && (XAMARIN_APPLETLS || XAMARIN_NO_TLS)
|
||||
#if !MTOUCH && !MMP && !MMP_TEST
|
||||
using Mono.Security.Interface;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MMP || MMP_TEST || MTOUCH
|
||||
namespace Xamarin.Bundler {
|
||||
#elif SYSTEM_NET_HTTP
|
||||
|
|
|
@ -1151,7 +1151,8 @@ namespace AppKit {
|
|||
[Export ("setSelectedObjects:"), Protected]
|
||||
bool SetSelectedObjects (NSObject [] objects);
|
||||
}
|
||||
|
||||
|
||||
[ThreadSafe]
|
||||
[BaseType (typeof (NSObject))]
|
||||
interface NSBezierPath : NSSecureCoding, NSCopying {
|
||||
|
||||
|
@ -6184,6 +6185,7 @@ namespace AppKit {
|
|||
NSFontPanelModeMask GetValidModes (NSFontPanel fontPanel);
|
||||
}
|
||||
|
||||
[ThreadSafe]
|
||||
[BaseType (typeof (NSObject))]
|
||||
[DisableDefaultCtor] // crash at runtime (e.g. description). Documentation state: "You don’t create NSFont objects using the alloc and init methods."
|
||||
partial interface NSFont : NSSecureCoding, NSCopying {
|
||||
|
@ -9703,6 +9705,7 @@ namespace AppKit {
|
|||
CGRect TotalBounds { get; }
|
||||
}
|
||||
|
||||
[ThreadSafe]
|
||||
[Category, BaseType (typeof (NSString))]
|
||||
interface NSStringDrawing_NSString {
|
||||
[Export ("sizeWithAttributes:")]
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Mono.Security" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="build\mac\mobile\**\*.cs">
|
||||
|
|
|
@ -196,6 +196,8 @@ $(TOP)/tools/mtouch/SdkVersions.cs: $(TOP)/tools/common/SdkVersions.cs.in
|
|||
.stamp-build-mono-unit-tests: $(TOP)/.git/modules/external/mono/HEAD
|
||||
make -j8 -C $(TOP)/external/mono/mcs/class -i do-test PROFILE=MONOTOUCH # TODO: This should not be needed and we should get the dlls from the SDK.
|
||||
make -j8 -C $(TOP)/external/mono/mcs/class -i do-xunit-test PROFILE=MONOTOUCH # TODO: This should not be needed and we should get the dlls from the SDK.
|
||||
make -j8 -C $(TOP)/external/mono/mcs/class -i do-test PROFILE=xammac_net_4_5 # TODO: This should not be needed and we should get the dlls from the SDK.
|
||||
make -j8 -C $(TOP)/external/mono/mcs/class -i do-xunit-test PROFILE=xammac_net_4_5 # TODO: This should not be needed and we should get the dlls from the SDK.
|
||||
nuget restore bcl-test/BCLTests/BCLTests.csproj
|
||||
$(Q) touch $@
|
||||
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
<?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>{EEE20F63-4282-450A-8584-93F640929D13}</ProjectGuid>
|
||||
<ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>%NAME%</RootNamespace>
|
||||
<MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
|
||||
<AssemblyName>%NAME%</AssemblyName>
|
||||
<NoWarn>67,168,169,219,414,612,618,649,672</NoWarn>
|
||||
<TargetFrameworkVersion>%TARGET FRAMEWORK VERSION%</TargetFrameworkVersion>
|
||||
%TARGET EXTRA INFO%
|
||||
<DefineConstants>%DEFINE CONSTANTS%</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\AnyCPU\%NAME%\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;MONOMAC;NO_GUI_TESTING;$(DefineConstants)</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<EnablePackageSigning>false</EnablePackageSigning>
|
||||
<CodeSigningKey>Mac Developer</CodeSigningKey>
|
||||
<EnableCodeSigning>false</EnableCodeSigning>
|
||||
<CreatePackage>false</CreatePackage>
|
||||
<LinkMode>None</LinkMode>
|
||||
<XamMacArch>x86_64</XamMacArch>
|
||||
<I18n>cjk,mideast,other,rare,west</I18n>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\AnyCPU\%NAME%\Release</OutputPath>
|
||||
<DefineConstants>MONOMAC;NO_GUI_TESTING;$(DefineConstants)</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<LinkMode>None</LinkMode>
|
||||
<CreatePackage>false</CreatePackage>
|
||||
<CodeSigningKey>Mac Developer</CodeSigningKey>
|
||||
<EnableCodeSigning>false</EnableCodeSigning>
|
||||
<EnablePackageSigning>false</EnablePackageSigning>
|
||||
<I18n>cjk,mideast,other,rare,west</I18n>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Xamarin.Mac" />
|
||||
<Reference Include="xunit.core">
|
||||
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.assert">
|
||||
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.assert.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.abstractions">
|
||||
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.execution.dotnet">
|
||||
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.execution.dotnet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunitlite">
|
||||
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\nunitlite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xunit.NetCore.Extensions">
|
||||
<HintPath>..\..\..\external\mono\external\xunit-binaries\Xunit.NetCore.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers">
|
||||
<HintPath>..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
||||
<HintPath>..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory">
|
||||
<HintPath>..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Primitives">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Configuration">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Configuration.Binder">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Options">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.runner.utility.netstandard20">
|
||||
<HintPath>..\..\..\packages\xunit.runner.utility.2.4.0\lib\netstandard2.0\xunit.runner.utility.netstandard20.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization.Formatters.Soap">
|
||||
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Runtime.Serialization.Formatters.Soap.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Configuration">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Console">
|
||||
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Console.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Options">
|
||||
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\netstandard1.3\Mono.Options.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
%REFERENCES%
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="%PLIST PATH%">
|
||||
<LogicalName>Info.plist</LogicalName>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
|
||||
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\ClassOrNamespaceFilter.cs">
|
||||
<Link>TestRunner.NUnit\ClassOrNamespaceFilter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
|
||||
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\LogWriter.cs">
|
||||
<Link>TestRunner.Core\LogWriter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\MinimumLogLevel.cs">
|
||||
<Link>TestRunner.Core\MinimumLogLevel.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TcpTextWriter.cs">
|
||||
<Link>TestRunner.Core\TcpTextWriter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestAssemblyInfo.cs">
|
||||
<Link>TestRunner.Core\TestAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestCompletionStatus.cs">
|
||||
<Link>TestRunner.Core\TestCompletionStatus.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestExecutionState.cs">
|
||||
<Link>TestRunner.Core\TestExecutionState.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestFailureInfo.cs">
|
||||
<Link>TestRunner.Core\TestFailureInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
|
||||
<Link>TestRunner.Core\TestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelector.cs">
|
||||
<Link>TestRunner.Core\TestRunSelector.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelectorType.cs">
|
||||
<Link>TestRunner.Core\TestRunSelectorType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
|
||||
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilterType.cs">
|
||||
<Link>TestRunner.xUnit\XUnitFilterType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitResultFileFormat.cs">
|
||||
<Link>TestRunner.xUnit\XUnitResultFileFormat.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitTestRunner.cs">
|
||||
<Link>TestRunner.xUnit\XUnitTestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\ApplicationOptions.cs">
|
||||
<Link>ApplicationOptions.cs</Link>
|
||||
</Compile>
|
||||
%REGISTER TYPE%
|
||||
<Compile Include="templates\macOS\MacTestMain.cs">
|
||||
<Link>MacTestMain.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\macOS\Assert.cs">
|
||||
<Link>Assert.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="templates\common\TestRunner.xUnit\NUnitXml.xslt">
|
||||
<Link>TestRunner.xUnit\NUnitXml.xslt</Link>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
|
||||
<Import Project="..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" />
|
||||
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets')" />
|
||||
</Project>
|
|
@ -210,6 +210,9 @@
|
|||
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
|
||||
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\ClassOrNamespaceFilter.cs">
|
||||
<Link>TestRunner.NUnit\ClassOrNamespaceFilter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
|
||||
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
|
||||
</Compile>
|
||||
|
@ -237,6 +240,12 @@
|
|||
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
|
||||
<Link>TestRunner.Core\TestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelector.cs">
|
||||
<Link>TestRunner.Core\TestRunSelector.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelectorType.cs">
|
||||
<Link>TestRunner.Core\TestRunSelectorType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
|
||||
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -184,9 +184,18 @@
|
|||
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
|
||||
<Link>TestRunner.Core\TestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelector.cs">
|
||||
<Link>TestRunner.Core\TestRunSelector.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelectorType.cs">
|
||||
<Link>TestRunner.Core\TestRunSelectorType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
|
||||
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\ClassOrNamespaceFilter.cs">
|
||||
<Link>TestRunner.NUnit\ClassOrNamespaceFilter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
|
||||
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -222,6 +222,9 @@
|
|||
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
|
||||
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.NUnit\ClassOrNamespaceFilter.cs">
|
||||
<Link>TestRunner.NUnit\ClassOrNamespaceFilter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
|
||||
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
|
||||
</Compile>
|
||||
|
@ -249,6 +252,12 @@
|
|||
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
|
||||
<Link>TestRunner.Core\TestRunner.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelector.cs">
|
||||
<Link>TestRunner.Core\TestRunSelector.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.Core\TestRunSelectorType.cs">
|
||||
<Link>TestRunner.Core\TestRunSelectorType.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
|
||||
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>%APPLICATION NAME%</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>%BUNDLE INDENTIFIER%</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>systemtests</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.9</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>LSUIElement</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -26,6 +26,7 @@ namespace BCLTests {
|
|||
Transport = defaults.StringForKey ("network.transport");
|
||||
SortNames = defaults.BoolForKey ("display.sort");
|
||||
LogFile = defaults.StringForKey ("log.file");
|
||||
ResultFile = defaults.StringForKey ("result.file");
|
||||
|
||||
bool b;
|
||||
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_AUTOEXIT"), out b))
|
||||
|
@ -61,6 +62,7 @@ namespace BCLTests {
|
|||
{ "enablexml", "Enable the xml reported.", v => EnableXml = false },
|
||||
{ "xmlmode", "The xml mode.", v => XmlMode = (XmlMode) Enum.Parse (typeof (XmlMode), v, false) },
|
||||
{ "logfile=", "A path where output will be saved.", v => LogFile = v },
|
||||
{ "result=", "The path to be used to store the result", v => ResultFile = v},
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -87,6 +89,8 @@ namespace BCLTests {
|
|||
public string Transport { get; set; } = "TCP";
|
||||
|
||||
public string LogFile { get; set; }
|
||||
|
||||
public string ResultFile { get; set; }
|
||||
|
||||
public bool ShowUseNetworkLogger {
|
||||
get { return (EnableNetwork && !String.IsNullOrWhiteSpace (HostName) && (HostPort > 0 || Transport == "FILE")); }
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Foundation;
|
||||
#if !MONOMAC
|
||||
using UIKit;
|
||||
#endif
|
||||
using ObjCRuntime;
|
||||
using Constants = global::ObjCRuntime.Constants;
|
||||
|
||||
|
@ -26,7 +28,7 @@ namespace Xamarin.iOS.UnitTests
|
|||
|
||||
static string UniqueIdentifier {
|
||||
get {
|
||||
#if !__WATCHOS__
|
||||
#if !__WATCHOS__ && !MONOMAC
|
||||
IntPtr handle = UIDevice.CurrentDevice.Handle;
|
||||
if (UIDevice.CurrentDevice.RespondsToSelector (new Selector ("uniqueIdentifier")))
|
||||
return NSString.FromHandle (objc_msgSend (handle, Selector.GetHandle("uniqueIdentifier")));
|
||||
|
@ -37,7 +39,7 @@ namespace Xamarin.iOS.UnitTests
|
|||
|
||||
public void InitLogging ()
|
||||
{
|
||||
#if !__WATCHOS__
|
||||
#if !__WATCHOS__ && !MONOMAC
|
||||
UIDevice device = UIDevice.CurrentDevice;
|
||||
#endif
|
||||
|
||||
|
@ -45,7 +47,7 @@ namespace Xamarin.iOS.UnitTests
|
|||
writer.WriteLine ("[Runner executing:\t{0}]", "Run everything");
|
||||
writer.WriteLine ("[MonoTouch Version:\t{0}]", Constants.Version);
|
||||
writer.WriteLine ("[Assembly:\t{0}.dll ({1} bits)]", typeof (NSObject).Assembly.GetName ().Name, IntPtr.Size * 8);
|
||||
#if !__WATCHOS__
|
||||
#if !__WATCHOS__ && !MONOMAC
|
||||
writer.WriteLine ("[{0}:\t{1} v{2}]", device.Model, device.SystemName, device.SystemVersion);
|
||||
writer.WriteLine ("[Device Name:\t{0}]", device.Name);
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,9 @@ using System.IO;
|
|||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
#if __IOS__
|
||||
using UIKit;
|
||||
#endif
|
||||
|
||||
namespace BCLTests.TestRunner.Core {
|
||||
public class TcpTextWriter : TextWriter {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.iOS.UnitTests
|
||||
{
|
||||
public class TestRunSelector
|
||||
{
|
||||
public string Assembly { get; set; }
|
||||
public string Value { get; set; }
|
||||
public TestRunSelectorType Type { get; set; }
|
||||
public bool Include { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.iOS.UnitTests
|
||||
{
|
||||
public enum TestRunSelectorType
|
||||
{
|
||||
Assembly,
|
||||
Namespace,
|
||||
Class,
|
||||
Single,
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ namespace Xamarin.iOS.UnitTests
|
|||
public long FilteredTests { get; protected set; } = 0;
|
||||
public bool RunInParallel { get; set; } = false;
|
||||
public string TestsRootDirectory { get; set; }
|
||||
public bool RunAllTestsByDefault { get; set; } = true;
|
||||
public bool LogExcludedTests { get; set; }
|
||||
public TextWriter Writer { get; set; }
|
||||
public List<TestFailureInfo> FailureInfos { get; } = new List<TestFailureInfo> ();
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using NUnit.Framework.Api;
|
||||
using NUnit.Framework.Internal;
|
||||
using NUnit.Framework.Internal.Filters;
|
||||
|
||||
namespace Xamarin.iOS.UnitTests.NUnit
|
||||
{
|
||||
public class ClassOrNamespaceFilter : TestFilter
|
||||
{
|
||||
bool isClassFilter;
|
||||
List <string> names;
|
||||
|
||||
public ClassOrNamespaceFilter (string name, bool isClassFilter)
|
||||
{
|
||||
AddName (name);
|
||||
this.isClassFilter = isClassFilter;
|
||||
}
|
||||
|
||||
public ClassOrNamespaceFilter (IEnumerable<string> names, bool isClassFilter)
|
||||
{
|
||||
if (names == null)
|
||||
throw new ArgumentNullException (nameof (names));
|
||||
|
||||
this.isClassFilter = isClassFilter;
|
||||
foreach (string n in names) {
|
||||
string name = n?.Trim ();
|
||||
if (String.IsNullOrEmpty (name))
|
||||
continue;
|
||||
|
||||
AddName (name);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddName (string name)
|
||||
{
|
||||
if (String.IsNullOrEmpty (name))
|
||||
throw new ArgumentException ("must not be null or empty", nameof (name));
|
||||
|
||||
if (names == null)
|
||||
names = new List <string> ();
|
||||
if (names.Contains (name))
|
||||
return;
|
||||
|
||||
names.Add (name);
|
||||
}
|
||||
|
||||
public override bool Match (ITest test)
|
||||
{
|
||||
if (test == null || names == null || names.Count == 0)
|
||||
return false;
|
||||
|
||||
if (test.FixtureType == null)
|
||||
return false; // It's probably an assembly name, all tests will have a fixture
|
||||
|
||||
if (isClassFilter)
|
||||
return NameMatches (test.FixtureType.FullName);
|
||||
|
||||
int dot = test.FixtureType.FullName.LastIndexOf ('.');
|
||||
if (dot < 1)
|
||||
return false;
|
||||
|
||||
return NameMatches (test.FixtureType.FullName.Substring (0, dot));
|
||||
}
|
||||
|
||||
bool NameMatches (string name)
|
||||
{
|
||||
foreach (string n in names) {
|
||||
if (n == null)
|
||||
continue;
|
||||
if (String.Compare (name, n, StringComparison.Ordinal) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
|
@ -21,9 +22,11 @@ namespace Xamarin.iOS.UnitTests.NUnit
|
|||
{
|
||||
Dictionary<string, object> builderSettings;
|
||||
TestSuiteResult results;
|
||||
bool runAssemblyByDefault;
|
||||
|
||||
public ITestFilter Filter { get; set; } = TestFilter.Empty;
|
||||
public bool GCAfterEachFixture { get; set; }
|
||||
public Dictionary<string, bool> AssemblyFilters { get; set; }
|
||||
|
||||
protected override string ResultsFileName { get; set; } = "TestResults.NUnit.xml";
|
||||
|
||||
|
@ -36,23 +39,31 @@ namespace Xamarin.iOS.UnitTests.NUnit
|
|||
{
|
||||
if (testAssemblies == null)
|
||||
throw new ArgumentNullException (nameof (testAssemblies));
|
||||
|
||||
|
||||
if (AssemblyFilters == null || AssemblyFilters.Count == 0)
|
||||
runAssemblyByDefault = true;
|
||||
else
|
||||
runAssemblyByDefault = AssemblyFilters.Values.Any (v => !v);
|
||||
|
||||
var builder = new NUnitLiteTestAssemblyBuilder ();
|
||||
var runner = new NUnitLiteTestAssemblyRunner (builder, new FinallyDelegate ());
|
||||
var testSuite = new TestSuite (NSBundle.MainBundle.BundleIdentifier);
|
||||
results = new TestSuiteResult (testSuite);
|
||||
|
||||
TotalTests = 0;
|
||||
foreach (TestAssemblyInfo assemblyInfo in testAssemblies) {
|
||||
if (assemblyInfo == null || assemblyInfo.Assembly == null)
|
||||
if (assemblyInfo == null || assemblyInfo.Assembly == null || !ShouldRunAssembly (assemblyInfo))
|
||||
continue;
|
||||
|
||||
|
||||
if (!runner.Load (assemblyInfo.Assembly, builderSettings)) {
|
||||
OnWarning ($"Failed to load tests from assembly '{assemblyInfo.Assembly}");
|
||||
continue;
|
||||
}
|
||||
if (runner.LoadedTest is NUnitTest tests)
|
||||
if (runner.LoadedTest is NUnitTest tests) {
|
||||
TotalTests += tests.TestCaseCount;
|
||||
testSuite.Add (tests);
|
||||
|
||||
}
|
||||
|
||||
// Messy API. .Run returns ITestResult which is, in reality, an instance of TestResult since that's
|
||||
// what WorkItem returns and we need an instance of TestResult to add it to TestSuiteResult. So, cast
|
||||
// the return to TestResult and hope for the best.
|
||||
|
@ -73,9 +84,45 @@ namespace Xamarin.iOS.UnitTests.NUnit
|
|||
results.AddResult (testResult);
|
||||
}
|
||||
|
||||
// NUnitLite doesn't report filtered tests at all, but we can calculate here
|
||||
FilteredTests = TotalTests - ExecutedTests;
|
||||
LogFailureSummary ();
|
||||
}
|
||||
|
||||
bool ShouldRunAssembly (TestAssemblyInfo assemblyInfo)
|
||||
{
|
||||
if (assemblyInfo == null)
|
||||
return false;
|
||||
|
||||
if (AssemblyFilters == null || AssemblyFilters.Count == 0)
|
||||
return true;
|
||||
|
||||
bool include;
|
||||
if (AssemblyFilters.TryGetValue (assemblyInfo.FullPath, out include))
|
||||
return ReportFilteredAssembly (assemblyInfo, include);
|
||||
|
||||
string fileName = Path.GetFileName (assemblyInfo.FullPath);
|
||||
if (AssemblyFilters.TryGetValue (fileName, out include))
|
||||
return ReportFilteredAssembly (assemblyInfo, include);
|
||||
|
||||
fileName = Path.GetFileNameWithoutExtension (assemblyInfo.FullPath);
|
||||
if (AssemblyFilters.TryGetValue (fileName, out include))
|
||||
return ReportFilteredAssembly (assemblyInfo, include);
|
||||
|
||||
return runAssemblyByDefault;
|
||||
}
|
||||
|
||||
bool ReportFilteredAssembly (TestAssemblyInfo assemblyInfo, bool include)
|
||||
{
|
||||
if (LogExcludedTests) {
|
||||
const string included = "Included";
|
||||
const string excluded = "Excluded";
|
||||
|
||||
OnInfo ($"[FILTER] {(include ? included : excluded)} assembly: {assemblyInfo.FullPath}");
|
||||
}
|
||||
return include;
|
||||
}
|
||||
|
||||
public bool Pass (ITest test)
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -1,28 +1,128 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.iOS.UnitTests.XUnit
|
||||
{
|
||||
public class XUnitFilter
|
||||
{
|
||||
public string TraitName { get; }
|
||||
public string TraitValue { get; }
|
||||
public string TestCaseName { get; }
|
||||
public bool Exclude { get; }
|
||||
public XUnitFilterType FilterType { get; }
|
||||
public string AssemblyName { get; private set; }
|
||||
public string SelectorName { get; private set; }
|
||||
public string SelectorValue { get; private set; }
|
||||
|
||||
public XUnitFilter (string testCaseName, bool exclude)
|
||||
public bool Exclude { get; private set; }
|
||||
public XUnitFilterType FilterType { get; private set; }
|
||||
|
||||
public static XUnitFilter CreateSingleFilter (string singleTestName, bool exclude, string assemblyName = null)
|
||||
{
|
||||
FilterType = XUnitFilterType.TypeName;
|
||||
TestCaseName = testCaseName;
|
||||
Exclude = exclude;
|
||||
if (String.IsNullOrEmpty (singleTestName))
|
||||
throw new ArgumentException("must not be null or empty", nameof (singleTestName));
|
||||
|
||||
return new XUnitFilter {
|
||||
AssemblyName = assemblyName,
|
||||
SelectorValue = singleTestName,
|
||||
FilterType = XUnitFilterType.Single,
|
||||
Exclude = exclude
|
||||
};
|
||||
}
|
||||
|
||||
public XUnitFilter (string traitName, string traitValue, bool exclude)
|
||||
public static XUnitFilter CreateAssemblyFilter (string assemblyName, bool exclude)
|
||||
{
|
||||
FilterType = XUnitFilterType.Trait;
|
||||
TraitName = traitName;
|
||||
TraitValue = traitValue;
|
||||
Exclude = exclude;
|
||||
if (String.IsNullOrEmpty (assemblyName))
|
||||
throw new ArgumentException("must not be null or empty", nameof (assemblyName));
|
||||
|
||||
return new XUnitFilter {
|
||||
AssemblyName = assemblyName,
|
||||
FilterType = XUnitFilterType.Assembly,
|
||||
Exclude = exclude
|
||||
};
|
||||
}
|
||||
|
||||
public static XUnitFilter CreateNamespaceFilter (string namespaceName, bool exclude, string assemblyName = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty (namespaceName))
|
||||
throw new ArgumentException("must not be null or empty", nameof (namespaceName));
|
||||
|
||||
return new XUnitFilter {
|
||||
AssemblyName = assemblyName,
|
||||
SelectorValue = namespaceName,
|
||||
FilterType = XUnitFilterType.Namespace,
|
||||
Exclude = exclude
|
||||
};
|
||||
}
|
||||
|
||||
public static XUnitFilter CreateClassFilter (string className, bool exclude, string assemblyName = null)
|
||||
{
|
||||
if (String.IsNullOrEmpty (className))
|
||||
throw new ArgumentException("must not be null or empty", nameof (className));
|
||||
|
||||
return new XUnitFilter {
|
||||
AssemblyName = assemblyName,
|
||||
SelectorValue = className,
|
||||
FilterType = XUnitFilterType.TypeName,
|
||||
Exclude = exclude
|
||||
};
|
||||
}
|
||||
|
||||
public static XUnitFilter CreateTraitFilter (string traitName, string traitValue, bool exclude)
|
||||
{
|
||||
if (String.IsNullOrEmpty (traitName))
|
||||
throw new ArgumentException("must not be null or empty", nameof (traitName));
|
||||
|
||||
return new XUnitFilter {
|
||||
AssemblyName = null,
|
||||
SelectorName = traitName,
|
||||
SelectorValue = traitValue ?? String.Empty,
|
||||
FilterType = XUnitFilterType.Trait,
|
||||
Exclude = exclude
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
var sb = new StringBuilder ("XUnitFilter [");
|
||||
|
||||
sb.Append ($"Type: {FilterType}; ");
|
||||
sb.Append (Exclude ? "exclude" : "include");
|
||||
|
||||
if (!String.IsNullOrEmpty (AssemblyName))
|
||||
sb.Append ($"; AssemblyName: {AssemblyName}");
|
||||
|
||||
switch (FilterType) {
|
||||
case XUnitFilterType.Assembly:
|
||||
break;
|
||||
|
||||
case XUnitFilterType.Namespace:
|
||||
AppendDesc ("Namespace", SelectorValue);
|
||||
break;
|
||||
|
||||
case XUnitFilterType.Single:
|
||||
AppendDesc ("Method", SelectorValue);
|
||||
break;
|
||||
|
||||
case XUnitFilterType.Trait:
|
||||
AppendDesc ("Trait name", SelectorName);
|
||||
AppendDesc ("Trait value", SelectorValue);
|
||||
break;
|
||||
|
||||
case XUnitFilterType.TypeName:
|
||||
AppendDesc ("Class", SelectorValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
sb.Append ("; Unknown filter type");
|
||||
break;
|
||||
}
|
||||
sb.Append (']');
|
||||
|
||||
return sb.ToString ();
|
||||
|
||||
void AppendDesc (string name, string value)
|
||||
{
|
||||
if (String.IsNullOrEmpty (value))
|
||||
return;
|
||||
|
||||
sb.Append ($"; {name}: {value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace Xamarin.iOS.UnitTests.XUnit
|
||||
{
|
||||
|
@ -6,5 +6,8 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
{
|
||||
Trait,
|
||||
TypeName,
|
||||
Assembly,
|
||||
Single,
|
||||
Namespace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
|
||||
XElement assembliesElement;
|
||||
List<XUnitFilter> filters;
|
||||
bool runAssemblyByDefault;
|
||||
|
||||
public XUnitResultFileFormat ResultFileFormat { get; set; } = XUnitResultFileFormat.NUnit;
|
||||
public AppDomainSupport AppDomainSupport { get; set; } = AppDomainSupport.Denied;
|
||||
|
@ -677,9 +678,23 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
if (testAssemblies == null)
|
||||
throw new ArgumentNullException (nameof (testAssemblies));
|
||||
|
||||
if (filters != null && filters.Count > 0) {
|
||||
do_log ("Configured filters:");
|
||||
foreach (XUnitFilter filter in filters) {
|
||||
do_log ($" {filter}");
|
||||
}
|
||||
}
|
||||
|
||||
List<XUnitFilter> assemblyFilters = filters?.Where (sel => sel != null && sel.FilterType == XUnitFilterType.Assembly)?.ToList ();
|
||||
if (assemblyFilters == null || assemblyFilters.Count == 0) {
|
||||
runAssemblyByDefault = true;
|
||||
assemblyFilters = null;
|
||||
} else
|
||||
runAssemblyByDefault = assemblyFilters.Any (f => f != null && f.Exclude);
|
||||
|
||||
assembliesElement = new XElement ("assemblies");
|
||||
foreach (TestAssemblyInfo assemblyInfo in testAssemblies) {
|
||||
if (assemblyInfo == null || assemblyInfo.Assembly == null)
|
||||
if (assemblyInfo == null || assemblyInfo.Assembly == null || !ShouldRunAssembly (assemblyInfo))
|
||||
continue;
|
||||
|
||||
if (String.IsNullOrEmpty (assemblyInfo.FullPath)) {
|
||||
|
@ -692,6 +707,9 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
try {
|
||||
OnAssemblyStart (assemblyInfo.Assembly);
|
||||
assemblyElement = Run (assemblyInfo.Assembly, assemblyInfo.FullPath);
|
||||
} catch (FileNotFoundException ex) {
|
||||
OnWarning ($"Assembly '{assemblyInfo.Assembly}' using path '{assemblyInfo.FullPath}' cannot be found on the filesystem. xUnit requires access to actual on-disk file.");
|
||||
OnWarning ($"Exception is '{ex}'");
|
||||
} finally {
|
||||
OnAssemblyFinish (assemblyInfo.Assembly);
|
||||
if (assemblyElement != null)
|
||||
|
@ -700,6 +718,50 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
}
|
||||
|
||||
LogFailureSummary ();
|
||||
|
||||
bool ShouldRunAssembly (TestAssemblyInfo assemblyInfo)
|
||||
{
|
||||
if (assemblyInfo == null)
|
||||
return false;
|
||||
|
||||
if (assemblyFilters == null)
|
||||
return true;
|
||||
|
||||
foreach (XUnitFilter filter in assemblyFilters) {
|
||||
if (String.Compare (filter.AssemblyName, assemblyInfo.FullPath, StringComparison.Ordinal) == 0)
|
||||
return ReportFilteredAssembly (assemblyInfo, filter);
|
||||
|
||||
string fileName = Path.GetFileName (assemblyInfo.FullPath);
|
||||
if (String.Compare (fileName, filter.AssemblyName, StringComparison.Ordinal) == 0)
|
||||
return ReportFilteredAssembly (assemblyInfo, filter);
|
||||
|
||||
string filterExtension = Path.GetExtension (filter.AssemblyName);
|
||||
if (String.IsNullOrEmpty (filterExtension) ||
|
||||
(String.Compare (filterExtension, ".exe", StringComparison.OrdinalIgnoreCase) != 0 &&
|
||||
String.Compare (filterExtension, ".dll", StringComparison.OrdinalIgnoreCase) != 0)) {
|
||||
string asmName = $"{filter.AssemblyName}.dll";
|
||||
if (String.Compare (asmName, fileName, StringComparison.Ordinal) == 0)
|
||||
return ReportFilteredAssembly (assemblyInfo, filter);
|
||||
|
||||
asmName = $"{filter.AssemblyName}.exe";
|
||||
if (String.Compare (asmName, fileName, StringComparison.Ordinal) == 0)
|
||||
return ReportFilteredAssembly (assemblyInfo, filter);
|
||||
}
|
||||
}
|
||||
|
||||
return runAssemblyByDefault;
|
||||
}
|
||||
|
||||
bool ReportFilteredAssembly (TestAssemblyInfo assemblyInfo, XUnitFilter filter)
|
||||
{
|
||||
if (LogExcludedTests) {
|
||||
const string included = "Included";
|
||||
const string excluded = "Excluded";
|
||||
|
||||
OnInfo ($"[FILTER] {(filter.Exclude ? excluded : included)} assembly: {assemblyInfo.FullPath}");
|
||||
}
|
||||
return !filter.Exclude;
|
||||
}
|
||||
}
|
||||
|
||||
public override string WriteResultsToFile ()
|
||||
|
@ -860,42 +922,88 @@ namespace Xamarin.iOS.UnitTests.XUnit
|
|||
|
||||
bool IsIncluded (ITestCase testCase)
|
||||
{
|
||||
if (testCase.Traits == null || testCase.Traits.Count == 0)
|
||||
return true;
|
||||
|
||||
if (testCase == null)
|
||||
return false;
|
||||
|
||||
bool haveTraits = testCase.Traits != null && testCase.Traits.Count > 0;
|
||||
foreach (XUnitFilter filter in filters) {
|
||||
List<string> values;
|
||||
if (filter == null)
|
||||
continue;
|
||||
|
||||
if (filter.FilterType == XUnitFilterType.Trait) {
|
||||
if (!testCase.Traits.TryGetValue (filter.TraitName, out values))
|
||||
if (!haveTraits || !testCase.Traits.TryGetValue (filter.SelectorName, out values))
|
||||
continue;
|
||||
|
||||
if (values == null || values.Count == 0) {
|
||||
// We have no values and the filter doesn't specify one - that means we match on
|
||||
// the trait name only.
|
||||
if (String.IsNullOrEmpty (filter.TraitValue))
|
||||
return !filter.Exclude;
|
||||
if (String.IsNullOrEmpty (filter.SelectorValue))
|
||||
return ReportFilteredTest (filter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (values.Contains (filter.TraitValue, StringComparer.OrdinalIgnoreCase))
|
||||
return !filter.Exclude;
|
||||
if (values.Contains (filter.SelectorValue, StringComparer.OrdinalIgnoreCase))
|
||||
return ReportFilteredTest (filter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter.FilterType == XUnitFilterType.TypeName) {
|
||||
Logger.Info ($"IsIncluded: filter: '{filter.TestCaseName}', test case name: {testCase.DisplayName}");
|
||||
if (String.Compare (testCase.DisplayName, filter.TestCaseName, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return !filter.Exclude;
|
||||
string testClassName = testCase.TestMethod?.TestClass?.Class?.Name?.Trim ();
|
||||
if (String.IsNullOrEmpty (testClassName))
|
||||
continue;
|
||||
|
||||
if (String.Compare (testClassName, filter.SelectorValue, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return ReportFilteredTest (filter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter.FilterType == XUnitFilterType.Single) {
|
||||
if (String.Compare (testCase.DisplayName, filter.SelectorValue, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return ReportFilteredTest (filter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter.FilterType == XUnitFilterType.Namespace) {
|
||||
string testClassName = testCase.TestMethod?.TestClass?.Class?.Name?.Trim ();
|
||||
if (String.IsNullOrEmpty (testClassName))
|
||||
continue;
|
||||
|
||||
int dot = testClassName.LastIndexOf ('.');
|
||||
if (dot <= 0)
|
||||
continue;
|
||||
|
||||
string testClassNamespace = testClassName.Substring (0, dot);
|
||||
if (String.Compare (testClassNamespace, filter.SelectorValue, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return ReportFilteredTest (filter);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter.FilterType == XUnitFilterType.Assembly) {
|
||||
continue; // Ignored: handled elsewhere
|
||||
}
|
||||
|
||||
throw new InvalidOperationException ($"Unsupported filter type {filter.FilterType}");
|
||||
}
|
||||
|
||||
return true;
|
||||
return RunAllTestsByDefault;
|
||||
|
||||
bool ReportFilteredTest (XUnitFilter filter)
|
||||
{
|
||||
if (LogExcludedTests) {
|
||||
const string included = "Included";
|
||||
const string excluded = "Excluded";
|
||||
|
||||
string selector;
|
||||
if (filter.FilterType == XUnitFilterType.Trait)
|
||||
selector = $"'{filter.SelectorName}':'{filter.SelectorValue}'";
|
||||
else
|
||||
selector = $"'{filter.SelectorValue}'";
|
||||
|
||||
do_log ($"[FILTER] {(filter.Exclude ? excluded : included)} test (filtered by {filter.FilterType}; {selector}): {testCase.DisplayName}");
|
||||
}
|
||||
return !filter.Exclude;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,12 @@ namespace BCLTests {
|
|||
{
|
||||
// var t = Path.GetFileName (typeof (ActivatorCas).Assembly.Location);
|
||||
foreach (var name in RegisterType.TypesToRegister.Keys) {
|
||||
var a = Assembly.Load (name);
|
||||
var a = RegisterType.TypesToRegister [name].Assembly;
|
||||
if (a == null) {
|
||||
Console.WriteLine ($"# WARNING: Unable to load assembly {name}.");
|
||||
continue;
|
||||
} else {
|
||||
Console.WriteLine ($"Loading assembly: {name}.");
|
||||
}
|
||||
yield return new TestAssemblyInfo (a, name);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
#if XAMCORE_2_0
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
#else
|
||||
using MonoTouch.Foundation;
|
||||
using MonoTouch.ObjCRuntime;
|
||||
#endif
|
||||
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Constraints;
|
||||
|
||||
namespace MonoTests {
|
||||
/*
|
||||
class CategoryAttribute : Attribute
|
||||
{
|
||||
public string Category { get; set; }
|
||||
|
||||
public CategoryAttribute (string category)
|
||||
{
|
||||
this.Category = category;
|
||||
}
|
||||
}
|
||||
/*
|
||||
static class Assert
|
||||
{
|
||||
public static void AreEqual (object a, object b, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.EqualTo (b), msg);
|
||||
}
|
||||
|
||||
public static void AreEqual (object a, object b)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.EqualTo (b));
|
||||
}
|
||||
|
||||
public static void IsNotNull (object o, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.Not.Null, msg);
|
||||
}
|
||||
|
||||
public static void IsNotNull (object o)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.Not.Null);
|
||||
}
|
||||
|
||||
public static void IsNull (object o, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.Null, msg);
|
||||
}
|
||||
|
||||
public static void IsNull (object o)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.Null);
|
||||
}
|
||||
|
||||
public static void IsTrue (object o, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.True, msg);
|
||||
}
|
||||
|
||||
public static void IsTrue (object o)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.True);
|
||||
}
|
||||
|
||||
public static void IsFalse (object o, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.False, msg);
|
||||
}
|
||||
|
||||
public static void IsFalse (object o)
|
||||
{
|
||||
NUnit.Framework.Assert.That (o, Is.False);
|
||||
}
|
||||
|
||||
public static void AreSame (object a, object b)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.SameAs (b));
|
||||
}
|
||||
|
||||
public static void AreSame (object a, object b, string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.SameAs (b), msg);
|
||||
}
|
||||
|
||||
public static void Fail (string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.Fail (msg);
|
||||
}
|
||||
}
|
||||
*/
|
||||
// nunit 1.x compatibility
|
||||
public class TestCase {
|
||||
protected virtual void SetUp ()
|
||||
{
|
||||
}
|
||||
|
||||
public static void Assert (string msg, bool condition)
|
||||
{
|
||||
NUnit.Framework.Assert.True (condition, msg);
|
||||
}
|
||||
|
||||
public static void AssertEquals (object a, object b)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.EqualTo (b));
|
||||
}
|
||||
|
||||
public static void AssertEquals (string msg, object a, object b)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.EqualTo (b), msg);
|
||||
}
|
||||
|
||||
public static void AssertNull (object a)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.Null);
|
||||
}
|
||||
|
||||
public static void AssertNull (string msg, object a)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.Null, msg);
|
||||
}
|
||||
|
||||
public static void AssertNotNull (object a)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.Not.Null);
|
||||
}
|
||||
|
||||
public static void AssertNotNull (string msg, object a)
|
||||
{
|
||||
NUnit.Framework.Assert.That (a, Is.Not.Null, msg);
|
||||
}
|
||||
|
||||
public static void Fail (string msg)
|
||||
{
|
||||
NUnit.Framework.Assert.Fail (msg);
|
||||
}
|
||||
}
|
||||
|
||||
public class Assertion : TestCase {
|
||||
}
|
||||
|
||||
public class TestFixtureSetUpAttribute : SetUpAttribute {
|
||||
}
|
||||
|
||||
public class StringAssert {
|
||||
#region StartsWith
|
||||
static public void StartsWith(string expected, string actual, string message, params object[] args)
|
||||
{
|
||||
Assert.That(actual, new StartsWithConstraint(expected), message, args);
|
||||
}
|
||||
|
||||
static public void StartsWith(string expected, string actual, string message)
|
||||
{
|
||||
StartsWith(expected, actual, message, null);
|
||||
}
|
||||
|
||||
static public void StartsWith(string expected, string actual)
|
||||
{
|
||||
StartsWith(expected, actual, string.Empty, null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Contains
|
||||
static public void Contains(string expected, string actual, string message, params object[] args)
|
||||
{
|
||||
Assert.That(actual, new SubstringConstraint(expected), message, args);
|
||||
}
|
||||
|
||||
static public void Contains(string expected, string actual, string message)
|
||||
{
|
||||
Contains(expected, actual, message, null);
|
||||
}
|
||||
|
||||
static public void Contains(string expected, string actual)
|
||||
{
|
||||
Contains(expected, actual, string.Empty, null);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
#if XAMCORE_2_0 || __UNIFIED__
|
||||
using AppKit;
|
||||
using Foundation;
|
||||
#else
|
||||
using MonoMac.AppKit;
|
||||
using MonoMac.Foundation;
|
||||
#endif
|
||||
using BCLTests;
|
||||
using Xamarin.iOS.UnitTests;
|
||||
using Xamarin.iOS.UnitTests.NUnit;
|
||||
using BCLTests.TestRunner.Core;
|
||||
using Xamarin.iOS.UnitTests.XUnit;
|
||||
using System.IO;
|
||||
|
||||
namespace Xamarin.Mac.Tests
|
||||
{
|
||||
static class MainClass
|
||||
{
|
||||
static int Main (string[] args)
|
||||
{
|
||||
NSApplication.Init();
|
||||
return RunTests (args);
|
||||
}
|
||||
|
||||
internal static IEnumerable<TestAssemblyInfo> GetTestAssemblies ()
|
||||
{
|
||||
// var t = Path.GetFileName (typeof (ActivatorCas).Assembly.Location);
|
||||
foreach (var name in RegisterType.TypesToRegister.Keys) {
|
||||
var a = RegisterType.TypesToRegister [name].Assembly;
|
||||
yield return new TestAssemblyInfo (a, name);
|
||||
}
|
||||
}
|
||||
|
||||
static int RunTests (string [] original_args)
|
||||
{
|
||||
Console.WriteLine ("Running tests");
|
||||
var options = ApplicationOptions.Current;
|
||||
|
||||
// we generate the logs in two different ways depending if the generate xml flag was
|
||||
// provided. If it was, we will write the xml file to the tcp writer if present, else
|
||||
// we will write the normal console output using the LogWriter
|
||||
var logger = new LogWriter (Console.Out);
|
||||
logger.MinimumLogLevel = MinimumLogLevel.Info;
|
||||
var testAssemblies = GetTestAssemblies ();
|
||||
TestRunner runner;
|
||||
if (RegisterType.IsXUnit)
|
||||
runner = new XUnitTestRunner (logger);
|
||||
else
|
||||
runner = new NUnitTestRunner (logger);
|
||||
|
||||
runner.Run (testAssemblies.ToList ());
|
||||
|
||||
using (var writer = new StreamWriter(options.ResultFile)) {
|
||||
runner.WriteResultsToFile (writer);
|
||||
}
|
||||
logger.Info ($"Xml result can be found {options.ResultFile}");
|
||||
|
||||
logger.Info ($"Tests run: {runner.TotalTests} Passed: {runner.PassedTests} Inconclusive: {runner.InconclusiveTests} Failed: {runner.FailedTests} Ignored: {runner.SkippedTests}");
|
||||
return runner.FailedTests != 0 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -159,6 +159,7 @@ namespace Xamarin.MMP.Tests
|
|||
// Binding project specific
|
||||
public string APIDefinitionConfig { get; set; }
|
||||
public string StructsAndEnumsConfig { get; set; }
|
||||
public string LinkWithName { get; set; } = null; // Only generates if non-null
|
||||
|
||||
// Unified Executable Specific
|
||||
public bool AssetIcons { get; set; }
|
||||
|
@ -204,21 +205,28 @@ namespace Xamarin.MMP.Tests
|
|||
{
|
||||
StringBuilder output = new StringBuilder ();
|
||||
Environment.SetEnvironmentVariable ("MONO_PATH", null);
|
||||
int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args != null ? args.ToString() : string.Empty, environment, output, suppressPrintOnErrors: shouldFail);
|
||||
int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args != null ? args.ToString () : string.Empty, environment, output, suppressPrintOnErrors: shouldFail);
|
||||
if (!shouldFail && compileResult != 0 && Xamarin.Bundler.Driver.Verbosity < 1) {
|
||||
// Driver.RunCommand won't print failed output unless verbosity > 0, so let's do it ourselves.
|
||||
Console.WriteLine ($"Execution failed; exit code: {compileResult}");
|
||||
Console.WriteLine (output);
|
||||
}
|
||||
Func<string> getInfo = () => getAdditionalFailInfo != null ? getAdditionalFailInfo() : "";
|
||||
if (!shouldFail)
|
||||
Assert.AreEqual (0, compileResult, stepName + " failed:\n\n'" + output + "' " + exe + " " + args + getInfo ());
|
||||
else
|
||||
Assert.AreNotEqual (0, compileResult, stepName + " did not fail as expected:\n\n'" + output + "' " + exe + " " + args + getInfo ());
|
||||
|
||||
Func<string> getInfo = () => getAdditionalFailInfo != null ? getAdditionalFailInfo () : "";
|
||||
bool passed = shouldFail ? compileResult != 0 : compileResult == 0;
|
||||
if (!passed) {
|
||||
string outputLine = PrintRedirectIfLong ($"{exe}{args} Output: {output} {getInfo ()}");
|
||||
Assert.Fail ($@"{stepName} {(shouldFail ? "passed" : "failed")} unexpectedly: {outputLine}");
|
||||
}
|
||||
return output.ToString ();
|
||||
}
|
||||
|
||||
public static string PrintRedirectIfLong (string outputLine)
|
||||
{
|
||||
if (outputLine.Length > 5000) {
|
||||
Console.WriteLine (outputLine);
|
||||
outputLine = "(Additional info redirected to console)";
|
||||
}
|
||||
return outputLine;
|
||||
}
|
||||
|
||||
public static string RunAndAssert (string exe, StringBuilder args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null, string[] environment = null)
|
||||
{
|
||||
return RunAndAssert (exe, args.ToString (), stepName, shouldFail, getAdditionalFailInfo, environment);
|
||||
|
@ -342,7 +350,19 @@ namespace Xamarin.MMP.Tests
|
|||
CopyFileWithSubstitutions (Path.Combine (sourceDir, "ApiDefinition.cs"), Path.Combine (config.TmpDir, "ApiDefinition.cs"), text => text.Replace ("%CODE%", config.APIDefinitionConfig));
|
||||
CopyFileWithSubstitutions (Path.Combine (sourceDir, "StructsAndEnums.cs"), Path.Combine (config.TmpDir, "StructsAndEnums.cs"), text => text.Replace ("%CODE%", config.StructsAndEnumsConfig));
|
||||
|
||||
string linkWithName = null;
|
||||
if (config.LinkWithName != null) {
|
||||
string fileName = Path.GetFileNameWithoutExtension (config.LinkWithName);
|
||||
linkWithName = $"{fileName}.linkwith.cs";
|
||||
File.WriteAllText (Path.Combine (config.TmpDir, linkWithName), $@"using ObjCRuntime;
|
||||
|
||||
[assembly: LinkWith (""{config.LinkWithName}"", SmartLink = true, ForceLoad = true)]");
|
||||
|
||||
}
|
||||
|
||||
return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName), Path.Combine (config.TmpDir, config.ProjectName), text => {
|
||||
if (linkWithName != null)
|
||||
text = text.Replace ("%ITEMGROUP%", $@"<ItemGroup><Compile Include=""{linkWithName}"" /></ItemGroup>%ITEMGROUP%");
|
||||
return ProjectTextReplacement (config, text);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
<Compile Include="src\RegistrarTests.cs" />
|
||||
<Compile Include="src\AssemblyReferencesTests.cs" />
|
||||
<Compile Include="src\PackageReferenceTests.cs" />
|
||||
<Compile Include="src\BindingProjectNoEmbeddingTests.cs" />
|
||||
<Compile Include="..\..\tools\mmp\SdkVersions.cs">
|
||||
<Link>SdkVersions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace Xamarin.MMP.Tests
|
||||
{
|
||||
public class BindingProjectNoEmbeddingTests
|
||||
{
|
||||
static void Touch (string projectPath) => File.SetLastWriteTimeUtc (projectPath, DateTime.UtcNow);
|
||||
|
||||
static void AssertNoResourceWithName (string tmpDir, string projectName, string resourceName)
|
||||
{
|
||||
string bindingName = BindingProjectTests.RemoveCSProj (projectName);
|
||||
string bindingLibraryPath = Path.Combine (tmpDir, $"bin/Debug/{bindingName}.dll");
|
||||
string resourceOutput = TI.RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/monodis", "--presources " + bindingLibraryPath, "monodis");
|
||||
Assert.False (resourceOutput.Contains (resourceName), "Binding project output contained embedded library");
|
||||
}
|
||||
|
||||
static void AssertFileInBundle (string tmpDir, BindingProjectType type, string path, bool assertIsSymLink = false)
|
||||
{
|
||||
string bundlePath = Path.Combine (tmpDir, $"bin/Debug/{(type == BindingProjectType.Modern ? "UnifiedExample" : "XM45Example")}.app/Contents/{path}");
|
||||
Assert.True (File.Exists (bundlePath), $"{path} not in bundle as expected.");
|
||||
if (assertIsSymLink)
|
||||
Assert.True (File.GetAttributes (bundlePath).HasFlag (FileAttributes.ReparsePoint));
|
||||
}
|
||||
|
||||
[TestCase (BindingProjectType.Modern, false)]
|
||||
[TestCase (BindingProjectType.Full, true)]
|
||||
public void LibrariesEmbeddedProperly (BindingProjectType type, bool useProjectReference)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
var projects = BindingProjectTests.GenerateTestProject (type, tmpDir);
|
||||
BindingProjectTests.SetNoEmbedding (projects.Item1);
|
||||
|
||||
string appBuildLog = BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, setupDefaultNativeReference: true).Item2;
|
||||
|
||||
AssertNoResourceWithName (tmpDir, projects.Item1.ProjectName, "SimpleClassDylib.dylib");
|
||||
AssertFileInBundle (tmpDir, type, "MonoBundle/SimpleClassDylib.dylib");
|
||||
});
|
||||
}
|
||||
|
||||
[TestCase (BindingProjectType.Modern, true)]
|
||||
[TestCase (BindingProjectType.Full, false)]
|
||||
public void FrameworksEmbeddedProperly (BindingProjectType type, bool useProjectReference)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
string frameworkPath = FrameworkBuilder.CreateThinFramework (tmpDir);
|
||||
|
||||
var projects = BindingProjectTests.GenerateTestProject (type, tmpDir);
|
||||
BindingProjectTests.SetNoEmbedding (projects.Item1);
|
||||
projects.Item1.ItemGroup = NativeReferenceTests.CreateSingleNativeRef (frameworkPath, "Framework");
|
||||
|
||||
string appBuildLog = BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, false).Item2;
|
||||
|
||||
AssertNoResourceWithName (tmpDir, projects.Item1.ProjectName, "Foo");
|
||||
AssertFileInBundle (tmpDir, type, "Frameworks/Foo.framework/Foo", assertIsSymLink: true);
|
||||
});
|
||||
}
|
||||
|
||||
[TestCase (BindingProjectType.Modern)]
|
||||
public void DoesNotSupportLinkWith (BindingProjectType type)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
var projects = BindingProjectTests.GenerateTestProject (type, tmpDir);
|
||||
BindingProjectTests.SetNoEmbedding (projects.Item1);
|
||||
|
||||
projects.Item1.LinkWithName = "SimpleClassDylib.dylib";
|
||||
|
||||
string libBuildLog = BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, false, shouldFail: true);
|
||||
Assert.True (libBuildLog.Contains ("Can't create a binding resource package unless there are native references in the binding project."), $"Did not fail as expected: {TI.PrintRedirectIfLong (libBuildLog)}");
|
||||
});
|
||||
}
|
||||
|
||||
[TestCase (true)]
|
||||
[TestCase (false)]
|
||||
public void MultipleNativeReferences (bool useProjectReference)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
// This is a bit of a hack, you can't just rename dylibs like this
|
||||
string secondNativeLibPath = Path.Combine (tmpDir, "SimpleClassDylib2.dylib");
|
||||
File.Copy (NativeReferenceTests.SimpleDylibPath, secondNativeLibPath);
|
||||
|
||||
var projects = BindingProjectTests.GenerateTestProject (BindingProjectType.Modern, tmpDir);
|
||||
BindingProjectTests.SetNoEmbedding (projects.Item1);
|
||||
projects.Item1.ItemGroup += NativeReferenceTests.CreateSingleNativeRef (secondNativeLibPath, "Dynamic");
|
||||
|
||||
BindingProjectTests.SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference, setupDefaultNativeReference: true);
|
||||
|
||||
// manifest and 2 dylibs
|
||||
Assert.AreEqual (3, Directory.GetFiles (Path.Combine (tmpDir, "bin/Debug/MobileBinding.resources")).Length);
|
||||
|
||||
// 2 dylibs + libMonoPosixHelper.dylib
|
||||
Assert.AreEqual (3, Directory.GetFiles (Path.Combine (tmpDir, "bin/Debug/UnifiedExample.app/Contents/MonoBundle")).Where (x => x.EndsWith (".dylib")).Count ());
|
||||
});
|
||||
}
|
||||
|
||||
[TestCase (true)]
|
||||
[TestCase (false)]
|
||||
public void MultipleDependencyChain (bool useProjectReference)
|
||||
{
|
||||
// App can depend on Lib that depends on binding lib with native reference and everything gets packaged in correctly
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
TI.UnifiedTestConfig binding = new TI.UnifiedTestConfig (tmpDir) { ProjectName = "MobileBinding.csproj" };
|
||||
binding.ItemGroup += NativeReferenceTests.CreateSingleNativeRef (NativeReferenceTests.SimpleDylibPath, "Dynamic");
|
||||
binding.APIDefinitionConfig += @"[BaseType (typeof (NSObject))]
|
||||
interface SimpleClass {
|
||||
[Export (""doIt"")]
|
||||
int DoIt ();
|
||||
}";
|
||||
BindingProjectTests.SetNoEmbedding (binding);
|
||||
|
||||
TI.GenerateBindingLibraryProject (binding);
|
||||
TI.BuildProject (Path.Combine (tmpDir, "MobileBinding.csproj"), true);
|
||||
|
||||
|
||||
TI.UnifiedTestConfig library = new TI.UnifiedTestConfig (tmpDir) { ProjectName = "UnifiedLibrary" };
|
||||
library.TestCode = "public class MyClass { public static void Go () { var c = new ExampleBinding.SimpleClass (); c.DoIt (); } }";
|
||||
|
||||
if (useProjectReference)
|
||||
library.References = $@"<ProjectReference Include=""MobileBinding.csproj"" />";
|
||||
else
|
||||
library.References = $@"<Reference Include=""MobileBinding""><HintPath>{Path.Combine (tmpDir, "bin/Debug", "MobileBinding.dll")}</HintPath></Reference>";
|
||||
|
||||
TI.GenerateUnifiedLibraryProject (library);
|
||||
TI.BuildProject (Path.Combine (tmpDir, "UnifiedLibrary.csproj"), true);
|
||||
|
||||
TI.UnifiedTestConfig project = new TI.UnifiedTestConfig (tmpDir) { ProjectName = "UnifiedExample.csproj" };
|
||||
project.TestCode = "MyClass.Go ();";
|
||||
|
||||
if (useProjectReference)
|
||||
project.References = $@"<ProjectReference Include=""UnifiedLibrary.csproj"" />";
|
||||
else
|
||||
project.References = $@"<Reference Include=""UnifiedLibrary""><HintPath>{Path.Combine (tmpDir, "bin/Debug", "UnifiedLibrary.dll")}</HintPath></Reference>";
|
||||
|
||||
TI.GenerateUnifiedExecutableProject (project);
|
||||
TI.BuildProject (Path.Combine (tmpDir, "UnifiedExample.csproj"), true);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanShouldRemoveBundle ()
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
var projects = BindingProjectTests.GenerateTestProject (BindingProjectType.Modern, tmpDir);
|
||||
BindingProjectTests.SetNoEmbedding (projects.Item1);
|
||||
|
||||
string libBuildLog = BindingProjectTests.SetupAndBuildBindingProject (projects.Item1, true);
|
||||
|
||||
TI.CleanUnifiedProject (Path.Combine (tmpDir, projects.Item1.ProjectName));
|
||||
Assert.False (Directory.Exists (Path.Combine (tmpDir, "bin/Debug/MobileBinding.resources")), "Resource bundle was not cleaned up");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +1,38 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace Xamarin.MMP.Tests
|
||||
{
|
||||
// There are a mess of different binding project configurations in the wild
|
||||
public enum BindingProjectType
|
||||
{
|
||||
Modern, // The ideal Modern - Sets TargetFrameworkVersion and TargetFrameworkIdentifier correclty
|
||||
ModernNoTag, // Sets neither TargetFrameworkVersion nor TargetFrameworkIdentifier
|
||||
Full, // Sets both TargetFrameworkVersion and UseXamMacFullFramework
|
||||
FullTVF, // Sets just TargetFrameworkVersion to 4.5 or later
|
||||
FullXamMacTag, // Sets just UseXamMacFullFramework
|
||||
}
|
||||
|
||||
public class BindingProjectTests
|
||||
{
|
||||
static string RemoveCSProj (string s) => s.Remove (s.IndexOf (".csproj", StringComparison.InvariantCulture));
|
||||
|
||||
static Tuple<string, string> BuildLinkedTestProjects (TI.UnifiedTestConfig binding, TI.UnifiedTestConfig project, string tmpDir)
|
||||
{
|
||||
binding.ItemGroup = NativeReferenceTests.CreateSingleNativeRef (Path.GetFullPath (NativeReferenceTests.SimpleDylibPath), "Dynamic");
|
||||
binding.StructsAndEnumsConfig = "public class UnifiedWithDepNativeRefLibTestClass {}";
|
||||
internal static string RemoveCSProj (string s) => s.Remove (s.IndexOf (".csproj", StringComparison.InvariantCulture));
|
||||
|
||||
string projectPath = TI.GenerateBindingLibraryProject (binding);
|
||||
string bindingBuildLog = TI.BuildProject (projectPath, true);
|
||||
internal static Tuple<string, string> SetupAndBuildLinkedTestProjects (TI.UnifiedTestConfig binding, TI.UnifiedTestConfig project, string tmpDir, bool useProjectReference, bool setupDefaultNativeReference)
|
||||
{
|
||||
string bindingBuildLog = SetupAndBuildBindingProject (binding, setupDefaultNativeReference);
|
||||
|
||||
string bindingName = RemoveCSProj (binding.ProjectName);
|
||||
|
||||
project.References = string.Format (@"<Reference Include=""{0}""><HintPath>{1}</HintPath></Reference>", bindingName, Path.Combine (tmpDir, "bin/Debug", bindingName + ".dll"));
|
||||
if (useProjectReference)
|
||||
project.References = $@"<ProjectReference Include=""{bindingName}.csproj"" />";
|
||||
else
|
||||
project.References = $@"<Reference Include=""{bindingName}""><HintPath>{Path.Combine (tmpDir, "bin/Debug", bindingName + ".dll")}</HintPath></Reference>";
|
||||
|
||||
project.TestCode = "System.Console.WriteLine (typeof (ExampleBinding.UnifiedWithDepNativeRefLibTestClass));";
|
||||
|
||||
string appBuildLog = TI.TestUnifiedExecutable (project).BuildOutput;
|
||||
|
@ -29,40 +40,42 @@ namespace Xamarin.MMP.Tests
|
|||
return new Tuple<string, string> (bindingBuildLog, appBuildLog);
|
||||
}
|
||||
|
||||
// There are a mess of different binding project configurations in the wild
|
||||
public enum ProjectType {
|
||||
Modern, // The ideal Modern - Sets TargetFrameworkVersion and TargetFrameworkIdentifier correclty
|
||||
ModernNoTag, // Sets neither TargetFrameworkVersion nor TargetFrameworkIdentifier
|
||||
Full, // Sets both TargetFrameworkVersion and UseXamMacFullFramework
|
||||
FullTVF, // Sets just TargetFrameworkVersion to 4.5 or later
|
||||
FullXamMacTag, // Sets just UseXamMacFullFramework
|
||||
internal static string SetupAndBuildBindingProject (TI.UnifiedTestConfig binding, bool setupDefaultNativeReference, bool shouldFail = false)
|
||||
{
|
||||
if (setupDefaultNativeReference)
|
||||
binding.ItemGroup += NativeReferenceTests.CreateSingleNativeRef (Path.GetFullPath (NativeReferenceTests.SimpleDylibPath), "Dynamic");
|
||||
|
||||
binding.StructsAndEnumsConfig = "public class UnifiedWithDepNativeRefLibTestClass {}";
|
||||
|
||||
string projectPath = TI.GenerateBindingLibraryProject (binding);
|
||||
return TI.BuildProject (projectPath, true, shouldFail: shouldFail);
|
||||
}
|
||||
|
||||
Tuple <TI.UnifiedTestConfig, TI.UnifiedTestConfig> GenerateTestProject (ProjectType type, string tmpDir)
|
||||
internal static Tuple <TI.UnifiedTestConfig, TI.UnifiedTestConfig> GenerateTestProject (BindingProjectType type, string tmpDir)
|
||||
{
|
||||
TI.UnifiedTestConfig binding = new TI.UnifiedTestConfig (tmpDir);
|
||||
TI.UnifiedTestConfig project = new TI.UnifiedTestConfig (tmpDir);
|
||||
switch (type) {
|
||||
case ProjectType.Modern:
|
||||
case BindingProjectType.Modern:
|
||||
binding.ProjectName = "MobileBinding.csproj";
|
||||
project.XM45 = false;
|
||||
break;
|
||||
case ProjectType.ModernNoTag:
|
||||
case BindingProjectType.ModernNoTag:
|
||||
binding.ProjectName = "BindingProjectWithNoTag.csproj";
|
||||
project.XM45 = false;
|
||||
break;
|
||||
case ProjectType.Full:
|
||||
case BindingProjectType.Full:
|
||||
binding.ProjectName = "XM45Binding.csproj";
|
||||
binding.CustomProjectReplacement = new Tuple<string, string> (
|
||||
"<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>",
|
||||
"<UseXamMacFullFramework>true</UseXamMacFullFramework><TargetFrameworkVersion>4.5</TargetFrameworkVersion>");
|
||||
project.XM45 = true;
|
||||
break;
|
||||
case ProjectType.FullTVF:
|
||||
case BindingProjectType.FullTVF:
|
||||
binding.ProjectName = "XM45Binding.csproj";
|
||||
project.XM45 = true;
|
||||
break;
|
||||
case ProjectType.FullXamMacTag:
|
||||
case BindingProjectType.FullXamMacTag:
|
||||
binding.ProjectName = "XM45Binding.csproj";
|
||||
binding.CustomProjectReplacement = new Tuple<string, string> (
|
||||
"<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>",
|
||||
|
@ -75,16 +88,21 @@ namespace Xamarin.MMP.Tests
|
|||
return new Tuple<TI.UnifiedTestConfig, TI.UnifiedTestConfig> (binding, project);
|
||||
}
|
||||
|
||||
[TestCase (ProjectType.Modern)]
|
||||
[TestCase (ProjectType.ModernNoTag)]
|
||||
[TestCase (ProjectType.Full)]
|
||||
[TestCase (ProjectType.FullTVF)]
|
||||
[TestCase (ProjectType.FullXamMacTag)]
|
||||
public void ShouldRemovePackagedLibrary_OnceInBundle (ProjectType type)
|
||||
internal static void SetNoEmbedding (TI.UnifiedTestConfig project)
|
||||
{
|
||||
project.CSProjConfig = "<NoBindingEmbedding>true</NoBindingEmbedding>";
|
||||
}
|
||||
|
||||
[TestCase (BindingProjectType.Modern)]
|
||||
[TestCase (BindingProjectType.ModernNoTag)]
|
||||
[TestCase (BindingProjectType.Full)]
|
||||
[TestCase (BindingProjectType.FullTVF)]
|
||||
[TestCase (BindingProjectType.FullXamMacTag)]
|
||||
public void ShouldRemovePackagedLibrary_OnceInBundle (BindingProjectType type)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
var projects = GenerateTestProject (type, tmpDir);
|
||||
BuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir);
|
||||
SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference: false, setupDefaultNativeReference: false);
|
||||
|
||||
string bindingName = RemoveCSProj (projects.Item1.ProjectName);
|
||||
string appName = RemoveCSProj (projects.Item2.ProjectName);
|
||||
|
@ -96,16 +114,21 @@ namespace Xamarin.MMP.Tests
|
|||
});
|
||||
}
|
||||
|
||||
[TestCase (ProjectType.Modern)]
|
||||
[TestCase (ProjectType.ModernNoTag)]
|
||||
[TestCase (ProjectType.Full)]
|
||||
[TestCase (ProjectType.FullTVF)]
|
||||
[TestCase (ProjectType.FullXamMacTag)]
|
||||
public void ShouldBuildWithoutErrors_AndLinkCorrectFramework (ProjectType type)
|
||||
[TestCase (BindingProjectType.Modern)]
|
||||
[TestCase (BindingProjectType.Modern, true)]
|
||||
[TestCase (BindingProjectType.ModernNoTag)]
|
||||
[TestCase (BindingProjectType.Full)]
|
||||
[TestCase (BindingProjectType.Full, true)]
|
||||
[TestCase (BindingProjectType.FullTVF)]
|
||||
[TestCase (BindingProjectType.FullXamMacTag)]
|
||||
public void ShouldBuildWithoutErrors_AndLinkCorrectFramework (BindingProjectType type, bool noEmbedding = false)
|
||||
{
|
||||
MMPTests.RunMMPTest (tmpDir => {
|
||||
var projects = GenerateTestProject (type, tmpDir);
|
||||
var logs = BuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir);
|
||||
if (noEmbedding)
|
||||
SetNoEmbedding (projects.Item1);
|
||||
|
||||
var logs = SetupAndBuildLinkedTestProjects (projects.Item1, projects.Item2, tmpDir, useProjectReference: false, setupDefaultNativeReference: noEmbedding);
|
||||
|
||||
Assert.False (logs.Item1.Contains ("mcs"), "Bindings project must not use mcs:\n" + logs.Item1);
|
||||
Assert.True (logs.Item1.Contains ("csc"), "Bindings project must use csc:\n" + logs.Item1);
|
||||
|
@ -116,14 +139,14 @@ namespace Xamarin.MMP.Tests
|
|||
var system = bgenParts.First (x => x.Contains ("System.dll"));
|
||||
|
||||
switch (type) {
|
||||
case ProjectType.Modern:
|
||||
case ProjectType.ModernNoTag:
|
||||
case BindingProjectType.Modern:
|
||||
case BindingProjectType.ModernNoTag:
|
||||
Assert.True (mscorlib.EndsWith ("lib/mono/Xamarin.Mac/mscorlib.dll", StringComparison.Ordinal), "mscorlib not found in expected Modern location: " + mscorlib);
|
||||
Assert.True (system.EndsWith ("lib/mono/Xamarin.Mac/System.dll", StringComparison.Ordinal), "system not found in expected Modern location: " + system);
|
||||
break;
|
||||
case ProjectType.Full:
|
||||
case ProjectType.FullTVF:
|
||||
case ProjectType.FullXamMacTag:
|
||||
case BindingProjectType.Full:
|
||||
case BindingProjectType.FullTVF:
|
||||
case BindingProjectType.FullXamMacTag:
|
||||
Assert.True (mscorlib.EndsWith ("lib/mono/4.5/mscorlib.dll", StringComparison.Ordinal), "mscorlib not found in expected Full location: " + mscorlib);
|
||||
Assert.True (system.EndsWith ("lib/mono/4.5/System.dll", StringComparison.Ordinal), "system not found in expected Full location: " + system);
|
||||
break;
|
||||
|
@ -146,15 +169,15 @@ namespace Xamarin.MMP.Tests
|
|||
});
|
||||
}
|
||||
|
||||
static string GetExpectedBCLVersion (ProjectType type)
|
||||
static string GetExpectedBCLVersion (BindingProjectType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ProjectType.Modern:
|
||||
case ProjectType.ModernNoTag:
|
||||
case BindingProjectType.Modern:
|
||||
case BindingProjectType.ModernNoTag:
|
||||
return "2.0.5.0";
|
||||
case ProjectType.Full:
|
||||
case ProjectType.FullTVF:
|
||||
case ProjectType.FullXamMacTag:
|
||||
case BindingProjectType.Full:
|
||||
case BindingProjectType.FullTVF:
|
||||
case BindingProjectType.FullXamMacTag:
|
||||
return "4.0.0.0";
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
|
|
|
@ -71,4 +71,44 @@ namespace MonoTests.System.Net.Http
|
|||
// The handlers throw different types of exceptions, so we can't assert much more than that something went wrong.
|
||||
}
|
||||
|
||||
}}
|
||||
#if !__WATCHOS__
|
||||
// ensure that we do get the same number of cookies as the managed handler
|
||||
[TestCase]
|
||||
public void TestNSUrlSessionHandlerCookies ()
|
||||
{
|
||||
bool areEqual = false;
|
||||
var manageCount = 0;
|
||||
var nativeCount = 0;
|
||||
Exception ex = null;
|
||||
|
||||
TestRuntime.RunAsync (DateTime.Now.AddSeconds (30), async () =>
|
||||
{
|
||||
try {
|
||||
var managedClient = new HttpClient (new HttpClientHandler ());
|
||||
var managedResponse = await managedClient.GetAsync ("https://google.com");
|
||||
if (managedResponse.Headers.TryGetValues ("Set-Cookie", out var managedCookies)) {
|
||||
var nativeClient = new HttpClient (new NSUrlSessionHandler ());
|
||||
var nativeResponse = await nativeClient.GetAsync ("https://google.com");
|
||||
if (managedResponse.Headers.TryGetValues ("Set-Cookie", out var nativeCookies)) {
|
||||
manageCount = managedCookies.Count ();
|
||||
nativeCount = nativeCookies.Count ();
|
||||
areEqual = manageCount == nativeCount;
|
||||
} else {
|
||||
manageCount = -1;
|
||||
nativeCount = -1;
|
||||
areEqual = false;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
}, () => areEqual);
|
||||
|
||||
Assert.IsTrue (areEqual, $"Cookies are different - Managed {manageCount} vs Native {nativeCount}");
|
||||
Assert.IsNull (ex, "Exception");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,16 @@ namespace MonoTouchFixtures {
|
|||
|
||||
Collect ();
|
||||
bool aot = symbols [1].Contains ("MonoTouchFixtures_Symbols_Collect");
|
||||
/* ves_pinvoke_method (slow path) and do_icall (fast path) are
|
||||
* MONO_NEVER_INLINE, so they should show up in the backtrace
|
||||
* reliably */
|
||||
bool interp = symbols [1].Contains ("ves_pinvoke_method") || symbols [1].Contains ("do_icall");
|
||||
bool interp = false;
|
||||
|
||||
if (!aot) {
|
||||
for (int i = 0; i < 4 && !interp; i++) {
|
||||
/* ves_pinvoke_method (slow path) and do_icall (fast path) are
|
||||
* MONO_NEVER_INLINE, so they should show up in the backtrace
|
||||
* reliably */
|
||||
interp |= symbols [i].Contains ("ves_pinvoke_method") || symbols [i].Contains ("do_icall");
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue (aot || interp, "#1");
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Xsl;
|
||||
using Xamarin;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace xharness
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace xharness.BCLTestImporter {
|
|||
}
|
||||
|
||||
// generate all the different test targets.
|
||||
public List<iOSTestProject> GetBclTargets ()
|
||||
public List<iOSTestProject> GetiOSBclTargets ()
|
||||
{
|
||||
var result = new List<iOSTestProject> ();
|
||||
// generate all projects, then create a new iOSTarget per project
|
||||
foreach (var (name, path, xunit, platforms) in projectGenerator.GenerateAllTestProjects ()) {
|
||||
foreach (var (name, path, xunit, platforms) in projectGenerator.GenerateAlliOSTestProjects ()) {
|
||||
var prefix = xunit ? "xUnit" : "NUnit";
|
||||
result.Add (new iOSTestProject (path) {
|
||||
Name = $"[{prefix}] Mono {name}",
|
||||
|
@ -46,5 +46,38 @@ namespace xharness.BCLTestImporter {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<MacTestProject> GetMacBclTargets (MacFlavors flavor)
|
||||
{
|
||||
Platform platform;
|
||||
if (flavor == MacFlavors.Full)
|
||||
platform = Platform.MacOSFull;
|
||||
else
|
||||
platform = Platform.MacOSModern;
|
||||
var result = new List<MacTestProject> ();
|
||||
foreach (var (name, path, xunit) in projectGenerator.GenerateAllMacTestProjects (platform)) {
|
||||
var prefix = xunit ? "xUnit" : "NUnit";
|
||||
result.Add (new MacTestProject (path, targetFrameworkFlavor: flavor, generateVariations: false) {
|
||||
Name = $"[{prefix}] Mono {name}",
|
||||
Platform = "AnyCPU",
|
||||
IsExecutableProject = true,
|
||||
Dependency = async () => {
|
||||
var rv = await Harness.BuildBclTests ();
|
||||
if (!rv.Succeeded)
|
||||
throw new Exception ($"Failed to build BCL tests, exit code: {rv.ExitCode}. Check the harness log for more details.");
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<MacTestProject> GetMacBclTargets ()
|
||||
{
|
||||
var result = new List<MacTestProject> ();
|
||||
foreach (var flavor in new [] { MacFlavors.Full, MacFlavors.Modern}) {
|
||||
result.AddRange (GetMacBclTargets (flavor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Net;
|
|||
using System.Runtime.Serialization.Json;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -308,6 +308,11 @@ namespace xharness
|
|||
MacTestProjects.Add (macTestProject);
|
||||
}
|
||||
}
|
||||
|
||||
var monoImportTestFactory = new BCLTestImportTargetFactory (this);
|
||||
foreach (var target in monoImportTestFactory.GetMacBclTargets ()) {
|
||||
MacTestProjects.Add (target);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoConfigureIOS ()
|
||||
|
@ -383,7 +388,7 @@ namespace xharness
|
|||
|
||||
// add all the tests that are using the precompiled mono assemblies
|
||||
var monoImportTestFactory = new BCLTestImportTargetFactory (this);
|
||||
foreach (var target in monoImportTestFactory.GetBclTargets ()) {
|
||||
foreach (var target in monoImportTestFactory.GetiOSBclTargets ()) {
|
||||
IOSTestProjects.Add (target);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
using Xamarin;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace xharness
|
||||
|
@ -296,14 +297,17 @@ namespace xharness
|
|||
yield return new TestData { Variation = "Debug (all optimizations)", MTouchExtraArgs = "--registrar:static --optimize:all", Debug = true, Profiling = false, Defines = "OPTIMIZEALL" };
|
||||
yield return new TestData { Variation = "Debug (interpreter)", MTouchExtraArgs = "--interpreter", Debug = true, Profiling = false, };
|
||||
yield return new TestData { Variation = "Debug (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = true, Profiling = false, };
|
||||
yield return new TestData { Variation = "Release (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = false, Profiling = false, };
|
||||
break;
|
||||
case "mscorlib":
|
||||
yield return new TestData { Variation = "Debug (interpreter)", MTouchExtraArgs = "--interpreter", Debug = true, Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
yield return new TestData { Variation = "Debug (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = true, Profiling = false, Ignored = true, Undefines = "FULL_AOT_RUNTIME" };
|
||||
yield return new TestData { Variation = "Debug (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = true, Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
yield return new TestData { Variation = "Release (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = false, Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
break;
|
||||
case "mini":
|
||||
yield return new TestData { Variation = "Debug (interpreter)", MTouchExtraArgs = "--interpreter", Debug = true, Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
yield return new TestData { Variation = "Debug (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = true, Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
yield return new TestData { Variation = "Release (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = false , Profiling = false, Undefines = "FULL_AOT_RUNTIME" };
|
||||
break;
|
||||
#if FIXME
|
||||
case "mono-native-compat":
|
||||
|
@ -867,6 +871,7 @@ namespace xharness
|
|||
build.ProjectPlatform = project.Platform;
|
||||
build.SpecifyPlatform = false;
|
||||
build.SpecifyConfiguration = build.ProjectConfiguration != "Debug";
|
||||
build.Dependency = project.Dependency;
|
||||
RunTestTask exec;
|
||||
IEnumerable<RunTestTask> execs;
|
||||
var ignored_main = ignored;
|
||||
|
|
|
@ -109,6 +109,8 @@ namespace xharness
|
|||
|
||||
// build/[install/]run targets for specific test projects.
|
||||
foreach (var target in allTargets) {
|
||||
if (target.Name.IndexOf ("BCLTests", StringComparison.Ordinal) != -1) // special case for those targets that are auto generated from the mono assemblies
|
||||
continue;
|
||||
var make_escaped_simplified_name = target.SimplifiedName.Replace (" ", "\\ ");
|
||||
var make_escaped_name = target.Name.Replace (" ", "\\ ");
|
||||
|
||||
|
|
|
@ -128,9 +128,18 @@ namespace xharness
|
|||
process.BeginOutputReadLine ();
|
||||
|
||||
cancellation_token?.Register (() => {
|
||||
if (!process.HasExited) {
|
||||
StderrStream.WriteLine ($"Execution was cancelled.");
|
||||
ProcessHelper.kill (process.Id, 9);
|
||||
var hasExited = false;
|
||||
try {
|
||||
hasExited = process.HasExited;
|
||||
} catch {
|
||||
// Process.HasExited can sometimes throw exceptions, so
|
||||
// just ignore those and to be safe treat it as the
|
||||
// process didn't exit (the safe option being to not leave
|
||||
// processes behind).
|
||||
}
|
||||
if (!hasExited) {
|
||||
StderrStream.WriteLine ($"Execution of {pid} was cancelled.");
|
||||
ProcessHelper.kill (pid, 9);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
using Xamarin.Utils;
|
||||
|
||||
namespace xharness
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Xamarin;
|
||||
|
||||
namespace xharness
|
||||
{
|
||||
|
|
|
@ -76,7 +76,9 @@
|
|||
</Compile>
|
||||
<Compile Include="Harness.cs" />
|
||||
<Compile Include="ProjectFileExtensions.cs" />
|
||||
<Compile Include="PListExtensions.cs" />
|
||||
<Compile Include="..\..\tools\common\PListExtensions.cs">
|
||||
<Link>PListExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="WatchOSTarget.cs" />
|
||||
<Compile Include="TVOSTarget.cs" />
|
||||
<Compile Include="Target.cs" />
|
||||
|
|
|
@ -16,7 +16,8 @@ namespace BCLTestImporter {
|
|||
{Platform.iOS, "monotouch"},
|
||||
{Platform.WatchOS, "monotouch_watch"},
|
||||
{Platform.TvOS, "monotouch_tv"},
|
||||
{Platform.MacOS, "xammac"},
|
||||
{Platform.MacOSFull, "xammac"},
|
||||
{Platform.MacOSModern, "xammac"},
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
@ -340,7 +341,7 @@ namespace BCLTestImporter {
|
|||
{ "iOS", "Specifies that the platform to which the projects are going to be build is iOS.", i => Platform = Platform.iOS },
|
||||
{ "watchOS", "Specifies that the platform to which the projects are going to be build is watchOS.", w => Platform = Platform.WatchOS },
|
||||
{ "tvOS", "Specifies that the platform to which the projects are going to be build is tvOS.", t => Platform = Platform.TvOS },
|
||||
{ "macOS", "Specifies that the platform to which the projects are going to be build is macOS.", m => Platform = Platform.MacOS },
|
||||
{ "macOS", "Specifies that the platform to which the projects are going to be build is macOS.", m => Platform = Platform.MacOSFull },
|
||||
{ "generate-project", "Flag used to state that a new test project should be generated."
|
||||
+ " Output path must be provided via -o.", f => GenerateProject = f != null },
|
||||
{ "generate-all-projects", "Flag used to state that all the test projects should be generated."
|
||||
|
|
|
@ -12,7 +12,8 @@ namespace BCLTestImporter {
|
|||
{Platform.iOS, "monotouch"},
|
||||
{Platform.WatchOS, "monotouch"},
|
||||
{Platform.TvOS, "monotouch"},
|
||||
{Platform.MacOS, "xammac"},
|
||||
{Platform.MacOSFull, "xammac_net_4_5"},
|
||||
{Platform.MacOSModern, "xammac_net_4_5"},
|
||||
};
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace BCLTestImporterTests {
|
|||
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
|
||||
var home = Environment.GetEnvironmentVariable ("HOME");
|
||||
var expectedPath = Path.Combine (home, "mcs/class/lib", "xammac", "tests", testAssemblyDefinition.Name);
|
||||
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.MacOS));
|
||||
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.MacOSFull));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace BCLTestImporter
|
|||
// Added for the workaround so that it does not make the code uglier
|
||||
public partial struct BCLTestProjectDefinition
|
||||
{
|
||||
static Dictionary<string, List<(string assembly, string hint)>> cachedAssemblyInfo =
|
||||
static Dictionary<string, List<(string assembly, string hint)>> iOSCachedAssemblyInfo =
|
||||
new Dictionary<string, List<(string assembly, string hint)>>
|
||||
{
|
||||
{"SystemNumericsTests", new List<(string assembly, string hint)> {
|
||||
|
@ -138,12 +138,316 @@ namespace BCLTestImporter
|
|||
}},
|
||||
};
|
||||
|
||||
private static Dictionary<string, List<(string assembly, string hint)>> macCachedAssemblyInfo =
|
||||
new Dictionary<string, List<(string assembly, string hint)>> {
|
||||
{"MonoCSharpTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"Mono.CSharp", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.CSharp.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_Mono.CSharp_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Mono.CSharp_test.dll"),
|
||||
}},
|
||||
{"MonoDataSqilteTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"Mono.Data.Sqlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Data.Sqlite.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_Mono.Data.Sqlite_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Mono.Data.Sqlite_test.dll"),
|
||||
}},
|
||||
{"MonoDataTdsTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"Mono.Data.Tds", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Data.Tds.dll"),
|
||||
(assembly:"xammac_net_4_5_Mono.Data.Tds_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Mono.Data.Tds_test.dll"),
|
||||
}},
|
||||
{"MonoPoxisTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"Mono.Posix", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Posix.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_Mono.Posix_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Mono.Posix_test.dll"),
|
||||
}},
|
||||
{"MonoSecurtiyTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"Mono.Security", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Security.dll"),
|
||||
(assembly:"xammac_net_4_5_Mono.Security_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Mono.Security_test.dll"),
|
||||
}},
|
||||
{"SystemComponentModelDataAnnotationsTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.ComponentModel.DataAnnotations", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.ComponentModel.DataAnnotations.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_System.ComponentModel.DataAnnotations_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.ComponentModel.DataAnnotations_test.dll"),
|
||||
}},
|
||||
{"SystemConfigurationTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Configuration", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Configuration.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Configuration_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Configuration_test.dll"),
|
||||
}},
|
||||
{"SystemCoreTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Core_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Core_test.dll"),
|
||||
}},
|
||||
{"SystemDataLinqTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Data.Linq", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.Linq.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Data.Linq_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Data.Linq_test.dll"),
|
||||
}},
|
||||
{"SystemDataTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Configuration", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Configuration.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"Mono.Data.Sqlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Data.Sqlite.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Data_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Data_test.dll"),
|
||||
}},
|
||||
{"SystemIOCompressionFileSystemTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.IO.Compression", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.IO.Compression.dll"),
|
||||
(assembly:"System.IO.Compression.FileSystem", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.IO.Compression.FileSystem.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_System.IO.Compression.FileSystem_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.IO.Compression.FileSystem_test.dll"),
|
||||
}},
|
||||
{"SystemIOCompressionTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.IO.Compression", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.IO.Compression.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.IO.Compression_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.IO.Compression_test.dll"),
|
||||
}},
|
||||
{"SystemIdentityModelTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.IdentityModel", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.IdentityModel.dll"),
|
||||
(assembly:"System.Runtime.Serialization", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Runtime.Serialization.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"xammac_net_4_5_System.IdentityModel_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.IdentityModel_test.dll"),
|
||||
}},
|
||||
{"SystemJsonTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Json", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Json.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Json_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Json_test.dll"),
|
||||
}},
|
||||
{"SystemNetHttpTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Net.Http", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Net.Http.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Net.Http_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Net.Http_test.dll"),
|
||||
}},
|
||||
{"SystemNumericsTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Numerics", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Numerics.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Numerics_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Numerics_test.dll"),
|
||||
}},
|
||||
{"SystemRuntimeSerializationFormattersSoapTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Runtime.Serialization.Formatters.Soap", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Runtime.Serialization.Formatters.Soap.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Runtime.Serialization.Formatters.Soap_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Runtime.Serialization.Formatters.Soap_test.dll"),
|
||||
}},
|
||||
{"SystemSecurityTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Security", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Security.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Security_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Security_test.dll"),
|
||||
}},
|
||||
{"SystemServiceModelTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.ServiceModel", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.ServiceModel.dll"),
|
||||
(assembly:"System.Runtime.Serialization", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Runtime.Serialization.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.IdentityModel", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.IdentityModel.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System.Security", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Security.dll"),
|
||||
(assembly:"xammac_net_4_5_System.ServiceModel_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.ServiceModel_test.dll"),
|
||||
}},
|
||||
{"SystemTransactionsTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Transactions", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Transactions.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Transactions_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Transactions_test.dll"),
|
||||
}},
|
||||
{"SystemXmlLinqTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"System.Xml.Linq", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.Linq.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Xml.Linq_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Xml.Linq_test.dll"),
|
||||
}},
|
||||
{"SystemXmlTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Xml_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Xml_test.dll"),
|
||||
}},
|
||||
{"SystemTests", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"nunitlite", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/nunitlite.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"System.Configuration", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Configuration.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"Mono.Security", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Mono.Security.dll"),
|
||||
(assembly:"xammac_net_4_5_System_test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System_test.dll"),
|
||||
}},
|
||||
{"MicrosoftCSharpXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"Microsoft.CSharp", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Microsoft.CSharp.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"xammac_net_4_5_Microsoft.CSharp_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_Microsoft.CSharp_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemCoreXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"Microsoft.CSharp", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Microsoft.CSharp.dll"),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"xunit.execution.dotnet", hint:""),
|
||||
(assembly:"xammac_net_4_5_System.Core_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Core_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemDataXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System.Data", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Data.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Data_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Data_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemJsonXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System.Json", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Json.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Json_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Json_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemNumericsXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System.Numerics", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Numerics.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"Microsoft.CSharp", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/Microsoft.CSharp.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Numerics_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Numerics_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemRuntimeCompilerServicesXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System.Runtime.CompilerServices.Unsafe", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Runtime.CompilerServices.Unsafe.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"xammac_net_4_5_System.Runtime.CompilerServices.Unsafe_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Runtime.CompilerServices.Unsafe_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemSecurityXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System.Security", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Security.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Security_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Security_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemXmlLinqXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"System.Xml", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System.Xml.Linq", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Xml.Linq.dll"),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System.Xml.Linq_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System.Xml.Linq_xunit-test.dll"),
|
||||
}},
|
||||
{"SystemXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"xammac_net_4_5_System_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_System_xunit-test.dll"),
|
||||
}},
|
||||
{"CorlibXunit", new List<(string assembly, string hint)> {
|
||||
(assembly:"mscorlib", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/mscorlib.dll"),
|
||||
(assembly:"xunit.core", hint:""),
|
||||
(assembly:"xunit.abstractions", hint:""),
|
||||
(assembly:"Xunit.NetCore.Extensions", hint:"{MONO_ROOT}external/xunit-binaries/Xunit.NetCore.Extensions.dll"),
|
||||
(assembly:"xunit.assert", hint:""),
|
||||
(assembly:"System", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.dll"),
|
||||
(assembly:"System.Core", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Core.dll"),
|
||||
(assembly:"System.Numerics", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Numerics.dll"),
|
||||
(assembly:"System.Runtime.CompilerServices.Unsafe", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/System.Runtime.CompilerServices.Unsafe.dll"),
|
||||
(assembly:"xammac_net_4_5_corlib_xunit-test.dll", hint:"{MONO_ROOT}mcs/class/lib/xammac_net_4_5/tests/xammac_net_4_5_corlib_xunit-test.dll"),
|
||||
}},
|
||||
};
|
||||
public List<(string assembly, string hintPath)> GetCachedAssemblyInclusionInformation (string monoRootPath,
|
||||
Platform platform)
|
||||
{
|
||||
if (!monoRootPath.EndsWith ("/"))
|
||||
monoRootPath += "/";
|
||||
var info = cachedAssemblyInfo[Name];
|
||||
var info = new List<(string assembly, string hintPath)> ();
|
||||
switch (platform){
|
||||
case Platform.iOS:
|
||||
case Platform.TvOS:
|
||||
case Platform.WatchOS:
|
||||
info = iOSCachedAssemblyInfo[Name];
|
||||
break;
|
||||
case Platform.MacOSFull:
|
||||
case Platform.MacOSModern:
|
||||
info = macCachedAssemblyInfo[Name];
|
||||
break;
|
||||
}
|
||||
// lets fix the path
|
||||
var fixedResult = new List<(string assembly, string hintPath)> ();
|
||||
foreach (var (assembly, hin) in info){
|
||||
|
|
|
@ -23,15 +23,22 @@ namespace BCLTestImporter {
|
|||
internal static readonly string WatchOSTemplatePathKey = "%TEMPLATE PATH%";
|
||||
internal static readonly string WatchOSCsporjAppKey = "%WATCH APP PROJECT PATH%";
|
||||
internal static readonly string WatchOSCsporjExtensionKey ="%WATCH EXTENSION PROJECT PATH%";
|
||||
internal static readonly string TargetFrameworkVersionKey = "%TARGET FRAMEWORK VERSION%";
|
||||
internal static readonly string TargetExtraInfoKey = "%TARGET EXTRA INFO%";
|
||||
internal static readonly string DefineConstantsKey = "%DEFINE CONSTANTS%";
|
||||
static readonly Dictionary<Platform, string> plistTemplateMatches = new Dictionary<Platform, string> {
|
||||
{Platform.iOS, "Info.plist.in"},
|
||||
{Platform.TvOS, "Info-tv.plist.in"},
|
||||
{Platform.WatchOS, "Info-watchos.plist.in"},
|
||||
{Platform.MacOSFull, "Info-mac.plist.in"},
|
||||
{Platform.MacOSModern, "Info-mac.plist.in"},
|
||||
};
|
||||
static readonly Dictionary<Platform, string> projectTemplateMatches = new Dictionary<Platform, string> {
|
||||
{Platform.iOS, "BCLTests.csproj.in"},
|
||||
{Platform.TvOS, "BCLTests-tv.csproj.in"},
|
||||
{Platform.WatchOS, "BCLTests-watchos.csproj.in"},
|
||||
{Platform.MacOSFull, "BCLTests-mac.csproj.in"},
|
||||
{Platform.MacOSModern, "BCLTests-mac.csproj.in"},
|
||||
};
|
||||
static readonly Dictionary<WatchAppType, string> watchOSProjectTemplateMatches = new Dictionary<WatchAppType, string>
|
||||
{
|
||||
|
@ -56,13 +63,15 @@ namespace BCLTestImporter {
|
|||
"System",
|
||||
"System.Xml",
|
||||
"System.Xml.Linq",
|
||||
"System.Core",
|
||||
"xunit.core",
|
||||
"xunit.abstractions",
|
||||
"xunit.assert",
|
||||
};
|
||||
|
||||
// Ww have different lists for the test projects:
|
||||
// 1. commonTestProjects: Those projects that can be ran in all platforms.
|
||||
// 2. iOSTestProjects: Those projects that can be ran on iOS
|
||||
|
||||
static readonly List<(string name, string[] assemblies)> commonTestProjects = new List<(string name, string[] assemblies)> {
|
||||
// we have two different types of list, those that are for the iOS like projects (ios, tvos and watch os) and those
|
||||
// for mac
|
||||
static readonly List<(string name, string[] assemblies)> commoniOSTestProjects = new List<(string name, string[] assemblies)> {
|
||||
// NUNIT TESTS
|
||||
|
||||
(name:"SystemTests", assemblies: new[] {"MONOTOUCH_System_test.dll"}),
|
||||
|
@ -153,6 +162,77 @@ namespace BCLTestImporter {
|
|||
"MONOTOUCH_Mono.Data.Tds_test.dll", // issue https://gist.github.com/mandel-macaque/d97fa28f8a73c3016d1328567da77a0b
|
||||
};
|
||||
|
||||
private static readonly List<(string name, string[] assemblies)> macTestProjects = new List<(string name, string[] assemblies)> {
|
||||
|
||||
// NUNIT Projects
|
||||
(name:"MonoCSharpTests", assemblies: new [] {"xammac_net_4_5_Mono.CSharp_test.dll"}),
|
||||
(name:"MonoDataSqilteTests", assemblies: new [] {"xammac_net_4_5_Mono.Data.Sqlite_test.dll"}),
|
||||
(name:"MonoDataTdsTests", assemblies: new [] {"xammac_net_4_5_Mono.Data.Tds_test.dll"}),
|
||||
(name:"MonoPoxisTests", assemblies: new [] {"xammac_net_4_5_Mono.Posix_test.dll"}),
|
||||
(name:"MonoSecurtiyTests", assemblies: new [] {"xammac_net_4_5_Mono.Security_test.dll"}),
|
||||
(name:"SystemComponentModelDataAnnotationsTests", assemblies: new [] {"xammac_net_4_5_System.ComponentModel.DataAnnotations_test.dll"}),
|
||||
(name:"SystemConfigurationTests", assemblies: new [] {"xammac_net_4_5_System.Configuration_test.dll"}),
|
||||
(name:"SystemCoreTests", assemblies: new [] {"xammac_net_4_5_System.Core_test.dll"}),
|
||||
(name:"SystemDataLinqTests", assemblies: new [] {"xammac_net_4_5_System.Data.Linq_test.dll"}),
|
||||
(name:"SystemDataTests", assemblies: new [] {"xammac_net_4_5_System.Data_test.dll"}),
|
||||
(name:"SystemIOCompressionFileSystemTests", assemblies: new [] {"xammac_net_4_5_System.IO.Compression.FileSystem_test.dll"}),
|
||||
(name:"SystemIOCompressionTests", assemblies: new [] {"xammac_net_4_5_System.IO.Compression_test.dll"}),
|
||||
(name:"SystemIdentityModelTests", assemblies: new [] {"xammac_net_4_5_System.IdentityModel_test.dll"}),
|
||||
(name:"SystemJsonTests", assemblies: new [] {"xammac_net_4_5_System.Json_test.dll"}),
|
||||
(name:"SystemNetHttpTests", assemblies: new [] {"xammac_net_4_5_System.Net.Http_test.dll"}),
|
||||
(name:"SystemNumericsTests", assemblies: new [] {"xammac_net_4_5_System.Numerics_test.dll"}),
|
||||
(name:"SystemRuntimeSerializationFormattersSoapTests", assemblies: new [] {"xammac_net_4_5_System.Runtime.Serialization.Formatters.Soap_test.dll"}),
|
||||
(name:"SystemSecurityTests", assemblies: new [] {"xammac_net_4_5_System.Security_test.dll"}),
|
||||
(name:"SystemServiceModelTests", assemblies: new [] {"xammac_net_4_5_System.ServiceModel_test.dll"}),
|
||||
(name:"SystemTransactionsTests", assemblies: new [] {"xammac_net_4_5_System.Transactions_test.dll"}),
|
||||
(name:"SystemXmlLinqTests", assemblies: new [] {"xammac_net_4_5_System.Xml.Linq_test.dll"}),
|
||||
(name:"SystemXmlTests", assemblies: new [] {"xammac_net_4_5_System.Xml_test.dll"}),
|
||||
(name:"SystemTests", assemblies: new [] {"xammac_net_4_5_System_test.dll"}),
|
||||
|
||||
// xUnit Projects
|
||||
(name:"MicrosoftCSharpXunit", assemblies: new [] {"xammac_net_4_5_Microsoft.CSharp_xunit-test.dll"}),
|
||||
(name:"SystemCoreXunit", assemblies: new [] {"xammac_net_4_5_System.Core_xunit-test.dll"}),
|
||||
(name:"SystemDataXunit", assemblies: new [] {"xammac_net_4_5_System.Data_xunit-test.dll"}),
|
||||
(name:"SystemJsonXunit", assemblies: new [] {"xammac_net_4_5_System.Json_xunit-test.dll"}),
|
||||
(name:"SystemNumericsXunit", assemblies: new [] {"xammac_net_4_5_System.Numerics_xunit-test.dll"}),
|
||||
(name:"SystemRuntimeCompilerServicesXunit", assemblies: new [] {"xammac_net_4_5_System.Runtime.CompilerServices.Unsafe_xunit-test.dll"}),
|
||||
(name:"SystemSecurityXunit", assemblies: new [] {"xammac_net_4_5_System.Security_xunit-test.dll"}),
|
||||
(name:"SystemXmlLinqXunit", assemblies: new [] {"xammac_net_4_5_System.Xml.Linq_xunit-test.dll"}),
|
||||
(name:"SystemXunit", assemblies: new [] {"xammac_net_4_5_System_xunit-test.dll"}),
|
||||
(name:"CorlibXunit", assemblies: new [] {"xammac_net_4_5_corlib_xunit-test.dll"}),
|
||||
};
|
||||
|
||||
static readonly List<string> macIgnoredAssemblies = new List<string> {
|
||||
"xammac_net_4_5_corlib_test.dll ", // exception when loading the image via refection
|
||||
"xammac_net_4_5_I18N.CJK_test.dll",
|
||||
"xammac_net_4_5_I18N.MidEast_test.dll",
|
||||
"xammac_net_4_5_I18N.Other_test.dll",
|
||||
"xammac_net_4_5_I18N.Rare_test.dll",
|
||||
"xammac_net_4_5_I18N.West_test.dll",
|
||||
"xammac_net_4_5_Mono.CSharp_test.dll", //issue https://github.com/xamarin/maccore/issues/1186
|
||||
"xammac_net_4_5_Mono.Data.Sqlite_test.dll", // issue https://github.com/xamarin/maccore/issues/1187
|
||||
"xammac_net_4_5_Mono.Posix_test.dll", // issue https://github.com/xamarin/maccore/issues/1188
|
||||
"xammac_net_4_5_Mono.Posix_test.dll", // issues https://github.com/xamarin/maccore/issues/1189 and https://github.com/xamarin/maccore/issues/1190
|
||||
"xammac_net_4_5_System.Core_test.dll", // issue https://github.com/xamarin/maccore/issues/1191
|
||||
"xammac_net_4_5_System.Data_test.dll", // issues https://github.com/xamarin/maccore/issues/1192 and https://github.com/xamarin/maccore/issues/1193
|
||||
"xammac_net_4_5_System.IdentityModel_test.dll", // issues https://github.com/xamarin/maccore/issues/1194
|
||||
"xammac_net_4_5_System.IO.Compression.FileSystem_test.dll", // issues https://github.com/xamarin/maccore/issues/1195
|
||||
"xammac_net_4_5_System.IO.Compression_test.dll", // issue https://github.com/xamarin/maccore/issues/1146
|
||||
"xammac_net_4_5_System.IdentityModel_test.dll", // issues https://github.com/xamarin/maccore/issues/1196
|
||||
"xammac_net_4_5_System.Security_test.dll", // issue https://github.com/xamarin/maccore/issues/1197
|
||||
"xammac_net_4_5_System.ServiceModel_test.dll", // issues https://github.com/xamarin/maccore/issues/1198
|
||||
"xammac_net_4_5_System_test.dll", // issues https://github.com/xamarin/maccore/issues/1199
|
||||
"xammac_net_4_5_System.Transactions_test.dll", // issues https://github.com/xamarin/maccore/issues/1200
|
||||
"xammac_net_4_5_System.Xml_test.dll", // issues https://github.com/xamarin/maccore/issues/1201 and https://github.com/xamarin/maccore/issues/1202
|
||||
"xammac_net_4_5_corlib_xunit-test.dll", // issues https://github.com/xamarin/maccore/issues/1203
|
||||
"xammac_net_4_5_System.Core_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1204
|
||||
"xammac_net_4_5_System.Data_xunit-test.dll", // issue https://gist.github.com/mandel-macaque/3f4d1eeca511cb8654fb518cc3bb2e92
|
||||
"xammac_net_4_5_System_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1209
|
||||
"xammac_net_4_5_System.Configuration_test.dll", // issue https://github.com/xamarin/maccore/issues/1189 and https://github.com/xamarin/maccore/issues/1190
|
||||
"xammac_net_4_5_System.Security_xunit-test.dll", // https://github.com/xamarin/maccore/issues/1243
|
||||
|
||||
};
|
||||
|
||||
readonly bool isCodeGeneration;
|
||||
public bool Override { get; set; }
|
||||
public string OutputDirectoryPath { get; private set; }
|
||||
|
@ -195,6 +275,10 @@ namespace BCLTestImporter {
|
|||
return Path.Combine (OutputDirectoryPath, $"{projectName}-tvos.csproj");
|
||||
case Platform.WatchOS:
|
||||
return Path.Combine (OutputDirectoryPath, $"{projectName}-watchos.csproj");
|
||||
case Platform.MacOSFull:
|
||||
return Path.Combine (OutputDirectoryPath, $"{projectName}-mac-full.csproj");
|
||||
case Platform.MacOSModern:
|
||||
return Path.Combine (OutputDirectoryPath, $"{projectName}-mac-modern.csproj");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -225,6 +309,9 @@ namespace BCLTestImporter {
|
|||
return Path.Combine (rootDir, "Info-tv.plist");
|
||||
case Platform.WatchOS:
|
||||
return Path.Combine (rootDir, "Info-watchos.plist");
|
||||
case Platform.MacOSFull:
|
||||
case Platform.MacOSModern:
|
||||
return Path.Combine (rootDir, "Info-mac.plist");
|
||||
default:
|
||||
return Path.Combine (rootDir, "Info.plist");
|
||||
}
|
||||
|
@ -285,8 +372,9 @@ namespace BCLTestImporter {
|
|||
return tvOSIgnoredAssemblies.Contains (a.Name);
|
||||
case Platform.WatchOS:
|
||||
return watcOSIgnoredAssemblies.Contains (a.Name);
|
||||
default:
|
||||
return true;
|
||||
case Platform.MacOSFull:
|
||||
case Platform.MacOSModern:
|
||||
return macIgnoredAssemblies.Contains (a.Name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -314,7 +402,7 @@ namespace BCLTestImporter {
|
|||
}
|
||||
var registerTypePath = Path.Combine (generatedCodeDir, "RegisterType.cs");
|
||||
var registerCode = await RegisterTypeGenerator.GenerateCodeAsync (def.name, projectDefinition.IsXUnit,
|
||||
RegisterTypesTemplatePath);
|
||||
RegisterTypesTemplatePath, Platform.WatchOS);
|
||||
using (var file = new StreamWriter (registerTypePath, false)) { // false is do not append
|
||||
await file.WriteAsync (registerCode);
|
||||
}
|
||||
|
@ -391,7 +479,7 @@ namespace BCLTestImporter {
|
|||
var registerTypePath = Path.Combine (generatedCodeDir, "RegisterType.cs");
|
||||
|
||||
var registerCode = await RegisterTypeGenerator.GenerateCodeAsync (def.name, projectDefinition.IsXUnit,
|
||||
RegisterTypesTemplatePath);
|
||||
RegisterTypesTemplatePath, Platform.iOS);
|
||||
|
||||
using (var file = new StreamWriter (registerTypePath, false)) { // false is do not append
|
||||
await file.WriteAsync (registerCode);
|
||||
|
@ -417,6 +505,48 @@ namespace BCLTestImporter {
|
|||
return projectPaths;
|
||||
}
|
||||
|
||||
async Task<List<(string name, string path, bool xunit)>> GenerateMacTestProjectsAsync (
|
||||
IEnumerable<(string name, string[] assemblies)> projects, string generatedDir, Platform platform)
|
||||
{
|
||||
var projectPaths = new List<(string name, string path, bool xunit)> ();
|
||||
foreach (var def in projects) {
|
||||
var projectDefinition = new BCLTestProjectDefinition (def.name, def.assemblies);
|
||||
if (IsIgnored (projectDefinition, platform)) // some projects are ignored, so we just continue
|
||||
continue;
|
||||
|
||||
if (!projectDefinition.Validate ())
|
||||
throw new InvalidOperationException ("xUnit and NUnit assemblies cannot be mixed in a test project.");
|
||||
// generate the required type registration info
|
||||
var generatedCodeDir = Path.Combine (generatedDir, projectDefinition.Name);
|
||||
Directory.CreateDirectory (generatedCodeDir);
|
||||
var registerTypePath = Path.Combine (generatedCodeDir, "RegisterType-mac.cs");
|
||||
|
||||
var registerCode = await RegisterTypeGenerator.GenerateCodeAsync (def.name, projectDefinition.IsXUnit,
|
||||
RegisterTypesTemplatePath, platform);
|
||||
|
||||
using (var file = new StreamWriter (registerTypePath, false)) { // false is do not append
|
||||
await file.WriteAsync (registerCode);
|
||||
}
|
||||
|
||||
var plistTemplate = Path.Combine (PlistTemplateRootPath, plistTemplateMatches[platform]);
|
||||
var plist = await BCLTestInfoPlistGenerator.GenerateCodeAsync (plistTemplate, projectDefinition.Name);
|
||||
var infoPlistPath = GetPListPath (generatedCodeDir, platform);
|
||||
using (var file = new StreamWriter (infoPlistPath, false)) { // false is do not append
|
||||
await file.WriteAsync (plist);
|
||||
}
|
||||
|
||||
var projectTemplatePath = Path.Combine (ProjectTemplateRootPath, projectTemplateMatches[platform]);
|
||||
var generatedProject = await GenerateMacAsync (projectDefinition.Name, registerTypePath,
|
||||
projectDefinition.GetCachedAssemblyInclusionInformation (MonoRootPath, platform), projectTemplatePath, infoPlistPath, platform);
|
||||
var projectPath = GetProjectPath (projectDefinition.Name, platform);
|
||||
projectPaths.Add ((name: projectDefinition.Name, path: projectPath, xunit: projectDefinition.IsXUnit));
|
||||
using (var file = new StreamWriter (projectPath, false)) { // false is do not append
|
||||
await file.WriteAsync (generatedProject);
|
||||
}
|
||||
}
|
||||
return projectPaths;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates all the project files for the given projects and platform
|
||||
/// </summary>
|
||||
|
@ -428,11 +558,19 @@ namespace BCLTestImporter {
|
|||
async Task<List<(string name, string path, bool xunit)>> GenerateTestProjectsAsync (
|
||||
IEnumerable<(string name, string[] assemblies)> projects, Platform platform, string generatedDir)
|
||||
{
|
||||
List<(string name, string path, bool xunit)> result;
|
||||
if (platform == Platform.WatchOS)
|
||||
List<(string name, string path, bool xunit)> result = new List<(string name, string path, bool xunit)> ();
|
||||
switch (platform) {
|
||||
case Platform.WatchOS:
|
||||
result = await GenerateWatchOSTestProjectsAsync (projects, generatedDir);
|
||||
else
|
||||
break;
|
||||
case Platform.iOS:
|
||||
result = await GenerateiOSTestProjectsAsync (projects, platform, generatedDir);
|
||||
break;
|
||||
case Platform.MacOSFull:
|
||||
case Platform.MacOSModern:
|
||||
result = await GenerateMacTestProjectsAsync (projects, generatedDir, platform);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -449,7 +587,7 @@ namespace BCLTestImporter {
|
|||
|
||||
var projects = new Dictionary<string, (string path, bool xunit, List<Platform> platforms)> ();
|
||||
foreach (var platform in new [] {Platform.iOS, Platform.TvOS, Platform.WatchOS}) {
|
||||
var generated = await GenerateTestProjectsAsync (commonTestProjects, platform, generatedCodePathRoot);
|
||||
var generated = await GenerateTestProjectsAsync (commoniOSTestProjects, platform, generatedCodePathRoot);
|
||||
foreach (var (name, path, xunit) in generated) {
|
||||
if (!projects.ContainsKey (name)) {
|
||||
projects [name] = (path, xunit, new List<Platform> { platform });
|
||||
|
@ -467,7 +605,7 @@ namespace BCLTestImporter {
|
|||
}
|
||||
|
||||
// creates all the projects that have already been defined
|
||||
public async Task<List<(string name, string path, bool xunit, List<Platform> platforms)>> GenerateAllTestProjectsAsync ()
|
||||
public async Task<List<(string name, string path, bool xunit, List<Platform> platforms)>> GenerateAlliOSTestProjectsAsync ()
|
||||
{
|
||||
var projectPaths = new List<(string name, string path, bool xunit, List<Platform> platforms)> ();
|
||||
if (!isCodeGeneration)
|
||||
|
@ -482,8 +620,23 @@ namespace BCLTestImporter {
|
|||
return projectPaths;
|
||||
}
|
||||
|
||||
public List<(string name, string path, bool xunit, List<Platform> platforms)> GenerateAllTestProjects () => GenerateAllTestProjectsAsync ().Result;
|
||||
public List<(string name, string path, bool xunit, List<Platform> platforms)> GenerateAlliOSTestProjects () => GenerateAlliOSTestProjectsAsync ().Result;
|
||||
|
||||
public async Task<List<(string name, string path, bool xunit)>> GenerateAllMacTestProjectsAsync (Platform platform)
|
||||
{
|
||||
if (!isCodeGeneration)
|
||||
throw new InvalidOperationException ("Project generator was instantiated to delete the generated code.");
|
||||
var generatedCodePathRoot = GeneratedCodePathRoot;
|
||||
if (!Directory.Exists (generatedCodePathRoot)) {
|
||||
Directory.CreateDirectory (generatedCodePathRoot);
|
||||
}
|
||||
|
||||
var generated = await GenerateTestProjectsAsync (macTestProjects, platform, generatedCodePathRoot);
|
||||
return generated;
|
||||
}
|
||||
|
||||
public List<(string name, string path, bool xunit)> GenerateAllMacTestProjects (Platform platform) => GenerateAllMacTestProjectsAsync (platform).Result;
|
||||
|
||||
/// <summary>
|
||||
/// Generates an iOS project for testing purposes. The generated project will contain the references to the
|
||||
/// mono test assemblies to run.
|
||||
|
@ -514,6 +667,39 @@ namespace BCLTestImporter {
|
|||
}
|
||||
}
|
||||
|
||||
static async Task<string> GenerateMacAsync (string projectName, string registerPath, List<(string assembly, string hintPath)> info, string templatePath, string infoPlistPath, Platform platform)
|
||||
{
|
||||
infoPlistPath = infoPlistPath.Replace ('/', '\\');
|
||||
var sb = new StringBuilder ();
|
||||
foreach (var assemblyInfo in info) {
|
||||
if (!excludeDlls.Contains (assemblyInfo.assembly))
|
||||
sb.AppendLine (GetReferenceNode (assemblyInfo.assembly, assemblyInfo.hintPath));
|
||||
}
|
||||
|
||||
using (var reader = new StreamReader(templatePath)) {
|
||||
var result = await reader.ReadToEndAsync ();
|
||||
result = result.Replace (NameKey, projectName);
|
||||
result = result.Replace (ReferencesKey, sb.ToString ());
|
||||
result = result.Replace (RegisterTypeKey, GetRegisterTypeNode (registerPath));
|
||||
result = result.Replace (PlistKey, infoPlistPath);
|
||||
switch (platform){
|
||||
case Platform.MacOSFull:
|
||||
result = result.Replace (TargetFrameworkVersionKey, "v4.5");
|
||||
result = result.Replace (TargetExtraInfoKey,
|
||||
"<UseXamMacFullFramework>true</UseXamMacFullFramework>");
|
||||
result = result.Replace (DefineConstantsKey, "XAMCORE_2_0;ADD_BCL_EXCLUSIONS;XAMMAC_4_5");
|
||||
break;
|
||||
case Platform.MacOSModern:
|
||||
result = result.Replace (TargetFrameworkVersionKey, "v2.0");
|
||||
result = result.Replace (TargetExtraInfoKey,
|
||||
"<TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>");
|
||||
result = result.Replace (DefineConstantsKey, "XAMCORE_2_0;ADD_BCL_EXCLUSIONS;MOBILE;XAMMAC");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal string GenerateWatchProject (string projectName, string template, string infoPlistPath)
|
||||
{
|
||||
var result = template.Replace (NameKey, projectName);
|
||||
|
@ -568,14 +754,14 @@ namespace BCLTestImporter {
|
|||
Directory.Delete (GeneratedCodePathRoot, true);
|
||||
// delete all the common projects
|
||||
foreach (var platform in new [] {Platform.iOS, Platform.TvOS}) {
|
||||
foreach (var testProject in commonTestProjects) {
|
||||
foreach (var testProject in commoniOSTestProjects) {
|
||||
var projectPath = GetProjectPath (testProject.name, platform);
|
||||
if (File.Exists (projectPath))
|
||||
File.Delete (projectPath);
|
||||
}
|
||||
}
|
||||
// delete each of the generated project files
|
||||
foreach (var projectDefinition in commonTestProjects) {
|
||||
foreach (var projectDefinition in commoniOSTestProjects) {
|
||||
var projectPath = GetProjectPath (projectDefinition.name, Platform.iOS);
|
||||
if (File.Exists (projectPath))
|
||||
File.Delete (projectPath);
|
||||
|
@ -593,7 +779,7 @@ namespace BCLTestImporter {
|
|||
foreach (var platform in new [] {Platform.iOS, Platform.TvOS}) {
|
||||
var testDir = BCLTestAssemblyDefinition.GetTestDirectory (MonoRootPath, platform);
|
||||
var missingAssembliesPlatform = Directory.GetFiles (testDir, NUnitPattern).Select (Path.GetFileName).Union (
|
||||
Directory.GetFiles (testDir, xUnitPattern).Select (Path.GetFileName)).ToList ();
|
||||
Directory.GetFiles (testDir, xUnitPattern).Select (Path.GetFileName)).ToList ();
|
||||
|
||||
foreach (var assembly in CommonIgnoredAssemblies) {
|
||||
missingAssembliesPlatform.Remove (assembly);
|
||||
|
@ -601,7 +787,7 @@ namespace BCLTestImporter {
|
|||
|
||||
// loop over the mono root path and grab all the assemblies, then intersect the found ones with the added
|
||||
// and ignored ones.
|
||||
foreach (var projectDefinition in commonTestProjects) {
|
||||
foreach (var projectDefinition in commoniOSTestProjects) {
|
||||
foreach (var testAssembly in projectDefinition.assemblies) {
|
||||
missingAssembliesPlatform.Remove (testAssembly);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace BCLTestImporter {
|
|||
iOS,
|
||||
WatchOS,
|
||||
TvOS,
|
||||
MacOS,
|
||||
MacOSFull,
|
||||
MacOSModern,
|
||||
}
|
||||
}
|
|
@ -170,7 +170,7 @@ namespace BCLTestImporter {
|
|||
outputWriter.WriteLine ("Generated project is:");
|
||||
outputWriter.WriteLine (generatedProject);
|
||||
|
||||
using (var file = new StreamWriter (appOptions.Output, !appOptions.Override)) { // falso is do not append
|
||||
using (var file = new StreamWriter (appOptions.Output, !appOptions.Override)) { // false is do not append
|
||||
file.Write (generatedProject);
|
||||
}
|
||||
return 0;
|
||||
|
@ -186,7 +186,7 @@ namespace BCLTestImporter {
|
|||
var generatedCode = RegisterTypeGenerator.GenerateCode (typesPerAssembly, appOptions.IsXUnit, appOptions.RegisterTypeTemplate);
|
||||
outputWriter.WriteLine ("Generated code is:");
|
||||
outputWriter.WriteLine (generatedCode);
|
||||
using (var file = new StreamWriter (appOptions.Output, !appOptions.Override)) { // falso is do not append
|
||||
using (var file = new StreamWriter (appOptions.Output, !appOptions.Override)) { // false is do not append
|
||||
file.Write (generatedCode);
|
||||
}
|
||||
return 0;
|
||||
|
@ -213,7 +213,9 @@ namespace BCLTestImporter {
|
|||
}
|
||||
|
||||
outputWriter.WriteLine ("Generating all the registered test projects");
|
||||
projectGenerator.GenerateAllTestProjectsAsync ().Wait ();
|
||||
projectGenerator.GenerateAlliOSTestProjectsAsync().Wait ();
|
||||
projectGenerator.GenerateAllMacTestProjectsAsync(Platform.MacOSFull).Wait ();
|
||||
projectGenerator.GenerateAllMacTestProjectsAsync(Platform.MacOSModern).Wait ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BCLTestImporter {
|
|||
|
||||
// the following cache is a workaround until mono does provide the required binaries precompiled, at that point
|
||||
// we will remove the dict and we will use the refection based method.
|
||||
static Dictionary<string, (string testNamespace, string testAssembly, string testType)> cache = new Dictionary<string, (string testNamespace, string testAssembly, string testType)> {
|
||||
static Dictionary<string, (string testNamespace, string testAssembly, string testType)> iOSCache = new Dictionary<string, (string testNamespace, string testAssembly, string testType)> {
|
||||
{"SystemNumericsTests", ("MonoTests.System.Numerics", "MONOTOUCH_System.Numerics_test.dll", "MonoTests.System.Numerics.BigIntegerTest")},
|
||||
{"SystemRuntimeSerializationTests", ("MonoTests", "MONOTOUCH_System.Runtime.Serialization_test.dll", "MonoTests.XmlComparer")},
|
||||
{"SystemXmlLinqTests", ("MonoTests.System.Xml", "MONOTOUCH_System.Xml.Linq_test.dll", "MonoTests.System.Xml.ExtensionsTest")},
|
||||
|
@ -33,14 +33,61 @@ namespace BCLTestImporter {
|
|||
{"SystemLinqXunit", ("Microsoft.Test.ModuleCore", "MONOTOUCH_System.Xml.Linq_xunit-test.dll", "Microsoft.Test.ModuleCore.LtmContext")},
|
||||
{"SystemRuntimeCompilerServicesUnsafeXunit", ("System.Runtime.CompilerServices", "MONOTOUCH_System.Runtime.CompilerServices.Unsafe_xunit-test.dll", "System.Runtime.CompilerServices.UnsafeTests")},
|
||||
};
|
||||
|
||||
static Dictionary<string, (string testNamespace, string testAssembly, string testType)> macCache = new Dictionary<string, (string testNamespace, string testAssembly, string testType)> {
|
||||
{"MonoCSharpTests", ("MonoTests.Visit", "xammac_net_4_5_Mono.CSharp_test.dll", "MonoTests.Visit.ASTVisitorTest")},
|
||||
{"MonoDataSqilteTests", ("MonoTests.Mono.Data.Sqlite", "xammac_net_4_5_Mono.Data.Sqlite_test.dll", "MonoTests.Mono.Data.Sqlite.SqliteiOS82BugTests")},
|
||||
{"MonoDataTdsTests", ("MonoTests.Mono.Data.Tds", "xammac_net_4_5_Mono.Data.Tds_test.dll", "MonoTests.Mono.Data.Tds.TdsConnectionPoolTest")},
|
||||
{"MonoPoxisTests", ("MonoTests.System.IO", "xammac_net_4_5_Mono.Posix_test.dll", "MonoTests.System.IO.StdioFileStreamTest")},
|
||||
{"MonoSecurtiyTests", ("MonoTests.System.Security.Cryptography", "xammac_net_4_5_Mono.Security_test.dll", "MonoTests.System.Security.Cryptography.SHA224ManagedTest")},
|
||||
{"SystemComponentModelDataAnnotationsTests", ("MonoTests.System.ComponentModel.DataAnnotations", "xammac_net_4_5_System.ComponentModel.DataAnnotations_test.dll", "MonoTests.System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProviderTests")},
|
||||
{"SystemConfigurationTests", ("MonoTests.System.Configuration", "xammac_net_4_5_System.Configuration_test.dll", "MonoTests.System.Configuration.ProviderCollectionTest")},
|
||||
{"SystemCoreTests", ("MonoTests.System.Threading", "xammac_net_4_5_System.Core_test.dll", "MonoTests.System.Threading.ReaderWriterLockSlimTests")},
|
||||
{"SystemDataLinqTests", ("DbLinqTest", "xammac_net_4_5_System.Data.Linq_test.dll", "DbLinqTest.MsSqlDataContextTest")},
|
||||
{"SystemDataTests", ("MonoTests.System.Xml", "xammac_net_4_5_System.Data_test.dll", "MonoTests.System.Xml.XmlDataDocumentTest2")},
|
||||
{"SystemIOCompressionFileSystemTests", ("MonoTests.System.IO.Compression.FileSystem", "xammac_net_4_5_System.IO.Compression.FileSystem_test.dll", "MonoTests.System.IO.Compression.FileSystem.ZipArchiveTests")},
|
||||
{"SystemIOCompressionTests", ("MonoTests.System.IO.Compression", "xammac_net_4_5_System.IO.Compression_test.dll", "MonoTests.System.IO.Compression.ZipArchiveTests")},
|
||||
{"SystemIdentityModelTests", ("MonoTests.System.IdentityModel.Tokens", "xammac_net_4_5_System.IdentityModel_test.dll", "MonoTests.System.IdentityModel.Tokens.InMemorySymmetricSecurityKeyTest")},
|
||||
{"SystemJsonTests", ("MonoTests.System", "xammac_net_4_5_System.Json_test.dll", "MonoTests.System.JsonValueTests")},
|
||||
{"SystemNetHttpTests", ("MonoTests.System.Net.Http", "xammac_net_4_5_System.Net.Http_test.dll", "MonoTests.System.Net.Http.ByteArrayContentTest")},
|
||||
{"SystemNumericsTests", ("MonoTests.System.Numerics", "xammac_net_4_5_System.Numerics_test.dll", "MonoTests.System.Numerics.BigIntegerTest")},
|
||||
{"SystemRuntimeSerializationFormattersSoapTests", ("MonoTests.System.Runtime.Serialization.Formatters.Soap", "xammac_net_4_5_System.Runtime.Serialization.Formatters.Soap_test.dll", "MonoTests.System.Runtime.Serialization.Formatters.Soap.SerializationCallbackTest")},
|
||||
{"SystemSecurityTests", ("MonoCasTests.System.Security.Cryptography", "xammac_net_4_5_System.Security_test.dll", "MonoCasTests.System.Security.Cryptography.CryptographicAttributeObjectCas")},
|
||||
{"SystemTransactionsTests", ("MonoTests.System.Transactions", "xammac_net_4_5_System.Transactions_test.dll", "MonoTests.System.Transactions.AsyncTest")},
|
||||
{"SystemXmlLinqTests", ("MonoTests.System.Xml", "xammac_net_4_5_System.Xml.Linq_test.dll", "MonoTests.System.Xml.ExtensionsTest")},
|
||||
{"SystemXmlTests", ("nist_dom.fundamental", "xammac_net_4_5_System.Xml_test.dll", "nist_dom.fundamental.AttrTest")},
|
||||
{"SystemTests", ("MonoCasTests.System", "xammac_net_4_5_System_test.dll", "MonoCasTests.System.FileStyleUriParserCas")},
|
||||
{"MicrosoftCSharpXunit", ("Microsoft.CSharp.RuntimeBinder.Tests", "xammac_net_4_5_Microsoft.CSharp_xunit-test.dll", "Microsoft.CSharp.RuntimeBinder.Tests.AccessTests")},
|
||||
{"SystemCoreXunit", ("System.Dynamic.Tests", "xammac_net_4_5_System.Core_xunit-test.dll", "System.Dynamic.Tests.BinaryOperationTests")},
|
||||
{"SystemDataXunit", ("System.Data.SqlClient.Tests", "xammac_net_4_5_System.Data_xunit-test.dll", "System.Data.SqlClient.Tests.CloneTests")},
|
||||
{"SystemJsonXunit", ("System.Json.Tests", "xammac_net_4_5_System.Json_xunit-test.dll", "System.Json.Tests.JsonArrayTests")},
|
||||
{"SystemNumericsXunit", ("System.Numerics.Tests", "xammac_net_4_5_System.Numerics_xunit-test.dll", "System.Numerics.Tests.GenericVectorTests")},
|
||||
{"SystemRuntimeCompilerServicesXunit", ("System.Runtime.CompilerServices", "xammac_net_4_5_System.Runtime.CompilerServices.Unsafe_xunit-test.dll", "System.Runtime.CompilerServices.UnsafeTests")},
|
||||
{"SystemXmlLinqXunit", ("Microsoft.Test.ModuleCore", "xammac_net_4_5_System.Xml.Linq_xunit-test.dll", "Microsoft.Test.ModuleCore.LtmContext")},
|
||||
{"SystemServiceModelTests", ("MonoTests.System.ServiceModel", "xammac_net_4_5_System.ServiceModel_test.dll", "MonoTests.System.ServiceModel.Bug36080")},
|
||||
{"SystemSecurityXunit", ("System.Security.Cryptography.Pkcs.Tests", "xammac_net_4_5_System.Security_xunit-test.dll", "System.Security.Cryptography.Pkcs.Tests.CryptographicAttributeObjectCollectionTests")},
|
||||
{"SystemXunit", ("RegexTestNamespace", "xammac_net_4_5_System_xunit-test.dll", "RegexTestNamespace.RegexTestClass")},
|
||||
{"CorlibXunit", ("System.Collections.Generic.Tests", "xammac_net_4_5_corlib_xunit-test.dll", "System.Collections.Generic.Tests.ByteComparersTests")},
|
||||
};
|
||||
|
||||
public static async Task<string> GenerateCodeAsync (string projectName, bool isXunit, string templatePath)
|
||||
public static async Task<string> GenerateCodeAsync (string projectName, bool isXunit, string templatePath, Platform platform)
|
||||
{
|
||||
var cachedData = cache[projectName];
|
||||
Dictionary<string, (string testNamespace, string testAssembly, string testType)> cache = null;
|
||||
switch (platform){
|
||||
case Platform.iOS:
|
||||
case Platform.TvOS:
|
||||
case Platform.WatchOS:
|
||||
cache = iOSCache;
|
||||
break;
|
||||
case Platform.MacOSFull:
|
||||
case Platform.MacOSModern:
|
||||
cache = macCache;
|
||||
break;
|
||||
}
|
||||
var importStringBuilder = new StringBuilder ();
|
||||
var keyValuesStringBuilder = new StringBuilder ();
|
||||
importStringBuilder.AppendLine ($"using {cachedData.testNamespace};");
|
||||
keyValuesStringBuilder.AppendLine ($"\t\t\t{{ \"{cachedData.testAssembly}\", typeof ({cachedData.testType})}}, ");
|
||||
importStringBuilder.AppendLine ($"using {cache[projectName].testNamespace};");
|
||||
keyValuesStringBuilder.AppendLine ($"\t\t\t{{ \"{cache[projectName].testAssembly}\", typeof ({cache[projectName].testType})}}, ");
|
||||
// got the lines we want to add, read the template and substitute
|
||||
using (var reader = new StreamReader(templatePath)) {
|
||||
var result = await reader.ReadToEndAsync ();
|
||||
|
|
|
@ -126,47 +126,10 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the source file has a time stamp later than the target file.
|
||||
//
|
||||
// Optionally check if the contents of the files are different after checking the timestamp.
|
||||
//
|
||||
// If check_stamp is true, the function will use the timestamp of a "target".stamp file
|
||||
// if it's later than the timestamp of the "target" file itself.
|
||||
|
||||
public static bool IsUptodate (string source, string target, bool check_contents = false, bool check_stamp = true)
|
||||
{
|
||||
if (Driver.Force)
|
||||
return false;
|
||||
|
||||
var tfi = new FileInfo (target);
|
||||
|
||||
if (!tfi.Exists) {
|
||||
Driver.Log (3, "Target '{0}' does not exist.", target);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check_stamp) {
|
||||
var tfi_stamp = new FileInfo (target + ".stamp");
|
||||
if (tfi_stamp.Exists && tfi_stamp.LastWriteTimeUtc > tfi.LastWriteTimeUtc) {
|
||||
Driver.Log (3, "Target '{0}' has a stamp file with newer timestamp ({1} > {2}), using the stamp file's timestamp", target, tfi_stamp.LastWriteTimeUtc, tfi.LastWriteTimeUtc);
|
||||
tfi = tfi_stamp;
|
||||
}
|
||||
}
|
||||
|
||||
var sfi = new FileInfo (source);
|
||||
|
||||
if (sfi.LastWriteTimeUtc <= tfi.LastWriteTimeUtc) {
|
||||
Driver.Log (3, "Prerequisite '{0}' is older than the target '{1}'.", source, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (check_contents && Cache.CompareFiles (source, target)) {
|
||||
Driver.Log (3, "Prerequisite '{0}' is newer than the target '{1}', but the contents are identical.", source, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
Driver.Log (3, "Prerequisite '{0}' is newer than the target '{1}'.", source, target);
|
||||
return false;
|
||||
return FileCopier.IsUptodate (source, target, check_contents, check_stamp);
|
||||
}
|
||||
|
||||
public static void RemoveResource (ModuleDefinition module, string name)
|
||||
|
@ -229,107 +192,6 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
|
||||
enum CopyFileFlags : uint {
|
||||
ACL = 1 << 0,
|
||||
Stat = 1 << 1,
|
||||
Xattr = 1 << 2,
|
||||
Data = 1 << 3,
|
||||
Security = Stat | ACL,
|
||||
Metadata = Security | Xattr,
|
||||
All = Metadata | Data,
|
||||
|
||||
Recursive = 1 << 15,
|
||||
NoFollow_Src = 1 << 18,
|
||||
NoFollow_Dst = 1 << 19,
|
||||
Unlink = 1 << 21,
|
||||
Nofollow = NoFollow_Src | NoFollow_Dst,
|
||||
Clone = 1 << 24,
|
||||
}
|
||||
|
||||
enum CopyFileState : uint {
|
||||
StatusCB = 6,
|
||||
}
|
||||
|
||||
enum CopyFileStep {
|
||||
Start = 1,
|
||||
Finish = 2,
|
||||
Err = 3,
|
||||
Progress = 4,
|
||||
}
|
||||
|
||||
enum CopyFileResult {
|
||||
Continue = 0,
|
||||
Skip = 1,
|
||||
Quit = 2,
|
||||
}
|
||||
|
||||
enum CopyFileWhat {
|
||||
Error = 0,
|
||||
File = 1,
|
||||
Dir = 2,
|
||||
DirCleanup = 3,
|
||||
CopyData = 4,
|
||||
CopyXattr = 5,
|
||||
}
|
||||
|
||||
[DllImport (Constants.libSystemLibrary)]
|
||||
static extern IntPtr copyfile_state_alloc ();
|
||||
|
||||
[DllImport (Constants.libSystemLibrary)]
|
||||
static extern int copyfile_state_free (IntPtr state);
|
||||
|
||||
[DllImport (Constants.libSystemLibrary)]
|
||||
static extern int copyfile_state_set (IntPtr state, CopyFileState flag, IntPtr value);
|
||||
|
||||
delegate CopyFileResult CopyFileCallbackDelegate (CopyFileWhat what, CopyFileStep stage, IntPtr state, string src, string dst, IntPtr ctx);
|
||||
|
||||
[DllImport (Constants.libSystemLibrary, SetLastError = true)]
|
||||
static extern int copyfile (string @from, string @to, IntPtr state, CopyFileFlags flags);
|
||||
|
||||
public static void UpdateDirectory (string source, string target)
|
||||
{
|
||||
if (!Directory.Exists (target))
|
||||
Directory.CreateDirectory (target);
|
||||
|
||||
// Mono's File.Copy can't handle symlinks (the symlinks are followed instead of copied),
|
||||
// so we need to use native functions directly. Luckily OSX provides exactly what we need.
|
||||
IntPtr state = copyfile_state_alloc ();
|
||||
try {
|
||||
CopyFileCallbackDelegate del = CopyFileCallback;
|
||||
copyfile_state_set (state, CopyFileState.StatusCB, Marshal.GetFunctionPointerForDelegate (del));
|
||||
int rv = copyfile (source, target, state, CopyFileFlags.Data | CopyFileFlags.Recursive | CopyFileFlags.Nofollow | CopyFileFlags.Clone);
|
||||
if (rv != 0)
|
||||
throw ErrorHelper.CreateError (1022, "Could not copy the directory '{0}' to '{1}': {2}", source, target, Target.strerror (Marshal.GetLastWin32Error ()));
|
||||
} finally {
|
||||
copyfile_state_free (state);
|
||||
}
|
||||
}
|
||||
|
||||
static CopyFileResult CopyFileCallback (CopyFileWhat what, CopyFileStep stage, IntPtr state, string source, string target, IntPtr ctx)
|
||||
{
|
||||
// Console.WriteLine ("CopyFileCallback ({0}, {1}, 0x{2}, {3}, {4}, 0x{5})", what, stage, state.ToString ("x"), source, target, ctx.ToString ("x"));
|
||||
switch (what) {
|
||||
case CopyFileWhat.File:
|
||||
if (!IsUptodate (source, target)) {
|
||||
if (stage == CopyFileStep.Finish)
|
||||
Driver.Log (1, "Copied {0} to {1}", source, target);
|
||||
return CopyFileResult.Continue;
|
||||
} else {
|
||||
Driver.Log (3, "Target '{0}' is up-to-date", target);
|
||||
return CopyFileResult.Skip;
|
||||
}
|
||||
case CopyFileWhat.Dir:
|
||||
case CopyFileWhat.DirCleanup:
|
||||
case CopyFileWhat.CopyData:
|
||||
case CopyFileWhat.CopyXattr:
|
||||
return CopyFileResult.Continue;
|
||||
case CopyFileWhat.Error:
|
||||
throw ErrorHelper.CreateError (1021, "Could not copy the file '{0}' to '{1}': {2}", source, target, Target.strerror (Marshal.GetLastWin32Error ()));
|
||||
default:
|
||||
return CopyFileResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateFile (string source, string target, bool check_contents = false)
|
||||
{
|
||||
if (!Application.IsUptodate (source, target, check_contents))
|
||||
|
@ -394,6 +256,11 @@ namespace Xamarin.Bundler {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void UpdateDirectory (string source, string target)
|
||||
{
|
||||
FileCopier.UpdateDirectory (source, target);
|
||||
}
|
||||
|
||||
[DllImport (Constants.libSystemLibrary)]
|
||||
static extern int readlink (string path, IntPtr buf, int len);
|
||||
|
|
|
@ -4,10 +4,11 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using System.Xml;
|
||||
using Mono.Cecil;
|
||||
using MonoTouch.Tuner;
|
||||
using ObjCRuntime;
|
||||
using Xamarin;
|
||||
using Xamarin.Utils;
|
||||
|
||||
#if MONOTOUCH
|
||||
|
@ -18,6 +19,39 @@ using PlatformException = Xamarin.Bundler.MonoMacException;
|
|||
|
||||
|
||||
namespace Xamarin.Bundler {
|
||||
|
||||
struct NativeReferenceMetadata
|
||||
{
|
||||
public bool ForceLoad;
|
||||
public string Frameworks;
|
||||
public string WeakFrameworks;
|
||||
public string LibraryName;
|
||||
public string LinkerFlags;
|
||||
public LinkTarget LinkTarget;
|
||||
public bool NeedsGccExceptionHandling;
|
||||
public bool IsCxx;
|
||||
public bool SmartLink;
|
||||
public DlsymOption Dlsym;
|
||||
|
||||
// Optional
|
||||
public LinkWithAttribute Attribute;
|
||||
|
||||
public NativeReferenceMetadata (LinkWithAttribute attribute)
|
||||
{
|
||||
ForceLoad = attribute.ForceLoad;
|
||||
Frameworks = attribute.Frameworks;
|
||||
WeakFrameworks = attribute.WeakFrameworks;
|
||||
LibraryName = attribute.LibraryName;
|
||||
LinkerFlags = attribute.LinkerFlags;
|
||||
LinkTarget = attribute.LinkTarget;
|
||||
NeedsGccExceptionHandling = attribute.NeedsGccExceptionHandling;
|
||||
IsCxx = attribute.IsCxx;
|
||||
SmartLink = attribute.SmartLink;
|
||||
Dlsym = attribute.Dlsym;
|
||||
Attribute = attribute;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Assembly
|
||||
{
|
||||
public List<string> Satellites;
|
||||
|
@ -112,138 +146,35 @@ namespace Xamarin.Bundler {
|
|||
// ignore framework assemblies, they won't have any LinkWith attributes
|
||||
if (IsFrameworkAssembly)
|
||||
return;
|
||||
|
||||
|
||||
var assembly = AssemblyDefinition;
|
||||
if (!assembly.HasCustomAttributes)
|
||||
return;
|
||||
|
||||
var exceptions = new List<Exception> ();
|
||||
string path;
|
||||
|
||||
//
|
||||
// Tasks:
|
||||
// * Remove LinkWith attribute: this is done in the linker.
|
||||
// * Remove embedded resources related to LinkWith attribute from assembly: this is done at a later stage,
|
||||
// here we just compile a list of resources to remove.
|
||||
// * Extract embedded resources related to LinkWith attribute to a file
|
||||
// * Modify the linker flags used to build/link the dylib (if fastdev) or the main binary (if !fastdev)
|
||||
//
|
||||
string resourceBundlePath = Path.ChangeExtension (FullPath, ".resources");
|
||||
string manifestPath = Path.Combine (resourceBundlePath, "manifest");
|
||||
if (File.Exists (manifestPath)) {
|
||||
foreach (NativeReferenceMetadata metadata in ReadManifest (manifestPath)) {
|
||||
LogNativeReference (metadata);
|
||||
ProcessNativeReferenceOptions (metadata);
|
||||
|
||||
for (int i = 0; i < assembly.CustomAttributes.Count; i++) {
|
||||
CustomAttribute attr = assembly.CustomAttributes[i];
|
||||
|
||||
if (attr.Constructor == null)
|
||||
continue;
|
||||
|
||||
TypeReference type = attr.Constructor.DeclaringType;
|
||||
if (!type.IsPlatformType ("ObjCRuntime", "LinkWithAttribute"))
|
||||
continue;
|
||||
|
||||
// Let the linker remove it the attribute from the assembly
|
||||
HasLinkWithAttributes = true;
|
||||
|
||||
LinkWithAttribute linkWith = GetLinkWithAttribute (attr);
|
||||
string libraryName = linkWith.LibraryName;
|
||||
|
||||
// Remove the resource from the assembly at a later stage.
|
||||
if (!string.IsNullOrEmpty (libraryName))
|
||||
AddResourceToBeRemoved (libraryName);
|
||||
|
||||
// We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled.
|
||||
if (!linkWith.SmartLink)
|
||||
App.DeadStrip = false;
|
||||
|
||||
// Don't add -force_load if the binding's SmartLink value is set and the static registrar is being used.
|
||||
if (linkWith.ForceLoad && !(linkWith.SmartLink && App.Registrar == RegistrarMode.Static))
|
||||
ForceLoad = true;
|
||||
|
||||
if (!string.IsNullOrEmpty (linkWith.LinkerFlags)) {
|
||||
if (LinkerFlags == null)
|
||||
LinkerFlags = new List<string> ();
|
||||
LinkerFlags.Add (linkWith.LinkerFlags);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (linkWith.Frameworks)) {
|
||||
foreach (var f in linkWith.Frameworks.Split (new char[] { ' ' })) {
|
||||
if (Frameworks == null)
|
||||
Frameworks = new HashSet<string> ();
|
||||
Frameworks.Add (f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (linkWith.WeakFrameworks)) {
|
||||
foreach (var f in linkWith.WeakFrameworks.Split (new char[] { ' ' })) {
|
||||
if (WeakFrameworks == null)
|
||||
WeakFrameworks = new HashSet<string> ();
|
||||
WeakFrameworks.Add (f);
|
||||
}
|
||||
}
|
||||
|
||||
if (linkWith.NeedsGccExceptionHandling)
|
||||
NeedsGccExceptionHandling = true;
|
||||
|
||||
if (linkWith.IsCxx)
|
||||
EnableCxx = true;
|
||||
|
||||
#if MONOTOUCH
|
||||
if (linkWith.Dlsym != DlsymOption.Default)
|
||||
App.SetDlsymOption (FullPath, linkWith.Dlsym == DlsymOption.Required);
|
||||
if (metadata.LibraryName.EndsWith (".framework", StringComparison.OrdinalIgnoreCase)) {
|
||||
AssertiOSVersionSupportsUserFrameworks (metadata.LibraryName);
|
||||
Frameworks.Add (metadata.LibraryName);
|
||||
#if MMP // HACK - MMP currently doesn't respect Frameworks on non-App - https://github.com/xamarin/xamarin-macios/issues/5203
|
||||
App.Frameworks.Add (metadata.LibraryName);
|
||||
#endif
|
||||
|
||||
if (!string.IsNullOrEmpty (libraryName)) {
|
||||
path = Path.Combine (App.Cache.Location, libraryName);
|
||||
if (path.EndsWith (".framework", StringComparison.Ordinal)) {
|
||||
#if MONOTOUCH
|
||||
if (App.Platform == Xamarin.Utils.ApplePlatform.iOS && App.DeploymentTarget.Major < 8) {
|
||||
throw ErrorHelper.CreateError (1305, "The binding library '{0}' contains a user framework ({0}), but embedded user frameworks require iOS 8.0 (the deployment target is {1}). Please set the deployment target in the Info.plist file to at least 8.0.",
|
||||
FileName, Path.GetFileName (path), App.DeploymentTarget);
|
||||
}
|
||||
#endif
|
||||
var zipPath = path + ".zip";
|
||||
if (!Application.IsUptodate (FullPath, zipPath)) {
|
||||
Application.ExtractResource (assembly.MainModule, libraryName, zipPath, false);
|
||||
Driver.Log (3, "Extracted third-party framework '{0}' from '{1}' to '{2}'", libraryName, FullPath, zipPath);
|
||||
LogLinkWithAttribute (linkWith);
|
||||
} else {
|
||||
Driver.Log (3, "Target '{0}' is up-to-date.", path);
|
||||
}
|
||||
|
||||
if (!File.Exists (zipPath)) {
|
||||
ErrorHelper.Warning (1302, "Could not extract the native framework '{0}' from '{1}'. " +
|
||||
"Please ensure the native framework was properly embedded in the managed assembly " +
|
||||
"(if the assembly was built using a binding project, the native framework must be included in the project, and its Build Action must be 'ObjcBindingNativeFramework').",
|
||||
libraryName, zipPath);
|
||||
} else {
|
||||
if (!Directory.Exists (path))
|
||||
Directory.CreateDirectory (path);
|
||||
|
||||
if (Driver.RunCommand ("/usr/bin/unzip", string.Format ("-u -o -d {0} {1}", StringUtils.Quote (path), StringUtils.Quote (zipPath))) != 0)
|
||||
throw ErrorHelper.CreateError (1303, "Could not decompress the native framework '{0}' from '{1}'. Please review the build log for more information from the native 'unzip' command.", libraryName, zipPath);
|
||||
}
|
||||
|
||||
Frameworks.Add (path);
|
||||
} else {
|
||||
if (!Application.IsUptodate (FullPath, path)) {
|
||||
Application.ExtractResource (assembly.MainModule, libraryName, path, false);
|
||||
Driver.Log (3, "Extracted third-party binding '{0}' from '{1}' to '{2}'", libraryName, FullPath, path);
|
||||
LogLinkWithAttribute (linkWith);
|
||||
} else {
|
||||
Driver.Log (3, "Target '{0}' is up-to-date.", path);
|
||||
}
|
||||
|
||||
if (!File.Exists (path))
|
||||
ErrorHelper.Warning (1302, "Could not extract the native library '{0}' from '{1}'. " +
|
||||
"Please ensure the native library was properly embedded in the managed assembly " +
|
||||
"(if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').",
|
||||
libraryName, path);
|
||||
|
||||
LinkWith.Add (path);
|
||||
#if MMP // HACK - MMP currently doesn't respect LinkWith - https://github.com/xamarin/xamarin-macios/issues/5203
|
||||
Driver.native_references.Add (metadata.LibraryName);
|
||||
#endif
|
||||
LinkWith.Add (metadata.LibraryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exceptions != null && exceptions.Count > 0)
|
||||
throw new AggregateException (exceptions);
|
||||
ProcessLinkWithAttributes (assembly);
|
||||
|
||||
// Make sure there are no duplicates between frameworks and weak frameworks.
|
||||
// Keep the weak ones.
|
||||
|
@ -258,16 +189,202 @@ namespace Xamarin.Bundler {
|
|||
|
||||
}
|
||||
|
||||
static void LogLinkWithAttribute (LinkWithAttribute linkWith)
|
||||
IEnumerable <NativeReferenceMetadata> ReadManifest (string manifestPath)
|
||||
{
|
||||
Driver.Log (3, " ForceLoad: {0}", linkWith.ForceLoad);
|
||||
Driver.Log (3, " Frameworks: {0}", linkWith.Frameworks);
|
||||
Driver.Log (3, " IsCxx: {0}", linkWith.IsCxx);
|
||||
Driver.Log (3, " LinkerFlags: {0}", linkWith.LinkerFlags);
|
||||
Driver.Log (3, " LinkTarget: {0}", linkWith.LinkTarget);
|
||||
Driver.Log (3, " NeedsGccExceptionHandling: {0}", linkWith.NeedsGccExceptionHandling);
|
||||
Driver.Log (3, " SmartLink: {0}", linkWith.SmartLink);
|
||||
Driver.Log (3, " WeakFrameworks: {0}", linkWith.WeakFrameworks);
|
||||
XmlDocument document = new XmlDocument ();
|
||||
document.LoadWithoutNetworkAccess (manifestPath);
|
||||
|
||||
foreach (XmlNode referenceNode in document.GetElementsByTagName ("NativeReference")) {
|
||||
|
||||
NativeReferenceMetadata metadata = new NativeReferenceMetadata ();
|
||||
metadata.LibraryName = Path.Combine (Path.GetDirectoryName (manifestPath), referenceNode.Attributes ["Name"].Value);
|
||||
|
||||
var attributes = new Dictionary<string, string> ();
|
||||
foreach (XmlNode attribute in referenceNode.ChildNodes)
|
||||
attributes [attribute.Name] = attribute.InnerText;
|
||||
|
||||
metadata.ForceLoad = ParseAttributeWithDefault (attributes ["ForceLoad"], false);
|
||||
metadata.Frameworks = attributes ["Frameworks"];
|
||||
metadata.WeakFrameworks = attributes ["WeakFrameworks"];
|
||||
metadata.LinkerFlags = attributes ["LinkerFlags"];
|
||||
metadata.NeedsGccExceptionHandling = ParseAttributeWithDefault (attributes ["NeedsGccExceptionHandling"], false);
|
||||
metadata.IsCxx = ParseAttributeWithDefault (attributes ["IsCxx"], false);
|
||||
metadata.SmartLink = ParseAttributeWithDefault (attributes ["SmartLink"], true);
|
||||
|
||||
// TODO - The project attributes do not contain these bits, is that OK?
|
||||
//metadata.LinkTarget = (LinkTarget) Enum.Parse (typeof (LinkTarget), attributes ["LinkTarget"]);
|
||||
//metadata.Dlsym = (DlsymOption)Enum.Parse (typeof (DlsymOption), attributes ["Dlsym"]);
|
||||
yield return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ParseAttributeWithDefault (string attribute, bool defaultValue) => string.IsNullOrEmpty (attribute) ? defaultValue : bool.Parse (attribute);
|
||||
|
||||
void ProcessLinkWithAttributes (AssemblyDefinition assembly)
|
||||
{
|
||||
//
|
||||
// Tasks:
|
||||
// * Remove LinkWith attribute: this is done in the linker.
|
||||
// * Remove embedded resources related to LinkWith attribute from assembly: this is done at a later stage,
|
||||
// here we just compile a list of resources to remove.
|
||||
// * Extract embedded resources related to LinkWith attribute to a file
|
||||
// * Modify the linker flags used to build/link the dylib (if fastdev) or the main binary (if !fastdev)
|
||||
//
|
||||
|
||||
for (int i = 0; i < assembly.CustomAttributes.Count; i++) {
|
||||
CustomAttribute attr = assembly.CustomAttributes [i];
|
||||
|
||||
if (attr.Constructor == null)
|
||||
continue;
|
||||
|
||||
TypeReference type = attr.Constructor.DeclaringType;
|
||||
if (!type.IsPlatformType ("ObjCRuntime", "LinkWithAttribute"))
|
||||
continue;
|
||||
|
||||
// Let the linker remove it the attribute from the assembly
|
||||
HasLinkWithAttributes = true;
|
||||
|
||||
LinkWithAttribute linkWith = GetLinkWithAttribute (attr);
|
||||
NativeReferenceMetadata metadata = new NativeReferenceMetadata (linkWith);
|
||||
|
||||
// If we've already processed this native library, skip it
|
||||
if (LinkWith.Any (x => Path.GetFileName (x) == metadata.LibraryName) || Frameworks.Any (x => Path.GetFileName (x) == metadata.LibraryName))
|
||||
continue;
|
||||
|
||||
// Remove the resource from the assembly at a later stage.
|
||||
if (!string.IsNullOrEmpty (metadata.LibraryName))
|
||||
AddResourceToBeRemoved (metadata.LibraryName);
|
||||
|
||||
ProcessNativeReferenceOptions (metadata);
|
||||
|
||||
if (!string.IsNullOrEmpty (linkWith.LibraryName)) {
|
||||
if (linkWith.LibraryName.EndsWith (".framework", StringComparison.OrdinalIgnoreCase)) {
|
||||
AssertiOSVersionSupportsUserFrameworks (linkWith.LibraryName);
|
||||
|
||||
Frameworks.Add (ExtractFramework (assembly, metadata));
|
||||
} else {
|
||||
LinkWith.Add (ExtractNativeLibrary (assembly, metadata));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssertiOSVersionSupportsUserFrameworks (string path)
|
||||
{
|
||||
#if MONOTOUCH
|
||||
if (App.Platform == Xamarin.Utils.ApplePlatform.iOS && App.DeploymentTarget.Major < 8) {
|
||||
throw ErrorHelper.CreateError (1305, "The binding library '{0}' contains a user framework ({0}), but embedded user frameworks require iOS 8.0 (the deployment target is {1}). Please set the deployment target in the Info.plist file to at least 8.0.",
|
||||
FileName, Path.GetFileName (path), App.DeploymentTarget);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ProcessNativeReferenceOptions (NativeReferenceMetadata metadata)
|
||||
{
|
||||
// We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled.
|
||||
if (!metadata.SmartLink)
|
||||
App.DeadStrip = false;
|
||||
|
||||
// Don't add -force_load if the binding's SmartLink value is set and the static registrar is being used.
|
||||
if (metadata.ForceLoad && !(metadata.SmartLink && App.Registrar == RegistrarMode.Static))
|
||||
ForceLoad = true;
|
||||
|
||||
if (!string.IsNullOrEmpty (metadata.LinkerFlags)) {
|
||||
if (LinkerFlags == null)
|
||||
LinkerFlags = new List<string> ();
|
||||
LinkerFlags.Add (metadata.LinkerFlags);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (metadata.Frameworks)) {
|
||||
foreach (var f in metadata.Frameworks.Split (new char [] { ' ' })) {
|
||||
if (Frameworks == null)
|
||||
Frameworks = new HashSet<string> ();
|
||||
Frameworks.Add (f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (metadata.WeakFrameworks)) {
|
||||
foreach (var f in metadata.WeakFrameworks.Split (new char [] { ' ' })) {
|
||||
if (WeakFrameworks == null)
|
||||
WeakFrameworks = new HashSet<string> ();
|
||||
WeakFrameworks.Add (f);
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.NeedsGccExceptionHandling)
|
||||
NeedsGccExceptionHandling = true;
|
||||
|
||||
if (metadata.IsCxx)
|
||||
EnableCxx = true;
|
||||
|
||||
#if MONOTOUCH
|
||||
if (metadata.Dlsym != DlsymOption.Default)
|
||||
App.SetDlsymOption (FullPath, metadata.Dlsym == DlsymOption.Required);
|
||||
#endif
|
||||
}
|
||||
|
||||
string ExtractNativeLibrary (AssemblyDefinition assembly, NativeReferenceMetadata metadata)
|
||||
{
|
||||
string path = Path.Combine (App.Cache.Location, metadata.LibraryName);
|
||||
|
||||
if (!Application.IsUptodate (FullPath, path)) {
|
||||
Application.ExtractResource (assembly.MainModule, metadata.LibraryName, path, false);
|
||||
Driver.Log (3, "Extracted third-party binding '{0}' from '{1}' to '{2}'", metadata.LibraryName, FullPath, path);
|
||||
LogNativeReference (metadata);
|
||||
} else {
|
||||
Driver.Log (3, "Target '{0}' is up-to-date.", path);
|
||||
}
|
||||
|
||||
if (!File.Exists (path))
|
||||
ErrorHelper.Warning (1302, "Could not extract the native library '{0}' from '{1}'. " +
|
||||
"Please ensure the native library was properly embedded in the managed assembly " +
|
||||
"(if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').",
|
||||
metadata.LibraryName, path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
string ExtractFramework (AssemblyDefinition assembly, NativeReferenceMetadata metadata)
|
||||
{
|
||||
string path = Path.Combine (App.Cache.Location, metadata.LibraryName);
|
||||
|
||||
var zipPath = path + ".zip";
|
||||
if (!Application.IsUptodate (FullPath, zipPath)) {
|
||||
Application.ExtractResource (assembly.MainModule, metadata.LibraryName, zipPath, false);
|
||||
Driver.Log (3, "Extracted third-party framework '{0}' from '{1}' to '{2}'", metadata.LibraryName, FullPath, zipPath);
|
||||
LogNativeReference (metadata);
|
||||
} else {
|
||||
Driver.Log (3, "Target '{0}' is up-to-date.", path);
|
||||
}
|
||||
|
||||
if (!File.Exists (zipPath)) {
|
||||
ErrorHelper.Warning (1302, "Could not extract the native framework '{0}' from '{1}'. " +
|
||||
"Please ensure the native framework was properly embedded in the managed assembly " +
|
||||
"(if the assembly was built using a binding project, the native framework must be included in the project, and its Build Action must be 'ObjcBindingNativeFramework').",
|
||||
metadata.LibraryName, zipPath);
|
||||
} else {
|
||||
if (!Directory.Exists (path))
|
||||
Directory.CreateDirectory (path);
|
||||
|
||||
if (Driver.RunCommand ("/usr/bin/unzip", string.Format ("-u -o -d {0} {1}", StringUtils.Quote (path), StringUtils.Quote (zipPath))) != 0)
|
||||
throw ErrorHelper.CreateError (1303, "Could not decompress the native framework '{0}' from '{1}'. Please review the build log for more information from the native 'unzip' command.", metadata.LibraryName, zipPath);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void LogNativeReference (NativeReferenceMetadata metadata)
|
||||
{
|
||||
Driver.Log (3, " LibraryName: {0}", metadata.LibraryName);
|
||||
Driver.Log (3, " From: {0}", metadata.Attribute != null ? "LinkWith" : "Binding Manifest");
|
||||
Driver.Log (3, " ForceLoad: {0}", metadata.ForceLoad);
|
||||
Driver.Log (3, " Frameworks: {0}", metadata.Frameworks);
|
||||
Driver.Log (3, " IsCxx: {0}", metadata.IsCxx);
|
||||
Driver.Log (3, " LinkerFlags: {0}", metadata.LinkerFlags);
|
||||
Driver.Log (3, " LinkTarget: {0}", metadata.LinkTarget);
|
||||
Driver.Log (3, " NeedsGccExceptionHandling: {0}", metadata.NeedsGccExceptionHandling);
|
||||
Driver.Log (3, " SmartLink: {0}", metadata.SmartLink);
|
||||
Driver.Log (3, " WeakFrameworks: {0}", metadata.WeakFrameworks);
|
||||
}
|
||||
|
||||
public static LinkWithAttribute GetLinkWithAttribute (CustomAttribute attr)
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Xamarin.Bundler {
|
||||
public static class FileCopier
|
||||
{
|
||||
enum CopyFileFlags : uint {
|
||||
ACL = 1 << 0,
|
||||
Stat = 1 << 1,
|
||||
Xattr = 1 << 2,
|
||||
Data = 1 << 3,
|
||||
Security = Stat | ACL,
|
||||
Metadata = Security | Xattr,
|
||||
All = Metadata | Data,
|
||||
|
||||
Recursive = 1 << 15,
|
||||
NoFollow_Src = 1 << 18,
|
||||
NoFollow_Dst = 1 << 19,
|
||||
Unlink = 1 << 21,
|
||||
Nofollow = NoFollow_Src | NoFollow_Dst,
|
||||
Clone = 1 << 24,
|
||||
}
|
||||
|
||||
enum CopyFileState : uint {
|
||||
StatusCB = 6,
|
||||
}
|
||||
|
||||
enum CopyFileStep {
|
||||
Start = 1,
|
||||
Finish = 2,
|
||||
Err = 3,
|
||||
Progress = 4,
|
||||
}
|
||||
|
||||
enum CopyFileResult {
|
||||
Continue = 0,
|
||||
Skip = 1,
|
||||
Quit = 2,
|
||||
}
|
||||
|
||||
enum CopyFileWhat {
|
||||
Error = 0,
|
||||
File = 1,
|
||||
Dir = 2,
|
||||
DirCleanup = 3,
|
||||
CopyData = 4,
|
||||
CopyXattr = 5,
|
||||
}
|
||||
|
||||
[DllImport ("/usr/lib/libSystem.dylib")]
|
||||
static extern IntPtr copyfile_state_alloc ();
|
||||
|
||||
[DllImport ("/usr/lib/libSystem.dylib")]
|
||||
static extern int copyfile_state_free (IntPtr state);
|
||||
|
||||
[DllImport ("/usr/lib/libSystem.dylib")]
|
||||
static extern int copyfile_state_set (IntPtr state, CopyFileState flag, IntPtr value);
|
||||
|
||||
delegate CopyFileResult CopyFileCallbackDelegate (CopyFileWhat what, CopyFileStep stage, IntPtr state, string src, string dst, IntPtr ctx);
|
||||
|
||||
[DllImport ("/usr/lib/libSystem.dylib", SetLastError = true)]
|
||||
static extern int copyfile (string @from, string @to, IntPtr state, CopyFileFlags flags);
|
||||
|
||||
// This code is shared between our packaging tools (mmp\mtouch) and msbuild tasks
|
||||
#if MMP || MTOUCH
|
||||
public static void Log (int min_verbosity, string format, params object[] args) => Driver.Log (min_verbosity, format, args);
|
||||
public static Exception CreateError (int code, string message, params object[] args) => ErrorHelper.CreateError (code, message, args);
|
||||
#else
|
||||
// LogMessage and LogError are instance objects on the tasks themselves and bubbling an event up is not ideal
|
||||
// msbuild handles uncaught exceptions as a task error
|
||||
public static void Log (int min_verbosity, string format, params object[] args) => Console.WriteLine (format, args);
|
||||
public static Exception CreateError (int code, string message, params object[] args) => throw new Exception ($"{code} {string.Format (message, args)}");
|
||||
#endif
|
||||
|
||||
public static void UpdateDirectory (string source, string target)
|
||||
{
|
||||
if (!Directory.Exists (target))
|
||||
Directory.CreateDirectory (target);
|
||||
|
||||
// Mono's File.Copy can't handle symlinks (the symlinks are followed instead of copied),
|
||||
// so we need to use native functions directly. Luckily OSX provides exactly what we need.
|
||||
IntPtr state = copyfile_state_alloc ();
|
||||
try {
|
||||
CopyFileCallbackDelegate del = CopyFileCallback;
|
||||
copyfile_state_set (state, CopyFileState.StatusCB, Marshal.GetFunctionPointerForDelegate (del));
|
||||
int rv = copyfile (source, target, state, CopyFileFlags.Data | CopyFileFlags.Recursive | CopyFileFlags.Nofollow | CopyFileFlags.Clone);
|
||||
if (rv != 0)
|
||||
throw CreateError (1022, "Could not copy the directory '{0}' to '{1}': {2}", source, target, strerror (Marshal.GetLastWin32Error ()));
|
||||
} finally {
|
||||
copyfile_state_free (state);
|
||||
}
|
||||
}
|
||||
|
||||
static CopyFileResult CopyFileCallback (CopyFileWhat what, CopyFileStep stage, IntPtr state, string source, string target, IntPtr ctx)
|
||||
{
|
||||
// Console.WriteLine ("CopyFileCallback ({0}, {1}, 0x{2}, {3}, {4}, 0x{5})", what, stage, state.ToString ("x"), source, target, ctx.ToString ("x"));
|
||||
switch (what) {
|
||||
case CopyFileWhat.File:
|
||||
if (!IsUptodate (source, target)) {
|
||||
if (stage == CopyFileStep.Finish)
|
||||
Log (1, "Copied {0} to {1}", source, target);
|
||||
return CopyFileResult.Continue;
|
||||
} else {
|
||||
Log (3, "Target '{0}' is up-to-date", target);
|
||||
return CopyFileResult.Skip;
|
||||
}
|
||||
case CopyFileWhat.Dir:
|
||||
case CopyFileWhat.DirCleanup:
|
||||
case CopyFileWhat.CopyData:
|
||||
case CopyFileWhat.CopyXattr:
|
||||
return CopyFileResult.Continue;
|
||||
case CopyFileWhat.Error:
|
||||
throw CreateError (1021, "Could not copy the file '{0}' to '{1}': {2}", source, target, strerror (Marshal.GetLastWin32Error ()));
|
||||
default:
|
||||
return CopyFileResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the source file has a time stamp later than the target file.
|
||||
//
|
||||
// Optionally check if the contents of the files are different after checking the timestamp.
|
||||
//
|
||||
// If check_stamp is true, the function will use the timestamp of a "target".stamp file
|
||||
// if it's later than the timestamp of the "target" file itself.
|
||||
public static bool IsUptodate (string source, string target, bool check_contents = false, bool check_stamp = true)
|
||||
{
|
||||
#if MMP || MTOUCH // msbuild does not have force
|
||||
if (Driver.Force)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
var tfi = new FileInfo (target);
|
||||
|
||||
if (!tfi.Exists) {
|
||||
Log (3, "Target '{0}' does not exist.", target);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check_stamp) {
|
||||
var tfi_stamp = new FileInfo (target + ".stamp");
|
||||
if (tfi_stamp.Exists && tfi_stamp.LastWriteTimeUtc > tfi.LastWriteTimeUtc) {
|
||||
Log (3, "Target '{0}' has a stamp file with newer timestamp ({1} > {2}), using the stamp file's timestamp", target, tfi_stamp.LastWriteTimeUtc, tfi.LastWriteTimeUtc);
|
||||
tfi = tfi_stamp;
|
||||
}
|
||||
}
|
||||
|
||||
var sfi = new FileInfo (source);
|
||||
|
||||
if (sfi.LastWriteTimeUtc <= tfi.LastWriteTimeUtc) {
|
||||
Log (3, "Prerequisite '{0}' is older than the target '{1}'.", source, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if MMP || MTOUCH // msbuild usages do not require CompareFiles optimization
|
||||
if (check_contents && Cache.CompareFiles (source, target)) {
|
||||
Log (3, "Prerequisite '{0}' is newer than the target '{1}', but the contents are identical.", source, target);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (check_contents)
|
||||
throw new NotImplementedException ("Checking file contents is not supported");
|
||||
#endif
|
||||
|
||||
Log (3, "Prerequisite '{0}' is newer than the target '{1}'.", source, target);
|
||||
return false;
|
||||
}
|
||||
|
||||
[DllImport ("/usr/lib/libSystem.dylib", SetLastError = true, EntryPoint = "strerror")]
|
||||
static extern IntPtr _strerror (int errno);
|
||||
|
||||
internal static string strerror (int errno)
|
||||
{
|
||||
return Marshal.PtrToStringAuto (_strerror (errno));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,11 +23,13 @@ namespace Xamarin
|
|||
Thumb = 64,
|
||||
LLVM = 128,
|
||||
ARMv7k = 256,
|
||||
ARM64e = 512,
|
||||
ARM64_32 = 1024,
|
||||
SimulatorArchMask = i386 | x86_64,
|
||||
DeviceArchMask = ARMv6 | ARMv7 | ARMv7s | ARMv7k | ARM64,
|
||||
DeviceArchMask = ARMv6 | ARMv7 | ARMv7s | ARMv7k | ARM64 | ARM64e | ARM64_32,
|
||||
ArchMask = SimulatorArchMask | DeviceArchMask,
|
||||
Arch64Mask = x86_64 | ARM64,
|
||||
Arch32Mask = i386 | ARMv6 | ARMv7 | ARMv7s | ARMv7k,
|
||||
Arch64Mask = x86_64 | ARM64 | ARM64e,
|
||||
Arch32Mask = i386 | ARMv6 | ARMv7 | ARMv7s | ARMv7k | ARM64_32 /* This is a 32-bit arch for our purposes */,
|
||||
}
|
||||
|
||||
public class MachO
|
||||
|
@ -47,6 +49,7 @@ namespace Xamarin
|
|||
|
||||
internal const uint MH_DYLIB = 0x6; /* dynamically bound shared library */
|
||||
|
||||
// Values here match the corresponding values in the Abi enum.
|
||||
public enum Architectures {
|
||||
None = 0,
|
||||
i386 = 1,
|
||||
|
@ -55,6 +58,9 @@ namespace Xamarin
|
|||
ARMv7s = 8,
|
||||
ARM64 = 16,
|
||||
x86_64 = 32,
|
||||
ARMv7k = 256,
|
||||
ARM64e = 512,
|
||||
ARM64_32 = 1024,
|
||||
}
|
||||
|
||||
internal enum LoadCommands : uint
|
||||
|
@ -382,7 +388,7 @@ namespace Xamarin
|
|||
return rv;
|
||||
}
|
||||
|
||||
static Abi GetArch (int cputype, int cpusubtype)
|
||||
public static Abi GetArch (int cputype, int cpusubtype)
|
||||
{
|
||||
switch (cputype) {
|
||||
case 12: // arm
|
||||
|
@ -399,7 +405,20 @@ namespace Xamarin
|
|||
return Abi.None;
|
||||
}
|
||||
case 12 | 0x01000000:
|
||||
return Abi.ARM64;
|
||||
switch (cpusubtype) {
|
||||
case 2:
|
||||
return Abi.ARM64e;
|
||||
case 0:
|
||||
default:
|
||||
return Abi.ARM64;
|
||||
}
|
||||
case 12 | 0x02000000: // CPU_TYPE_ARM | CPU_ARCH_ABI64_32 (64-bit hardware with 32-bit types; LP32)
|
||||
switch (cpusubtype) {
|
||||
case 1: // CPU_SUBTYPE_ARM64_32_V8
|
||||
return Abi.ARM64_32;
|
||||
default:
|
||||
return Abi.None;
|
||||
}
|
||||
case 7: // x86
|
||||
return Abi.i386;
|
||||
case 7 | 0x01000000: // x64
|
||||
|
@ -635,27 +654,7 @@ namespace Xamarin
|
|||
|
||||
public MachO.Architectures Architecture {
|
||||
get {
|
||||
switch (cputype) {
|
||||
case 12: // arm
|
||||
switch (cpusubtype) {
|
||||
case 6:
|
||||
return MachO.Architectures.ARMv6;
|
||||
case 9:
|
||||
return MachO.Architectures.ARMv7;
|
||||
case 11:
|
||||
return MachO.Architectures.ARMv7s;
|
||||
default:
|
||||
return MachO.Architectures.None;
|
||||
}
|
||||
case 12 | 0x01000000:
|
||||
return MachO.Architectures.ARM64;
|
||||
case 7: // x86
|
||||
return MachO.Architectures.i386;
|
||||
case 7 | 0x01000000: // x64
|
||||
return MachO.Architectures.x86_64;
|
||||
}
|
||||
|
||||
return MachO.Architectures.None;
|
||||
return (MachO.Architectures) MachO.GetArch (cputype, cpusubtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
namespace xharness
|
||||
namespace Xamarin
|
||||
{
|
||||
static class PListExtensions
|
||||
{
|
|
@ -98,14 +98,6 @@ namespace Xamarin.Bundler {
|
|||
#endif
|
||||
}
|
||||
|
||||
[DllImport (Constants.libSystemLibrary, SetLastError = true, EntryPoint = "strerror")]
|
||||
static extern IntPtr _strerror (int errno);
|
||||
|
||||
internal static string strerror (int errno)
|
||||
{
|
||||
return Marshal.PtrToStringAuto (_strerror (errno));
|
||||
}
|
||||
|
||||
[DllImport (Constants.libSystemLibrary, SetLastError = true)]
|
||||
static extern string realpath (string path, IntPtr zero);
|
||||
|
||||
|
@ -116,7 +108,7 @@ namespace Xamarin.Bundler {
|
|||
return rv;
|
||||
|
||||
var errno = Marshal.GetLastWin32Error ();
|
||||
ErrorHelper.Warning (54, "Unable to canonicalize the path '{0}': {1} ({2}).", path, strerror (errno), errno);
|
||||
ErrorHelper.Warning (54, "Unable to canonicalize the path '{0}': {1} ({2}).", path, FileCopier.strerror (errno), errno);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace Xamarin.Bundler {
|
|||
static List<string> resources = new List<string> ();
|
||||
static List<string> resolved_assemblies = new List<string> ();
|
||||
static List<string> ignored_assemblies = new List<string> ();
|
||||
static List<string> native_references = new List<string> ();
|
||||
public static List<string> native_references = new List<string> ();
|
||||
static List<string> native_libraries_copied_in = new List<string> ();
|
||||
|
||||
static Action action;
|
||||
|
@ -828,16 +828,6 @@ namespace Xamarin.Bundler {
|
|||
// if not then the compilation really failed
|
||||
throw new MonoMacException (5103, true, String.Format ("Failed to compile. Error code - {0}. Please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new", ret));
|
||||
}
|
||||
if (frameworks_copied_to_bundle_dir) {
|
||||
int install_ret = XcodeRun ("install_name_tool", $"{StringUtils.Quote (AppPath)} -add_rpath @loader_path/../Frameworks");
|
||||
if (install_ret != 0)
|
||||
throw new MonoMacException (5310, true, "install_name_tool failed with an error code '{0}'. Check build log for details.", ret);
|
||||
}
|
||||
if (dylibs_copied_to_bundle_dir) {
|
||||
int install_ret = XcodeRun ("install_name_tool", $"{StringUtils.Quote (AppPath)} -add_rpath @loader_path/../{BundleName}");
|
||||
if (install_ret != 0)
|
||||
throw new MonoMacException (5310, true, "install_name_tool failed with an error code '{0}'. Check build log for details.", ret);
|
||||
}
|
||||
|
||||
if (generate_plist)
|
||||
GeneratePList ();
|
||||
|
@ -1271,6 +1261,11 @@ namespace Xamarin.Bundler {
|
|||
args.Append (StringUtils.Quote (finalLibPath)).Append (' ');
|
||||
}
|
||||
|
||||
if (frameworks_copied_to_bundle_dir)
|
||||
args.Append ("-rpath @loader_path/../Frameworks ");
|
||||
if (dylibs_copied_to_bundle_dir)
|
||||
args.Append ($"-rpath @loader_path/../{BundleName} ");
|
||||
|
||||
if (is_extension)
|
||||
args.Append ("-e _xamarin_mac_extension_main -framework NotificationCenter").Append(' ');
|
||||
|
||||
|
|
|
@ -292,6 +292,9 @@
|
|||
<Compile Include="..\..\src\ObjCRuntime\Registrar.cs">
|
||||
<Link>external\Registrar.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\PListExtensions.cs">
|
||||
<Link>external\PListExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\TargetFramework.cs">
|
||||
<Link>external\TargetFramework.cs</Link>
|
||||
</Compile>
|
||||
|
@ -364,6 +367,9 @@
|
|||
<Compile Include="linker\MonoMac.Tuner\MacBaseProfile.cs">
|
||||
<Link>MonoMac.Tuner\MacBaseProfile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\FileCopier.cs">
|
||||
<Link>external\FileCopier.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\Symbols.cs">
|
||||
<Link>external\Symbols.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -2230,7 +2230,14 @@ namespace Xamarin.Bundler {
|
|||
return false;
|
||||
if (PackageManagedDebugSymbols)
|
||||
return false;
|
||||
if (IsInterpreted (Assembly.GetIdentity (path)))
|
||||
/* FIXME: should be `if (IsInterpreted (Assembly.GetIdentity (path)))`.
|
||||
* The problem is that in mixed mode we can't do the transition
|
||||
* between "interp"->"aot'd methods using gsharedvt", so we
|
||||
* fall back to the interp and thus need the IL not to be
|
||||
* stripped out. Once Mono supports this, we can add back the
|
||||
* more precise check.
|
||||
* See https://github.com/mono/mono/issues/11942 */
|
||||
if (UseInterpreter)
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
<Compile Include="..\..\src\build\ios\Constants.cs">
|
||||
<Link>external\Constants.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\PListExtensions.cs">
|
||||
<Link>external\PListExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\cache.cs">
|
||||
<Link>external\cache.cs</Link>
|
||||
</Compile>
|
||||
|
@ -371,6 +374,9 @@
|
|||
<Compile Include="..\common\Optimizations.cs">
|
||||
<Link>external\Optimizations.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\FileCopier.cs">
|
||||
<Link>external\FileCopier.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\ObjCRuntime\BindingImplAttribute.cs">
|
||||
<Link>external\maccore\BindingImplAttribute.cs</Link>
|
||||
</Compile>
|
||||
|
|
Загрузка…
Ссылка в новой задаче