Compiling Mosh for OpenIndiana

A buddy of mine has convinced me of the merits of Mosh, and I want to use it with my OpenIndiana file server. There’s no package for it, so I’ve got to compile from source. This is the first time I’ve ever done anything like this, so it’s all a bit daunting. Coming from Ubuntu where installing things are generally never more complicated than ‘apt-get install $package’, having to do things the old fashioned way is a bit more difficult.
tl;dr

So, to do it, I first grabbed Protocol Buffers from here, and the Mosh tarball from their homepage.

wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
wget https://github.com/downloads/keithw/mosh/mosh-1.2.tar.gz

I had to install header-math with pkg before I could get protobuf to compile, and make sure to use gnu-make, NOT Solaris make.

The first time I installed protobuf, things went fine, but installing Mosh was impossible. I’m not sure if this is caused by me not having configured a proper compilation environment; not knowing what I’m doing; OpenIndiana; or a combination of the three, but I had to set a few variables when configuring protobuf. It originally installed /usr/local/bin, which caused the Mosh configure to fail because it couldn’t find protoc, because /usr/local/bin is not part of $PATH by default. Adding it to my path worked got me past that point, but then it couldn’t find ncurses.

It started to fail with:

configure: error: Unable to find libtinfo or libncurses.

Checking the config.log I found:

configure:7005: checking for TINFO
configure:7012: $PKG_CONFIG --exists --print-errors "tinfo"
Package tinfo was not found in the pkg-config search path.
Perhaps you should add the directory containing `tinfo.pc'
to the PKG_CONFIG_PATH environment variable
No package 'tinfo' found
configure:7015: $? = 1
configure:7029: $PKG_CONFIG --exists --print-errors "tinfo"
Package tinfo was not found in the pkg-config search path.
Perhaps you should add the directory containing `tinfo.pc'
to the PKG_CONFIG_PATH environment variable
No package 'tinfo' found
configure:7032: $? = 1
configure:7046: result: no
No package 'tinfo' found
configure:7064: checking for TINFO
configure:7071: $PKG_CONFIG --exists --print-errors "ncurses"
Package ncurses was not found in the pkg-config search path.
Perhaps you should add the directory containing `ncurses.pc'
to the PKG_CONFIG_PATH environment variable
No package 'ncurses' found
configure:7074: $? = 1
configure:7088: $PKG_CONFIG --exists --print-errors "ncurses"
Package ncurses was not found in the pkg-config search path.
Perhaps you should add the directory containing `ncurses.pc'
to the PKG_CONFIG_PATH environment variable
No package 'ncurses' found
configure:7091: $? = 1
configure:7105: result: no
No package 'ncurses' found

I know ncurses is installed, because I had to install it to get iftop work to narrow down some networking problems I was having. So, I checked where the ncuses libraries are, then added those to NCURSES_CPPFLAGS and NCURSES_LDFLAGS since those were the only mentions of ncurses in the configure –help file; this did nothing, and I still failed with the same error.

So I turned to the OI mailing list which proved to help me figure out what I was actually doing even further than my shit fisted earlier fumblings did. Then I set LD_LIBRARY_PATH to include /usr/gnu to try to force gcc to go somewhere:

export PKG_CONFIG_PATH="/usr/lib/amd64/pkgconfig/:/usr/lib/pkgconfig/:/usr/share/pkgconfig/"
export LD_LIBRARY_PATH="/usr/lib/:/usr/lib/:/usr/lib/amd64/"

This didn’t help get configure to run completely. Turns out what I actually needed to do was set the C and C++ compiler flags to know to look into the default library directory as well as wherever else it does:

CFLAGS=”-L/usr/gnu/lib” CXXFLAGS=”-L/usr/gnu/lib” ; export CFLAGS CXXFLAGS

This got me past both the ncurses error, but now I received:

checking for protobuf... no
configure: error: Package requirements (protobuf) were not met:
No package 'protobuf' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

ARGH, I thought I fixed the fucking protobuf errors. Apparently not, reading a bunch of stuff about what actually happens when you’re running a configure script, I realized what I was doing wrong. The protocolbuffer’s configure script was putting things in /usr/local/bin, and then when I ran the Mosh configure, it wasn’t looking there because it’s an asshole or something. SO, let’s figure out how to get protobuf to install like the rest of everything does instead of trying to get Mosh to figure out how to deal with things in places all over everywhere.

Checking protobuf’s configure –help let me see how to override the binary and library directories. So I removed the old files, and reconfigured, re-make’d and re-installed:

./configure --bindir=/usr/gnu/bin/ --libdir=/usr/gnu/lib/

Which put all the proto files in the right places and let the configure script finish properly. Well, sort of, I had some errors:

configure: WARNING: Unable to find byte swapping functions; using built-in routines.
checking whether IP_MTU_DISCOVER is declared... no
checking whether __STDC_ISO_10646__ is declared... no
configure: WARNING: C library doesn't advertise wchar_t is Unicode (OS X works anyway with workaround).
checking whether IUTF8 is declared... no
configure: WARNING: No IUTF8 termios mode; character-erase of multibyte character sequence probably does not work properly in canonical mode on this platform.
checking for protobuf... yes
configure: creating ./config.status

So, clearly there were still going to be problems.

Googling around for the first error regarding byte swapping led me to Mosh bug 107 and a thread with a rather successful multiplatform workaround:

sudo mkdir /usr/include/libkern /usr/include/libkern/machine
sudo wget -O/usr/include/libkern/OSByteOrder.h http://iphone-dev.googlecode.com/svn/trunk/odcctools/include/libkern/OSByteOrder.h
sudo wget -O/usr/include/libkern/machine/OSByteOrder.h http://iphone-dev.googlecode.com/svn/trunk/odcctools/include/libkern/machine/OSByteOrder.h
sudo cp /usr/include/libkern/OSByteOrder.h /usr/include/libkern/OSByteOrder.h.orig
sudo sh -c '(echo "#define __LITTLE_ENDIAN__"; cat /usr/include/libkern/OSByteOrder.h.orig) > /usr/include/libkern/OSByteOrder.h'

Which gets some header files from a BSD licensed Apple project, and clears up that warning.

But it still doesn’t compile. Now I fail at:

make[3]: Entering directory `/home/robbie/compiling/moshing/server/mosh-1.2/src/network'
CXX network.o
In file included from network.cc:39:0:
network.h:79:48: error: expected ',' or '...' before '.' token
network.cc: In constructor 'Network::Packet::Packet(std::string, Crypto::Session*)':
network.cc:62:3: error: '__STRING' was not declared in this scope
network.cc: In constructor 'Network::Connection::Connection(const char*, const char*)':
network.cc:174:61: error: no matching function for call to 'Network::Connection::try_bind(int&, uint32_t&, long int&)'
network.cc:174:61: note: candidate is:
network.h:79:17: note: static bool Network::Connection::try_bind(int, uint32_t)
network.h:79:17: note: candidate expects 2 arguments, 3 provided
network.cc:186:54: error: no matching function for call to 'Network::Connection::try_bind(int&, unsigned int, long int&)'
network.cc:186:54: note: candidate is:
network.h:79:17: note: static bool Network::Connection::try_bind(int, uint32_t)
network.h:79:17: note: candidate expects 2 arguments, 3 provided
network.cc: At global scope:
network.cc:197:49: error: expected ',' or '...' before '.' token
network.cc: In static member function 'static bool Network::Connection::try_bind(int, uint32_t)':
network.cc:201:32: error: request for member 'S_addr' in 'S_un', which is of non-class type 'uint32_t {aka unsigned int}'
network.cc:205:16: error: invalid use of member (did you forget the '&' ?)
network.cc:206:32: error: argument of type 'int (Network::Connection::)()const' does not match 'int'
network.cc: In member function 'std::string Network::Connection::recv()':
network.cc:298:3: error: '__STRING' was not declared in this scope
make[3]: *** [network.o] Error 1
make[3]: Leaving directory `/home/robbie/compiling/moshing/server/mosh-1.2/src/network'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/robbie/compiling/moshing/server/mosh-1.2/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/robbie/compiling/moshing/server/mosh-1.2'
make: *** [all] Error 2

Which is where I am now. There’s talk on the OI mailinglist about how to get this to compile, but I cannot replicate the success. Probably because of the aforementioned lack of understanding regarding how code compilation actually functions. So, I’m off to try to learn more about that so I can hopefully get a bit further than I currently am with this.