1. Resolve the dependency of gnu-gettext

In most cases, the gettext(3C) on solaris could fulfill the requirements of your application. You could make following change in configure.in (or configure.ac):

-AM_GNU_GETTEXT
+AM_GLIB_GNU_GETTEXT
+LTLIBINTL=
+AC_SUBST(LTLIBINTL)

The source package may ship with a completed gnu-gettext in its source tree (normally named 'intl'), remove it from the 'SUBDIRS' in the top-level Makefile.am. Sometimes, there is a 'm4' directory in the source tree, contains some macro files for checking gnu libraries or GCC compiler options, remove the option '-I m4' from 'ACLOCAL_AMFLAGS' in the top-level Makefile.am.

Then execute the following steps to update m4 macros and configure script:

glib-gettextize --force
aclocal $ACLOCAL_FLAGS
autoheader
libtoolize -c --automake
automake --add-missing
autoconf


Another note is, the gnu-gettext could not retrieve the localized message compiled by solaris' msgfmt (/usr/bin/msgfmt), but solaris' gettext works fine with the message compiled by gnu's msgfmt.

2. Build socket programs

You may find that the commonly used macro 'SUN_LEN' is not defined in Solaris, add the follow definition in your header file:

+#if defined(sun) && !defined(SUN_LEN)
+#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif


And before you run configure script, set the LDFLAGS as following:

export LDFLAGS=-lsocket

3. 0-sized array member in C struct

struct Foo {int bar; char data[0];};

-char data[0];
+char data[];    //change the 0-sized array to flexible array


Note, according to C99 standard, the flexible array member could only be placed in the end of a structure. And this change will not impact the layout and size of the original data structure. (Thanks tchaikov for providing the perfect solution!) While, if the 0-sized array member is not on the tail, you may have to use 'union', which requires to change the accessing code.

4. struct initialization

struct point {int x, y, z;};
- struct point x = {x:2, z:3};
+ struct point x = {.x=2, .z=3}; // c99 extension,
not supported
                                 // by sunstudio C++ compiler

5. alloca(3C) on Solaris

You need include alloca.h in your source file where you call alloca(3C).

6. wchar_t

Do NOT assume a wide char is always a UCS4 character. It's true only in UTF-8 locales on Solaris.

7. Using gcc if the source uses too much gcc extensions.

The last choice, /usr/sfw/bin/gcc. The SunStudio C compiler and gcc are compatible in ABI. But C++ compilers are different. If you are building the package on SPARC platform, GCC4SS has better performance than gcc.
评论:

I usually end up having to add -lnsl to -lsocket in LDFLAGS

发表于 Mads 在 2008年01月04日, 07:40 下午 CST #

- char dummy[0];
+ char *dummy;

But they are not always interchangeable. Such kind of dummy array is an idiom used when declaring a vary length array embodied in a structure.

To reference the element in the vary length array by its name, programmers always allocate a larger memory area than this struct's real size. Like:

struct Foo {int bar; char payload[0];};
........
struct Foo *f = malloc(sizeof(struct Foo)+payload_len);

f->payload[0] = 'a';
f->payload[1] = 'm';
f->payload[2] = 'd';
f->payload[3] = 0;

If you replace `char payload[0];' with `char *payload;', payload will be no more an array, but a pointer whose value is some random number on the heap. Apparently, we can not dereference it using f->payload[index] as we did.

发表于 tchaikov 在 2008年01月05日, 11:07 下午 CST #

Hi, tchaikov, you are right, I should add that the programmer needs explicitly initialize the address of 'payload' after the memory allocation.

发表于 Yong Sun 在 2008年01月06日, 01:16 上午 CST #

Hi, tchaikov, I thought it over, and it's much better to change the 0-sized array as 1-sized array, if the 0-sized array is on the tail. If it's in middle of a structure, 'union' maybe the only choice.

发表于 Yong Sun 在 2008年01月06日, 11:07 上午 CST #

@Yong,

Thanks for your update.

1-sized array could work in some cases. But even if this array sits at the end of struct, this approach could break some network/codec programs without more modification.

e.g. In following code snippet, f->bar is an indicator for whether f->payload is valid or not, like what a typical XDR union with a void member compiles into:
packet_len = sizeof(*f) + f->bar?0:strlen(f->payload);

On a 32-bit machine,
a) if f->payload is an 0-sized array: packet_len = 4
b) if f->payload is an 1-sized array, because of compiler's padding for word alignment: packet_len = 8,

But according to C99, `flexible array member' is allowed as the last element of a structrue. like:
struct Foo { int bar; char payload[]; };

And fortunately, Sun's C compiler supports this feature since Sun ONE Studio 8[1].

--
[1] http://docs.sun.com/source/817-5064/c99.app.html

发表于 tchaikov 在 2008年01月06日, 03:50 下午 CST #

Wow, cool, thanks for the info about flexible array :) Yeah, we should change the 0-sized array to flexible array :)

发表于 Yong Sun 在 2008年01月06日, 05:33 下午 CST #

发表一条评论:
该日志评论功能被禁用了。

This blog copyright 2009 by yongsun