> Jörg uttered the holy words :
> Many years ago, it certainly used to be much easier to
> write something first (with some care) on Solaris, and
> then port it to other platforms, rather than the other
> way around.
I too envision a world of POSIX spec compliance. However,
that will happen as fast as peace in the middle east.
Wow, that was dreary. Sorry.
Let me give you a very very small example of something
that I run into all the time. Let's look at something
trivial like GNU patch.
If you try a quick and dirty "configure make" sequence you will
get a surprise on Solaris 10 ( or Solaris 8 ) but on something
Solaris Nevada or OpenSolaris-like it "just works".
The big diff is in libC. The "Standard C Library Functions" seem to be
different from Solaris to OpenSolaris.
Let me show you.
$ uname -a
SunOS aequitas 5.11 snv_138 i86pc i386 i86pc
Now see man -s 5 standards and look for this :
Utilities
If the behavior required by POSIX.2, POSIX.2a, XPG4, SUS, or
SUSv2 conflicts with historical Solaris utility behavior,
the original Solaris version of the utility is unchanged; a
new version that is standard-conforming has been provided in
/usr/xpg4/bin. If the behavior required by POSIX.1-2001 or
SUSv3 conflicts with historical Solaris utility behavior, a
new version that is standard-conforming has been provided in
/usr/xpg4/bin or in /usr/xpg6/bin. If the behavior required
by POSIX.1-2001 or SUSv3 conflicts with POSIX.2, POSIX.2a,
SUS, or SUSv2, a new version that is SUSv3 standard-
conforming has been provided in /usr/xpg6/bin.
An application that wants to use standard-conforming utili-
tues must set the PATH (sh(1) or ksh(1)) or path (csh(1))
environment variable to specify the directories listed below
in the order specified to get the appropriate utilities:
.
. <snip>
.
POSIX.1-2001, SUSv3
1. /usr/xpg6/bin
2. /usr/xpg4/bin
3. /usr/ccs/bin
4. /usr/bin
5. directory containing binaries for your compiler
6. other directories containing binaries needed by
the application
OKay, so let's do that :
$
PATH=/usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/studio/SOS12.1/SUNWspro/bin:/usr/sbin:/bin:/sbin:/opt/schily/bin:/opt/csw/bin
$ export PATH
I have a few other things I need ( for this experiment ):
$ SRC=/shared/gar/src
$ export SRC
This is just for this test case :
$ LD_OPTIONS=\-R/usr/local/lib\ \-L/usr/local/lib
$ export LD_OPTIONS
$ CPPFLAGS=\-I/usr/local/include
$ export CPPFLAGS
I don't need these but I'll set them for giggles :
$ CC=/opt/studio/SOS12.1/SUNWspro/bin/cc
$ export CC
$ CXX=/opt/studio/SOS12.1/SUNWspro/bin/CC
$ export CXX
Now let's set a few CFLAGS, nothing too fancy :
CFLAGS=\-xstrconst\ \-xildoff\ \-xarch=386\ \-xnolibmil\ \-Xa\ \-Kpic\
\-xregs=no%frameptr\ \-xlibmieee\ \-g\ \-Qy\ \-xs\ \-D_TS_ERRNO
export CFLAGS
Note the "-g" there. We may want to use dbx later and -xs sure helps with
debugging.
Okay .. now watch this :
$ cd /tmp
$ star -x -z file=$SRC/patch-2.6.1.tar.gz
star: 132 blocks + 0 bytes (total of 1351680 bytes = 1320.00k).
$ cd patch-2.6.1
$ ./configure [ with my annoying thoughts interjected ]
checking for gcc... /opt/studio/SOS12.1/SUNWspro/bin/cc
Checking for gcc ? Why? Isn't a real C compiler good enough ?
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... no
Well, no. That was determined above.
checking whether /opt/studio/SOS12.1/SUNWspro/bin/cc accepts -g... yes
checking for /opt/studio/SOS12.1/SUNWspro/bin/cc option to accept ISO
C89... none needed
checking how to run the C preprocessor...
/opt/studio/SOS12.1/SUNWspro/bin/cc -E
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking whether make sets $(MAKE)... yes
checking for ed... /usr/xpg6/bin/ed
checking for bash... /usr/bin/bash
checking build system type... i386-pc-solaris2.11
checking host system type... i386-pc-solaris2.11
checking for grep that handles long lines and -e... /usr/bin/ggrep
checking for egrep... /usr/bin/ggrep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for /opt/studio/SOS12.1/SUNWspro/bin/cc option to accept ISO
C99... none needed
checking for /opt/studio/SOS12.1/SUNWspro/bin/cc option to accept ISO
Standard C... (cached) none needed
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... 64
checking for ANSI C header files... (cached) yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking utime.h usability... yes
checking utime.h presence... yes
checking for utime.h... yes
checking for mode_t... yes
checking for off_t... yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for utime.h... (cached) yes
checking for struct utimbuf... yes
checking for d_ino member in directory struct... yes
checking whether system is Windows or MSDOS... no
checking for long file names... yes
checking for pathconf... yes
checking whether // is distinct from /... no
checking whether strerror_r is declared... yes
checking for strerror_r... yes
checking whether strerror_r returns char *... no
checking for error_at_line... no
checking for memchr... yes
Watch this ***
checking whether strndup is declared... no
checking for working strndup... no
*** okay .. saw that ?
checking whether strnlen is declared... yes
checking for working strnlen... yes
*** and that ?
checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking for getopt_long_only... yes
checking whether optreset is declared... no
checking for working GNU getopt function... no
checking whether getenv is declared... yes
checking for ssize_t... yes
checking for strcasecmp... yes
checking for strncasecmp... yes
checking for inline... inline
checking whether the compiler generally respects inline... yes
checking whether mktemp is declared... yes
checking for geteuid... yes
checking for getuid... yes
checking for mktemp... yes
checking for raise... yes
checking for sigaction... yes
checking for sigprocmask... yes
checking for sigsetmask... no
checking for _LARGEFILE_SOURCE value needed for large files... no
checking whether clearerr_unlocked is declared... no
checking whether feof_unlocked is declared... no
checking whether ferror_unlocked is declared... no
checking whether fflush_unlocked is declared... no
checking whether fgets_unlocked is declared... no
checking whether fputc_unlocked is declared... no
checking whether fputs_unlocked is declared... no
checking whether fread_unlocked is declared... no
checking whether fwrite_unlocked is declared... no
checking whether getc_unlocked is declared... yes
checking whether getchar_unlocked is declared... yes
checking whether putc_unlocked is declared... yes
checking whether putchar_unlocked is declared... yes
checking whether malloc, realloc, calloc are POSIX compliant... yes
checking for dirent.h that defines DIR... yes
checking for library containing opendir... none required
checking whether closedir returns void... no
checking for fcntl.h... (cached) yes
checking for unistd.h... (cached) yes
checking for DOS-style setmode... no
checking for vprintf... yes
checking for _doprnt... yes
checking for mkdir... yes
checking whether mkdir takes only one argument... no
checking whether system is Windows or MSDOS... (cached) no
checking for long file names... (cached) yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
Follow that with a gmake ( I guess /usr/xpg4/bin/make would suffice also ) :
You get to see a bucket load of things fly by.
Ultimately you get this :
/opt/studio/SOS12.1/SUNWspro/bin/cc -o src/patch -xstrconst -xildoff
-xarch=386 -xnolibmil -Xa -Kpic -xregs=no%frameptr -xlibmieee -g -Qy -xs
-D_TS_ERRNO gl/lib/argmatch.o gl/lib/backupfile.o gl/lib/basename.o
gl/lib/dirname.o gl/lib/stripslash.o gl/lib/error.o gl/lib/exitfail.o
gl/lib/strndup.o gl/lib/getopt.o gl/lib/getopt1.o gl/lib/hash.o
gl/lib/quote.o gl/lib/quotearg.o gl/lib/safe-write.o gl/lib/xmalloc.o
gl/lib/xstrndup.o gl/lib/full-write.o src/merge.o src/inp.o src/maketime.o
src/partime.o src/patch.o src/pch.o src/quotesys.o src/util.o
src/version.o
$ ldd src/patch
libc.so.1 => /lib/libc.so.1
libm.so.2 => /lib/libm.so.2
$ elfdump -d src/patch
Dynamic Section: .dynamic
index tag value
[0] NEEDED 0x1f05 libc.so.1
[1] INIT 0x807815c
[2] FINI 0x8078178
[3] RUNPATH 0x1f5b /usr/local/lib
[4] RPATH 0x1f5b /usr/local/lib
[5] HASH 0x8050118
[6] STRTAB 0x8053338
[7] STRSZ 0x216a
[8] SYMTAB 0x8051908
[9] SYMENT 0x10
[10] SUNW_SYMTAB 0x8050e38
[11] SUNW_SYMSZ 0x2500
[12] SUNW_SORTENT 0x4
[13] SUNW_SYMSORT 0x805586c
[14] SUNW_SYMSORTSZ 0x73c
[15] CHECKSUM 0x2581
[16] VERNEED 0x80554a4
[17] VERNEEDNUM 0x1
[18] PLTRELSZ 0x2b8
[19] PLTREL 0x11
[20] JMPREL 0x8055fc8
[21] REL 0x8055fa8
[22] RELSZ 0x2d8
[23] RELENT 0x8
[24] DEBUG 0
[25] FEATURE_1 0x1 [ PARINIT ]
[26] SUNW_CAP 0x8050108
[27] FLAGS 0 0
[28] FLAGS_1 0 0
[29] SUNW_STRPAD 0x200
[30] SUNW_LDMACH 0x3 EM_386
[31] PLTGOT 0x808b4d8
[32-42] NULL 0
also .. let me do this and it will make sense later :
$ elfdump src/patch > /tmp/patch.elfout
Just take note of this :
ELF Header
ei_magic: { 0x7f, E, L, F }
ei_class: ELFCLASS32 ei_data: ELFDATA2LSB
ei_osabi: ELFOSABI_SOLARIS ei_abiversion: EAV_SUNW_CURRENT
e_machine: EM_386 e_version: EV_CURRENT
e_type: ET_EXEC
e_flags: 0
e_entry: 0x8056800 e_ehsize: 52 e_shstrndx: 36
e_shoff: 0x6a5d0 e_shentsize: 40 e_shnum: 37
e_phoff: 0x34 e_phentsize: 32 e_phnum: 6
Anyone know what "ELFOSABI_SOLARIS" is ?
Then there is this nasty baby :
Interpreter Section: .interp
/usr/lib/ld.so.1
Version Needed Section: .SUNW_version
index file version
[2] libc.so.1 SUNW_1.23 <-- nice high rev
[3] SUNW_1.22 [ INFO ]
[4] SUNW_1.18 [ INFO ]
[5] SUNW_1.1 [ INFO ]
[6] SUNW_0.7 [ INFO ]
[7] SUNWprivate_1.1
[8] SYSVABI_1.3 [ INFO ]
$ digest -a sha256 src/patch
9da74decca8d58b64c640ace637221a15cf93292b0215cc02c158121d15003d7
$ src/patch --version
patch 2.6.1
Copyright (C) 1988 Larry Wall
Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
written by Larry Wall and Paul Eggert
So that all seems to work right ?
Well what happens if you take that binary and try to run it on Solaris 10?
Let me show you :
Last login: Tue Mar 30 12:48:21 2010 from login.blastwave
Inside the Blastwave server farm we have many planetoids.
___ _ __ ___ _ _ ___
/ _ \| '__/ __| | | / __| A: amd64, i386
| (_) | | | (__| |_| \__ \ O: Solaris 10
\___/|_| \___|\__,_|___/ T: Unstable
Orcus is a large Kuiper Belt object with a
large companion and is likely a dwarf planet.
$ digest -a sha256 /tmp/patch
9da74decca8d58b64c640ace637221a15cf93292b0215cc02c158121d15003d7
$ ldd /tmp/patch
libc.so.1 => /lib/libc.so.1
libm.so.2 => /lib/libm.so.2
$ /tmp/patch --version
patch 2.6.1
Copyright (C) 1988 Larry Wall
Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
written by Larry Wall and Paul Eggert
$
Looks like the libC revs are good to go on a well patched up to date
Solaris 10 server !
This is seen in the output from elfdump /lib/libc.so.1 :
Version Definition Section: .SUNW_version
index version dependency
[1] libc.so.1 [ BASE ]
[2] SUNW_1.23 * * * cool * * * SUNW_1.22.5
[3] SUNW_1.22.5 SUNW_1.22.4
[4] SUNW_1.22.4 SUNW_1.22.3
[5] SUNW_1.22.3 SUNW_1.22.2
[6] SUNW_1.22.2 SUNW_1.22.1
[7] SUNW_1.22.1 SUNW_1.22
[8] SUNW_1.22 SUNW_1.21.3
[9] SUNW_1.21.3 SUNW_1.21.2
[10] SUNW_1.21.2 SUNW_1.21.1
[11] SUNW_1.21.1 SUNW_1.21
[12] SUNW_1.21 SUNW_1.20.4
[13] SUNW_1.20.4 SUNW_1.20.1
[14] SUNW_1.20.1 SUNW_1.20
[15] SUNW_1.20 SUNW_1.19
[16] SUNW_1.19 SUNW_1.18.1
[17] SUNW_1.18.1 SUNW_1.18
[18] SUNW_1.18 SUNW_1.17
[19] SUNW_1.17 SUNW_1.16
[20] SUNW_1.16 SUNW_1.15
[21] SUNW_1.15 SUNW_1.14
[22] SUNW_1.14 SUNW_1.13
[23] SUNW_1.13 SUNW_1.12
[24] SUNW_1.12 SUNW_1.11
[25] SUNW_1.11 SUNW_1.10
[26] SUNW_1.10 SUNW_1.9
[27] SUNW_1.9 SUNW_1.8
[28] SUNW_1.8 SUNW_1.7
[29] SUNW_1.7 SUNW_1.6
[30] SUNW_1.6 SUNW_1.5
[31] SUNW_1.5 SUNW_1.4
[32] SUNW_1.4 SUNW_1.3
[33] SUNW_1.3 SUNW_1.2
[34] SUNW_1.2 SUNW_1.1
[35] SUNW_1.1 SUNW_0.9
[36] SUNW_0.9 SUNW_0.8
[37] SUNW_0.8 SUNW_0.7
[38] SUNW_0.7 SYSVABI_1.3
[39] SYSVABI_1.3
[40] SUNWprivate_1.1
What if we go back a few mores revs? Right into the basement ?
$ uname -a
SunOS titan 5.8 Generic_127722-03 i86pc i386 i86pc
$ /opt/csw/libexec/common/sha256 /tmp/patch
9da74decca8d58b64c640ace637221a15cf93292b0215cc02c158121d15003d7
$ /tmp/patch --version
ld.so.1: patch: fatal: libc.so.1: version `SUNW_1.23' not found (required
by file /tmp/patch)
ld.so.1: patch: fatal: libc.so.1: open failed: No such file or directory
Killed
$ ldd /tmp/patch
libc.so.1 => /usr/lib/libc.so.1
libc.so.1 (SUNW_1.23) => (version not found)
libc.so.1 (SUNW_1.22) => (version not found)
libdl.so.1 => /usr/lib/libdl.so.1
Okay .. so whatever is in the newer libC on the most recent revs
of Solaris and OpenSolaris are not at all the same as what is in
the older Solaris revs.
No surprise right ?
Well, here comes a crazy thought, what if we compile GNU patch on a
really old baseline Solaris config? We would fully expect that it
would work on all the newer revs of Solaris and OpenSolaris. Seems
reasonable right ?
Watch this :
$ uname -a
SunOS titan 5.8 Generic_127722-03 i86pc i386 i86pc
LANG=C
export LANG
SRC=/shared/gar/src
export SRC
$
PATH=/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/studio/SOS11/SUNWspro/bin:/usr/sbin:/bin:/sbin:/opt/schily/bin:/opt/csw/bin
$ export PATH
$ LD_OPTIONS=\-R/usr/local/lib\ \-L/usr/local/lib
$ export LD_OPTIONS
$ CPPFLAGS=\-I/usr/local/include
$ export CPPFLAGS
$ CC=/opt/studio/SOS11/SUNWspro/bin/cc
$ export CC
$ CXX=/opt/studio/SOS11/SUNWspro/bin/CC
$ export CXX
$ CFLAGS=\-erroff\ \-xstrconst\ \-xildoff\ \-xarch=386\ \-xnolibmil\ \-Xa\
\-Kpic\ \-xregs=no%frameptr\ \-xlibmieee\ \-g\ \-Qy\ \-xdebugformat=dwarf\
\-xs\ \-D_TS_ERRNO
$ export CFLAGS
Here we go again except on the oldest Solaris rev currently supports ( at
least until 2012 ):
$ cd /tmp
$ star -x -z file=$SRC/patch-2.6.1.tar.gz
star: 132 blocks + 0 bytes (total of 1351680 bytes = 1320.00k).
$ cd patch-2.6.1
$ ./configure
checking for gcc... /opt/studio/SOS11/SUNWspro/bin/cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... no
checking whether /opt/studio/SOS11/SUNWspro/bin/cc accepts -g... yes
checking for /opt/studio/SOS11/SUNWspro/bin/cc option to accept ISO C89...
none needed
checking how to run the C preprocessor...
/opt/studio/SOS11/SUNWspro/bin/cc -E
checking for a BSD-compatible install... /opt/csw/bin/ginstall -c
checking whether make sets $(MAKE)... yes
checking for ed... /usr/xpg4/bin/ed
checking for bash... /usr/bin/bash
checking build system type... i386-pc-solaris2.8
checking host system type... i386-pc-solaris2.8
checking for grep that handles long lines and -e... /opt/csw/bin/ggrep
checking for egrep... /opt/csw/bin/ggrep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... no
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for /opt/studio/SOS11/SUNWspro/bin/cc option to accept ISO C99...
unsupported
checking for /opt/studio/SOS11/SUNWspro/bin/cc option to accept ISO C89...
(cached) none needed
checking for /opt/studio/SOS11/SUNWspro/bin/cc option to accept ISO
Standard C... (cached) none needed
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... 64
checking for ANSI C header files... (cached) yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking utime.h usability... yes
checking utime.h presence... yes
checking for utime.h... yes
checking for mode_t... yes
checking for off_t... yes
checking for stdbool.h that conforms to C99... no
checking for _Bool... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for utime.h... (cached) yes
checking for struct utimbuf... yes
checking for d_ino member in directory struct... yes
checking whether system is Windows or MSDOS... no
checking for long file names... yes
checking for pathconf... yes
checking whether // is distinct from /... no
checking whether strerror_r is declared... no
checking for strerror_r... no
checking whether strerror_r returns char *... no
checking for error_at_line... no
checking for memchr... yes
* * * here comes the fun part * * *
checking whether strndup is declared... no
checking for working strndup... no
checking whether strnlen is declared... no
checking for working strnlen... no
checking getopt.h usability... no
checking getopt.h presence... no
checking for getopt.h... no
checking whether getenv is declared... yes
checking for ssize_t... yes
checking for strcasecmp... yes
checking for strncasecmp... yes
checking for inline... inline
checking whether the compiler generally respects inline... yes
checking whether mktemp is declared... yes
checking for geteuid... yes
checking for getuid... yes
checking for mktemp... yes
checking for raise... yes
checking for sigaction... yes
checking for sigprocmask... yes
checking for sigsetmask... no
checking for _LARGEFILE_SOURCE value needed for large files... no
checking whether clearerr_unlocked is declared... no
checking whether feof_unlocked is declared... no
checking whether ferror_unlocked is declared... no
checking whether fflush_unlocked is declared... no
checking whether fgets_unlocked is declared... no
checking whether fputc_unlocked is declared... no
checking whether fputs_unlocked is declared... no
checking whether fread_unlocked is declared... no
checking whether fwrite_unlocked is declared... no
checking whether getc_unlocked is declared... yes
checking whether getchar_unlocked is declared... yes
checking whether putc_unlocked is declared... yes
checking whether putchar_unlocked is declared... yes
checking whether malloc, realloc, calloc are POSIX compliant... yes
checking for dirent.h that defines DIR... yes
checking for library containing opendir... none required
checking whether closedir returns void... no
checking for fcntl.h... (cached) yes
checking for unistd.h... (cached) yes
checking for DOS-style setmode... no
checking for vprintf... yes
checking for _doprnt... yes
checking for mkdir... yes
checking whether mkdir takes only one argument... no
checking whether system is Windows or MSDOS... (cached) no
checking for long file names... (cached) yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
Want to try the XPG4 make utility ?
$ which make
/usr/xpg4/bin/make
$ make
make: Fatal error in reader: Makefile, line 108: Unexpected end of line seen
No .. you don't want to try that. OKay.
$ gmake
./update-version.sh: git: not found
rm -f stdbool.h-t stdbool.h
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
sed -e 's/@''HAVE__BOOL''@/1/g' \
< ./gl/lib/stdbool.hin; \
} > stdbool.h-t
mv stdbool.h-t stdbool.h
/opt/studio/SOS11/SUNWspro/bin/cc -c -I/usr/local/include -DHAVE_CONFIG_H
-Ded_PROGRAM=\"/usr/xpg4/bin/ed\" -DENABLE_MERGE -I. -I./src -I./gl/lib
-erroff -xstrconst -xildoff -xarch=386 -xnolibmil -Xa -Kpic
-xregs=no%frameptr -xlibmieee -g -Qy -xdebugformat=dwarf -xs -D_TS_ERRNO
-o gl/lib/argmatch.o gl/lib/argmatch.c
/opt/studio/SOS11/SUNWspro/bin/cc -c -I/usr/local/include -DHAVE_CONFIG_H
-Ded_PROGRAM=\"/usr/xpg4/bin/ed\" -DENABLE_MERGE -I. -I./src -I./gl/lib
-erroff -xstrconst -xildoff -xarch=386 -xnolibmil -Xa -Kpic
-xregs=no%frameptr -xlibmieee -g -Qy -xdebugformat=dwarf -xs -D_TS_ERRNO
-o gl/lib/backupfile.o gl/lib/backupfile.c
.
.<snip>
.
/opt/studio/SOS11/SUNWspro/bin/cc -o src/patch -erroff -xstrconst -xildoff
-xarch=386 -xnolibmil -Xa -Kpic -xregs=no%frameptr -xlibmieee -g -Qy
-xdebugformat=dwarf -xs -D_TS_ERRNO gl/lib/argmatch.o gl/lib/backupfile.o
gl/lib/basename.o gl/lib/dirname.o gl/lib/stripslash.o gl/lib/error.o
gl/lib/exitfail.o gl/lib/strndup.o gl/lib/strnlen.o gl/lib/getopt.o
gl/lib/getopt1.o gl/lib/hash.o gl/lib/quote.o gl/lib/quotearg.o
gl/lib/safe-write.o gl/lib/xmalloc.o gl/lib/xstrndup.o gl/lib/full-write.o
src/merge.o src/inp.o src/maketime.o src/partime.o src/patch.o src/pch.o
src/quotesys.o src/util.o src/version.o
ld: fatal: file gl/lib/strnlen.o: open failed: No such file or directory
ld: fatal: File processing errors. No output written to src/patch
gmake: *** [src/patch] Error 1
So that won't work.
Why?
Because this object file gl/lib/strnlen.o does not exist.
Why not? What went wrong?
Why did this compile/link just fine on snv_138 type thing but not here?
The source did not change and the only lib this thing needs is libC so
what changed?
Clearly something in libC. Something documented?
Something in the source of libC but no where else?
Let me cut to the chase :
$ diff strndup.c strndup.c_bork
33,44c33
< /*******************************************
< * As per string(3C) and the POSIX C spec
< * there is no strnlen in the Standard C
< * Library Functions
< * Strangely this "just works" on snv_138
< * Also man -s 3C strnlen returns nothing
< * on Solaris 8 and 9 and 10 but a binary
< * compiled on snv_138 works on Solaris 10.
< *******************************************/
< /* size_t len = strnlen (s, n); */
< size_t len = strlen (s);
<
---
> size_t len = strnlen (s, n);
$
Now what do we get ?
$ file src/patch
src/patch: ELF 32-bit LSB executable 80386 Version 1, dynamically
linked, not stripped
$ ldd src/patch
libc.so.1 => /usr/lib/libc.so.1
libdl.so.1 => /usr/lib/libdl.so.1
$
$ src/patch --version
patch 2.6.1
Copyright (C) 1988 Larry Wall
Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
written by Larry Wall and Paul Eggert
$
$ /opt/csw/libexec/common/sha256 src/patch
6d79ccab884322c27d4060076fac1cbfdec4421f731aa1cd7892393fa62c37b0
$ elfdump src/patch > /tmp/patch.elfout
ELF Header
ei_magic: { 0x7f, E, L, F }
ei_class: ELFCLASS32 ei_data: ELFDATA2LSB
e_machine: EM_386 e_version: EV_CURRENT
e_type: ET_EXEC
e_flags: 0
e_entry: 0x80592b0 e_ehsize: 52 e_shstrndx: 32
e_shoff: 0x7a5bc e_shentsize: 40 e_shnum: 33
e_phoff: 0x34 e_phentsize: 32 e_phnum: 6
I don't see a "ei_osabi: ELFOSABI_SOLARIS" there do you?
That's a mystery.
also check this out :
Interpreter Section: .interp
/usr/lib/ld.so.1
Version Needed Section: .SUNW_version
file version
libc.so.1 SUNW_1.18 <-- welcome to the basement
SUNWprivate_1.1
Let's see what happens when we take that to Solaris 10 :
$ uname -a
SunOS orcus 5.10 Generic_142901-06 i86pc i386 i86pc
$ digest -a sha256 /tmp/patch
6d79ccab884322c27d4060076fac1cbfdec4421f731aa1cd7892393fa62c37b0
$ /tmp/patch --version
patch 2.6.1
Copyright (C) 1988 Larry Wall
Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
written by Larry Wall and Paul Eggert
What about on a Solaris Nevada OpenSolaris snv_138 hacky thing ?
$ uname -a
SunOS aequitas 5.11 snv_138 i86pc i386 i86pc
$ digest -a sha256 /tmp/patch
6d79ccab884322c27d4060076fac1cbfdec4421f731aa1cd7892393fa62c37b0
$ /tmp/patch --version
patch 2.6.1
Copyright (C) 1988 Larry Wall
Copyright (C) 2003, 2009 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
written by Larry Wall and Paul Eggert
* * * Seems to function everywhere. * * *
Also .. back on that Solaris 8 box in the basement that compiled this
binary with Studio 11 I see that "gmake check" reports :
All tests succeeded!
So the point I am trying to make is that you may be able to get
something built and running on a non-standard platform like
OpenSolaris ( Sorry, its not UNIX(R) yet ) but there is no promise
it will work anywhere else. You may have to climb in and hunt
around on things a whole lot less trivial to get them to compile
and pass their own test harnesses. I can tell you that tcl/tk/expect
are a misery. You can get those from Blastwave also. :-)
If code were written first on a standards compliant platform which
does not have undocumented hidden things in libC ( or elsewhere )
then you can expect that it would run anywhere that a C compiler
works. The presence of assembly language is a major roadblock to
such portability. Want a good example ? Go look at the digest binary
on Solaris. Then go digging and see mdigest from Jörg Schilling :
$ /opt/schily/bin/mdigest -a sha256 src/patch
6d79ccab884322c27d4060076fac1cbfdec4421f731aa1cd7892393fa62c37b0 src/patch
That thing is written entirely in C and it is portable everywhere.
Also, based on my tests, it is faster than digest or openssl.
The process of getting software from the Linux world to run on Solaris,
and run well, is non-trivial. It is a hell of a lot of work.
I can not think of an application written on Solaris lately that anyone
wanted to port to Linux. Can you? If you can then please I want to
hear about that.
Enough of this .. I think you can see what I was saying.
--
Dennis Clarke
[email protected] <- Email related to the open source Solaris
[email protected] <- Email related to open source for Solaris
ps: GNU patch fails to build on Solaris 10 also btw.
_______________________________________________
opensolaris-discuss mailing list
[email protected]