Porting Content to Mandrake Linux 7.0 with Red Hat Motif 2.1 ------------------------------------------------------------ These notes describe the changes I made in the vibrant and content source trees to port Content 1.5 to Mandrake Linux 7.0 with Red Hat Motif 2.1. In performing the port, I followed the directions in the file mandrake7.0_inst. My hardware and software configurations are also described in that document. You might want to read that file first before reading this one. 1. Once I altered $CONTENT/vibrant/make/viball.lnx to include -lXp and the path to the Motif header files /usr/X11R6/include/Xm, the vibrant library compiled without incident. 2. I altered the make file $CONTENT/content/makefile_v as I described in my Mandrake 7.0 installation document. When I attempted to make Content, I encountered the following errors. ./libcontent.a(curve.o): In function `StartCR': curve.o(.text+0x7437): undefined reference to `__setfpucw' ./libcontent.a(curve.o): In function `EndCR': curve.o(.text+0x74e4): undefined reference to `__setfpucw' collect2: ld returned 1 exit status make[2]: *** [content] Error 1 make[2]: Leaving directory `/usr/local/src/content-1.5/content/victor' The function __setfpucw is used to set the floating point unit command word under glibc1. There is a new facility for accomplishing this task under glibc2. The FPU command word may be changed using the macro _FPU_SETCW under glibc2. This macro resides in /usr/include/fpu_control.h. It take a single argument of type fpu_control_t. The macro is defined as #define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw)) The command __asm__ ("fldcw %0" : : "m" (*&cw)) accepts a single input that is a memory address and produces no output. It executes the assembler command "fldcw" with the given input. See "Extended Asm", also called "Assembler Instructions with C Expression Operands", under the "Extensions to the C Language Family" section of the GCC Manual http://gcc.gnu.org/onlinedocs/gcc_4.html#SEC96 and "Constraints", also called "Operand Constraints", under the "Machine Descriptions" section of the GCC manual http://gcc.gnu.org/onlinedocs/gcc_16.html#SEC179 for further details. The URLs http://www.netlib.no/netlib/ampl/solvers/fpinit.c http://gcc.gnu.org/ml/gcc-bugs/1999-11/msg00846.html http://gcc.gnu.org/ml/gcc-bugs/1999-11/msg00871.html show examples of how to use the macro. The function __setfpucw is only used in $CONTENT/victor/curve.c, once in each of the functions StartCR and EndCR. To correct the error for glibc2, I defined a variable of type fpu_control_t at the top of each of these functions when the compilation was occuring for a system of type _UNIX_LNX #ifdef _UNIX_LNX fpu_control_t cw; #endif /* _UNIX_LNX */ Where __setfpucw was used in the previous code, I set cw to the appropriate value and invoked _FPU_SETCW on cw for each function // StartCR cw = _FPU_IEEE^(_FPU_MASK_IM|_FPU_MASK_OM|_FPU_MASK_ZM); _FPU_SETCW(cw); // EndCR cw = _FPU_IEEE; _FPU_SETCW(cw); Rather than replacing the __setfpucw code, it would be easy to create a conditional to execute either __setfpucw or _FPU_SETCW depending on which one was available. One of the examples listed above shows one way to do this. 3. Once I made the above changes to $CONTENT/content/victor/curve.c, Content compiled without difficulty aside from the segmentation fault problem described in my installation document. However, when I tried to execute the setup program from the root shell, it failed because the C++ compiler stopped on errors in $CONTENT/content/autodif.c. The errors were In file included from autodif.cc:61: autodif.c: In function `char * Mult(char *, char *, char)': autodif.c:509: assignment to `char *' from `const char *' discards qualifiers autodif.c: In function `char * Sub(char *, char *, char)': autodif.c:659: assignment to `char *' from `const char *' discards qualifiers autodif.c:668: assignment to `char *' from `const char *' discards qualifiers autodif.c: In function `char * Div(char *, char *, char)': autodif.c:753: assignment to `char *' from `const char *' discards qualifiers autodif.c: In function `char * rel(char *, char *, char *, int)': autodif.c:1609: assignment to `char *' from `const char *' discards qualifiers autodif.c: In function `char * GetExpr_(const Gradient &)': autodif.c:1872: return to `char *' from `const char *' discards qualifiers autodif.c: In function `char * GetDer1_(const Gradient &, int)': autodif.c:1888: return to `char *' from `const char *' discards qualifiers autodif.c: In function `char * GetDer2_(const Gradient &, int, int)': autodif.c:1904: return to `char *' from `const char *' discards qualifiers autodif.c: In function `char * GetDer3_(const Gradient &, int, int, int)': autodif.c:1921: return to `char *' from `const char *' discards qualifiers To solve this problem, I added casts to the lines containing errors to make the values on the right hand sides or the return values of type "char *" rather than "const char *". For example, I changed 508,509c508,509 < f=lneed ? (rneed ? "(%s)*(%s)" : "(%s)*%s") : < (rneed ? "%s*(%s)" : "%s*%s"); to > f=lneed ? (char *)(rneed ? "(%s)*(%s)" : "(%s)*%s") : > (char *)(rneed ? "%s*(%s)" : "%s*%s"); and 1872c1872 < return p ? p : "0"; to > return p ? p : (char *)"0"; 4. Resolving these problems allowed me to successfully compile and install Content. I tested my work by setting up Content as a user and invoking it for an example problem. Everything seemed to work fine.