The GNU build system distinguishes between 'build', 'host' and 'target' machines.
The 'build' machine is where compilers are run, the 'host' machine where the package
being built will run, and for cross compiling the 'target' machine, on which the compiler
built will generate code for.

When using GNU autotools to configure a package config.guess and config.sub from autotools-dev
are used to find out the build machine identity: CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM.
For GNU/Hurd config.guess gives 'i686-unknown-gnu0.3'. Sometimes a quadruple is used
adding KERNEL, e.g. for Linux on an amd64: 'x86_64-unknown-linux-gnu'. This
is however actually a triple, it just happens that the operating system part
unfortunately contains a '-'. config.sub is used to
canonicalize on these triplets, e.g. config.sub i686-gnu gives 'i686-pc-gnu'.

On Debian systems the build Makefile is debian/rules and some Debian packages will set $host to
'i486-pc-gnu'. This is accomplished with the 'dpkg-architecture -qDEB_HOST_GNU_TYPE' construct
forwarded to configure in debian/rules, e.g. configure --host=$DEB_HOST_GNU_TYPE.
Another way to set $build, $host etc is via the Debian dh_auto_configure script from the debhelper
package which uses the Perl code autoconf.pm to find out these variables.

Note: some of such statements are not from the source package itself, but from aclocal.m4 which is actually from libtool. In such case, the package simply needs to be re-libtoolize-d.

Preprocessor Define

IRC, freenode, #hurd, 2013-10-23

<C-Keen> Is there a preprocessor define gcc sets for hurd which I can check
in my code?
<braunr> __GNU__
<braunr> glibc sets it if i'm right
<C-Keen> I also see that __MACH__ gets set
<azeem> that's also set on Mac OS X
<C-Keen> right, which uncovered a bug in the code
<braunr> the microkernel doesn't always implies what operating system runs
on top of it
<C-Keen> braunr: but __GNU__ is the correct define for hurd specific code?
<braunr> yes

If you get Bad File Descriptor error when trying to read from a file (or accessing it at all), check the open() invocation. The second argument is the access method. If it is a hard coded number instead of a symbol defined in the standard header files, the code is screwed and should be fixed to either use O_RDONLY, O_WRONLY or O_RDWR. This bug was observed in the fortunes and mtools packages for example.

Every unconditionalized use of PATH_MAX, MAX_PATH or MAXPATHLEN is a POSIX incompatibility. If there is no upper limit on the length of a path (as its the case for GNU), this symbol is not defined in any header file. Instead, you need to either use a different implementation that does not rely on the length of a string or use sysconf() to query the length at runtime. If sysconf() returns -1, you have to use realloc() to allocate the needed memory dynamically. Usually it is thus simpler to just use dynamic allocation. Sometimes the amount is actually known. Else, a geometrically growing loop can be used: for instance, see Alioth patch or Pulseaudio patch. Note that in some cases there are GNU extensions that just work fine: when the __GLIBC__ macro is defined, getcwd() calls can be just replaced by get_current_dir_name() calls.

Note: constants such as _POSIX_PATH_MAX are only the minimum required value
for a potential corresponding PATH_MAX macro. They are not a replacement for
PATH_MAX, just the minimum value that one can assume.

Note 2: Yes, some POSIX functions such as realpath() actually assume that
PATH_MAX is defined. This is a bug of the POSIX standard, which got fixed in
the latest revisions, in which one can simply pass NULL to get a dynamically
allocated buffer.

Same as PATH_MAX. When you find a gethostname() function, which acts on a static buffer, you can replace it with Neal's xgethostname function which returns the hostname as a dynamic buffer. For example:

GNU specific #define

If you need to include specific code for GNU/Hurd using #if ... #endif, then you can use the __GNU__ symbol to do so. But think (at least) thrice! before doing so. In most situations, this is completely unnecessary and will create more problems than it may solve. Better ask on the mailing list how to do it right if you can't think of a better solution.

If a program has only support for sys_errlist[] you will have to do some work to make it compile on GNU, which has dropped support for it and does only provide strerror(). Steinar Hamre writes about strerror():

strerror() should be used because:

It is the modern, POSIX way.

It is localized.

It handles invalid signals/numbers out of range. (better errorhandling and not a buffer-overflow-candidate/security risk)

strerror() should always be used if it is available. Unfortunaly there are still some old non-POSIX systems that do not have strerror(), only sys_errlist[].

Today, only supporting strerror() is far better than only supporting sys_errlist[]. The best (from a portability viewpoint), however is supporting both. For configure.in, you will need:

You can for example look in the latest coreutils (the above is a simplified version of what I found there.) Patches should of course be sent to upstream maintainers, this is very useful even for systems with a working sys_errlist[].

Of course, if you don't care about broken systems (like MS-DOG) not supporting strerror() you can just replace sys_errlist[] directly (upstream might not accept your patch, but debian should have no problem)

The rationale behind is that on the Hurd ioctl numbers actually encode how the
data should be transferred via RPC: here struct termios holds 4 members of
type tcflag_ts, then NCCS members of type cc_tsi and finaly 2 members of
type speed_ts, so the RPC mecanism will know how to transfer them.

As you can see, this limits the number of contiguous kinds of members to 3, and
in addition to that (see the bitfield described in ioctls.h), the third kind
of member is limited to 3 members. This is a design limitation, there is no way
to overcome it at the moment.

Note: if a field member is a pointer, then the ioctl can't be expressed
this way, and that makes sense, since the server you're talking to
doesn't have direct access to your memory. Ways other than ioctls must
then be found.

Configure script often hardcode the library that contains dlopen & such (-ldl), and only for Linux. Simply add the other GNU OS cases: replace linux* with linux*|gnu*|k*bsd*-gnu*

struct sockaddr, sa_len/sa_family

IRC, freenode, #hurd, 2014-02-18

<braunr> if there is someone here that can help, i've traced the https
issue in iceweasel down to nspr
<braunr> the problem being that the hurd uses the old 4.4bsd sockaddr
structure that includes sa_len before sa_family, and nspr directly maps
that into its own structure, assuming the internal layout is the same
<braunr> i need to change a configure script so that a macro is defined for
the hurd
<braunr> let's see if that works
<braunr> better :)
<braunr> there, ssl now works
<braunr> \o/
<braunr> it's still the experimental one
<braunr> and there are other minor issues
<braunr> (like no logo on the about panel :p)
<cluck> that's a feature^TM
<braunr> maybe it's not a mistake
<braunr> i haven't seen that version on linux to actually compare
*** rbraun_hurd (c3445c23@gateway/web/freenode/ip.195.68.92.35) has joined
channel #hurd
<rbraun_hurd> webchat from freenode :)
<teythoon> :D
<rbraun_hurd> there is also this weird :"Failed to truncate cookie file:
Invalid argument Failed to write cookie file: Unknown error (os/kern)
303" error
<rbraun_hurd> but i guess it's simply a matter of supporting an option in
glibc/hurd somewhere
<braunr> 18:06 CTCP VERSION reply from rbraun_hurd: qwebirc v0.91,
copyright (C) 2008-2011 Chris Porter and the qwebirc project --
Mozilla/5.0 (X11; GNU i686-AT386; rv:27.0) Gecko/20100101 Firefox/27.0
Iceweasel/27.0
<braunr> hm, i didn't version the iceweasel packages :/
<braunr> i'll rebuild them properly and put them on my repository
<braunr> oh, the freenode webchat actually runs in gnash oO

IRC, freenode, #hurd, 2014-02-19

<braunr> http://darnassus.sceen.net/~rbraun/nspr4_hurd.patch
<braunr> in short: nsprt has its own struct sockaddr, which it assumes to
have the same layout as the native one
<youpi> doesn't kfreebsd also have sockaddr_len ?
<braunr> and of course, that's not the case on the hurd, because we use an
old 4.4bsd header that defines sa_len before sa_family, making all sorts
of tests fail in nspr
<braunr> hm
<braunr> i don't know
<braunr> we could discuss that with them
<braunr> but i doubt they don't use iceweasel :)
<youpi> it really seems kfreebsd has sa_len etc.
<youpi> kfreebsd really has sa_len
<youpi> so put it in the new case too :)
<braunr> i'll ask them first
<braunr> something in nspr might already take care of the bsd case
elsewhere
<braunr> nspr knows more about bsd systems than it knows about the hurd :)
<braunr> but with all these fixed, i could run iceweasel for a whole day at
work, multiple tabs, gnash running (things like youtube and freenode web
chat client among other things)

Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license
is included in the section entitled
GNU Free Documentation License.