在android 下支持c code写的开源软件真是一件费力的事情,原因是android 下的libc是uclib的一个子集,在移植过程中发现要实现libc没有但uclib有的一些函数,不然程序跑不起来。还有就是android .mk 需从新编写,来取代automake生成的makefile文件。
1. 编写android .mk
将ntfs-3g解压在externel目录下,在解压后的ntfs-3g目录下添加android.mk,可以参照externel目录下的其他软件包。本人也是参照一些模板,网上查了一些android.mk资料。对于静态库和应用程序这一条路的生成走通了。对于ntfs-3g内容如下
ifneq ($(TARGET_SIMULATOR), true)
LOCAL_PATH := $(call my-dir)
###################################################################
## For stage1, we have to make libfuse
###################################################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := /
libfuse-lite/fuse.c libfuse-lite/fusermount.c libfuse-lite/fuse_kern_chan.c libfuse-lite/fuse_loop.c/
libfuse-lite/fuse_lowlevel.c libfuse-lite/fuse_opt.c libfuse-lite/fuse_session.c libfuse-lite/fuse_signals.c/
libfuse-lite/helper.c libfuse-lite/mount.c libfuse-lite/mount_util.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/fuse-lite
LOCAL_CFLAGS := -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H
LOCAL_MODULE := libfuse
LOCAL_MODULE_TAGS :=
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
include $(BUILD_STATIC_LIBRARY)
###################################################################
## For stage2, we have to make libntfs-3g
###################################################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libntfs-3g/acls.c libntfs-3g/attrib.c libntfs-3g/attrlist.c libntfs-3g/bitmap.c/
libntfs-3g/bootsect.c libntfs-3g/cache.c libntfs-3g/collate.c libntfs-3g/compat.c libntfs-3g/compress.c /
libntfs-3g/debug.c libntfs-3g/device.c libntfs-3g/dir.c libntfs-3g/efs.c libntfs-3g/index.c libntfs-3g/inode.c/
libntfs-3g/lcnalloc.c libntfs-3g/logfile.c libntfs-3g/logging.c libntfs-3g/mft.c libntfs-3g/misc.c libntfs-3g/mst.c/
libntfs-3g/object_id.c libntfs-3g/reparse.c libntfs-3g/runlist.c libntfs-3g/security.c libntfs-3g/unistr.c/
libntfs-3g/unix_io.c libntfs-3g/volume.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/fuse-lite $(LOCAL_PATH)/include/ntfs-3g
LOCAL_CFLAGS := -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H
LOCAL_MODULE := libntfs-3g
LOCAL_MODULE_TAGS :=
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
include $(BUILD_STATIC_LIBRARY)
###################################################################
## For stage3, we make ntfs-3g
###################################################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := src/ntfs-3g.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/fuse-lite $(LOCAL_PATH)/include/ntfs-3g /
$(LOCAL_PATH)/src
LOCAL_CFLAGS := -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H
LOCAL_MODULE := ntfs-3g
LOCAL_MODULE_TAGS :=
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
LOCAL_STATIC_LIBRARIES := libfuse libntfs-3g
include $(BUILD_EXECUTABLE)
2. 修改源码
在 android .mk 顶层 添加 -DHAVE_CONFIG_H,支持config.h
config.h 添加
#define MOUNTED "/etc/mtab"
#define _PATH_MOUNTED "/etc/mtab"
去除(因anroid没有支持)
#define HAVE_SYS_STATVFS_H 1
#define HAVE_SETXATTR 1
ntfstime.h文件
删除 重复定义
struct timespec {
time_t tv_sec;
long tv_nsec;
} ;
fuse.h,fuse_lowlevel.h 关于#include <sys/statvfs.h>和引用struct statvfs的函数添加
#if HAVE_SYS_STATVFS_H
#endif 宏
libfuse-lite目录
fuse_misc.h 添加
typedef struct _pthread_rwlock_t
{
// struct _pthread_fastlock __rw_lock; /* Lock to guarantee mutual exclusion */
int __rw_readers; /* Number of readers */
// _pthread_descr __rw_writer; /* Identity of writer, or NULL if none */
// _pthread_descr __rw_read_waiting; /* Threads waiting for reading */
// _pthread_descr __rw_write_waiting; /* Threads waiting for writing */
int __rw_kind; /* Reader/Writer preference selection */
int __rw_pshared; /* Shared between processes or not */
} pthread_rwlock_t;
typedef struct
{
int __lockkind;
int __pshared;
} pthread_rwlockattr_t;
static inline int pthread_rwlock_init (pthread_rwlock_t * __rwlock,
pthread_rwlockattr_t *__attr)
{
return 1;
}
static inline int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
{
return 1;
}
/* Acquire read lock for RWLOCK. */
static inline int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
{
return 1;
}
/* Acquire write lock for RWLOCK. */
static inline int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
{
return 1;
}
fuse.c fuse_lowlevel.c引用struct statvfs的函数添加
#if HAVE_SYS_STATVFS_H
#endif 宏
fusermount.c 添加
struct mntent *getmntent_r (FILE *filep,
struct mntent *mnt, char *buff, int bufsize)
{
static const char sep[] = " /t/n";
char *cp, *ptrptr;
if (!filep || !mnt || !buff)
return NULL;
/* Loop on the file, skipping comment lines. - FvK 03/07/93 */
while ((cp = fgets(buff, bufsize, filep)) != NULL) {
if (buff[0] == '#' || buff[0] == '/n')
continue;
break;
}
/* At the EOF, the buffer should be unchanged. We should
* check the return value from fgets ().
*/
if (cp == NULL)
return NULL;
ptrptr = 0;
mnt->mnt_fsname = strtok_r(buff, sep, &ptrptr);
if (mnt->mnt_fsname == NULL)
return NULL;
mnt->mnt_dir = strtok_r(NULL, sep, &ptrptr);
if (mnt->mnt_dir == NULL)
return NULL;
mnt->mnt_type = strtok_r(NULL, sep, &ptrptr);
if (mnt->mnt_type == NULL)
return NULL;
mnt->mnt_opts = strtok_r(NULL, sep, &ptrptr);
if (mnt->mnt_opts == NULL)
mnt->mnt_opts = "";
cp = strtok_r(NULL, sep, &ptrptr);
mnt->mnt_freq = (cp != NULL) ? atoi(cp) : 0;
cp = strtok_r(NULL, sep, &ptrptr);
mnt->mnt_passno = (cp != NULL) ? atoi(cp) : 0;
return mnt;
}
struct mntent *getmntent(FILE * filep)
{
struct mntent *tmp;
static char *buff = NULL;
static struct mntent mnt;
// __UCLIBC_MUTEX_LOCK(mylock);
if (!buff) {
buff = malloc(BUFSIZ);
if (!buff)
abort();
}
tmp = getmntent_r(filep, &mnt, buff, BUFSIZ);
// __UCLIBC_MUTEX_UNLOCK(mylock);
return(tmp);
}
int addmntent(FILE * filep, const struct mntent *mnt)
{
if (fseek(filep, 0, SEEK_END) < 0)
return 1;
return (fprintf (filep, "%s %s %s %s %d %d/n", mnt->mnt_fsname, mnt->mnt_dir,
mnt->mnt_type, mnt->mnt_opts, mnt->mnt_freq, mnt->mnt_passno) < 0 ? 1 : 0);
}
char *hasmntopt(const struct mntent *mnt, const char *opt)
{
return strstr(mnt->mnt_opts, opt);
}
FILE *setmntent(const char *name, const char *mode)
{
return fopen(name, mode);
}
int endmntent(FILE * filep)
{
if (filep != NULL)
fclose(filep);
return 1;
}
libntfs-3g 目录
acls.c 删除 #include "secaudit.h"
security.c 的 ntfs_get_perm() 用#if 0 #endif屏蔽ntfs_allowed_access()直接return 1;
Src 目录
ntfs-3g.c
引用struct statvfs的函数添加
#if HAVE_SYS_STATVFS_H
#endif 宏
3. 总结
从上可以看出 android 对于c库支持还是比较弱,需要移植uclib中的实现函数才能支持一般linux 上的应用程序.