HowTo compile on IRIX SGI O2
From AMule Project FAQ
Contents |
Introduction
This document deals with the configuration, compilation and linking of aMule-2.1.3 on a SGI O2 R5000 (MIPS IP32) IRIX 6.5 machine.
I strongly suggest to take more than a casual look to this page and this one, particularly here and here.
Be prepared to a long conf/comp/link session. SGI offers you some precompiled packages but a lot of them are outdated (pretty old, actually) so you need to compile a whole bunch of libraries starting from source packages.
Prerequisites
I assume you have a working knowledge of IRIX's "inst" tool and its GUI, "swmgr".
- OS: IRIX 6.5.19f or later, first release providing /dev/urandom special file and, if the case, a proper set of installation media.
- Hardware: O2 SGI R5000, a 32-bit CPU.
- Software:
- First of all you need a working installation of GCC. You can find a pre-compiled version of GCC (gcc-3.3) here. Read carefully the description notes and, if the case, install appropriate SGI back end (SGI ld, as, kernel headers and so on from Development Foundation and Development Libraries CDs).
- Another relevant piece of software is GNU make (gmake-3.8.0 here). Again, read the description notes and act accordingly. I shamelessly renamed original IRIX /sbin/make putting a symlink to gmake. On my system:
# ls -la /sbin/make* lrwxr-xr-x 1 root sys 23 Mar 31 15:11 /sbin/make -> /usr/freeware/bin/gmake -rwxr-xr-x 1 root sys 110264 Dec 1 2003 /sbin/make.orig
- Dependencies:
- If, while compiling required libraries (see later on), "configure" complains about missing pieces, try to install the SGI pre-compiled versions, if newer enough. Try to start from sources if you can not get through in any other way. Don't try to install the bleeding-edge, last-minute version. Stick to the minimum requirements as long as you can. Keep a low profile. After all, you are running on a quite old piece of hardware. I'm talking about a 180 MHz CPU. aMule takes more than five hours to compile, not to mention all required libraries.
- Almost surely you'll need other pieces of software you can download from SGI freeware site. A good choice is to install all the "basic" software, diffutils, fileutils, byacc, bison and so on. You know what I mean. A quite good tool is the "dependency calculator": please refer to that page for any unresolved dependencies.
Just a note: I strongly discourage to install binutils. I used SGI ld and as, NOT GNU binutils and GNU linker and assembler. Nothing wrong in binutils itself (it's a great piece of software on other platforms) but you will find it quite hard to get a working executable from scratch (SGI does NOT give you pre-compiled software). I'd like to stress this point again: GCC compiler and native SGI linker, assembler and loader!
aMule requires:
zlib >= 1.1.4
You can find libz-1.1.4 here. Read the description note.
gdlib >= 2.0.0
SGI offers you gd-1.8.4, so you have to download a more recent version from [1], configure, compile and install it, standard procedure. I used gd-2.0.35 with default (/usr/local) prefix.
libpng >= 1.2.0
SGI offers you libpng-1.0.15, so you have to download a more recent version from [2]. Download the with config script version, configure it, compile and install it, standard procedure. I used libpng-1.2.25 with default (/usr/local) prefix but I suppose newer versions fit good as well.
wxWidgets >= 2.6.0
SGI offers the old environment wxWindows-GTK-2.3.3 so you have to download a newer version from [3]. Configure/compile/install as usual. I used wxGTK-2.6.0.
aMule suggests:
libiconv
Download and install libiconv-1.12 [4]. Do NOT install libiconv-1.8 from SGI freeware, definitely outdated.
libintl
Install gettext-0.11.5 from SGI and read the notes.
readline
Install readline-4.3 from SGI and read the notes.
aMule suggests and/or requires
libcrypto >=5.1
Here it is. The tricky part. As you surely know, you can choose from two options, internal aMule libcrypto or external libcrypto >= 5.1. If you compile aMule-2.1.3 from unmodified sources you'll get broken executables. When amule is launched, it complains about three missing external functions, multi3, udivti3 and umodti3, all of them 64-bit library functions. No surprise your libgcc does not have such a beast. See here for the details. Again: all the tests and final builds were done on a 32 bit CPU. I have no idea on how to get through on a mips64 machine. So I preferred to download libcrypto-5.5.2 from here and compile it from source. For a reason, I dare to say: source tarball has a testsuite to check against compiled libraries.
Needless to say, I got the very same error: even libcrypto is broken for MIPS. Worse, libcrypto has no configure/make at all so you have to guess correct parameters and settings. First of all you have to patch config.h in the source directory of libcrypto.
The snippet of the patch for libcrypto is:
*** config.h Tue Apr 8 11:31:29 2008
--- config.h.orig Tue Apr 8 11:31:29 2008
***************
*** 124,137 ****
#endif
// define hword, word, and dword. these are used for multiprecision integer arithmetic
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE
! #define CRYPTOPP_SLOW_WORD64 // use alternative code that avoids word64
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
! // typedef byte hword;
! // typedef word16 word;
! // typedef word32 dword;
const unsigned int WORD_SIZE = sizeof(word);
const unsigned int WORD_BITS = WORD_SIZE * 8;
--- 124,159 ----
#endif
// define hword, word, and dword. these are used for multiprecision integer arithmetic
+ // Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx
+ #if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && \
(defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) \
|| (defined(__INTEL_COMPILER) && defined(__x86_64__))
+ typedef word32 hword;
+ typedef word64 word;
+ #else
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE
! #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \
defined(__x86_64__) || defined(__mips64) || defined(__sparc64__)
! #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
! typedef word32 hword;
! typedef word64 word;
! typedef __uint128_t dword;
! typedef __uint128_t word128;
! #define CRYPTOPP_WORD128_AVAILABLE
! #else
! // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain
// 128-bit multiplication results
! typedef word16 hword;
! typedef word32 word;
! typedef word64 dword;
! #endif
! #elif defined(WORD64_AVAILABLE)
! #define CRYPTOPP_SLOW_WORD64 // use alternative code that avoids word64
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
! #else
! typedef byte hword;
! typedef word16 word;
! typedef word32 dword;
! #endif
! #endif
const unsigned int WORD_SIZE = sizeof(word);
const unsigned int WORD_BITS = WORD_SIZE * 8;
You can apply the patch to your config.h as usual. Of course you could edit appropriate aMule files, namely CryptoPP.h by yourself. Patch is quite the same but I prefer to compile libcrypto from scratch because of the tests provided with.
The makefile must be tailored for your need, too. I used these settings:
CP = cp MKDIR = mkdir EGREP = egrep PREFIX = /usr/local AR = ar ARFLAGS = -rs CPPFLAGS='-I/usr/local/include -I/usr/freeware/include' LDFLAGS=-LD_LAYOUT:lgot_buffer=1024 -rpath /usr/local/lib:/usr/freeware/lib32:/usr/freeware/lib \ -L/usr/local/lib -L/usr/freeware/lib32 -L/usr/freeware/lib -lgcc CXXFLAGS = -DNDEBUG -g -DCRYPTOPP_DISABLE_ASM -mabi=n32
Cut away all the heading lines of "GNUmakefile" up to
SRCS = $(shell echo *.cpp)
(leaving untouched this last line) then pasting the snippet above. Name the file something like "Make_for_cryptopp" and launch make as
# make -f Make_for_cryptopp
Following the INSTALL directives, make the final test to double-check your libraries are working before installing them.
# ./conftest.exe v && make install
puts the libraries and header in a somewhat non-standard place. Headers go in /usr/local/include/cryptopp while library goes in /usr/local/lib. As usual, default "prefix" is /usr/local but you can modify it in "Makefile_for_cryptopp")
Patching aMule
In order to get a working aMule set of executables, you need to patch aMule sources in three different places. First of all you need to modify src/FileLock.h according to the lines:
*** FileLock.h.orig Fri Feb 3 13:25:17 2006
--- FileLock.h Thu Apr 3 13:35:30 2008
***************
*** 32,37 ****
--- 32,41 ----
#include <fcntl.h>
#include <cerrno>
+ #ifdef __mips__
+ #include <unistd.h>
+ #endif
+
/**
* This class provides an easy way to lock non-critical
The second patch is on src/ArchSpecific.h:
*** ArchSpecific.h.orig Wed Apr 9 22:39:18 2008
--- ArchSpecific.h Wed Apr 9 22:38:22 2008
***************
*** 96,102 ****
// \}
! #if defined(__arm__) or defined(__sparc__)
#define ARM_OR_SPARC
#endif
--- 96,102 ----
// \}
! #if defined(__arm__) or defined(__sparc__) or defined(__mips__)
#define ARM_OR_SPARC
#endif
Third patch is actually a kludge and you actually need it if and only if you use external libcrypto. I don't know why but IRIX's sed behaves differently if the very same command is issued on a Linux or a Cygwin machine. So lines 7871, 7880 and 7884 of configure:
crypto_version=`grep "Reference Manual" $crypto_prefix/cryptopp/cryptlib.h | sed -e's#.*\s\(\([0-9]\+\.\?\)\+\)\s.*#\1#g'`
which work perfectly on other UN*X flavors, must be changed as
crypto_version=`grep "Reference Manual" /usr/local/include/cryptopp/cryptlib.h | sed -e's#.*\([0-9]\.[0-9]\.[0-9] \).*#\1#g'`
which is ugly, at best. Note that IRIX's sed does not recognize \s as a metacharacter, considering it literal s so you have to explicitly use a blank space.
Few lines further, line 7923, must be changed (again, if and only if you plan to use external libcrypto) according to:
sources) CXXFLAGS="$CXXFLAGS -I$crypto_prefix -D__CRYPTO_SOURCE__"
crypto_prefix_lib=/usr/local/lib
LDFLAGS="$LDFLAGS -L$crypto_prefix_lib"
CRYPTOLIBS="-lcryptopp"
Now we're ready to start the real configuration.
Configuring aMule
I prefer to use a small script to launch configuration, so keeping track of all the test and tryouts: at the end of the story I configured aMule with the following:
#!/bin/sh
./configure \
--enable-webserver \
--enable-amule-daemon \
--enable-amule-gui \
--enable-amulecmd \
--disable-embedded-crypto \
--with-zlib=/usr/freeware/lib32 \
--with-gdlib-config=/usr/local/bin/gdlib-config \
--with-libpng-config=/usr/local/bin/libpng-config \
--with-wx-config=/usr/freeware/bin/wx-config \
--with-libiconv-prefix=/usr/local \
--with-crypto-prefix=/usr/local/include \
--with-libintl-prefix=/usr/freeware \
LDFLAGS='-w -LD_LAYOUT:lgot_buffer=1024 -rpath /usr/local/lib:/usr/freeware/lib32:/usr/freeware/lib -L/usr/local/lib \
-L/usr/freeware/lib32 -L/usr/freeware/lib' \
CPPFLAGS='-I/usr/local/include -I/usr/freeware/include' \
CXXFLAGS='-w' \
YACC='bison -y'
Of course you can wipe out lines '--disable-embedded-crypto' and '--with-crypto-prefix=/usr/local/include' if you prefer to patch by yourself eMule source code (see notes above). Do not forget the linker directive '-LD_LAYOUT:lgot_buffer=1024' or you'll get a 'got overflow' during the linking stage. Five hours later, I mean. Don't you forget the '-rpath' directive too, (see the Introduction of this document).
Compiling aMule
Just
make && make install
and take your time. I'm pretty sure I've already told you it takes a while.
Starting aMuled as a daemon
As a final remark, here it is an init script to start amuled at boot:
#!/bin/sh
##
## Start or stop amuled and amuleweb
##
export TERM=iris-tp
P2P_DAEMON=/usr/local/bin/amuled
WEB_DAEMON=/usr/local/bin/amuleweb
USER=emule
IS_ON=/etc/chkconfig
if $IS_ON verbose; then
ECHO=echo
else
ECHO=:
fi
start_amuled()
{
$ECHO -n "Starting amuled... "
rm -rf /var/run/amuled.pid
su - $USER -c "$P2P_DAEMON -f" 1> /dev/null 0> /dev/null
while ! pidof -s amuled > /var/run/amuled.pid ; do sleep 1 ; done
$ECHO "Started."
}
start_amuleweb()
{
$ECHO -n "Starting amuleweb... "
rm -rf /var/run/amuleweb.pid
su - $USER -c "$WEB_DAEMON --quiet &" 1> /dev/null 0> /dev/null
while ! pidof -s amuleweb > /var/run/amuleweb.pid ; do sleep 1 ; done
$ECHO "Started."
}
kill_amuled()
{
if [ -r /var/run/amuled.pid ]; then
$ECHO -n "Stopping amuled... "
amuled_pid=`cat /var/run/amuled.pid`
ps -p $amuled_pid | grep amuled > /dev/null
if [ $? -eq 0 ]; then
/usr/bin/kill -15 $amuled_pid
fi
rm -rf /var/run/amuled.pid
$ECHO "Stopped."
fi
}
kill_amuleweb()
{
if [ -r /var/run/amuleweb.pid ]; then
$ECHO -n "Stopping amuleweb... "
amuleweb_pid=`cat /var/run/amuleweb.pid`
ps -p $amuleweb_pid | grep amuleweb > /dev/null
if [ $? -eq 0 ]; then
/usr/bin/kill -15 $amuleweb_pid
fi
rm -rf /var/run/amuleweb.pid
$ECHO "Stopped."
fi
}
case "$1" in
start)
kill_amuleweb
kill_amuled
start_amuled
start_amuleweb
;;
stop)
kill_amuleweb
kill_amuled
exit 0
;;
*)
echo "usage: $0 {start|stop}"
;;
esac
exit 0
Put it as, let's say, 'amuled' under '/etc/init.d' and then
cd /etc/rc0.d ln -s ../init.d/amuled K10amuled cd /etc/rc2.d ln -s ../init.d/amuled S98amuled
and you are done.
Version
Created by Gaznevada on 15.04.08 at 21:00
