Thursday, 25 August 2011

Cross compiling ports for ARM under FreeBSD

So this is something I've been working on and off for the last few months, but now I think I found the probably most elegant solution, although it's not working for every single port so far.
I managed to compile important ports like net/mpd5 and www/thttpd as well as some others, but failed for now with net/gateway6 or net-p2p/transmission-daemon.
But some tweaking might fix that.

But in general the following steps will get you to your cross-compiled ports:

1) Get the cross-compiler and tools:

This step is quite easy to achieve. Check out the source tree into /usr/devel (or whichever folder you prefer) and run

make TARGET=arm KERNCONF="" kernel-toolchain toolchain

This will place the cross-compiler, all the necessary tools and the libraries into /usr/obj/arm.arm/usr/devel/

2) Create the cross-compile environment

I started an extra shell (bash), in order not to mess up my current environment, and exported the following env variables:

export CC=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/gcc
export CPP=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/cpp
export CXX=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/g++
export AS=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/as
export NM=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/nm
export RANLIB=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/gnu-ranlib
export LD=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/ld
export OBJCOPY=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/objcopy
export SIZE=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/size
export AR=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/gnu-ar
export STRIPBIN=/usr/obj/arm.arm/usr/devel/tmp/usr/bin/strip
export MACHINE=arm

export MACHINE_ARCH=arm

3) Compile a port:

First create two folders, one into which to install the ports, one to use as working directory for the port. In my case /home/arm/portinstall and /home/arm/portwork. This keeps things clean.

Then cd into a ports directory and issue the following command:

make PREFIX=/home/arm/portinstall WRKDIRPREFIX=/home/arm/portwork CONFIGURE_ARGS+="--host=arm --prefix=/home/arm/portinstall" LDFLAGS+="-rpath=/usr/obj/arm.arm/usr/devel/tmp/lib:/usr/obj/arm.arm/usr/devel/tmp/usr/lib:/home/arm/portinstall/lib:/usr/obj/arm.arm/usr/devel/lib -L/usr/obj/arm.arm/usr/devel/tmp/lib -L/usr/obj/arm.arm/usr/devel/tmp/usr/lib -L/home/arm/portinstall/lib -L/usr/obj/arm.arm/usr/devel/lib" NO_PKG_REGISTER=1 clean install

The command explained:
PREFIX sets the installation prefix for the port
WRKDIRPREFIX sets the working directory
CONFIGURE_ARGS+= are additional arguments passed to the configure script, which does not always observe the environment variables. Therefore prefix and host are declared again. For ftp/curl for example you also need to pass --without-random.
LDFLAGS sets the library search paths. As you're cross-compiling you need to make sure that the program links to the correct library, the ARM one not the one of the host you're compiling on.
This is fixed using the -L flags and the -rpath flag. Experience has shown you need both.
NO_PKG_REGISTER needs to be set in order to avoid the package being registered for the local system. If you cross-compile a port that is not already also installed in the current system, you also don't want the system to think it has been installed, where it's actually not, as it's been cross-compiled.

The information in this post is based on the outdated information found here

Some ports might need additional tweaking, by passing additional options to LDFLAGS or CONFIGURE_ARGS.
Ports might also need additional compilers or make tools (like gmake) and might try to install them as part of the ports installation process. You have to make sure that they are installed on the local system beforehand, as the cross-compiler will generate ARM binaries otherwise, and the cross-compilation of the main port will fail.

An other possibility is to create a separate jail in which you do the cross compilation and install the ports in the default directory instead of using the PREFIX directive. It's a bit more messy as all ARM and non ARM ports are installed in the same location, but you can use a

make package

and then install the package on the destination machine.
The biggest problem in this situation though are the ports which have the same port as build dependency and run-time dependency. In that case you'd need an ARM and a non ARM port in the same place, which won't work..
Having not personally tried the jails solution, I can not suggest a proper workaround for this problem.

[edit]
Aleksandr Rybalko also has some hints about cross-compiling which can be found here
Specifically point 2 in that blog deals with dependencies.

Installing Matlab 2011a on FreeBSD

After having had to move my Linux box from my desk due to Occupational Health and Safety issues (It seems that 5 PC's around you are just too many), I had to install Matlab on my main PCBSD 8.2 box.
A scary task after having failed with 2009b, and 2010a a while ago (on a box running 8-CURRENT though).

Now it seems to work just fine. All you need is the Linux compatibility layer and libraries and tweak some of the files:

For the installation:

Edit the "installer" file and replace

#!/bin/sh
with
#!/compat/linux/bin/sh

Then install Matlab, muck around with the license stuff, and cd to the installation folder.

In the installation folder edit file "bin/matlab" and replace

#!/bin/sh
with
#!/compat/linux/bin/sh

as before. Then edit "bin/util/oscheck.sh" and again replace

#!/bin/sh
with
#!/compat/linux/bin/sh

Then start Matlab by simply typing "matlab"

It worked, and the java interface still crashes when trying to work with multiple directories containing lots (about 10000 or more) of files, like it did with 2010b under Linux.
Well, gotta live with that.

Monday, 11 April 2011

Konica Minolta Bizhub C652, C652DS, C650 driver with Account Tracking for CUPS

We recently got a new printer on the 6th floor of the EN buiding where our Faculty and Research Group resides. It's a Konica Minolta Bizhub C652DS, the slightly newer model of the C650 found on the 5th floor.

Quite a massive printer, with additions like folding, stapling and hole punching units etc.
The CUPS drivers from Konica are actually not too bad, with the exception that they do not support account tracking, which is used within the faculty.

With the help of John and Jason and some searching I was able to create two PPD files for the C652 and C650 printers, using the femperonpsc250mu.pl filter by Rui Ferrera.

It's now as simple as copying the femperonpsc250mu.pl script to the cups filter directory (like /usr/libexec/cups/filter) and setting the right owner and permissions, and then installing the printer using the new C652 and C650 PPD files found here, using the lpd:// protocol.
(It might also work via https:// as described here)

As CUPS does not yet allow to create an input field for options, you need to set the account key etc. by pull down menu (or combobox or whatever you call them).

It also works if you install the printer on a single CUPS printserver, and just point the various clients to it. In that case anyhow you'll need to set your own passcode or account key in each printing UI (like once for KDE apps once for GTK apps)

Happy printing!

Download the tarball

Tuesday, 5 April 2011

Issues with PC-BSD 8.2

Coming back to work from my break, it was about time to get rid of FreeBSD 9.0 CURRENT on my production machine and to install a more stable system. As Grenville had almost only good things to say about PC-BSD (like a super easy ZFS installation), I gave it a shot.

I have to say: the installation process is really nice, not like FreeBSD. Took only a few clicks and a bit of waiting, and it worked. Installing additional programs was easy through the PBI system - for the software available. to get more, I had to use the ports system as usual. No problem at all, no conflicts (except that PC-BSD ships with howl, but I prefer avahi).

It's not all good and shiny though.Upon firing up VirtualBox for example, it fired up kdesu and asked me to login as root to continue. Well - done that, thought not much about it, must be PC-BSD's way. Same thing then for Skype, and things started not to make much sense, specially as Skype just wouldn't start that way. Upon firing up Wireshark it wanted to run it as root again. Well that's a no-no, except you really intend to, which most of the time I do not. It also comes up with a big fat warning if you do that.

I don't know why PC-BSd sets the programs up to start like that from KMenu or the KLauncher (ALT+F2), but it doesn't make sense. so to get rid of that behaviour, just right klick on the KMenu -> Menu editor , select the program in question, go to the Advanced tab and deselect the "run as different user" checkbox.


Now, the next thing to fix is Kile which complains about Okular not being installed although it is and getting KDE programs to find the printers, which GTK programs already do.

Monday, 4 April 2011

Embedding fonts in PDFs using ghostscript without recompiling or reexporting the source text

Well, this has been tackled many times already in a variety of blogs and webpages, but I keep it here as reference.

There is always some crappy program that doesn't embed the fonts when exporting to PDF -- which is needed for some conference papers.

In my case the crappy tool is Matlab. Instead of going back and fiddling around with Matlab to export the graphs again and try to get it to embed fonts, I prefer the following shortcut found here.

Actually the solution in the comments further down works best:

pdftops file.pdf
ps2pdf -dSAFER -dNOPLATFONTS -sPAPERSIZE=letter -dEmbedAllFonts=true -dPDFSETTINGS=/prepress file.ps file.pdf

On FreeBSD you need poppler-utils and ghostscript to get the pftops and ps2pdf commands.

And because I had a bunch of graphs in PDF format without fonts embedded I needed a script to automate the process. Using tcsh it works like that:

cd figures
mkdir non-embedded
mv *.pdf non-embedded
foreach file (non-embedded/*.pdf)
pdftops $file
set psfile = `echo $file | cut -d"." -f1`.ps
set pdffile = `echo $file | cut -d "/" -f2
ps2pdf -dSAFER -dNOPLATFONTS -sPAPERSIZE=letter -dEmbedAllFonts=true -dPDFSETTINGS=/prepress $psfile $pdffile
end

And a similar script can be used to crop the graphs in PDF format using pdfcrop:

foreach file (*.pdf)
pdfcrop $file
set cropped = `echo $file | cut -d "." -f 1`-crop.pdf
rm -rf $file
mv $cropped $file
end

This removes all extra white space around all graphs. Again useful to handle crappy Matlab outputs.

Edit:

And here's the magic command to create a pdf with embedded fonts, optimized and 600dpi resolution (as requested by Sheridan Press for example):

pdftops file.pdf
ps2pdf -dSAFER -dNOPLATFONTS -sPAPERSIZE=letter -dEmbedAllFonts=true -dPDFSETTINGS=/prepress -dOPTIMIZE=true -dCompatibility=1.4 -r600 file.ps file.pdf

Installing a FreeBSD guest system on VirtualBox (binary version) on a Linux host

I think this solution is a good start for my blog, I also added some pics :-).

FreeBSD 8.2 was not so keen to install on VirtualBox 4.0.4  as it should, refusing to use the DVD iso I mounted and booted off from as installation medium.

Well turns out, the default settings VirtualBox provides for a FreeBSD install are no good. FreeBSD seems not to be happy with the CDROM drive being attached at an IDE adapter, so you need to switch to SATA:




Furthermore, FreeBSD doesn't seem to be happy with the EHCI USB controller of the binary VirtualBox, so you need to disable that if you want to use USB 2.0 devices in FreeBSD. They'll revert to slow USB 1.1, but at least you can access them.


And if you want to do FreeBSD development work like I do, using one or more copies of the FreeBSD source tree, you need to allocate a larger disk as well, the default 8GB will not be enough. I would suggest at least 30GB.