SylixOS之glib移植
来源:互联网 发布:瘦脸针副作用 知乎 编辑:程序博客网 时间:2024/06/14 00:25
glib中间件
glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。
glib是GTK+和GNOME工程的基础底层核心程序库,是一个综合用途的实用的轻量级的C程序库,它提供C语言的常用的数据结构的定义、相关的处理函数,有趣而实用的宏,可移植的封装和一些运行时机能,如事件循环、线程、动态调用、对象系统等的API。它能够在类UNIX的操作系统平台(如LINUX,HP-UNIX等),WINDOWS,OS2和BeOS等操作系统台上运行。
移植思路
移植Linux中间件到SylixOS上的思路请参考《TN0029_SylixOS第三方中间件移植方法》。
移植实现
glib源码包下载地http://ftp.gnome.org/pub/gnome/sources/glib/2.24/,使用的是glib-2.22.5.tar.gz。在Linux下编译glib需要libffi的支持,所以需要先交叉编译libffi库,使用的是libffi-3.2.1.tar.gz。libffi源码包下载地址:https://www.sourceware.org/libffi/。
在Linux下生成配置文件
根据评估了解glib工程比较大,采用一般方法直接移植编译问题太多,无法快速解决问题。在官网上了解glib库整个工程又分成三个小的工程,如图 31所示。
图 31 glib工程框架图
根据glib工程框架图可知,可以把整个分为三个模块:libgio、libgobject和libglib三个部分。
把官网下载的源码在Linux环境下编译执行,产生配置文件如图 32所示。
图 32 linux环境生成配置文件
自动配置产生了Makefile和config.h文件,这两个是移植的关键。根据图 31所示,把整个工程分成三个模块,在自动配置时,在各个模块下也生成各个模块的配置文件,如图 33、图 34、图 35所示。
图 33 libgio工程配置
图 34 libgobject工程配置
图 35 libglib工程配置
所以根据这三个模块下的Makefile分别编译libgio、libgobject和libglib这三个模块,最后在把这三个模块整合起来成为一个完整的glib库工程。
这样在Linux环境下生成了配置文件,然后把整个源码包导出。
移植到SylixOS
把源码工程导入到RealEvo-IDE开发环境上进行开发编译。
创建libgio模块工程
创建libgio工程,并把gio源码导入工程如图 36所示。
图 36 libgio工程
设置工程为专家模式,即手动修改Makefile。根据libgio模块下的Makefile配置工程的gio.mk,如图 37所示。然后编译工程根据错误提示修改。
图 37 libgio的gio.mk配置
创建libgobject模块工程
创建libgobject工程,并把gobject源码导入工程如图 38所示。
图 38 libgobject工程
设置工程为专家模式,即手动修改Makefile。根据libgobject模块下的Makefile配置工程的gobject.mk,如图 39所示。然后编译工程根据错误提示修改。
图 39 libobject的object.mk配置
创建libglib模块工程
创建libglib工程,并把libglib源码导入工程如图 310所示。
图 310 libglib工程
设置工程为专家模式,即手动修改Makefile。根据libglib模块下的Makefile配置工程的glib.mk,如图 311所示。然后编译工程根据错误提示修改。
图 311 libglib的glib.mk配置
模块整合
当三个模块编译都能通过时,进行工程整合如图 312所示。
图 312 libglib工程整合
把三个工程的*.mk的配置整合到libglib.mk上,如图 313所示。
图 313 libglib.mk整合
这样把三个工程整合起来初步编译时通过的,然后进行功能测试时,慢慢完善工程。
修改编译错误
1.
这边有些头文件加上这一句,因为这边暂未定义GIO_COMPILATION宏。
#if!defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
#error"Only <gio/gio.h> can be included directly."
#endif
编译时经常出现的错误,解决方法是在acoinfo.h中定义#define GIO_COMPILATION
__GIO_GIO_H_INSIDE__这个宏在gio.h中定义#define。
2.
GIO_MODULE_DIR(giomodule.c文件388行使用,未定义),这个在Linux下Makefile定义为安装目录下/lib/gio/modules的路径,在acoinfo.h中#define GIO_MODULE_DIR "/lib/modules";主要是为了加载路径下的模块。
3.
在glocalfileenumerator.c文件中使用dirent结构体与系统冲突。dirent结构体是存储短文件名信息,与glib不吻合。为编译使用,在acoinfo.h定义dirent结构体。
SylixOS结构体:
struct dirent {
char d_name[NAME_MAX + 1]; /* 文件名 */
unsignedchard_type; /* 文件类型 (可能为 DT_UNKNOWN)*/
chard_shortname[13]; /* fat 短文件名 (可能不存在) */
PVOID *d_resv; /* 保留 */
};
重新定义(在Linux下找出来的):
struct acoinfo_dirent
{
longd_ino; /* inode number 索引节点号 */
off_td_off; /* offset to this dirent在目录文件中的偏移 */
unsignedshortd_reclen; /* length of this d_name 文件名长 */
unsignedchard_type; /* the type of d_name 文件类型 */
chard_name [NAME_MAX+1]; /* file name (null-terminated)文件名,最长256字符 */
};
4.
times[0].tv_usec = statbuf.st_atim.tv_nsec / 1000;(glocalfileinfo.c文件2099行2132行974行985行996行)计算时间精度为微妙级,和Linux下不同,所以修改成SylixOS拥有的。
SylixOS结构体
struct stat {
dev_tst_dev/* device */
ino_tst_ino; /* inode */
mode_tst_mode; /* protection */
nlink_tst_nlink; /* number of hard links */
uid_tst_uid; /* user ID of owner */
gid_tst_gid; /* group ID of owner */
dev_tst_rdev; /* device type (if inode device)*/
off_tst_size; /* total size, in bytes */
time_tst_atime; /* time of last access */
time_tst_mtime; /* time of last modification */
time_tst_ctime; /* time of last create */
blksize_tst_blksize; /* blocksize for filesystem I/O */
blkcnt_tst_blocks; /* number of blocks allocated */
void *st_resv1;
void *st_resv2;
void *st_resv3;
};
Linux结构体
struct stat {
unsignedlong st_dev; /* Device. */
unsignedlong st_ino; /* File serial number. */
unsignedint st_mode; /* File mode. */
unsignedint st_nlink; /* Link count. */
unsignedint st_uid; /* User ID of the file's owner. */
unsignedint st_gid; /* Group ID of the file's group. */
unsignedlongst_rdev; /* Device number, if device. */
unsignedlong __pad1;
long st_size; /* Size of file, in bytes. */
int st_blksize; /* Optimal block size for I/O. */
int __pad2;
long st_blocks; /* Number 512-byte blocks allocated. */
long st_atime; /* Time of last access. */
unsignedlong st_atime_nsec;
long st_mtime; /* Time of last modification. */
unsignedlong st_mtime_nsec;
long st_ctime; /* Time of last status change. */
unsignedlong st_ctime_nsec;
unsignedint __unused4;
unsignedint __unused5;
};
5.
我们系统下没有libintl.h头文件,主要是用作数据窗口控件的。SylixOS暂时不支持,所以在config.h中关闭宏ENABLE_NLS。
6.
在giounix.c中未定义宏SSIZE_MAX,这个宏是在posix标准中定义,根据网上资料定义:#define SSIZE_MAX 32767。
7.
在xdgmime.h中Define定义很多函数名,为做到解决can not find symbol,重新定义函数名。修改例子如下:
#ifndef SYLIXOS
constchar xdg_mime_type_unknown[] = "application/octet-stream";
#else
constchar_gio_xdg_type_unknown[] = "application/octet-stream";
#endif
8.
在gio/inotify路径下:SylixOS下没有inotify,inotify主要功能是内核用于通知用户空间程序文件系统变化的机制。为了编译通过,在Linux上拷贝出inotify.h文件(该文件主要就是宏定义)。
9.
ssize_tgetxattr(constchar *path, constchar *name, void *value, size_tsize);
ssize_tlgetxattr(constchar *path, constchar *name, void *value, size_tsize);
ssize_tlistxattr(constchar *path, char *namebuf, size_tsize);
intfgetxattr(constintfd, constchar *xattr, char *value, size_tsize);
intsetxattr(constchar *path, constchar *name, char *value, size_tsize, inti);
ssize_tflistxattr(constintfd, char *list, gsizesize);
ssize_tllistxattr(constchar *path, char *namebuf, size_tsize);
intinotify_init1(intflags);
intinotify_init(void);
gint32inotify_add_watch(constintfd, constchar *path, guint32mask);
gint32inotify_rm_watch(constintfd, gint32wd);
struct mntent *getmntent (FILE *__stream);
这几个和文件系统有关的API,SylixOS暂时未实现,为编译通过做虚假实现。
10.
在glib/libcharset/localcharset.c文件中LIBDIR宏未定义,实际是在Makefile中定义为安装目录下的lib路径,所以在acoinfo.h定义如下:#define LIBDIR "/lib"。
11.
在文件gunixmounts.c中使用到setmntent和endmntent为linux自带函数,glib考虑到非linux环境使用,所以define换成通用的,如下所示:
#ifndef HAVE_SETMNTENT
#define setmntent(f,m) fopen(f,m)
#endif
#ifndef HAVE_ENDMNTENT
#define endmntent(f) fclose(f)
#endif
把HAVE_SETMNTENT和HAVE_ENDMNTENT关闭(该宏在config.h中379行定义)。
12.
gunixmounts.c中hasmntopt函数为挂载信息读取,SylixOS暂未实现。glib考虑不同系统使用,做了兼容考虑,可在config.h中关闭宏HAVE_HASMNTOPT(239行)。
13.
gdbus功能被删除(移植版本使用的是glib 2.22.5,没有gdbus功能 )。
14.
在测试glib时(测试程序/gio/tests/readwrite.c)一直不成功,在rename时出错。在/glib/gfileutils.c的1084行做出如下修改:
#ifdef SYLIXOS
g_unlink (filename);
#endif
原因:SylixOS的rename函数不支持删除新文件名的文件(rename(oldname, newname),两个文件名都存在,不能删除newname文件)。
移植总结
在评估移植时,要注意在官网上查看资料信息。官网一般会对工程移植做介绍,提示注意事项等。在修改SylixOS下的Makefile时,一定要学会查看源码下的Makefile。注意工程用到哪些*.c文件,定义了哪些宏(在编译时遇到一些宏未定义时可去Makefile中查看)。
移植还有一点需要注意就是细心和耐心!
- SylixOS之glib移植
- SylixOS下移植glib时clock_gettime函数分析
- SylixOS音频驱动移植
- SylixOS移植Boa服务器
- 移植libffi到SylixOS
- arm平台移植glib
- 移植glib到arm
- glib 移植依赖 libmount 移植
- SylixOS伯克利数据库移植笔记
- SylixOS的LCD驱动移植
- SylixOS中间件移植方法总结
- SylixOS SPI Flash驱动移植
- SylixOS下移植C++工程
- SylixOS ICAN 协议移植笔记
- SylixOS移植Redis库总结
- SylixOS之TFTP使用
- glib移植到ARM上
- Vxworks工程移植到SylixOS应用笔记
- JVM进阶(十三)——阶段回顾
- bom对象
- Linux下修改Mysql的用户(root)的密码
- 深入理解Java中的String
- 软件测试需要学习些什么技能
- SylixOS之glib移植
- Java NIO UDP发送接收数据
- android 反调试常见方法
- Android Studio常见问题以及解决方式
- 单链表快速排序
- 常用地道口语
- Vue2+VueRouter2+webpack 构建项目实战(二)目录以及文件结构
- android问题汇总2017
- C语言编程代码优化