Introduction
Mono allows us to run Windows Applications in our Linux environment. It is an open source implementation of Microsoft’s .NET Framework. The problem is, CentOS (and Red Hat) 6.x ship with Mono v2.4 which is a little outdated. You can’t take advantage of the newer apps .NET developers are writing. In fact, you can’t run anything that requires a newer version of v3.5 of the .NET runtime libraries.
In addition to that, Mono v3.4 grants your CentOS system more support for .NET applications that weren’t otherwise available for you in v2.4.
Compatibility | Mono v2.4 | Mono v3.4 |
---|---|---|
.NET 1.0 | Yes | No (dropped support) |
.NET 2.0 | Yes | Yes |
C# 3.0 | Yes | Yes |
ASP.NET 2.0 | Yes | Yes |
.NET 3.5 | Partial | Yes |
.NET 4.0 | No | Yes |
.NET 4.5 | No | Yes |
C# 4.0 | No | Yes |
ASP.NET 4.0 | No | Yes |
C# 5.0 | No | Yes |
What’s so special about the repackaging you did?
Well first of all… it’s actually an RPM package. It doesn’t require you to haul in a ton of development libraries and compile it from scratch. Another point is that Mono v2.4 (shipped with CentOS & Red Hat 6) had many patches applied to it. These patches forced Mono to conform to the common directory structure used natively by our Operating System. It took me several hours to recreate all of these patches forcing Mono v3.4 to comply with the same standards.
Finally (and at the time of writing this blog), this is the first package of Mono v3.4 that I’ve found that can be installed via an RPM and not require you to recompile everything yourself. Hence you don’t even need to haul in any development libraries at all. Mono will just work as is. Since my repackaging was based off of the original, I tried to keep all of the external rpm packages the same. That said, I did get a little confused with all of the new packages and binary tools that ship with Mono v3.x. Since I’m not a Microsoft Developer, I tried to sort these new packages accordingly as best as I could. Please feel free to let me know how I can improve this package if you notice anything I’ve done wrong.
Just hand over all your work already!
Absolutely, here they are:
Binary Packages:
- mono-core-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-data-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-data-oracle-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-data-postgresql-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-data-sqlite-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-devel-3.4.0-1.el6.nuxref.x86_64.rpm
- monodoc-3.4.0-1.el6.nuxref.x86_64.rpm
- monodoc-devel-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-extras-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-locale-extras-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-nunit-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-nunit-devel-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-reactive-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-wcf-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-web-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-web-devel-3.4.0-1.el6.nuxref.x86_64.rpm
- mono-winforms-3.4.0-1.el6.nuxref.x86_64.rpm
Note: Mono (v3) was a bit picky about it’s SQLite version it referenced. I had to update it’s package to a slightly newer version as well for everything to play nicely. Only if you intend to haul in the mono-data-sqlite-*.rpm package, will you be required to haul in this newer version. I’ve already provided this on my repository, but for the sceptics who want to build it themselves, I’ll include those instructions too.
- lemon-3.8.1-2.el6.x86_64.rpm
- sqlite-3.8.1-2.el6.x86_64.rpm
- sqlite-devel-3.8.1-2.el6.x86_64.rpm
- sqlite-doc-3.8.1-2.el6.noarch.rpm
- sqlite-tcl-3.8.1-2.el6.x86_64.rpm
Source Packages:
Debug Info Packages
Alternatively, you can get it from my repository too (this is the best and easiest way). The below instructions assume you’ve set yourself up.
# Make sure you're hooked up with my repository for this to # work: http://nuxref.com/nuxref-repository/ ################################################################ # Install Mono ################################################################ yum install -y --enablerepo=nuxref --enablerepo=nuxref-shared mono-core ################################################################ # Install additional packages too if you wish (depending on your # needs. ################################################################ yum install -y --enablerepo=nuxref --enablerepo=nuxref-shared mono-web
I’ll Never Trust Your Stuff; Let Me Do It Myself
Sure, First you’re going to need to fetch all the patches I had to create (plus the old ones carried forth from Mono v2.4:
- old: Patch 0: mono-3.4-ppc-threading.patch was carried forward from a patch created for Mono v2.4.
- old: Patch 1: mono-1.2.3-use-monodir.patch was carried forward from a patch created for Mono v2.4.
- old: Patch 2: mono-2.2-uselibdir.patch was carried forward from a patch created for Mono v2.4.
- old: Patch 3: mono-2.0-monoservice.patch was carried forward from a patch created for Mono v2.4.
- new: Patch 4: mono-3.4-libgdiplusconfig.patch was carried forward from a patch created for Mono v2.4 but recreated since the old one had HUNK failures due to new changes in v3.4.
- new: Patch 5: mono-3.4-libdir.patch was carried forward from a patch created for Mono v2.4 but recreated since the old one did not work correctly. This patch was drastically changed to accommodate for all of the new files and incorrect library references.
- new: Patch 6: mono-3.4-POSIX_ARG_MAX.patch was taken from the SPEC file as a handbomb fix in v2.4 and converted into a proper patch for this v3.4. This is effectively carried over from the previous packaging.
- new: Patch 7: mono-3.4.xamarin.BZ18690.patch For more information, see this link here.
You can additionally view the RPM SPEC file I created here.
First prepare our development environment with mock if you haven’t already:
# Install 'mock' into your environment if you don't have it already # This step will require you to be the superuser (root) in your native # environment. yum install -y mock # Grant your normal every day user account access to the mock group # This step will also require you to be the root user. usermod -a -G mock YourNonRootUsername
# Download the official mono packages from their official # hosting site: wget http://origin-download.mono-project.com/sources/mono/mono-3.4.0.tar.bz2 # Download all of the building blocks you'll need wget --output-document=mono.spec https://www.dropbox.com/sh/9dt7klam6ex1kpp/AAAiqD2KjHhakweKY_mkLLPba/20140713/mono/mono.spec?dl=1 wget --output-document=monodir.c https://www.dropbox.com/sh/9dt7klam6ex1kpp/AABZHv5NeWFICyAAAw--eiJoa/20140713/mono/monodir.c?dl=1 wget --output-document=mono.snk https://www.dropbox.com/sh/9dt7klam6ex1kpp/AADoY6UvThpcQbUHhs7XUecsa/20140713/mono/mono.snk?dl=1 wget --output-document=lc https://www.dropbox.com/sh/9dt7klam6ex1kpp/AACkja0kNxmO1ytHOIw523HTa/20140713/mono/lc?dl=1 wget --output-document=mono-3.4-ppc-threading.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AAAKrjdqRR826osJjbqZIu5la/20140713/mono/mono-3.4-ppc-threading.patch?dl=1 wget --output-document=mono-1.2.3-use-monodir.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AABHvxieGDqU8eDB24ghS_Dua/20140713/mono/mono-1.2.3-use-monodir.patch?dl=1 wget --output-document=mono-2.2-uselibdir.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AABSjbMfIRj5JB7HKWydQVpja/20140713/mono/mono-2.2-uselibdir.patch?dl=1 wget --output-document=mono-2.0-monoservice.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AADsL0DBfI0VixRAw6uI0Vkpa/20140713/mono/mono-2.0-monoservice.patch?dl=1 wget --output-document=mono-3.4-libgdiplusconfig.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AAAHvISVzxIPq9xCmw2m2tcPa/20140713/mono/mono-3.4-libgdiplusconfig.patch?dl=1 wget --output-document=mono-3.4-libdir.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AACHrlv_iSp36jhSeOn4ki0fa/20140713/mono/mono-3.4-libdir.patch?dl=1 wget --output-document=mono-3.4-POSIX_ARG_MAX.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AADSN5WhjyqTQptMoWthDnYHa/20140713/mono/mono-3.4-POSIX_ARG_MAX.patch?dl=1 wget --output-document=mono-3.4.xamarin.BZ18690.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/AAAwWsEKkOlnzYZCshp29wuwa/20140713/mono/mono-3.4.xamarin.BZ18690.patch?dl=1 # Initialize our Environment mock -v -r epel-6-x86_64 --init # Dependencies mock -v -r epel-6-x86_64 --install libpng-devel libjpeg-devel ligiflib-devel lilibtiff-devel lilibexif-devel lilibX11-devel lifontconfig-devel ligettext limake ligcc-c++ libison liglib2-devel lipkgconfig lilibicu-devel lilibgdiplus-devel lizlib-devel li automake libtool gettext-devel mono-core gcc-c++ mediainfo gettext giflib-devel libtiff-devel libexif-devel libX11-devel fontconfig-devel bison glib2-devel libicu-devel libgdiplus-devel mysql-devel postgresql-devel sqlite-devel # Copy our packages into our environment mock -v -r epel-6-x86_64 --copyin mono.spec /builddir/build/SPECS mock -v -r epel-6-x86_64 --copyin *.patch mono-3.4.0.tar.bz2 mono.snk lc monodir.c /builddir/build/SOURCES # Shell into our environment mock -v -r epel-6-x86_64 --shell # Change to our build directory cd builddir/build # Enable Bootstrapping for the first time # mono actually requires 'mono' (itself) to build. Weird Right? # But still necessary! For this reason I prepared an easier # way of enabling bootstrapping for your first build. # # Once you install the binaries created from your first build # we can rebuild the package again (but this time without # bootstrapping). The purpose of this is to ensure the mono # binaries and packages we created are equivalent to the # the bootstrapped content. # So... on with the bootstrapping; Note: this will take # 20 to 30 minutes depending on how fast your system is. rpmbuild -ba --define "_with_bootstrap=1" SPECS/mono.spec # Now that we've created mono from a bootstrap, we can # install the package back into our virtual environment # and rebuild it again. But this time we rebuild it # without the bootstrap reference. rpm -Uhi RPMS/mono-core-3.4.0-1.el6.nuxref.x86_64.rpm RPMS/mono-devel-3.4.0-1.el6.nuxref.x86_64.rpm # Now rebuild the whole thing all over again to confirm # your build was good; Note: This will take another 20 to 30 # minutes again... rpmbuild -ba SPECS/mono.spec # we're now done with our mock environment for now; Press Ctrl-D to # exit or simply type exit on the command line of our virtual # environment exit # We'll return to the directory we were previously in. We can copy # out the packages we just built at this point.Ignore the warning # about SELinux if you get one. It doesn't impact our goals at this # moment. mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/mono-3.4.0-1.el6.nuxref.src.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-core-3.4.0-1.el6.nuxref.x86_64.rpm mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-data-3.4.0-1.el6.nuxref.x86_64.rpm mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-data-oracle-3.4.0-1.el6.nuxref.x86_64.rpm mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-data-postgresql-3.4.0-1.el6.nuxref.x86_64.rpm mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-data-sqlite-3.4.0-1.el6.nuxref.x86_64.rpm mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-devel-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/monodoc-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/monodoc-devel-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-extras-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-locale-extras-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-nunit-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-nunit-devel-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-reactive-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-wcf-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-web-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-web-devel-3.4.0-1.el6.nuxref.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-winforms-3.4.0-1.el6.nuxref.x86_64.rpm . # The debuginfo package will only exist if you successfully rebuilt # everything without the bootstrap set mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/mono-debuginfo-3.4.0-1.el6.nuxref.x86_64.rpm .
Upgrading SQLite
For me, I just visited pkgs.org and downloaded the fedora 20 (source -src.rpm) release of SQLite. Then I extracted it’s contents as follows:
# I can't promise this link will work, as this package is always # evolving, but if you do the search above, you'll get the idea wget http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Everything/source/SRPMS/s/sqlite-3.8.1-2.fc20.src.rpm # Alternatively, you can download the source rpm package I'm # already hosting: wget http://repo.nuxref.com/centos/6/en/source/custom/sqlite-3.8.1-2.el6.src.rpm # Then extracted it using this neat technique: rpm2cpio sqlite-*.src.rpm | cpio -idmv # Initialize our Environment mock -v -r epel-6-x86_64 --init # Dependencies mock -v -r epel-6-x86_64 --install ncurses-devel readline-devel glibc-devel autoconf /usr/bin/tclsh tcl-devel # You'll already have the block you need as nothing is # changed with this package. We're just using it as is mock -v -r epel-6-x86_64 --copyin sqlite-*.zip /builddir/build/SOURCES mock -v -r epel-6-x86_64 --copyin *.patch /builddir/build/SOURCES mock -v -r epel-6-x86_64 --copyin sqlite.spec /builddir/build/SPECS # Shell into our environment mock -v -r epel-6-x86_64 --shell # Change to our build directory cd builddir/build # Build our packages (process doesn't take long ~2 min) rpmbuild -ba SPECS/sqlite.spec # we're now done with our mock environment for now; Press Ctrl-D to # exit or simply type exit on the command line of our virtual # environment exit # We'll return to the directory we were previously in. We can copy # out the packages we just built at this point. Ignore the warning # about SELinux if you get one. It doesn't impact our goals at this # moment. mock -v -r epel-6-x86_64 --copyout /builddir/build/SRPMS/sqlite-3.8.1-2.el6.src.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sqlite-3.8.1-2.el6.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sqlite-devel-3.8.1-2.el6.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sqlite-doc-3.8.1-2.el6.noarch.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/lemon-3.8.1-2.el6.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sqlite-tcl-3.8.1-2.el6.x86_64.rpm . mock -v -r epel-6-x86_64 --copyout /builddir/build/RPMS/sqlite-debuginfo-3.8.1-2.el6.x86_64.rpm .
Credit
This blog took me a very (,very) long time to put together and test! The repository hosting alone now accommodates all my blog entries up to this date. If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.
I’ve tried hard to make this a complete working solution out of the box. Please feel free to email me or post comments below with any suggestions you have so I can ensure this blog is as complete as possible! Positive feedback is always welcome too!
Repository
This blog makes use of my own repository I loosely maintain. If you’d like me to continue to monitor and apply updates as well as hosting the repository for long terms, please consider donating or offering a mirror server to help me out! This would would be greatly appreciated!
Sources
The majority of my efforts came from the following sites:
- Official Mono Project Website
- Mono Official Compatibility List
- A search on pkgs.org for mono and downloading the src.rpm as a base to start with. The src.rpm carried most of the blue-prints I’d need to rebuild a newer version.
- Mono source repository
- A search on pkgs.org for SQLite and downloading the src.rpm as a base to start with. You’ll want to use SQLite v3.8.1 or higher.
- Official SQLite Website