Configure Scripts with Interix

Operating System

Windows Services for UNIX 3.0 Technical Note

Abstract

Many popular packages of software come with a configure script of some kind. The configure script is supposed to deduce features of the operating system and set a series of compile-time macros which in turn will turn on and off code appropriate to the operating system. This paper describes ways of making configure scripts work with Interix.

On This Page

Configure Scripts with Interix Configure Scripts with Interix
Related Links Related Links

Configure Scripts with Interix

Many popular packages of software come with a configure script of some kind. The configure script is supposed to deduce features of the operating system and set a series of compile-time macros which in turn will turn on and off code appropriate for the current operating system. These scripts work best on systems about which they have been given prior knowledge. Since Interix is a new UNIX environment, only newer scripts will have code that recognizes Interix. This paper describes ways of making configure scripts work with Interix.

This document applies to only to SFU 3.0; it does not apply to earlier versions of Interix, such as Interix 2.2 and OPENNT 2.0 and 2.1. The information here may or may not apply to later versions (when they are released). We also assume your Interix environment already has the Interix Software Development Kit (SDK) installed.

There are many different configuration programs producing configuration scripts, such as Larry Wall's Metaconfig and the GNU program autoconfig. Each produces scripts which use a different strategy, and as the configuration programs evolve, they change strategies. For the most part, this paper describes configure scripts generated with the popular GNU program autoconfig version 2.52.

Every package has different needs. There are too many packages for this paper to be all-inclusive. Please regard it as a guide only.

Differences in Interix

With respect to configuration scripts, the following are areas where Interix may differ from other historical UNIX systems and therefore may not be handled properly by the configuration scripts:

  • Even within filesystem hierarchy, the directory structure isn't exactly like other systems.

  • The structure of the header files isn't exactly like any other system.

  • Not all of the system calls (section 2 of the manual) have entry points in libc.a. Instead, many of them have entry points in the dynamic library psxdll.a, which is loaded for all Interix processes.

Some of these are explained further below.

Interix Directory Structure

A standard Services for UNIX 3.0/Interix installation has the following directory structure in “/”:

bin/
etc/
pubs/
tmp/
usr/
     X11R5/
     bin
     contrib/
     examples/
     include/
     lib/
     local/
     sbin/
     share/
var/
     mail/
     spool/
     adm/
            log/

For the most part, the meanings are the same as on traditional open systems:

bin:

Interix binaries, such as the shell and other base POSIX.2 utilities. Note that lex in this directory is based on flex, and yacc is based on bison. According to POSIX.2, the path to the base utilities can always be found with the command getconf CS_PATH.

etc:

System control files, such as the global profile or csh.cshrc files.

tmp:

A temporary directory.

usr:

User-related directories, similar in spirit to /usr on UNIX systems.

usr/X11R5:

The X11R5 subtree.

usr/bin:

This is a symbolic link to /bin

usr/contrib/bin:

This directory contains binaries ported to Interix from source code that was contributed from various sources such as GNU utilities. This directory is included in the default PATH for users.

usr/examples:

Examples of source and scripts.

usr/include:

Header files. Note the addition of /usr/include/interix, which contains some Interix-specific header files.

usr/local:

This is the directory where perl and the bind libraries and headers are installed. PERL 5.6.1 is included with SFU 3.0 as well as BIND 8.1.2

usr/lib:

Library files. See Libraries below for a list of the provided libraries.

usr/sbin:

Special system binaries for use by system managers.

usr/share:

A variety of shared files for applications. The formatted man pages are here (usr/share/man), the system Makefile (usr/share/mk/sys.mk), the termcap and terminfo databases, the mailx and more help files, the bc library, and the magic file.

var/mail:

Default location for mailbox files; examined by mailx and sendmail.

Header Files

The header files in Interix are structured according to the relevant standards (such as POSIX.1 and the Single UNIX Specification).

For ease of portability, other popular but non standard header files have been created which may include other existing header files. For example, <sys/param.h> includes <features.h>, <sys/types.h>, and <limits.h>.

Libraries

The Interix Software Development Kit provides the following libraries:

libc.a

Standard C library.

libcurses.a

Ncurses (System V curses) library ported to Interix.

libdl.so

The dynamic linking library. Please note that this is only available for applications using the gcc compiler.

libform.a

Forms library (part of Ncurses).

libl.a

Lex library.

libmenu.a

Menu library (part of Ncurses).

libpanel.a

Panel library (part of Ncurses).

librpclib.a

ONC Remote Procedure Call library

libsocket.a

Stub for compatibility; not actually required.

libtermcap.a

Termcap library.

psxdll.a

Interix API entry points as a DLL.

Interix also includes dynamic libraries counterparts to the above list and libc.a and libpsx.a are combined into a single libc.so. Metaconfig scripts search specified files for APIs. They do not find many of the system calls because the psxdll.a file is not specified for the scripts.

gcc versus c89 versus cc

Services for UNIX 3.0 provides the gcc compiler as well as the cc and c89 utilities which are wrappers for use with a Microsoft C compiler.. We assume you will use gcc, because most configure scripts look specifically for gcc.

Some notes about cc and c89:

  • cc accepts the traditional ordering of options and operands where certain options (such as -o and –L ) can be located anywhere on the command line. The c89 utility follows the POSIX argument ordering conventions where all options must be specified before any operands.

  • cc pre-defines several useful feature macros:

    -DUNIX -D__INTERIX -D_ALL_SOURCE -D__STDC__

  • c89 defines only __INTERIX.

For compatibility with older programs, use cc instead of c89.

Target Directories

Where should software be installed on a Services for UNIX 3.0 system?

Installing software in /bin or /usr/contrib is generally a bad idea for these reasons:

  • If the new binary has the same name as an existing binary, your new binary will be replaced when Interix is re-installed or upgraded.

  • Even if it has a different name than any existing binary, it's sometimes convenient to be able to remove existing software before a re-install by using a command such as:

rm -rf /bin /usr/contrib

This is not possible if there are local files installed in these directories.

If you are the only user who logs in to your Interix system, you may just want to install in $HOME/bin and add this directory to your PATH. This is convenient but means that those binaries are unavailable if you have to login as Administrator.

You may want to create directories for local binaries, such as /usr/local/bin or /opt. Be sure to add this directory to the default PATH environment variable in /etc/profile.lcl or /etc/csh.lcl and make sure that the permissions on the directory are correctly set.

Configure and Autoconf 2.52

The autoconf program is a package of m4 scripts which produce a script, named configure by convention.

The configure script uses a number of tests to check for the presence or absence of a specified feature, but many of them involve small programs which are then run through the C preprocessor or compiled. The feature test is generally based on the output of the C preprocessor or driver rather than on execution of the test program.

Services for UNIX 3.0 may have the following problems with configure scripts:

  • Some APIs are provided as macros. For example, herror() is an alias for perror(). Tests checking for those APIs as functions will fail.

Guessing the Host

Some packages require special knowledge of the host system, and many configure scripts need to know the name of the host system. Along with configure, sometimes there is another script called config.guess, which tries to determine the name of the host. Support for detecting Interix 3.0 was added to autoconf sometime between 2.52 and 2.57. When config.guess fails, you can still supply the host name to configure with the --host option.

If for some reason you want to update the config.guess script, the following addition to the config.guess script will allow it to identify Interix systems. In the long case statement examining the output of the uname command, add a block:

x86:Interix*:3*)
    echo i586-pc-interix3
    exit 0 ;;

Obviously any host-specific code in the software package itself will have to be written or ported by you, since the package isn't (yet) written with Interix in mind.

Running Configure Scripts

We have had some success running configure scripts with the following command line (broken across lines for readability):

$ CFLAGS=”-D_ALL_SOURCE” CXXFLAGS=”-D_ALL_SOURCE” \
./configure --prefix=/usr/local \
--host=i586-pc-interix3

Not all options are recognized by all configure scripts. And remember that the directories specified for these options need to exist before running the script if you change them from what is mentioned here.

Since the command line is bulky and difficult to type, you may want to encapsulate it in a shell script or create a local config.site file for your system.

Creating a config.site File

As described in the autoconf documentation, the config.site file describes site-specific default values for some configuration values. If the environment variable CONFIG_SITE is set, configure uses its value as the name of a shell script to read. Otherwise, it reads the shell script /share/config.site if it exists, then /etc/config.site. Settings in machine-specific files override those in machine-independent ones.

This config.site file does the same as the command line above.

# config.site for an Interix system
# This is a notational convenience so lines
# don't have to be broken in this text:
# Set defaults
# If you've created usr/local/bin & sbin:
if [ "$bindir" = NONE ] && [ -d /usr/local/bin ]
then
     bindir=/usr/local/bin
else
     bindir=/usr/contrib
fi
if [ "$sbindir" = NONE ] && [ -d /usr/local/sbin ]
then
     bindir=/usr/local/sbin
else
     bindir=/usr/contrib
fi
if [ "$cache_file" = ./config.cache ]
then
     cache_file="/usr/local/lib/config.cache"
fi
if [ “$host” = NONE ]
then
   host=586-pc-interix3
fi

To invoke it, you must either set CONFIG_SITE to the pathname of the file or use the –prefix option to configure:

$ ./configure --prefix=/usr/local

The last block of the file refers to a site-wide config.cache file. If you do not want to have a site-wide config.cache file, delete the lines:

if [ "$cache_file" = ./config.cache ]
then
     cache_file="/usr/local/lib/config.cache"
     # A cache file is only valid for one C compiler
fi

A Sample Site config.cache File

After porting several packages, you may want to create a site-specific config.cache file. Here's a small one which came from configuring fetchmail, GNU tar, and autoconf. Some package-specific values have been removed.

# This file is a shell script that caches the results of
# configure tests run on this system so they can be
# shared between configure scripts and configure runs.
# It is not useful on other systems. If it contains
# results you don't want to keep, you may remove or edit
# it.
ac_cv_c_const=${ac_cv_c_const=yes}
ac_cv_c_stack_direction=${ac_cv_c_stack_direction='-1'}
ac_cv_func_alloca_works=${ac_cv_func_alloca_works=no}
ac_cv_func_atexit=${ac_cv_func_atexit=yes}
ac_cv_func_gethostbyname=${ac_cv_func_gethostbyname=yes}
ac_cv_func_getopt_long=${ac_cv_func_getopt_long=no}
ac_cv_func_seteuid=${ac_cv_func_seteuid=yes}
ac_cv_func_setlinebuf=${ac_cv_func_setlinebuf=yes}
ac_cv_func_setsid=${ac_cv_func_setsid=yes}
ac_cv_func_snprintf=${ac_cv_func_snprintf=yes}
ac_cv_func_strcasecmp=${ac_cv_func_strcasecmp=yes}
ac_cv_func_strerror=${ac_cv_func_strerror=yes}
ac_cv_func_strrchr=${ac_cv_func_strrchr=yes}
ac_cv_func_strstr=${ac_cv_func_strstr=yes}
ac_cv_func_poll=${ac_cv_func_poll=no}
ac_cv_func_stty=${ac_cv_func_stty=no}
ac_cv_func_syslog=${ac_cv_func_syslog=yes}
ac_cv_func_tcsetattr=${ac_cv_func_tcsetattr=yes}
ac_cv_func_vprintf=${ac_cv_func_vprintf=yes}
ac_cv_func_vsnprintf=${ac_cv_func_vsnprintf=yes}
ac_cv_func_vsyslog=${ac_cv_func_vsyslog=yes}
ac_cv_func_wait3=${ac_cv_func_wait3=no}
ac_cv_func_waitpid=${ac_cv_func_waitpid=yes}
ac_cv_header_alloca_h=${ac_cv_header_alloca_h=yes}
ac_cv_header_fcntl_h=${ac_cv_header_fcntl_h=yes}
ac_cv_header_minix_config_h=${ac_cv_header_minix_config_h=no}
ac_cv_header_sgtty_h=${ac_cv_header_sgtty_h=no}
ac_cv_header_stdarg_h=${ac_cv_header_stdarg_h=yes}
ac_cv_header_stdc=${ac_cv_header_stdc=yes}
ac_cv_header_sys_fcntl_h=${ac_cv_header_sys_fcntl_h=yes}
ac_cv_header_sys_itimer_h=${ac_cv_header_sys_itimer_h=no}
ac_cv_header_termio_h=${ac_cv_header_termio_h=no}
ac_cv_header_termios_h=${ac_cv_header_termios_h=yes}
ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes}
ac_cv_lib_inet_socket=${ac_cv_lib_inet_socket=no}
ac_cv_lib_l_yywrap=${ac_cv_lib_l_yywrap=yes}
ac_cv_lib_socket_socket=${ac_cv_lib_socket_socket=yes}
ac_cv_os_cray=${ac_cv_os_cray=no}
ac_cv_path_install=${ac_cv_path_install='install -c'}
ac_cv_prog_CC=${ac_cv_prog_CC=gcc}
ac_cv_prog_CPP=${ac_cv_prog_CPP='cpp'}
ac_cv_prog_LEX=${ac_cv_prog_LEX=lex}
ac_cv_prog_cc_cc_c_o=${ac_cv_prog_cc_cc_c_o=yes}
ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no}
ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes}
ac_cv_prog_gcc=${ac_cv_prog_gcc=yes}
ac_cv_sizeof_int=${ac_cv_sizeof_int=4}
ac_cv_sizeof_long=${ac_cv_sizeof_long=4}
ac_cv_sizeof_short=${ac_cv_sizeof_short=2}
ac_cv_type_pid_t=${ac_cv_type_pid_t=yes}
ac_cv_type_signal=${ac_cv_type_signal=void}
ac_cv_type_size_t=${ac_cv_type_size_t=yes}