Recently I've got a MacBook at work. Of course, the temptation of using it for other purposes than official ones was too high to resist. So I've started porting Tagsistant to MacOS X.
Compiling GNU/Linux software on MacOS X needs some fine tuning but not as much
as I thought. After reading some docs on the net, I've learned about
FUSE port called
MacFUSE.
Installing MacFUSE is a piece of cake. Using it no. Autoconf script needs some
tweaking to guess the architecture type. But it's quite easy to add it. Insert
a AC_CANONICAL_TARGET macro in configure.ac or
configure.in file to let it figure out the four-field values for
$host variable, like in i686-pc-linux-gnu example.
MacOS X 10.5.1 returns i686-apple-darwin9.1.0 on a Core 2 Duo
host.
Using $host value the script will be able to make some
adjustments to compile and link options. Just add some bash scripting like the
following:
echo configure detected host $host
case $host in
*-*-linux*)
echo "Live long and prosper, GNU/Linux"
;;
*-*-darwin*)
AC_SUBST([CFLAGS],["${CFLAGS} -D__FreeBSD__=10 -DMACOSX -DFUSE_USE_VERSION=25"])
AC_SUBST([LDFLAGS],["${LDFLAGS} -flat_namespace -force_flat_namespace"])
;;
esacAs you see, we add -D__FreeBSD__=10 -DMACOSX
-DFUSE_USE_VERSION=25 to CFLAGS and -flat_namespace
-force_flat_namespace to LDFLAGS. __FreeBSD__ macro appears
in some headers, like in MacFUSE's, to declare some structures dedicated to BSD
hosts. MACOSX is a macro I've declared to include some conditional
compiling inside tagsistant. May be it's not the best name since it can easily
conflict with symbols having the same name but elsewhere declared. But it's
working so we'll keep it. Also, BSD requires FUSE API to be at least version
2.5. After running configure you can check inside Makefiles if
proper CFLAGS and LDFLAGS appeared.
After adding this code, I've run a compilation test which ended good, if we
ignore the small, insignificant side effect due to link failure:
strndup() and getline() were missing! Damn GNU
extensions! So comfortable to use, that you'll forget about portability issues!
Ok, don't worry, we can rewrite it.
I know that rewriting libc functions does not seem to be the right thing,
but just in this case it is, as I can assure after reading on-line the bunch of
documentation talking about that. Especially a paper on Grid Computing on MacOS
X confirmed me that getline() is usually replaced with POSIX
fgets() and that strndup() is rewritten, probably,
using memcpy() as i did. This is the code:
#ifdef MACOSX
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
if (*lineptr == NULL)
*lineptr = calloc(sizeof(char), *n + 1);
if (*lineptr == NULL)
return 0;
if (fgets(*lineptr, *n, stream) == NULL)
*n = 0;
else
*n = strlen(*lineptr);
return *n;
}
char *strndup(const char *s, size_t n)
{
char *result = calloc(sizeof(char), n+1);
if (result == NULL)
return NULL;
memcpy(result, s, n);
result[n] = '\0';
return result;
}
#endifAfter adding this code to my project, compilation went good and now I have a
working tagsistant installation on a MacBook. It seemed a complete success, but
something happened to ruin everything. Something I've not yet solved.
mknod() is not working! Why the hell I'm not able to create a file
inside a tagsistant filesystem while everything else works and the same code
works perfectly under GNU/Linux? Files are stored inside the
~/.tagsistant/archive/ directory which is created with user's
permissions and ownership. Why it's failing? It's a MacFUSE security
restriction? I don't know so far, so if someone has some clue I would really
appreciate it.
Leave a comment