termux / termux-packages

A package build system for Termux.
https://termux.dev
Other
13.41k stars 3.1k forks source link

Package Request: .NET Core #516

Open christianrondeau opened 8 years ago

christianrondeau commented 8 years ago

This project is a very promising initiative to develop in .Net with real cross platform support.

Website: https://www.microsoft.com/net/core (already supports multiple Linux distros)

And the cli on github: https://github.com/dotnet/cli

christianrondeau commented 8 years ago

I have started a branch, and it compiles on my machine, but I will need some help to make sure it works: https://github.com/christianrondeau/termux-packages/tree/dotnet-dev/packages/dotnet-dev

I searched for high level instructions on how to:

  1. Test the package I just built on Termux on my Android device. How can I do that? Should I just copy the files and "trust" that it'll work once on Termux's apt repo?
  2. Clarifications on the HOSTBUILD; should every device build it, or can I have Termux's repo host the binaries?

A few links to get started would be very helpful, rather than fiddling (and probably making easy to avoid mistakes)

Thanks! Once I have the information I need, I might contribute to the documentation once I understand all pieces.

vishalbiswas commented 8 years ago

After building the package, you can find its deb package(s) in the termux-packages/debs folder of your cloned git repo. Make sure you have built the package for your devices' architecture. If not run build-package.sh -a <arch> <package> replacing arch with the actual arch. Copy the deb file(s) over to your device. Install them with dpkg -i <deb_filename>. If the package dependencies haven't been met, run apt install -f. Then, if you have compiled it correctly, you can run the dotnet executable.

christianrondeau commented 8 years ago

Thank you very much @vishalbiswas - I should have enough to get going for a while :) I'm still trying to understand the relationship between .Net Core repositories and their apt-get counterpart, but I'll reach out if I get stuck.

cydhaselton commented 8 years ago

I've actually built coreclr in termux on device, as well as the necessary bits of corefx. Unfortunately I failed to push commits to my forked coreclr repo so I have to rebuild from scratch.
I can post back once I'm done.

christianrondeau commented 8 years ago

@cydhaselton that would be amazing, I'm still trying to figure out the build part of dotnet-cli (works from a checkout, not from their release tar file for multiple reasons), the relationship with the three .deb files generated in the Microsoft Ubuntu release as well as the subtleties of Termux itself :) Also the time I can put on this per day is near to zero so that will probably take forever! Hopefully I'll learn something from this though.

Let me know if I can help, I'll continue slowly progressing on my branch in the meantime.

christianrondeau commented 8 years ago

Small info : dotnet/cli master builds, and /t:Compile skips tests correctly... but the v1.0.0-preview2.1 tag does not on Ubuntu x64.

So either we build on a custom commit rather than the release, or we monkey patch dynamically. Or I got it wrong :P

I'll continue my investigation.

cydhaselton commented 8 years ago

@christianrondeau: Best of luck with your efforts...I'm still banging my head against this, as I'd like to get Powershell running in Termux. I will say that, from what I understand, the key build is System.Private.Corelib.dll; this can't be built on an "unsupported" device (no idea what constitutes an unsupported device) and is key to running various bits of .NET core.

If you are ever able to build it for Termux let me know. I'd be more than happy to test.

EDIT: So you have a dotnet/cli that runs on Termux? Care to share?

christianrondeau commented 8 years ago

Not yet, no - I have the build-package.sh building dotnet/cli correctly (pushed this morning), but I'm now trying to understand what build-package.sh does after the build, and what files should I move where for the rest of the build process to work (like I said, very small steps every day!)

There is a bunch of output folders generated by the dotnet/cli build, with multiple stages, .deb files and more and looking at other termux packages, there's some magic that "move files around" between stages that I don't understand, so I'm pretty much reading scripts for now. Once I clarify how to get that build process going through the end, I'll be able to try the executable on my Android device and report back.

vishalbiswas commented 8 years ago

@christianrondeau build-package.sh steps:

  1. Download source
  2. Configure source
  3. Run make, or your overrided function
  4. Run make install This will get all the compiled and/or other configs, etc from elsewhere and put them into the massage dir. This directly has every file which goes into the final package. If your project is not based on Makefile, be sure to override termux_step_make_install to install all required files under $TERMUX_PREFIX, to ensure they are included in the package.
  5. Massage package
  6. Create package
christianrondeau commented 8 years ago

Thanks again @vishalbiswas, this was indeed my understanding (but I prefer knowing this rather than just relying on my guesses). Where I am at (for those who are interested):

Lookin at the Ubuntu distribution of .NET core, I see the .deb file referenced in https://apt-mo.trafficmanager.net/repos/dotnet-release/dists/xenial/main/binary-amd64/Packages contains:

And when I build locally .NET, if I look at https://github.com/dotnet/cli/blob/rel/1.0.0/Documentation/developer-guide.md#buildingrunning I can see I need the stage 2 output, which looks like this (excluding third party notices and license files):

So two things I'm not sure about.

  1. I have a single git repository, which looks like is actually generating the files of the dotnet-host-ubuntu.16.04-x64.1.1.0-preview1-001100-00.deb file.
  2. The output files do contain the executable, but the file structure is completely different

So my next steps are to:

  1. Try to copy just the dotnet executable, like the host deb file, in the massage folder and see what happens,
  2. Test it on my device, and hopefully get a helpful error message saying that something's missing!

It's moving forward!

christianrondeau commented 8 years ago

I can now build the .deb file successfully! But here's my first roadblock. I copied the list of dependencies from the ubuntu .Net Core target, and I tried to install them. Most of them are not available for termux (see output below). Does this mean I'm screwed?

Reading package lists... Building dependency tree... Reading state information... Package libc6 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libcurl3 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libgcc1 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libgssapi-krb5-2 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libicu55 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package liblldb-3.6 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package liblttng-ust0 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libssl1.0.0 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libstdc++6 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libunwind8 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package libuuid1 is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

Package zlib1g is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

christianrondeau commented 8 years ago

Skipping dependencies using dpkg --ignore-dependencies shows me I got something wrong even before getting dependencies (on termux) :

$ dpkg -i --ignore-depends=... dotnet-dev_1.0.0-preview2.0.1-0_aarch64.deb
(Reading database ... 8408 files and directories currently installed.)
Preparing to unpack .../dotnet-dev_1.0.0-preview2.0.1-0_aarch64.deb ...
Unpacking dotnet-dev (1.0.0-preview2.0.1-0) over (1.0.0-preview2.0.1-0) ...
Setting up dotnet-dev (1.0.0-preview2.0.1-0) ...

$ dotnet
-bash: /data/data/com.termux/files/usr/bin/dotnet: cannot execute binary file: Exec format error

I'm on a S7 (aarch64), I compiled on Ubuntu 16.04 x64, and I took the file from the termux-packages/debs folder.

The built executable works on Ubuntu, but the massaged version spits out (on ubuntu) :

$ ~/.termux-build/dotnet-dev/massage/data/data/com.termux/files/usr/bin/dotnet
realpath(): Invalid argument
Failed to resolve full path of the current executable [/proc/self/exe]

I guess this part is normal, but I can't say for sure.

Not sure where to go from there. Any idea?

vishalbiswas commented 8 years ago

@christianrondeau Turn off HOSTBUILD. From my understanding, hostbuild will build for the build machine. It should only be enabled for arch independent and/or packages that don't require libc (I'm not sure). Also remove libc6 from depends list, termux uses system provided libc, bionic. Change libcurl3 to libcurl and also remove version requirements from them. Multiple packages in your Depends array are not available for termux yet. You may need yo port them, too, or disable respective features before compiling.

christianrondeau commented 8 years ago

HOSTBUILD is already off: https://github.com/christianrondeau/termux-packages/blob/dotnet-dev/packages/dotnet-dev/build.sh

For the librairies, it makes sense and I can work through them, thanks.

I'm still stumped for Exec format error though.

I'll try cleaning my environment and make sure it's not a copy error on my part...

vishalbiswas commented 8 years ago

@christianrondeau That Exec format error is because its built for your build machine (probably). I think the Compile command implicitly uses your system gcc and friends. There must be a way to set them to the toolchain ones. You can run readelf on the executable to see what's wrong.

christianrondeau commented 8 years ago

I rebuilt it to make sure. When I extract the generated deb file from termux-packages/debs` on ubuntu, it says:

$ ./data/data/com.termux/files/usr/bin/dotnet
realpath(): Invalid argument
Failed to resolve full path of the current executable [/proc/self/exe]

Which shows it is indeed the massaged version. I also see in build-package.sh output that the architecture is aarch64.

When I force-install it on Termux (and ignore dependencies):

$ dotnet
-bash: /data/data/com.termux/files/usr/bin/dotnet: cannot execute binary file: Exec format error

Either I misunderstood what target arch to use when building the. NET Core source (right now it's ubuntu 16.04 x64), or the build-package.sh script is not yet configured correctly.

Any ideas?

vishalbiswas commented 8 years ago

@christianrondeau run readelf -hwhich dotnet``

christianrondeau commented 8 years ago

Here's the output in Termux on my S7:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x40c980
  Start of program headers:          64 (bytes into file)
  Start of section headers:          150432 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 28

Fun fact: I piped the command output to termux-clipboard-set and pasted here. Termux is awesome.

I also ran file:

/data/data/com.termux/files/usr/bin/dotnet: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped
christianrondeau commented 8 years ago

I think I see what I misunderstood; build-package.sh does not magically make programs work on aarch64; I still need to compile for ARM before build-package.sh massages the output (which is obvious at this point, but wasn't at the beginning). So, I know where to go from there. I'm linking a few items on .NET Core's project, since it doesn't really have anything for targeting ARM, I'll have to monkey patch something.

@cydhaselton if you have stuff to share, that'll help.

So, I'm afraid I'm quite a few steps back. I now need to find how to target ARM/aarch64 in the .NET Core CLI before moving forward on the Termux side. Thanks, I'll keep this thread updated. Hopefully my dream of developing .NET Core apps on my phone with Vim is not too far fetched!


Update: It is on Microsoft's roadmap for Q4 2016 - Q1 2017: https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/ which will make things much easier... I'll still try in the meantime!

vishalbiswas commented 8 years ago

It would be better to port mono, until upstream .Net Core adds support for arm.

christianrondeau commented 8 years ago

@vishalbiswas that would not work for my purposes, my objective is to build "Standard" .Net Core apps (no dependency on an installed. Net frameworks) rather than the "full" framework.

I see that arm is actually kind of supported in the master branches, so I can probably get at least a non official build of it and fiddle with it. So when they're ready, I will be too :)

christianrondeau commented 8 years ago

Here's the overview of what I found on how to build it on ARM:

On other OSes than Ubuntu/Debian, there is a single "apt" instead of the four described before, so that might be the way to go here. But I feel like too many pieces are missing to realistically use cli on arm today ... So maybe this issue will have to wait a few months :(

I'll continue fiddling, my only hope now is to at least get the framework (coreclr/corefx) working on this branch, so that it will be easier once cli supports arm to finish these build scripts. If anyone have a better idea, I'm open to them.

cydhaselton commented 8 years ago

@christianrondeau I've got a working port of mono on Termux, so I've been attempting to build parts of cli using the Roslyn csharp compiler (which runs with the mono runtime) or mono's xbuild (since the cli directory contains proj files). It's hit and miss: xbuild doesn't want to use relative paths and throws a permissions error when accessing "/data" and the source wasn't structured to build using the commandline csharp compiler. Or I'm not familiar enough with the csharp compiler…which is also possible.

I'm currently re-building coreclr on device so that I can upload the patched sources to github. I've already got corefx built and the changes pushed to my fork.

If you're motivated you can search the dotnet/cli gitter archives for my efforts to figure out what in the cli source tree can be built using the utilities I've already built for Termux.

vishalbiswas commented 8 years ago

@cydhaselton How about building in chroot on device?

cydhaselton commented 8 years ago

@vishalbiswas: Interesting idea. I've built in a completely chrooted environment before but it was pre-installed (kbox); I'd have to figure out how to set it up.

I'll give it a shot once coreclr is done.

EDIT: Would there be issues with running a program built in proot in regular termux-space?

christianrondeau commented 8 years ago

@cydhaselton So what you're saying, is that you tried to use a custom mono build for Termux, to run the Roslyn compiler and then use that to build dotnet cli? My head hurts :)

So I see that your branch has a termux-fix-shebang #! so that it builds on Termux, which bring the question: where does build-package.sh actually run? I thought it was on Ubuntu 16.04. Also, I looked at your fork and I see that it's 2674 commits behind upstream's master, so it might be worth it to see if their branch now works as-is (it's supposed to, if I read their doc right).

Anyway, I got coreclr building for arm64 already without any custom branches nor monkey patching, so I guess I can already push this, which brings the question: Should we do like A) Ubuntu, and provide a different package for clr, fx and cli, or B) build and bundle everything together? I'm not sure yet because is looks like there are cross-dependencies between them. Splitting would allow easier tracking than this mega-thread. Probably something to discuss after it works :)

I feel like I'm way out of my league with this, but there's movement and lots of learning, so it's all good I guess!

vishalbiswas commented 8 years ago

build-package.sh runs on Ubuntu. He is talking about extracting and building cli from source on device. As for the package layout, you could create a main package i.e. dotnet and have corefx.subpackage.sh and coreclr.subpackage.sh

cydhaselton commented 8 years ago

Yeah, I build everything on-device; I don't have easy access to Linux builds (and yes I do know about the various prebuilt VMs out there…its a space issue) and my tablet is always with me.

I'm aware my branch is behind; I have a limited knowledge of git and a full plate at work so updating the branch is on a to-do list for now.

My recommendation would be to provide the packages separately with dependencies where appropriate. The various moving parts of .NET can be huge.

@christianrondeau Yup, that's about right. Getting rosyn to work with mono was easy; basically someone told me that roslyn would execute under the mono runtime. The difficult part is figuring out all of the dependencies for .NET Core, which repos contain which dependencies and exactly what is needed to run Powershell…which is my ultimate goal.

Let me know if/when the coreclr is available for termux; I'll quit the build I'm currently working on and focus on corecli

christianrondeau commented 8 years ago

@cydhaselton I'm afraid I'm not really moving forward on my side; there are many things that I don't quite understand, so I'm trying to fill the gaps rather than actually advancing this. And as can be expected, I have limited time to invest in this currently.

You can look at my branch but nothing actually works. I can build coreclr targeting arm64, but doing the same inside build-package.sh yields errors like /usr/bin/aarch64-linux-gnu-ld: cannot find crt1.o: No such file or directory amongst many others; I think this is due to the symlinks not being available in the termux "context", but the whole pile of things I have moderate to low knowledge of is getting high.

This being said, coreclrdoes build outside of build-package, but just copying the corerun executable inside Termux doesn't seem to be working. Using readelf, I think that even though the files are generated in the Linux.arm64.Debug folder, they are still x86-64 for some reason.

That's where I'm at!

https://github.com/christianrondeau/termux-packages/blob/dotnet-dev/packages/dotnet-coreclr/build.sh

cydhaselton commented 8 years ago

@christianrondeau Can you explain what you mean by 'build outside of build-package.sh'? I assume this means that you are using cmake or some other dev environment to build coreclr but I'm not sure. Additionally, are you running into problems with building corefx, coreclr or both?

Lastly, to get an idea of How Things Work Together, you may want to look at the coreclr build docs, if you haven't already, specifically the "Relationship With the CoreFX Repository" section.

christianrondeau commented 8 years ago

@cydhaselton I mean the same command, ./build.sh aarch64 skiptests compiles when I clone coreclr sources as-is (after installing all dependencies as documented), but when I run this in my termux packages's build.sh (using build-package.sh dotnet-cli I have various errors like:

make[2]: *** No rule to make target 'src/corefx/System.Globalization.Native/CMakeFiles/System.Globalization.Native.dir/build'.  Stop.
make[1]: *** [src/corefx/System.Globalization.Native/CMakeFiles/System.Globalization.Native.dir/all] Error 2

CMakeFiles/Makefile2:103: recipe for target 'src/corefx/System.Globalization.Native/CMakeFiles/System.Globalization.Native.dir/all' failed make[1]

It might just be some invalid paths on my end.

Previously I had errors because of my script using amd64 rather than aarch64... I'm mostly fighting against human (my) errors and stuff I don't know.

To answer your last question, I read it, and I think I understand the relationships in principle, but they seem to reference themselves through nuget and download cli, so how to use a custom corecli to build a custom corefx and cli is not yet clear; the other confusion I have is trying to compare to Microsoft's bundling on Ubuntu; but I think these are concerns for after I get a build that works on my phone :P

TLDR: I don't know what I'm doing :) But I move through each error one by one, so I will get it working at some point, though it might some time.

cydhaselton commented 8 years ago

@christianrondeau Try ./build.sh arm64 skiptests. That's what works when building on Termux.

christianrondeau commented 8 years ago

Same result. When I compare (vimdiff) the build log from termux build-package.sh and from source, this "recipe for target... failed" is the main thing I can see.

vishalbiswas commented 8 years ago

@christianrondeau Can post the diff here?

vishalbiswas commented 8 years ago

http://pastebin.com/6nvVkdri This should get you to the part where it actually builds for aarch64. Now, you'll need to compile the dependencies before building coreclr. The first one is libunwind.

christianrondeau commented 8 years ago

Thanks @vishalbiswas - the build.sh patch makes it build, but the patch to gen-buildsys-clang.sh gives me these new errors:

-- The ASM compiler identification is Clang   -- Found assembler: /home/christian/.termux-build/_lib/toolchain-aarch64-ndk13-api21-v2/bin/aarch64-linux-android-clang
Detected Linux x86_64
CMake Error at src/corefx/System.Globalization.Native/CMakeLists.txt:13 (message):
Cannont find utypes.h, try installing libicu-dev (or the appropriate package for your platform)

But libicu-dev is already installed. Without that patch, the generated executable still looks like a x86_64.

vishalbiswas commented 8 years ago

@christianrondeau lets switch to gitter

christianrondeau commented 8 years ago

I have created a channel here: https://gitter.im/christianrondeau/termux-packages - I will post minor updates and interrogations there from now on instead, until I have something usable, in which case I'll post actual progress here. Keep in mind that I can only fiddle with this a few minutes every day, so don't expect too much :) Thanks for your help though, hopefully I'll get it done, but in the meantime I'm learning a lot.

cydhaselton commented 8 years ago

System.Private.Corelib.dll built

cydhaselton commented 8 years ago

Unfortunately I'm getting complaints from android about libcoreclr (when running corerun) having text relocations $``which corerun``usr/opt/microsoft/powershell/6.0.0-alpha.12/powershell.dll dlopen failed to open the libcoreclr.so with error dlopen failed: text relocations (DT_TEXTREL) found in 64-bit ELF file "/data/data/com.termux/files/usr/bin/Product/Linux.arm64.Debug/libcoreclr.so"

Oddly, the corerun should be using the libcoreclr that was copied to the /lib directory

christianrondeau commented 8 years ago

Where did you get the termux-compatible coreclr/corerun?

cydhaselton commented 8 years ago

I built them on-device.

christianrondeau commented 8 years ago

You mean, you built coreclr on Termux? But some of the dependencies (like icu) aren't yet ported to termux... unless there is a corerun as part of corefx too?

Or you are just crazy fast :P

cydhaselton commented 8 years ago

Built the dependencies on-device as well; my tablet is basically my build machine. I think I did a make install INSTALLDIR=/alt/location for all of the dependencies I ported.

cydhaselton commented 8 years ago

In case it is termux-related, here's the issue I'm running into when trying to rebuild coreclr

CtrlAltCuteness commented 8 years ago

I'm just going to throw this out as I seemed to have gotten lost in all the content (and I forgot if this Android browser I'm using right now supports the equiv of Windows' common Ctrl-F)... I assume the open-source Mono project (.NET alternative, and only reliable alternative, for *nix-style OSes) was tried already, or is no longer maintained?

christianrondeau commented 8 years ago

Hehe I'm lost in all this content myself :)

Mono is an implementation of Microsoft .Net indeed, but. Net Core is a different framework, with a high compatibility but different nonetheless. @cydhaselton used mono to build the corefx librairies, and I'm struggling (actually not moving at all for now) with coreclr and cli; these three components (along with roslyn and aspnet core) make up .Net Core.

My (personal) objective is to write a cross platform app and use my Android device to develop it on the go, so mono is not what I'm looking for. It would be great to have too, though... But that would be another package.

Microsoft will have official Android support soon, so in the meantime I'm mostly porting dependencies...

cydhaselton commented 8 years ago

@christianrondeau Small correction...I used mono to build the System.Private.Corelib.dll and mscorlib.dll found in the coreclr repo; I used mono's xbuild with the Roslyn csharp compiler. I built corefx...specifically the necessary native bits...using Termux build tools (cmake, clang, etc).

For corefx, all I needed were the native bits, which can be built on Termux. After cloning the source tree, navigate to the src/Native directory and run build-native.sh. The script may need some hacks to run, but they should be trivial; you can reference the changes made in my fork.

cydhaselton commented 8 years ago

FYI, currently working on getting a simple 'hello world' working with corerun and unpackaged assemblies

christianrondeau commented 8 years ago

Thanks @cydhaselton and @rogersachan for the updates. That's amazing! Nothing moving on my end however.