Can't compile code with semaphore under Solaris?
-
23-02-2021 - |
Question
I have written some code which compiles fine under linux but on Solaris I am given some compiling errors. I use gcc test_compile.c -o tes -pthreads
to compile.
#include <semaphore.h>
int main(){
sem_t semaphore;
sem_init(&semaphore, 0, 0);
return 0;
}
Gives me
itchy:~/edu/sysprog> gcc test_compile.c -o tes -pthreads
Undefined first referenced
symbol in file
sem_init /var/tmp//ccUiSK6A.o
ld: fatal: Symbol referencing errors. No output written to tes
I am not sure what's going on. I tryied replacing sem_init
with sema_init
and it compiles(saw that somewhere online). However that would mean that I must go through my whole code and replace sem with sema. Isn't there a simpler solution? And what does it really mean?
Solution
You need to link with the realtime extensions library librt
:
gcc test_compile.c -o tes -lrt -pthreads
This is documented in the man page for sem_init(3RT)
:
SYNOPSIS
cc [ flag... ] file... -lrt [ library... ]
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
OTHER TIPS
Before all of this, I'd first make sure you're linking correctly. It seems like compiled fine, but failed at the linking step. So first make sure you actually have semaphore.h
and that it includes sem_init(...)
. If you do, and my guess is that you do, check your compile command. If that is your compile command in your question, try adding -lpthread
to your compile line to link in the posix thread library.
So you should double check that sema does what you want, since they're different libraries -- sem
is from the POSIX pthreads
library and sema
is from the solaris thread
library. (See this also) But if they're code compatible, and if you're looking for cross-platform compatible code, you'd probably want to do something like create simple wrapper functions and then conditionally include it.
Your wrapper functions would be really simple, accept the same types and return the same type, e.g.
ret_type sem_init(argtype arg1, argtype arg2, argtype arg3)
{
return sema_init(arg1, arg2, arg3)
}
And then conditionally include it with something like
#ifdef SOLARIS
#include semaphore_wrappers.h
#endif
Note that SOLARIS isn't going to be defined. You'll either have to manually #define SOLARIS
when compiling on solaris, or define it in your compile command line / makefile.
At least thats how I'd do it.
Note that if this is not to be cross-platform compatible, it's much easier to read and debug if you just do a global search and replace.