Patches for Amule CVS on O2
From AMule Project FAQ
Contents |
Introduction
Just few lines on how to compile aMule on IRIX 6.5 running on a 32 bit machine, namely a SGI O2 R5000 (MIPS IP32).
A warning to the curious: I'm not this big code warrior, so double check what I'm going to say.
Compiling and linking aMule on such an old piece of hardware is quite a big deal of work. Compilation takes six hours, so I could afford not so many tests. The CVS sandbox version I made my test with was CVS 20080423.
In the following you can find patches file after file. Patches are slightly edited for the wiki page. patch should be smart enough to eat the snippet of the wiki source codes but let me know if you need the actual patchfiles.
Here we go.
Configure
Comments:
Lines 8291 to 8304: IRIX fails to evaluate the token $(command) so you have to replace it with a `command`. All in all, configure is a shell script (first line is shebang) and a well behaved shell execute commands and assignes the result to a variable if the command is encolsed between backapexes. Fix me if I'm wrong.
Lines 8333 to 8340: just cosmetic: $CRYPTO_PP_VERSION_NUMBER is the "numberized" version of the library version, stored in $CRYPTO_PP_VERSION_STRING, actually. I prefer to see the version (eg 5.5.2) and not a misleading 50502 or the like.
Patch file:
*** configure.orig Mon Apr 28 23:04:15 2008
--- configure Mon Apr 28 23:09:45 2008
***************
*** 8291,8304 ****
crypto_pp_include_dir="$crypto_pp_include_i/$CRYPTO_PP_INCLUDE_PREFIX"
crypto_pp_header_path="$crypto_pp_include_dir/$crypto_pp_file_with_version"
! CRYPTO_PP_VERSION_STRING=$(grep "Reference Manual" $crypto_pp_header_path | \
! sed -e 's/[^0-9]*\([0-9.]*\).*/\1/')
! CRYPTO_PP_VERSION_NUMBER=$(echo $CRYPTO_PP_VERSION_STRING | \
! $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}')
! minvers=$(echo $min_crypto_version | \
! $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}')
if test -n "$CRYPTO_PP_VERSION_NUMBER" && test "$CRYPTO_PP_VERSION_NUMBER" -ge $minvers; then
result="yes (version $CRYPTO_PP_VERSION_STRING, $CRYPTO_PP_STYLE)"
--- 8291,8304 ----
crypto_pp_include_dir="$crypto_pp_include_i/$CRYPTO_PP_INCLUDE_PREFIX"
crypto_pp_header_path="$crypto_pp_include_dir/$crypto_pp_file_with_version"
! CRYPTO_PP_VERSION_STRING=`grep "Reference Manual" $crypto_pp_header_path | \
! sed -e 's/[^0-9]*\([0-9.]*\).*/\1/'`
! CRYPTO_PP_VERSION_NUMBER=`echo $CRYPTO_PP_VERSION_STRING | \
! $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
! minvers=`echo $min_crypto_version | \
! $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
if test -n "$CRYPTO_PP_VERSION_NUMBER" && test "$CRYPTO_PP_VERSION_NUMBER" -ge $minvers; then
result="yes (version $CRYPTO_PP_VERSION_STRING, $CRYPTO_PP_STYLE)"
***************
*** 8333,8340 ****
! { echo "$as_me:$LINENO: Crypto++ version number is $CRYPTO_PP_VERSION_NUMBER" >&5
! echo "$as_me: Crypto++ version number is $CRYPTO_PP_VERSION_NUMBER" >&6;}
CXXFLAGS="$CXXFLAGS $CRYPTO_PP_CXXFLAGS"
--- 8333,8340 ----
! { echo "$as_me:$LINENO: Crypto++ version number is $CRYPTO_PP_VERSION_STRING" >&5
! echo "$as_me: Crypto++ version number is $CRYPTO_PP_VERSION_STRING" >&6;}
CXXFLAGS="$CXXFLAGS $CRYPTO_PP_CXXFLAGS"
ArchSpecific.h
Comments:
This #define chooses between two methods to return a pointer to memory. IRIX gcc compiles fine but a SIGBUS error pops up at runtime. A debug session of the core told me that the problem was in memcpy call. So I tried to #define ARM_OR_SPARC, switching to the other method. Actually, the man memcpy on IRIX says that the definition of the call is slightly different from the coded call.
Anyway, it works. Up to now, I mean... The very same patch holds on aMule 2.1.3.
Patch file:
*** src/ArchSpecific.h.orig Tue Apr 29 03:42:09 2008
--- src/ArchSpecific.h Tue Apr 29 03:43:23 2008
***************
*** 103,109 ****
// \}
! #if defined(__arm__) || defined(__sparc__)
#define ARM_OR_SPARC
#endif
--- 103,109 ----
// \}
! #if defined(__arm__) || defined(__sparc__) || defined(__mips__)
#define ARM_OR_SPARC
#endif
php_core_lib.cpp and php_core_syntree.cpp
Comments:
PRIu64 and the whole bunch of PRInXX should be included in <inttypes.h> according to ANSI/ISO C C99 and POSIX 1003.1-2001
By the way: configure says that PRIxNN macros are good and working. This is definitely a lie on an IRIX system: IRIX does not have any PRInXX macro. Please, would you be so kind to double-check that section of configure? conftest.c seems to me an empty file. Maybe I'm wrong.
Another note: PRInXX macros, IMHO, are The Evil: definitely non-standard and non-portable. Avoid it as long as you can. Stress on IMHO ;)
IRIX 6.5 does not define those macros in <inttypes.h>, canonical place, so we have to roughly fix it with this horrible crook.
More: I'm afraid that _ABI64 is defined just on mips64 CPU's (Origin, Altix and the like). I don't know how to tell if a machine is 32- or 64-bits by a single variable defined on the headers.
wuischke: I've simplified the patch a bit.
Patch file:
--- src/webserver/src/php_syntree.h (revision 8458) +++ src/webserver/src/php_syntree.h (working copy) @@ -35,6 +35,16 @@ #endif #include <inttypes.h> +#if !defined PRIu64 +# ifdef _ABI64 +# define PRIu64 "lu" +# else +# define PRIu64 "llu" +# endif +#endif
amuled.cpp
Comments:
amuled.cpp calls strerror_r in three places but strerror_r is not defined on IRIX. In a lot of other Unices, anyway...
A note on configure: a check is made on strerror (standard on all Unices) but no check at all on strerror_r! Maybe better to fix it, I think.
So I introduced a conditional compilation variable, HAVE_STRERROR_R_H which should be defined by configure at a proper point. I'm not going to patch configure this way, I prefer to leave the decision to you developers. I'd like just only to highlight the problem.
Patch file:
*** src/amuled.cpp.orig Tue Apr 29 17:38:42 2008
--- src/amuled.cpp Wed May 7 23:25:18 2008
***************
*** 29,34 ****
--- 29,39 ----
#ifdef HAVE_CONFIG_H
#include "config.h" // Needed for HAVE_SYS_RESOURCE_H
+ // Needed for HAVE_STRERROR_R_H
+ #endif
+
+ #ifndef HAVE_STRERROR_R_H
+ #include "Strerror_r.h"
#endif
#include <wx/utils.h>
Strerror_r.h
Comments:
So you have to write a brand new, homebrew system call. Again: I'm not this great coder, so my substitute could be coded better, for sure, but it works:
Patch file:
--- src/Strerror_r.h Thu May 1 18:15:45 2008 *************** *** 0 **** --- 1,74 ---- + /* + + Looking at the call of strerror_r in amuled.cpp, it looks like + a POSIX (not GNU) flavored strerror_r: + + NAME + strerror_r: convert error number to string and copy to buffer + + SYNOPSIS + #include <errno.h> + #include <string.h> + int strerror_r(int errnum, char *buffer, size_t n); + + DESCRIPTION + strerror_r converts the error number errnum into a + string and copies the result into the supplied buffer for + a length up to n, including the NUL terminator. The value of + errnum is usually a copy of errno. If errnum is not a known + error number, the result is the empty string. + + RETURNS + The strerror_r() function returns 0 on success and -1 on failure, + setting errno. + + PORTABILITY + + POSIX + + ======================================================================= + Not in all systems (notably IRIX, Sun Solaris, HP-UX 11 and others, see + http://www.gnu.org/software/gnulib/manual/html_node/strerror_005fr.html + so we have to deal with what we have. + + We use a strerror_r replacement using strerror. Sort of poorman strerror_r + + NAME + strerror - get error message string + + SYNOPSIS + #include <string.h> + char *strerror (int errnum); + + DESCRIPTION + strerror maps the error number in errnum to an error message string, and + returns a pointer to that string. strerror uses the same set of error + messages as perror. The returned string should not be overwritten. + + */ + + #include <string.h> + #include <errno.h> + + int strerror_r(int errnum, char *buffer, size_t n) + { + if ( errnum < 0 ) { + char *local_error = "Unknown Error"; + strncpy(buffer, local_error, n); + return 0; + } + else if ( errnum == 0 ) { + char *local_error = "No Error"; + strncpy(buffer, local_error, n); + return 0; + } + else if ( errnum > 0 && errnum < sys_nerr ) { + strncpy(buffer, strerror(errnum), n); + return 0; + } + else { + char *local_error = "strerror_r() failed"; + strncpy(buffer, local_error, n); + return -1; + } + }
Alternate implementation of strerror_r from dietlibc
#include <string.h>
extern const char __sys_err_unknown[];
int astrerror_r(int errnum, char *buf, size_t n) {
const char* x=strerror(errnum);
if (x==__sys_err_unknown || n<1) return -1;
strncpy(buf,strerror(errnum),n);
buf[n-1]=0;
return 0;
}
That's all, folks.
Feeback is warmly welcomed!
-- Cheers.
-- Gaznevada
