Build standards

Table of contents

Compilers

Our standard compiler is the sun compiler(s), which should be used in preference to gcc, unless the software only compiles with gcc. Builds will be done on both Solaris 8 x86 and Solaris 8 sparc, unless there is need for a Solaris-9 specific binary. In this case, both Solaris 8 and Solaris 9 packages must be created (unless the maintainer chooses to package binaries for both solaris 8 and 9 in a single package, and make it work transparently to the user).

Please Note: If you use newer (studio 9 or later) sun compilers, you must force it to generate v8 sparc binaries, not just take the default. See

Some areas where separate Solaris 9 packages may be needed are:

Builds should be configured with whatever is equivalent to

   configure --prefix=/opt/csw

Libraries, library paths, and linking

All programs and libraries should be built with an appropriate "RPATH" in the executable or library, to take advantage of fully-optimized binaries, when available. An easy way to do this, is usually to set the LD_OPTIONS variable, as follows:

   export LD_OPTIONS='-R/opt/csw/lib/$ISALIST -R/opt/csw/lib -L/opt/csw/lib'
   #
   # You may also need/want
   #  export CPPFLAGS=-I/opt/csw/include
   # Additionally, it may be useful to define the -L path
   # as  -L$YOUR_BUILD_DIR/lib:/opt/csw/lib
   #
   # When compiling 64bit programs, you will need
   #   export LD_OPTIONS="-R/opt/csw/lib/64 -L/opt/csw/lib/64"
plus any other needed -R type dependancies. Generally speaking, binaries that we provide, should ONLY be linked against Solaris/Sun provided libraries, and our own libraries packaged under /opt/csw.

The -R options above are useful for multiple reasons:

  1. Some programs will have problems "finding" our libraries
  2. Some programs will try to pick up stuff in /usr/local first otherwise
  3. The $ISALIST means that if there are CPU-optimized versions of shared libraries, the program will take advantage of them at runtime, rather than being stuck using the default "generic cpu" libraries.

The -L option is useful for making sure programs get "linked"(compiled) against the csw libraries. However, it is important to note that when a program itself contains newer,incompatible versions of libraries already in /opt/csw/lib*, adjustments may have to be made, as per the -L$YOUR_BUILD_DIR comment, above. (Or alternatively, pkgrm the older version in /opt/csw)

If feasible, libraries should be compiled with -D_REENTRANT. Many autoconf configured programs do this automatically.

It is advantageous to have shared libraries compiled with any other shared library dependancies as part of them. 'autoconf' driven programs tend to do this automatically, but for non-autoconf compiles, you may want to add "-z defs" to your LD_OPTIONS.

Binaries should be 'strip'ed. Libraries should generally be stripped, but with "strip -x", to make it easier for people to debug programs that use the libraries. (This preserves the "symbol table").

static libraries should generally NOT be included, unless there is specific and clear benefit for providing them. Usually, everything just uses the shared libs.

New packages should take care to EXCLUDE libtool .la files. They are not helpful, and often create more problems than they solve. Unfortunately, existing packages may need to preserve them, until all dependant packages have their own configs adjusted to not use .la files.

CPU optimizations (SPARC)

Our base OS is Solaris 8. Since sparcv7 cpus are not supported by Solaris 8, the standard cpu target for sparc should be sparcv8. Eg:
 #Sun CC
cc -xarch=v8
# GNU cc
gcc -mcpu=v8
For a reasonable standard of optimization with Sun CC, it is currently recommended to use
 cc -fast -xarch=v8  #studio 8
 cc -fast -xarch=v8 -xnolibmopt  #studio 10, forcing use of shared libm.so
 # if sparc files are still large, add -xnolibmil as well

	 
Note that it must be in that order!!
Note2: If you are using newer compilers than studio8, you must specify -xarch=v8, otherwise it will generate code that will not run on some of the older, yet still supported, sparc platforms.
Note3: the v8 flag causes old sparc5 (sun4m) machines to perform poorly, due to lack of a hardware multiply. If you wish to be kind to the older sun4m desktop machines, you may use -xarch=v8a instead of v8.

warning: -fast in rare cases causes bad code. You may have to drop back down to -O instead.

Mantainers may choose to provide additional cpu-optimized libraries, beyond a standard one. The compiler options of interest are;

 #### for 32bit, "sparcv8plus"
#Sun CC
cc -fast -xarch=v8plus
# GNU cc (either for this, or sparcv8plus+vis, not sure)
gcc -mcpu=ultrasparc

#### for 32bit, "sparcv8plus+vis"
#Sun CC (this automatically implies -xarch=v8plusa, and other things)
cc -fast -xtarget=ultra
# GNU cc (either for this, or sparcv8plus+vis, not sure)
gcc -mv8plus

#### for 64bit
#Sun CC
cc -fast -xtarget=ultra -xarch=v9
# GNU cc
gcc -mcpu=ultrasparc -m64

You may want to use the following additional flags for Sun CC:

   -xstrconst
puts "quoted strings" in read-only memory, which allows compression,
faster loading time, and more efficient memory usage for programs,
since it can be shared memory.
-xildoff
turns the incremental linker off. Not normally 'needed', but sometimes
programs compile themselves with -g, which will result in the ild
adding extra space to the executables that 'strip' will not remove

Optimized libraries go in places such as /opt/csw/lib/sparcv8plus or /opt/csw/lib/sparcv9 as apropriate. CPU-optimized executables, go in places such as /opt/csw/bin/sparcv8plus or /opt/csw/bin/sparcv9. For more details on how to package multiple libraries/binaries in a single packages, see the page on use of the 'isaexec' wrapper .

CPU optimizations (x86)

The currently prefered x86 platform optimization flags are
(for sun cc)  cc -fast -xarch=386  # -xarch=486 does not exist
(for gcc) gcc -march=i486

warning: -fast in rare cases causes bad code. You may have to drop back down to -O instead.

It should be reasonable to optimize for 486 for a "base" executable or library, since Solaris 8 does not support plain old 386 processors.

It MAY be suitable to optimize for pentium by default, but this is still being considered. It is always acceptible to provide an alternative binary for pentium.
[cc -xtarget=pentium, or gcc -march=i586]

Some architectures to evaluate for special optimization on x86:

See our isaexec page for details on how to set up multiple binaries in your package. As mentioned in the sparc section, you should consider whether it would be beneficial to provide multi-arch support for binaries, AND libraries.

64bit vs 32bit

Most binaries should actually be compiled as 32-bit binaries, even on modern sparc cpus. This is for both space and performance reasons. 32bit binaries often perform better than 64bit ones, even though that seems to be counter-intuitive.

The following reasons are about the only reasons why you should build 64-bit anything:

Libraries have a side consideration. There may not be an intrinsic benefit of using the library itself in 64bit mode.. however, some executable may require the library to be provided in 64bit form, so that that executable may then be compiled in 64bit form.

Whenever possible/practical, a package maintainer should provide a single package containing both 64bit and 32bit executables/libraries. For extremely large packages, this guideline may be reexamined, by bringing up the issue on the maintainers list.

See our isaexec page for details on how to set up multiple binaries in your package.

Package filenames and versioning

Submitted package files should be named with the following standard:
{SOFTWARENAME}-{REV.NUM}-`uname -s``uname -r`-{ARCH}-CSW.pkg

EG:

ncurses-5.3,REV=2002.12.31-SunOS5.8-i386-CSW.pkg
The '-' character is an explicit field separator, so it is illegal to use except in the places shown.

Please note: the ",REV=YYYY.MM.DD" is now Mandatory. It provides a fixed-format way of telling how recent the package really is, for version comparison download purposes. At some point, it will be the primary comparison key for pkg-get.(but not yet)

For purposes of backward compatibility, anything to the left of ",REV" must be purely numeric. ie: [0-9.] If your software has funky alphabetic additions to the release, you should use

xxxx-#.#.#,REV=YYYY.MM.DD_rev=abcde-xxxxxxx

{ARCH} is usually the output of `uname -p`. But for certain special packages that run on all solaris hardware, or are otherwise architecture-neutral, it may be preferable to have ARCH=all

Note that the filename should exactly show the full VERSION field, including the REV section.

The naming of the file does matter!! It determines how your package will be cataloged for people using pkg-get to download it.

Software names (and thus the first component of the filename) must be all lower case. This is an ease of use issue, so people dont have to think about whether they should use

  1. pkg-get install imagemagick
  2. pkg-get install Imagemagick
  3. pkg-get install ImageMagick
(Plus, it makes the directory listing sort properly.)

Multi-OS packages

Whenever practical, we need to have a single OS version of our packages. (It should be the "lowest" OS version we support: currently, Solaris 8)

The reason is so that we can better support our customers that want to put our packages on a single NFS shared filesystem. (see our User Guide for a reminder)

This does not mean, however, that it is impossible to support features in newer revs of Solaris. It is usually possible to provide some amount of auto-detection and "do the right thing" depending on the currently running OS. See the lsof package, for an example.