2018-02-02 09:09:04 +03:00
using System ;
2019-10-14 17:18:46 +03:00
using System.Collections.Generic ;
2018-02-02 09:09:04 +03:00
using System.IO ;
using System.Linq ;
using System.Text ;
using NUnit.Framework ;
using Xamarin.Utils ;
namespace Xamarin.Tests
{
public enum LinkerOption
{
Unspecified ,
LinkAll ,
LinkSdk ,
DontLink ,
LinkPlatform , // only applicable for XM
}
public enum RegistrarOption
{
Unspecified ,
Dynamic ,
Static ,
}
[Flags]
enum I18N
{
None = 0 ,
CJK = 1 ,
MidEast = 2 ,
Other = 4 ,
Rare = 8 ,
West = 16 ,
All = CJK | MidEast | Other | Rare | West ,
Base
}
// This class represents options/logic that is identical between mtouch and mmp
abstract class BundlerTool : Tool
{
public const string None = "None" ;
2018-07-30 11:55:23 +03:00
public bool AlwaysShowOutput ;
2018-02-02 09:09:04 +03:00
#pragma warning disable 0649 // Field 'X' is never assigned to, and will always have its default value Y
// These map directly to mtouch/mmp options
// These options are ordered alphabetically
public string Abi ; // This is --abi for mtouch and --arch for mmp
public string Cache ;
public string [ ] CustomArguments ; // Sometimes you want to pass invalid arguments to mtouch, in this case this array is used. No processing will be done, if quotes are required, they must be added to the arguments in the array.
public bool? Debug ;
public bool? Extension ;
public string GccFlags ; // This is --gcc_flags for mtouch and --link_flags for mmp
public string HttpMessageHandler ;
public I18N I18N ;
public LinkerOption Linker ;
public string [ ] LinkSkip ;
public int [ ] NoWarn ; // null array: nothing passed to mtouch/mmp. empty array: pass --nowarn (which means disable all warnings).
public string [ ] Optimize ;
public Profile Profile ;
public bool? Profiling ;
public string [ ] References ; // This is -r for mtouch and -a for mmp
public RegistrarOption Registrar ;
public string ResponseFile ;
public string RootAssembly ;
public string Sdk ;
public string SdkRoot ;
public string TargetFramework ;
public string TargetVer ; // this is --targetver for mtouch and --minos for mmp
public int Verbosity ;
public int [ ] WarnAsError ; // null array: nothing passed to mtouch/mmp. empty array: pass --warnaserror (which means makes all warnings errors).
public string [ ] XmlDefinitions ;
2018-10-10 18:02:28 +03:00
public string Interpreter ;
2018-02-02 09:09:04 +03:00
// These are a bit smarter
public bool NoPlatformAssemblyReference ;
#pragma warning restore 0649
bool IsMtouchTool {
get {
return GetType ( ) . Name = = "MTouchTool" ;
}
}
2019-10-14 17:18:46 +03:00
protected void AddVerbosity ( IList < string > args )
2018-02-02 09:09:04 +03:00
{
if ( Verbosity = = 0 ) {
2019-10-14 17:18:46 +03:00
// do nothing
2018-02-02 09:09:04 +03:00
} else if ( Verbosity > 0 ) {
2019-10-14 17:18:46 +03:00
args . Add ( "-" + new string ( 'v' , Verbosity ) ) ;
2018-02-02 09:09:04 +03:00
} else {
2019-10-14 17:18:46 +03:00
args . Add ( "-" + new string ( 'q' , - Verbosity ) ) ;
2018-02-02 09:09:04 +03:00
}
}
2019-10-14 17:18:46 +03:00
protected IList < string > ToolArguments {
2018-02-02 09:09:04 +03:00
get {
2019-10-14 17:18:46 +03:00
var sb = new List < string > ( ) ;
2018-02-02 09:09:04 +03:00
BuildArguments ( sb ) ;
2019-10-14 17:18:46 +03:00
return sb ;
2018-02-02 09:09:04 +03:00
}
}
protected virtual string GetDefaultAbi ( )
{
return null ;
}
2019-10-14 17:18:46 +03:00
protected virtual void BuildArguments ( IList < string > sb )
2018-02-02 09:09:04 +03:00
{
// Options are processed alphabetically
if ( Abi = = None ) {
// add nothing
} else if ( ! string . IsNullOrEmpty ( Abi ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( IsMtouchTool ? "--abi" : "--arch" ) ;
sb . Add ( Abi ) ;
2018-02-02 09:09:04 +03:00
} else {
var a = GetDefaultAbi ( ) ;
if ( ! string . IsNullOrEmpty ( a ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( IsMtouchTool ? "--abi" : "--arch" ) ;
sb . Add ( a ) ;
2018-02-02 09:09:04 +03:00
}
}
2019-10-14 17:18:46 +03:00
if ( ! string . IsNullOrEmpty ( Cache ) ) {
sb . Add ( "--cache" ) ;
sb . Add ( Cache ) ;
}
2018-02-02 09:09:04 +03:00
if ( CustomArguments ! = null ) {
foreach ( var arg in CustomArguments ) {
2019-10-14 17:18:46 +03:00
sb . Add ( arg ) ;
2018-02-02 09:09:04 +03:00
}
}
if ( Debug . HasValue & & Debug . Value )
2019-10-14 17:18:46 +03:00
sb . Add ( "--debug" ) ;
2018-02-02 09:09:04 +03:00
if ( Extension = = true )
2019-10-14 17:18:46 +03:00
sb . Add ( "--extension" ) ;
2018-02-02 09:09:04 +03:00
2019-10-14 17:18:46 +03:00
if ( ! string . IsNullOrEmpty ( GccFlags ) ) {
sb . Add ( IsMtouchTool ? "--gcc_flags" : "--link_flags" ) ;
sb . Add ( GccFlags ) ;
}
2018-02-02 09:09:04 +03:00
if ( ! string . IsNullOrEmpty ( HttpMessageHandler ) )
2019-10-14 17:18:46 +03:00
sb . Add ( $"--http-message-handler={HttpMessageHandler}" ) ;
2018-02-02 09:09:04 +03:00
if ( I18N ! = I18N . None ) {
2019-10-14 17:18:46 +03:00
sb . Add ( "--i18n" ) ;
var i18n = new List < string > ( ) ;
2018-02-02 09:09:04 +03:00
if ( ( I18N & I18N . CJK ) = = I18N . CJK )
2019-10-14 17:18:46 +03:00
i18n . Add ( "cjk" ) ;
2018-02-02 09:09:04 +03:00
if ( ( I18N & I18N . MidEast ) = = I18N . MidEast )
2019-10-14 17:18:46 +03:00
i18n . Add ( "mideast" ) ;
2018-02-02 09:09:04 +03:00
if ( ( I18N & I18N . Other ) = = I18N . Other )
2019-10-14 17:18:46 +03:00
i18n . Add ( "other" ) ;
2018-02-02 09:09:04 +03:00
if ( ( I18N & I18N . Rare ) = = I18N . Rare )
2019-10-14 17:18:46 +03:00
i18n . Add ( "rare" ) ;
2018-02-02 09:09:04 +03:00
if ( ( I18N & I18N . West ) = = I18N . West )
2019-10-14 17:18:46 +03:00
i18n . Add ( "west" ) ;
sb . Add ( string . Join ( "," , i18n ) ) ;
2018-02-02 09:09:04 +03:00
}
switch ( Linker ) {
case LinkerOption . LinkAll :
case LinkerOption . Unspecified :
break ;
case LinkerOption . DontLink :
2019-10-14 17:18:46 +03:00
sb . Add ( "--nolink" ) ;
2018-02-02 09:09:04 +03:00
break ;
case LinkerOption . LinkSdk :
2019-10-14 17:18:46 +03:00
sb . Add ( "--linksdkonly" ) ;
2018-02-02 09:09:04 +03:00
break ;
case LinkerOption . LinkPlatform :
2019-10-14 17:18:46 +03:00
sb . Add ( "--linkplatform" ) ;
2018-02-02 09:09:04 +03:00
break ;
default :
throw new NotImplementedException ( ) ;
}
if ( LinkSkip ? . Length > 0 ) {
foreach ( var ls in LinkSkip )
2019-10-14 17:18:46 +03:00
sb . Add ( $"--linkskip:{ls}" ) ;
2018-02-02 09:09:04 +03:00
}
if ( NoWarn ! = null ) {
if ( NoWarn . Length > 0 ) {
2019-10-14 17:18:46 +03:00
sb . Add ( $"--nowarn:{string.Join (" , ", NoWarn.Select ((v) => v.ToString ()))}" ) ;
2018-02-02 09:09:04 +03:00
} else {
2019-10-14 17:18:46 +03:00
sb . Add ( "--nowarn" ) ;
2018-02-02 09:09:04 +03:00
}
}
if ( Optimize ! = null ) {
foreach ( var opt in Optimize )
2019-10-14 17:18:46 +03:00
sb . Add ( $"--optimize:{opt}" ) ;
2018-02-02 09:09:04 +03:00
}
if ( Profiling . HasValue )
2019-10-14 17:18:46 +03:00
sb . Add ( $"--profiling:{(Profiling.Value ? " true " : " false ")}" ) ;
2018-02-02 09:09:04 +03:00
if ( References ! = null ) {
foreach ( var r in References )
2019-10-14 17:18:46 +03:00
sb . Add ( ( IsMtouchTool ? "-r:" : "-a:" ) + r ) ;
2018-02-02 09:09:04 +03:00
}
switch ( Registrar ) {
case RegistrarOption . Unspecified :
break ;
case RegistrarOption . Dynamic :
2019-10-14 17:18:46 +03:00
sb . Add ( "--registrar:dynamic" ) ;
2018-02-02 09:09:04 +03:00
break ;
case RegistrarOption . Static :
2019-10-14 17:18:46 +03:00
sb . Add ( "--registrar:static" ) ;
2018-02-02 09:09:04 +03:00
break ;
default :
throw new NotImplementedException ( ) ;
}
if ( ! string . IsNullOrEmpty ( ResponseFile ) )
2019-10-14 17:18:46 +03:00
sb . Add ( "@" + ResponseFile ) ;
2018-02-02 09:09:04 +03:00
if ( ! string . IsNullOrEmpty ( RootAssembly ) )
2019-10-14 17:18:46 +03:00
sb . Add ( RootAssembly ) ;
2018-02-02 09:09:04 +03:00
if ( Sdk = = None ) {
// do nothing
} else if ( ! string . IsNullOrEmpty ( Sdk ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( "--sdk" ) ;
sb . Add ( Sdk ) ;
2018-02-02 09:09:04 +03:00
} else {
2019-10-14 17:18:46 +03:00
sb . Add ( "--sdk" ) ;
sb . Add ( Configuration . GetSdkVersion ( Profile ) ) ;
2018-02-02 09:09:04 +03:00
}
if ( SdkRoot = = None ) {
// do nothing
} else if ( ! string . IsNullOrEmpty ( SdkRoot ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( "--sdkroot" ) ;
sb . Add ( SdkRoot ) ;
2018-02-02 09:09:04 +03:00
} else {
2019-10-14 17:18:46 +03:00
sb . Add ( "--sdkroot" ) ;
sb . Add ( Configuration . xcode_root ) ;
2018-02-02 09:09:04 +03:00
}
if ( TargetFramework = = None ) {
// do nothing
} else if ( ! string . IsNullOrEmpty ( TargetFramework ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( "--target-framework" ) ;
sb . Add ( TargetFramework ) ;
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
} else {
2018-02-02 09:09:04 +03:00
switch ( Profile ) {
case Profile . iOS :
case Profile . tvOS :
case Profile . watchOS :
case Profile . macOSFull :
case Profile . macOSMobile :
case Profile . macOSSystem :
2019-10-14 17:18:46 +03:00
sb . Add ( "--target-framework" ) ;
sb . Add ( Configuration . GetTargetFramework ( Profile ) ) ;
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
if ( ! NoPlatformAssemblyReference )
sb . Add ( "-r:" + Configuration . GetBaseLibrary ( Profile ) ) ;
2018-02-02 09:09:04 +03:00
break ;
default :
throw new NotImplementedException ( ) ;
}
}
if ( TargetVer = = None ) {
// do nothing
} else if ( ! string . IsNullOrEmpty ( TargetVer ) ) {
2019-10-14 17:18:46 +03:00
sb . Add ( IsMtouchTool ? "--targetver" : "--minos" ) ;
sb . Add ( TargetVer ) ;
2018-02-02 09:09:04 +03:00
}
2019-10-14 17:18:46 +03:00
AddVerbosity ( sb ) ;
2018-02-02 09:09:04 +03:00
if ( WarnAsError ! = null ) {
if ( WarnAsError . Length > 0 ) {
2019-10-14 17:18:46 +03:00
sb . Add ( $"--warnaserror:{string.Join (" , ", WarnAsError.Select ((v) => v.ToString ()))}" ) ;
2018-02-02 09:09:04 +03:00
} else {
2019-10-14 17:18:46 +03:00
sb . Add ( "--warnaserror" ) ;
2018-02-02 09:09:04 +03:00
}
}
if ( XmlDefinitions ? . Length > 0 ) {
foreach ( var xd in XmlDefinitions )
2019-10-14 17:18:46 +03:00
sb . Add ( $"--xml:{xd}" ) ;
2018-02-02 09:09:04 +03:00
}
2018-10-10 18:02:28 +03:00
if ( Interpreter ! = null ) {
if ( Interpreter . Length = = 0 )
2019-10-14 17:18:46 +03:00
sb . Add ( "--interpreter" ) ;
2018-10-10 18:02:28 +03:00
else
2019-10-14 17:18:46 +03:00
sb . Add ( "--interpreter=" + Interpreter ) ;
2018-10-10 18:02:28 +03:00
}
2018-02-02 09:09:04 +03:00
}
public string CreateTemporaryDirectory ( )
{
return Xamarin . Cache . CreateTemporaryDirectory ( ) ;
}
public void CreateTemporaryCacheDirectory ( )
{
Cache = Path . Combine ( CreateTemporaryDirectory ( ) , "mtouch-test-cache" ) ;
Directory . CreateDirectory ( Cache ) ;
}
public virtual int Execute ( )
{
2018-07-30 11:55:23 +03:00
return Execute ( ToolArguments , always_show_output : Verbosity > 0 | | AlwaysShowOutput ) ;
2018-02-02 09:09:04 +03:00
}
public virtual void AssertExecute ( string message = null )
{
var rv = Execute ( ) ;
if ( rv = = 0 )
return ;
var errors = Messages . Where ( ( v ) = > v . IsError ) . ToList ( ) ;
Assert . Fail ( $"Expected execution to succeed, but exit code was {rv}, and there were {errors.Count} error(s): {message}\n\t" +
string . Join ( "\n\t" , errors . Select ( ( v ) = > v . ToString ( ) ) ) ) ;
}
Optimize calls to BlockLiteral.SetupBlock to inject the block signature. (#3391)
* [linker] Optimize calls to BlockLiteral.SetupBlock to inject the block signature.
Optimize calls to BlockLiteral.SetupBlock[Unsafe] to calculate the block
signature at build time, and inject it into the call site.
This makes block invocations 10-15x faster (I've added tests that asserts at
least an 8x increase).
It's also required in order to be able to remove the dynamic registrar code in
the future (since calculating the block signature at runtime requires the
dynamic registrar).
* [mtouch/mmp] Add support for reporting errors/warnings that point to the code line causing the error/warning.
Add support for reporting errors/warnings that point to the code line causing
the error/warning by adding ErrorHelper overloads that take the exact
instruction to report (previously we defaulted to the first line/instruction
in a method).
* [tests] Add support for asserting filename/linenumber in warning messages.
* Make all methods that manually create BlockLiterals optimizable.
* [tests] Create a BaseOptimizeGeneratedCodeTest test that's included in both XI's and XM's link all test.
* [tests] Add link all test (for both XI and XM) to test the BlockLiteral.SetupBlock optimization.
* [tests] Add mtouch/mmp tests for the BlockLiteral.SetupBlock optimization.
* [tests][linker] Make the base test class abstract, so tests in the base class aren't executed twice.
* [tests][linker] Don't execute linkall-only tests in linksdk.
The optimization tests only apply when the test assembly is linked, and that
only happens in linkall, so exclude those tests in linksdk.
* [tests][mmptest] Update test according to mmp changes.
Fixes these test failures:
1) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("inline-runtime-arch")
The warning 'MM0132: Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output:
Message #1 did not match:
actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.'
expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.'
Message #2 did not match:
actual: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.'
expected: 'Unknown optimization: 'inline-runtime-arch'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.'
2) Failed : Xamarin.MMP.Tests.MMPTests.MM0132("foo")
The warning 'MM0132: Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.' was not found in the output:
Message #1 did not match:
actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.'
expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.'
Message #2 did not match:
actual: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock.'
expected: 'Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size.'
* [tests][linker] Fix typo.
Fixes this test failure:
1) SetupBlock_CustomDelegate (Linker.Shared.BaseOptimizeGeneratedCodeTest.SetupBlock_CustomDelegate)
Counter
Expected: 1
But was: 2
* [registrar] Minor adjustment to error message to match previous (and better) behavior.
Fixes this test failure:
1) Failed : Xamarin.Registrar.GenericType_WithInvalidParameterTypes
The error 'MT4136: The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)'' was not found in the output:
Message #1 did not match:
actual: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<Foundation.NSObject>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)''
expected: 'The registrar cannot marshal the parameter type 'System.Collections.Generic.List`1<U>' of the parameter 'arg' in the method 'Open`1.Bar(System.Collections.Generic.List`1<U>)''
* [docs] mmp shows MM errors/warnings.
* [docs] Improve according to reviews.
* [tests] Fix merge failure causing test duplication.
2018-02-06 09:08:15 +03:00
public void AssertExecuteFailure ( string message = null )
{
Assert . AreEqual ( 1 , Execute ( ) , message ) ;
}
2020-04-17 13:15:01 +03:00
public abstract void CreateTemporaryApp ( Profile profile , string appName = "testApp" , string code = null , IList < string > extraArgs = null , string extraCode = null , string usings = null ) ;
2018-02-02 09:09:04 +03:00
2020-04-17 13:15:01 +03:00
public static string CompileTestAppExecutable ( string targetDirectory , string code = null , IList < string > extraArgs = null , Profile profile = Profile . iOS , string appName = "testApp" , string extraCode = null , string usings = null )
2018-02-02 09:09:04 +03:00
{
if ( code = = null )
code = "public class TestApp { static void Main () { System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ()); } }" ;
if ( usings ! = null )
code = usings + "\n" + code ;
if ( extraCode ! = null )
code + = extraCode ;
2020-04-17 13:15:01 +03:00
return CompileTestAppCode ( "exe" , targetDirectory , code , extraArgs , profile , appName ) ;
2018-02-02 09:09:04 +03:00
}
2019-10-14 17:18:46 +03:00
public static string CompileTestAppLibrary ( string targetDirectory , string code , IList < string > extraArgs = null , Profile profile = Profile . iOS , string appName = "testApp" )
2018-02-02 09:09:04 +03:00
{
2019-10-14 17:18:46 +03:00
return CompileTestAppCode ( "library" , targetDirectory , code , extraArgs , profile , appName ) ;
2018-02-02 09:09:04 +03:00
}
2020-04-17 13:15:01 +03:00
public static string CompileTestAppCode ( string target , string targetDirectory , string code , IList < string > extraArgs = null , Profile profile = Profile . iOS , string appName = "testApp" )
2018-02-02 09:09:04 +03:00
{
var ext = target = = "exe" ? "exe" : "dll" ;
var cs = Path . Combine ( targetDirectory , "testApp.cs" ) ;
var assembly = Path . Combine ( targetDirectory , appName + "." + ext ) ;
var root_library = Configuration . GetBaseLibrary ( profile ) ;
File . WriteAllText ( cs , code ) ;
string output ;
2019-10-14 17:18:46 +03:00
var args = new List < string > ( ) ;
2020-04-17 13:15:01 +03:00
string fileName = Configuration . GetCompiler ( profile , args ) ;
2019-10-14 17:18:46 +03:00
args . Add ( "/noconfig" ) ;
args . Add ( $"/t:{target}" ) ;
args . Add ( "/nologo" ) ;
args . Add ( $"/out:{assembly}" ) ;
args . Add ( $"/r:{root_library}" ) ;
args . Add ( cs ) ;
if ( extraArgs ! = null )
args . AddRange ( extraArgs ) ;
if ( ExecutionHelper . Execute ( fileName , args , out output ) ! = 0 ) {
2018-02-02 09:09:04 +03:00
Console . WriteLine ( "{0} {1}" , fileName , args ) ;
Console . WriteLine ( output ) ;
throw new Exception ( output ) ;
}
return assembly ;
}
2018-02-13 13:04:40 +03:00
// The directory where the assemblies are located in the built app
public abstract string GetAppAssembliesDirectory ( ) ;
// The path to the platform assembly in the built app.
public string GetPlatformAssemblyInApp ( )
{
var asm = Path . GetFileName ( Configuration . GetBaseLibrary ( Profile ) ) ;
return Path . Combine ( GetAppAssembliesDirectory ( ) , asm ) ;
}
2018-02-02 09:09:04 +03:00
}
}