Mail Archives: djgpp/1998/11/17/03:59:22
On Mon, 16 Nov 1998, Jeff Williams wrote:
> For example, if I set HOME in autoexec.bat, then start bash, HOME will
> sometimes (and sometimes not) be set in bash. I can't figure out what
> I'm doing differently when this happens.
This has never happened to me. Please post details, in particular, if
you invoke Bash in several different ways.
> SYSROOT=
> HOME=
> PATH_EXPAND=
> PATH_SEPARATOR=
> PATH_SLASH=
> TMPDIR=
>
> Do these variables have to be set in autoexec.bat, or in _bashrc,
> or does it matter?
It shouldn't matter.
> Do these variables have to be EXPORTed if they are set in _bashrc?
If Bash runs interactively, it always reads _bashrc, so you don't need
to EXPORT them. But if you want them to be in effect when Make runs
Bash, then you do need to EXPORT them.
> Do these variables have to be set in any particular order?
No.
> Is the value for any of these variables determined by pre-existing DOS
> environment variables, e.g., if PATH uses `;' must PATH_SEPARATOR be
> `;' too?
No. When you set PATH_SEPARATOR=:, Bash will automatically convert
the value of PATH to replace ; with : and x: with //x/ (where x is any
drive letter).
> In general, how should these variables be set to achieve maximum
> portability of my applications (mostly C programs, makefiles, and sh
> scripts) from my Sun Unix box at work to my DJGPP box at home?
If you want to have a portable Unix/DOS environment, you will need to
make some effort in order to make it work. Here are some hints; ask
more specific questions if they don't solve all your problems.
1) Makefiles and shell scripts--the easy way:
The easy way is to set PATH_SEPARATOR=: and PATH_EXPAND=y in your
DJGPP setup. This converts PATH to Unix-style form, but Bash
will convert any //x/foo/bar pathnames back to their DOS form
x:/foo/bar when invoking external programs. This works in many
simple cases.
Unfortunately, it does NOT work well enough in some non-trivial
cases. The reason is that only Bash supports these //x/foo file
names, and it only converts them to the DOS format when running
EXTERNAL programs. This means that if the script/Makefile uses
an internal command like `echo', you get the unconverted
//x/foo. One example where this would bite you is when a script
such as the GNU-standard configure creates a Makefile. If you
use PATH_SEPARATOR=:, you will typically see a line like this in
a generated Makefile:
INSTALL=//d/djgpp/bin/ginstall
And this will of course fail when Make will later try to run this
Makefile.
2) Makefiles and shell scripts--take 2:
If PATH_SEPARATOR+PATH_EXPAND don't work, you will have to make
your shell scripts and Makefiles OS-aware. There are several
differences between Unix and DOS/Windows that should be handled
differently (see below). A portable script should find out on
which type of system does it run and behave accordingly.
Here's one way of detecting the OS type:
if test -z "$COMSPEC$ComSpec"; then
os_type=unix
else
os_type=dosish
fi
(The $ComSpec thing is for the NT, in case you are running a
Win32 port of Bash.)
If a Makefile, use either the conditional directives or the
$(shell) function to do the same.
Typically, you will run this test at the beginning of a script or
a Makefile, and then use the result wherever an OS-dependent
behavior is called for.
3) Things to watch for:
Here are some subtle differences between Unix and DOS/Windows
that need to be resolved once $os_type is set as above:
- The PATH separator (: as opposed to ;). One way to handle this
is to have a variable, say, $sep which is set to : or ;
depending on $os_type.
- Looking for an executable program: do NOT use "test -f gcc",
because on DOS/Windows you will have gcc.exe. "test -x gcc" is
the way to go, as the ported Bash knows to look for executable
extensions when you use the -x switch. If your shell on the
Unix side doesn't support "test -x", compute the switch
dynamically using $os_type.
- The format of an absolute file name. Some scripts test file
names for being absolute and behave differently if they aren't.
Typically, they think that "/*" is the wildcard pattern for an
absolute file name. But on DOS/Windows you need to use
something like "/*|[A-z]:/*" instead.
- Hard-wired names for standard programs: do NOT use names like
"/bin/rm" and "/tmp"; use "rm" and "${TMPDIR-/tmp}" instead.
- Temporary files: avoid names like mytemp-$$.foo or temp.foo-$$,
since they might clash in the DOS 8+3 namespace. Since $$ can
produce up to 5 characters in DJGPP, don't use more than 3
characters in addition to $$, and don't put $$ into the
extension.
The best way to use temporary files safely is to create a
temporary DIRECTORY and then put any files there without caring
about their names.
- End-of-line format. Do NOT assume that every line in a text
file ends with a single Newline: most DOS files end with a
CR-LF pair. This means, for example, that you need to use
`diff' as opposed to `cmp' when comparing text files for
identity.
4) It is advisable to put a line like this on your DJGPP.ENV in the
[bash] and [sh] sections:
PATH=%/>PATH%
This converts PATH to lower-case and mirrors all backslashes to
the forward Unix style, and avoids some subtle problems which are
too long to describe.
5) Last, but not least: always make sure your shell scripts say
"#!/bin/sh" on its first line, and your Makefile have a line
which says "SHELL=/bin/sh". This causes Bash, Make, and all
other DJGPP programs behave correctly when they run such
Makefiles and shell scripts.
- Raw text -