Linux => OpenSolaris Porting Code Fixes
This page lists various common issues encountered when porting Linux code to Nexenta. It aims to collect the various common issues faced when moving packages from Ubuntu to NCP.
Please note some packages are not even meant to build or run under OpenSolaris (ex.: some Linux kernel-related ones). Also note that support for (Open)Solaris improved lately in the Free Software world, so sometimes a fix already exists in some newer version and no porting effort is actually needed from your part.
Patch resources
Existing Solaris patches for various packages can be found at the below sources:
Development articles
- Tutorial on building packages part1, and part2
- Adding SMF Support to a package.
Common code patches/changes
Changing Dependencies
(these changes would go to the Depends: field of debian/control in)
at -> at | sunwcsu pax -> pax | sunwcsu
sys_errlist[errno]
This way of accessing errors is deprecated. Convert these calls to
strerror(errno)
isfinite()
Add the following to offending cpp file.
#if defined(sun) #ifndef isfinite #define isfinite(val) (val <= std::numeric_limits::max()) #endif #endif
alloca
Add
#include <alloca.h>
to the file.
readdir_r
Add
-D_POSIX_PTHREAD_SEMANTICS
to CFLAGS in the configure.in file.
undefined reference to libintl_gettext
Application needs to be linked with libintl. Either configure script or debian/rules needs to be fixed. Defining
LDFLAGS=-lintl
in debian/rules is easier but fixing configure script to correctly 'detect' libintl is the cleanest.
apt-get install package : dpkg: error processing * : trying to overwrite file
This occurs when a package tries to overwrite a file that has already been installed to the system by another package. Only one package may install a file to the system. To workaround this, you can:-
- Modify the "install" target in the Makefile of the package to remove the file from being installed
You can remove this file after build in debian/rules add the following lines:
install/packagename::rm debian/packagebuilddirname/path/to/file
or
rm -f debian/packagebuilddirname/path/to/file
- Use dpkg-divert: http://www.debian-administration.org/articles/118
Dpatch error: unable to patch 01somepatch: No permission
This usually occurs when the patched in the debian/patches directory are missing the executable flag. Workaround is to go into the patches directory and
chmod +x *patch
implicit declaration of function 'asprintf'
Either add
-D_GNU_SOURCE
as a parameter to gcc in the Makefile/configure.in or add a
#define _GNU_SOURCE
in the offending C file
u_int32_t not defined (or u_int16_t not defined or u_int64_t not defined)
Add the following to the offending file. Usually, you'll need to add the below lines for all three variants.
#ifndef u_int32_t #define u_int32_t uint32_t #endif
error: 'NAME_MAX' undeclared (first use in this function)
If you want the maximum length of a full path name, and not just the length of the basename, you can use PATH_MAX.
strerror_r : cannot convert int to char *
Background here .. this function is defined differently in POSIX and GNU. You'd need to port from first method to second:
char *result = strerror_r(errnum, buf, bufsize);
#ifndef __sun__
char *result = strerror_r(errnum, buf, bufsize);
#else
strerror_r(errnum, buf, bufsize);
char *result = buf;
#endif
winsize not defined.
This would have been in sys/ioctl.h on GNU/Linux, but is found in sys/termios.h in Solaris. Add below to offending line
#ifdef __sun__ #include#endif
error: 'struct dirent' has no member named 'd_type' DT_DIR undeclared (first use this function)
The struct dirent definition in Solaris does not contain the d_type field. You would need to make the changes as follows
if (de->d_type == DT_DIR)
{
return 0;
}
becomes
struct stat s; /*include sys/stat.h if necessary */
..
..
stat(de->d_name, &s);
if (s.st_mode & S_IFDIR)
{
return 0;
}
FNM_CASEFOLD not defined
Add the following at the beginning of the file
#ifndef FNM_CASEFOLD #define FNM_CASEFOLD (1 << 4) #endif
Compiler or options invalid for pre-UNIX 03 X/Open applications and pre-2001 POSIX applications
Remove the
-std=c9x
or
-std=c99
option in CFLAGS, either in configure.ac, configure or Makefile
alternatively, add
-D_XPG6
undefined reference to error_print_progname' undefined reference toerror'
add
LDFLAGS += -lrecodeto debian/rules **error: #error "Compiler or options invalid for pre-UNIX 03 X/Open applications and pre-2001 POSIX applications"** Multiple reasons.. try removing
--std=c9xflag to _configure_ if present. **error: paths.h: No such file or directory** Todo: explain **error: mntent.h: No such file or directory** On Linux, mntent.h is in /usr/include and on Solaris it is in /usr/include/sys as part of the sunwhea package. change
#include <mntent.h>
to
#ifdef __sun__ #include <sys/mntent.h> #else #include <mntent.h> #endif
cfmakeraw not declared in scope
See Cfmakeraw
openpty() not defined / not in scope
This isn't available on Solaris. Example of porting.
if (openpty(&master, &slave, line, NULL, NULL) == -1) {
return -1;
}
becomes
#ifdef __sun __
char * slavename;
//extern char *ptsname(int *);
master = open("/dev/ptmx", O_RDWR);
if (master == -1) return -1;
grantpt(master); unlockpt(master);
slavename = ptsname(master);
slave = open(slavename, O_RDWR);
#else
if (openpty(&master, &slave, line, NULL, NULL) == -1) {
return -1;
}
#endif
Mixing GNU and SUN ld (the linker) in a build
In NCP 2.0 we use GNU ld (/usr/bin/ld) by default. Traditionally on Solaris even when GCC is used, the Solaris ld (/usr/csc/bin/ld) is used. You should be careful to ensure that only GNU ld is used. A few important things to watch for in configure/configure.in and Makefile/Makefile.am/Makefile.in
*LD=; change to this LD=/usr/bin/ld or just comment it out *LDFLAGS=-G; change -G to this to -shared
switch_gethostbyname undefined reference
This was used around SunOS 5.2, because gethostbyname was unavailable then. Find the #ifdef test which defines gethostbyname to this symbol, and correct it (by commenting out or changing the #ifdef test).
LOCK_SH undeclared
Add the below to header file/source file
#ifdef __sun__ #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ #define LOCK_NB 4 /* don't block when locking */ #define LOCK_UN 8 /* unlock */ #endif
error: declaration of 'iob' as array of references or the code line has defined String:std stdout or stderr
Rename stdout/stderr as mystdout/mystderr throughout the function/program
MSG_NOSIGNAL undeclared
Add below to header/source file.
#ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif
vasprintf was not declared
Add below to the file.
extern int asprintf(char **, const char *, ...); extern int vasprintf(char **, const char *, __va_list);
This will be resolved in newer version of stdio.h. http://opensolaris.org/os/community/on/flag-days/pages/2009011401/
error: too few arguments to function ctime_r
Add
-D_POSIX_PTHREAD_SEMANTICS
to the Makefile.
Test failed during compilation
Prevent test suite from building. You may need to patch Makefile.in. For example: aptitude package.