Open christianrondeau opened 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:
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.
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.
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.
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.
@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.
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.
@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?
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.
@christianrondeau build-package.sh steps:
termux_step_make_install
to install all required files under $TERMUX_PREFIX, to ensure they are included in the package.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):
fxr/1.0.1/libhostfxr.so
)1.0.0-preview3-000001/
and lots of files)Microsoft.NETCore.App/1.0.1/
and lots of files)So two things I'm not sure about.
dotnet-host-ubuntu.16.04-x64.1.1.0-preview1-001100-00.deb
file.So my next steps are to:
dotnet
executable, like the host
deb
file, in the massage folder and see what happens,It's moving forward!
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
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?
@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.
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...
@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.
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?
@christianrondeau run readelf -h
which dotnet``
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
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!
It would be better to port mono, until upstream .Net Core adds support for arm.
@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 :)
Here's the overview of what I found on how to build it on ARM:
dotnet
executable (for building, running and creating projects). This is confusing, it downloads binaries that are not arm-compatible, and I can't find how to make the build process use arm assemblies, or whether there are efforts to cross compile it.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.
@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.
@cydhaselton How about building in chroot on device?
@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?
@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!
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
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
@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
@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.
@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.
@christianrondeau Try ./build.sh arm64 skiptests. That's what works when building on Termux.
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.
@christianrondeau Can post the diff here?
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.
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.
@christianrondeau lets switch to gitter
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.
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
Where did you get the termux-compatible coreclr/corerun?
I built them on-device.
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
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.
In case it is termux-related, here's the issue I'm running into when trying to rebuild coreclr
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?
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...
@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.
FYI, currently working on getting a simple 'hello world' working with corerun and unpackaged assemblies
Thanks @cydhaselton and @rogersachan for the updates. That's amazing! Nothing moving on my end however.
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