1.glib中间件

glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。

glibGTK+GNOME工程的基础底层核心程序库,是一个综合用途的实用的轻量级的C程序库,它提供C语言的常用的数据结构的定义、相关的处理函数,有趣而实用的宏,可移植的封装和一些运行时机能,如事件循环、线程、动态调用、对象系统等的API。它能够在类UNIX的操作系统平台(如LINUXHP-UNIX等),WINDOWSOS2BeOS等操作系统台上运行。

2.移植思路

移植Linux中间件到SylixOS上的思路请参考《TN0029_SylixOS第三方中间件移植方法》。

3.移植实现

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.gzlibffi源码包下载地址:https://www.sourceware.org/libffi/

3.1在Linux下生成配置文件

根据评估了解glib工程比较大,采用一般方法直接移植编译问题太多,无法快速解决问题。在官网上了解glib库整个工程又分成三个小的工程,如 31所示。

SylixOS之glib库移植笔记 _第三方

图3-1 glib工程框架图

根据glib工程框架图可知,可以把整个分为三个模块:libgiolibgobjectlibglib三个部分。

把官网下载的源码在Linux环境下编译执行,产生配置文件如 32所示。

SylixOS之glib库移植笔记 _第三方_02

图 3-2  Linux环境生成配置文件

         自动配置产生了Makefileconfig.h文件,这两个是移植的关键。根据 31所示,把整个工程分成三个模块,在自动配置时,在各个模块下也生成各个模块的配置文件,如 33 34 35所示。

SylixOS之glib库移植笔记 _第三方_03

图 3-3  libgio工程配置

SylixOS之glib库移植笔记 _中间件_04

图 3-4  libgobject工程配置

SylixOS之glib库移植笔记 _中间件_05

图 3-5 libglib工程配置

         所以根据这三个模块下的Makefile分别编译libgiolibgobjectlibglib这三个模块,最后在把这三个模块整合起来成为一个完整的glib库工程。

这样在Linux环境下生成了配置文件,然后把整个源码包导出。

3.2移植到SylixOS

把源码工程导入到RealEvo-IDE开发环境上进行开发编译。

3.2.1创建libgio模块工程

创建libgio工程,并把gio源码导入工程如 36所示。

SylixOS之glib库移植笔记 _SylixOS_06

图 3-6 libgio工程

    设置工程为专家模式,即手动修改Makefile。根据libgio模块下的Makefile配置工程的gio.mk,如 37所示。然后编译工程根据错误提示修改。

  SylixOS之glib库移植笔记 _SylixOS_07

图 3-7 libgio的gio.mk配置

3.2.2创建libgobject模块工程

创建libgobject工程,并把gobject源码导入工程如 38所示。

SylixOS之glib库移植笔记 _SylixOS_08

图 3-8  libgobject工程

设置工程为专家模式,即手动修改Makefile。根据libgobject模块下的Makefile配置工程的gobject.mk,如 39所示。然后编译工程根据错误提示修改。

SylixOS之glib库移植笔记 _第三方_09

图 3-9 libobject的object.mk配置

3.2.3创建libglib模块工程

创建libglib工程,并把libglib源码导入工程如 310所示。

SylixOS之glib库移植笔记 _第三方_10

图 3-10 libglib工程

    设置工程为专家模式,即手动修改Makefile。根据libglib模块下的Makefile配置工程的glib.mk,如 311所示。然后编译工程根据错误提示修改。

SylixOS之glib库移植笔记 _中间件_11

图 3-11 libglib的glib.mk配置

当三个模块编译都能通过时,进行工程整合如 312所示。

SylixOS之glib库移植笔记 _第三方_12

图 3-12 libglib工程整合

把三个工程的*.mk的配置整合到libglib.mk上,如 313所示。

SylixOS之glib库移植笔记 _第三方_13

图 3-13 libglib.mk整合

这样把三个工程整合起来初步编译时通过的,然后进行功能测试时,慢慢完善工程。

3.2.5修改编译错误

        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_DIRgiomodule.c文件388行使用,未定义),这个在LinuxMakefile定义为安装目录下/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];                      /*  文件名                */          

    unsignedchar        d_type;                                       /*  文件类型 (可能为 DT_UNKNOWN)*/

    char                d_shortname[13];                              /*  fat 短文件名 (可能不存在)   */

    PVOID            *d_resv;                                       /*  保留                        */

};

重新定义(在Linux下找出来的):

struct acoinfo_dirent

{

         long            d_ino;                                     /* inode number 索引节点号 */

         off_t           d_off;                                      /* offset to this dirent 在目录文件中的偏移 */

         unsignedshort   d_reclen;                                    /* length of this d_name 文件名长 */

         unsignedchar   d_type;                                      /* the type of d_name 文件类型 */

         char           d_name [NAME_MAX+1];                     /* file name (null-terminated)文件名,最长256字符 */

};

4.

times[0].tv_usec = statbuf.st_atim.tv_nsec / 1000;glocalfileinfo.c文件20992132974985996行)计算时间精度为微妙级,和Linux下不同,所以修改成SylixOS拥有的。

SylixOS结构体

struct stat {

    dev_t         st_dev                                               /* device                       */

    ino_t         st_ino;                                               /* inode                        */

    mode_t        st_mode;                                            /* protection                   */

    nlink_t       st_nlink;                                              /* number of hard links         */

    uid_t         st_uid;                                               /* user ID of owner             */

    gid_t         st_gid;                                               /* group ID of owner            */

    dev_t         st_rdev;                                              /* device type (if inode device)*/

    off_t         st_size;                                               /* total size, in bytes         */

    time_t        st_atime;                                              /* time of last access          */

    time_t        st_mtime;                                             /* time of last modification    */

    time_t        st_ctime;                                              /* time of last create          */

    blksize_t     st_blksize;                                             /* blocksize for filesystem I/O */

    blkcnt_t      st_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. */

         unsignedlong     st_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.hDefine定义很多函数名,为做到解决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下没有inotifyinotify主要功能是内核用于通知用户空间程序文件系统变化的机制。为了编译通过,在Linux上拷贝出inotify.h文件(该文件主要就是宏定义)。

9.

ssize_t  getxattr(constchar *path, constchar *name, void *value, size_tsize)

ssize_t  lgetxattr(constchar *path, constchar *name, void *value, size_tsize)

ssize_t  listxattr(constchar *path, char *namebuf, size_tsize)

int     fgetxattr(constintfd, constchar *xattr, char *value, size_tsize)

int     setxattr(constchar *path, constchar *name, char *value, size_tsize, inti)

ssize_t  flistxattr(constintfd, char *list, gsizesize)

ssize_t  llistxattr(constchar *path, char *namebuf, size_tsize)

int     inotify_init1(intflags)

int     inotify_init(void)

gint32  inotify_add_watch(constintfd, constchar *path, guint32mask)

gint32  inotify_rm_watch(constintfd, gint32wd)

struct  mntent *getmntent (FILE *__stream)

这几个和文件系统有关的APISylixOS暂时未实现,为编译通过做虚假实现。

10.

glib/libcharset/localcharset.c文件中LIBDIR宏未定义,实际是在Makefile中定义为安装目录下的lib路径,所以在acoinfo.h定义如下:#define LIBDIR              "/lib"

11.

在文件gunixmounts.c中使用到setmntentendmntentlinux自带函数,glib考虑到非linux环境使用,所以define换成通用的,如下所示:

#ifndef HAVE_SETMNTENT

#define setmntent(f,m) fopen(f,m)

#endif

#ifndef HAVE_ENDMNTENT

#define endmntent(f) fclose(f)

#endif

HAVE_SETMNTENTHAVE_ENDMNTENT关闭(该宏在config.h379行定义)。

12.

gunixmounts.chasmntopt函数为挂载信息读取,SylixOS暂未实现。glib考虑不同系统使用,做了兼容考虑,可在config.h中关闭宏HAVE_HASMNTOPT239行)。

13.

gdbus功能被删除(移植版本使用的是glib 2.22.5,没有gdbus功能)。

14.

在测试glib时(测试程序/gio/tests/readwrite.c)一直不成功,在rename时出错。在/glib/gfileutils.c1084行做出如下修改:

#ifdef SYLIXOS

  g_unlink (filename);

#endif

原因:SylixOSrename函数不支持删除新文件名的文件(renameoldname, newname),两个文件名都存在,不能删除newname文件)。

4.移植总结

在评估移植时,要注意在官网上查看资料信息。官网一般会对工程移植做介绍,提示注意事项等。在修改SylixOS下的Makefile时,一定要学会查看源码下的Makefile。注意工程用到哪些*.c文件,定义了哪些宏(在编译时遇到一些宏未定义时可去Makefile中查看)。

移植还有一点需要注意就是细心和耐心!