xamarin / Xamarin.Legacy.Sdk

Starting from a .NET 6 project, adds the ability to target legacy Xamarin target frameworks such as monoandroid11.0 or xamarin.ios10. *Not fully supported*
MIT License
35 stars 6 forks source link

Mutil targets occurs build error #53

Closed jingliancui closed 1 year ago

jingliancui commented 1 year ago

NativeLoaderBinding.zip

This config will occurs error: <TargetFrameworks>monoandroid11.0;net6.0-android;net7.0-android</TargetFrameworks>

This config can build successfully: <TargetFrameworks>monoandroid11.0;net7.0-android</TargetFrameworks>

buildlog.txt BuildLogFromCommand.txt

jingliancui commented 1 year ago
Screenshot 2023-04-18 at 22 47 03
jonpryor commented 1 year ago

@jingliancui : NativeLoaderBinding.zip builds for me!

(Which isn't particularly helpful, I'm sure.)

That said, reading buildlog.txt raises a question: buildlog.txt errors out with:

error MSB6003: The specified task executable "dotnet" could not be run.
System.ComponentModel.Win32Exception (2):
  An error occurred trying to start process '/usr/local/bin/dotnet' with working directory
  '…/NativeLoaderBinding/NativeLoaderBinding'. No such file or directory

Yet earlier in the same log we see the successful csc invocation:

/usr/local/share/dotnet/dotnet exec "/usr/local/share/dotnet/sdk/7.0.203/Roslyn/bincore/csc.dll" …

/usr/local/share/dotnet/dotnet != /usr/local/bin/dotnet.

The question then becomes, where is /usr/local/bin/dotnet coming from?

Please rebuild your project, from clean, with diagnostic logging enabled:

MSBUILDLOGALLENVIRONMENTVARIABLES=1 dotnet build -v:diag NativeLoaderBinding.csproj > buildlog-diag.txt

and attach buildlog-diag.txt.


For comparison, in my diagnostic build log the net6.0-android build contains:

Task "ClassParse" (TaskId:112)
  Task Parameter:
      SourceJars=
          nativeloader-0.10.3.jar
                  Bind=true
                  Pack=true (TaskId:112)
  Task Parameter:OutputFile=obj/Debug/net6.0-android/api.xml.class-parse (TaskId:112)
  Task Parameter:ToolPath=/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.485/tools (TaskId:112)
  Using: dotnet /usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.485/tools/class-parse.dll (TaskId:112)
  [class-parse] response file: obj/Debug/net6.0-android/class-parse.rsp (TaskId:112)
  --o="obj/Debug/net6.0-android/api.xml.class-parse" (TaskId:112)
  "nativeloader-0.10.3.jar" (TaskId:112)
  /usr/local/share/dotnet/dotnet /usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.485/tools/class-parse.dll "@obj/Debug/net6.0-android/class-parse.rsp"  (TaskId:112)

Aside: .NET 7 added https://github.com/xamarin/xamarin-android/commit/23e245b465ae75de5a69bdb192b5805b198e979b , which alters the logic to find dotnet, preferring to use the same dotnet as is used for the build, vs. "whatever happens to be in $PATH".

This still leaves me somewhat confused: why does my net6.0-android build log just have dotnet path/to/class-parse.dll, while your failing build log has /usr/local/bin/dotnet path/to/class-parse.dll? Where is /usr/local/bin/dotnet coming from?!

jingliancui commented 1 year ago

@jonpryor Oh, it can be build now. I don't know why. buildlog-diag.txt Then I try to using vs to build and vs build successfully.

jingliancui commented 1 year ago

Interesting, when I using bash scrpit to build it, it will throw error: buildlog-diag.txt

jingliancui commented 1 year ago
ericcui@ericdeMacBook-Pro NativeLoaderBinding % ls -lF /usr/local/bin/dotnet
lrwxr-xr-x  1 root  wheel  34 Jan 23  2022 /usr/local/bin/dotnet@ -> /usr/local/share/dotnet/x64/dotnet
ericcui@ericdeMacBook-Pro NativeLoaderBinding % 
jingliancui commented 1 year ago
ericcui@ericdeMacBook-Pro NativeLoaderBinding % ls -lF /usr/local/share/dotnet/x64/dotnet
ls: /usr/local/share/dotnet/x64/dotnet: No such file or directory
ericcui@ericdeMacBook-Pro NativeLoaderBinding % 
jingliancui commented 1 year ago

It's work after did it: sudo rm /usr/local/bin/dotnet

jonpryor commented 1 year ago

Also of note is the $PATH value from buildlog.txt:

PATH = /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin

As surmised previously, the <ClassParse/> task invocation was using the first dotnet found in $PATH, which in this case:

  1. Was /usr/local/bin/dotnet, as $PATH has /usr/local/bin before /usr/local/share/dotnet, and
  2. /usr/local/bin/dotnet was a symlink to /usr/local/share/dotnet/x64/dotnet, and
  3. that/usr/local/share/dotnet/x64/dotnet does not exist

This entirely explains why the <ClassParse/> task fails, and why removing the invalid symlink fixes the issue.