gstreamer移植qnx(二):交叉编译glib

2023-05-16

一、简介

​ 这里以glib的2.63.0版本,QNX系统的版本是:6.6 。这里是为了编译gstreamer的依赖库,也就是说最终目标,是将gstreamer移植到QNX6.6系统上。 我选择的是gstreamer 1.16,他需要的glib版本是2.40以上,因此就索性使用最新的glib版本。 编译用的host系统是Ubuntu18.04。

二、准备cross-file

​ 因为最新的glib其构建系统是使用的meson, 而我们这边是要交叉编译,所以需要准备一个cross-file的来配置交叉编译工具链

2.1 填写工具链

​ 首先是需要填写CPU和系统信息,以及工具链信息, 顺便还可以填写编译完成之后,安装的目录,其内容如下:

[host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'

[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'

[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'
      

2.2 填写编译flag信息

​ 第一个就是需要定义一个 _QNX_SOURCE宏,不然在编译和POSIX thread相关的部分时,就会出现“error: #error POSIX Scheduling needs P1003.1b-1993 or later” 这类似的错误。

[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = []

修改之后的完整版cross-file文件,qnx_arm.txt如下所示:

host_machine]
system = 'qnx'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'


[binaries]
c = 'arm-unknown-nto-qnx6.6.0eabi-gcc'
cpp = 'arm-unknown-nto-qnx6.6.0eabi-g++'
ar = 'arm-unknown-nto-qnx6.6.0eabi-ar'
strip = 'arm-unknown-nto-qnx6.6.0eabi-strip'


[properties]
c_args = ['-D_QNX_SOURCE=1']
c_link_args = []


[paths]
prefix = '/media/guwen/workspace/project/gstreamer/out'

三、 修改meson.build

​ 因为某些特性,qnx6.6的toolchain里面没有,比如xattr, 因此这里需要修改meson的option选项,这里有两种方式:

  • 直接在meson的命令行参数,以 -Dxattr=false的方式进
  • 修改glib里面的meson.build文件里面default_options部分

​ 这里为了方便,就选择了修改meson.build 文件,免得每次敲命令 都要带一长串参数。 当然,也可以把这个配置过程写到一个shell脚本里面。

​ 修改后的default_options如下所示:

  default_options : [
    'buildtype=release',
    'warning_level=1',
    'c_std=gnu99',
    'xattr=false',
    'force_posix_threads=true',
    'libmount=false'
  ]  
  

​ qnx的libintl没有ngettext这个函数,因此需要使用glib自带的libintl库,

​ 修改前的原始版本:

# First check in libc, fallback to libintl, and as last chance build
# proxy-libintl subproject.
# FIXME: glib-gettext.m4 has much more checks to detect broken/uncompatible
# implementations. This could be extended if issues are found in some platforms.
if cc.has_function('ngettext')
  libintl = []
  have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset')
else
  libintl = cc.find_library('intl', required : false)
  if not libintl.found()
    libintl = subproject('proxy-libintl').get_variable('intl_dep')
    have_bind_textdomain_codeset = true  # proxy-libintl supports it
  else
    have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset',
                                                  dependencies : libintl)
  endif
endif

​ 修改之后的版本:

# First check in libc, fallback to libintl, and as last chance build
# proxy-libintl subproject.
# FIXME: glib-gettext.m4 has much more checks to detect broken/uncompatible
# implementations. This could be extended if issues are found in some platforms.
if cc.has_function('ngettext')
  libintl = []
  have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset')
else
  #libintl = cc.find_library('intl', required : false)
  #if not libintl.found()
    libintl = subproject('proxy-libintl').get_variable('intl_dep')
    have_bind_textdomain_codeset = true  # proxy-libintl supports it
  #else
  #  have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset',
  #                                                 dependencies : libintl)
  #endif
endif

四、修改 gio目录下的内容

4.1 修改gio目录下的meson.build

​ 因为qnx里面没有libresolv,也没有libbind, res_query函数是在libsocket库里面。因此需要修改gio目录下的meson.build文件。

原始内容如下:

if host_system != 'windows'
  # res_query()
  res_query_test = '''#include <resolv.h>
                      int main (int argc, char ** argv) {
                        return res_query("test", 0, 0, (void *)0, 0);
                      }'''
  res_query_test_full = '''#include <sys/types.h>
                           #include <netinet/in.h>
                           #include <arpa/nameser.h>
                        ''' + res_query_test
  if not cc.links(res_query_test_full, name : 'res_query()')
    if cc.links(res_query_test_full, args : '-lresolv', name : 'res_query() in -lresolv')
      network_libs += [ cc.find_library('resolv') ]
      network_args += [ '-lresolv' ]
    elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind')
      network_libs += [ cc.find_library('bind') ]
      network_args += [ '-lbind' ]
    else
      error('Could not find res_query()')
    endif
  endif

  # socket()
  socket_test = '''#include <sys/types.h>
                   #include <sys/socket.h>
                   int main (int argc, char ** argv) {
                     return socket(1, 2, 3);
                   }'''
  if not cc.links(socket_test, name : 'socket()')
    if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket')
      network_libs += [ cc.find_library('socket') ]
      network_args += [ '-lsocket' ]
    else
      error('Could not find socket()')
    endif
  endif

修改之后如下:

if host_system != 'windows'
  # res_query()
  res_query_test = '''#include <resolv.h>
                      int main (int argc, char ** argv) {
                        return res_query("test", 0, 0, (void *)0, 0);
                      }'''
  res_query_test_full = '''#include <sys/types.h>
                           #include <netinet/in.h>
                           #include <arpa/nameser.h>
                        ''' + res_query_test
  if not cc.links(res_query_test_full, name : 'res_query()')
    if cc.links(res_query_test_full, args : '-lsocket', name : 'res_query() in -lsocket')
      network_libs += [ cc.find_library('socket') ]
      network_args += [ '-lsocket' ]
    elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind')
      network_libs += [ cc.find_library('bind') ]
      network_args += [ '-lbind' ]
    else
      error('Could not find res_query()')
    endif
  endif

  # socket()
  socket_test = '''#include <sys/types.h>
                   #include <sys/socket.h>
                   int main (int argc, char ** argv) {
                     return socket(1, 2, 3);
                   }'''
  if not cc.links(socket_test, name : 'socket()')
    if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket')
      network_libs += [ cc.find_library('socket') ]
      network_args += [ '-lsocket' ]
    else
      error('Could not find socket()')
    endif
  endif

4.2 修改gunixmounts.c

​ 因为glib没有实现qnx平台的 _g_get_unix_mounts 和 _g_get_unix_mount_points 以及get_mtab_monitor_file 函数,因此编译会出现如下错误:

…/gio/gunixmounts.c:954:2: error: #error No _g_get_unix_mounts() implementation for system
…/gio/gunixmounts.c:1477:2: error: #error No g_get_mount_table() implementation for system

​ 因此需要在 954行和1477行添加qnx版本的的实现,其实也不是实现,就是留个空,代码如下:

//在954行添加
/* Common code {{{2 */
#elif defined(__QNX__)
static GList* _g_get_unix_mounts (void)
{
    return NULL;
}

static const char* get_mtab_monitor_file (void)
{
	return NULL;
}

#else
#error No _g_get_unix_mounts() implementation for system
#endif


//在1477行添加
/* Common code {{{2 */
#elif defined(__QNX__)
static GList * _g_get_unix_mount_points (void)
{
    return NULL;
}

#else
#error No g_get_mount_table() implementation for system
#endif

五、编译过程

  • 新建build目录并进入build目录:
mkdir build
cd build
  • meson配置
meson .. --cross-file ../qnx_arm.txt
  • ninja编译和安装
ninja
ninja install
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gstreamer移植qnx(二):交叉编译glib 的相关文章

随机推荐

  • 【C++】类和对象-继承

    目录 一 继承基本方式 1 公 共 继 承 2 保 护 继 承 3 私 有 继 承 二 继承中的对象模型 三 继承中的构造和析构顺序 四 继承中同名成员处理方式 1 成员变量的处理方式 2 成员函数的处理方式 五 继承同名静态成员处理方式
  • Pytorch param.grad.data. 出现 AttributeError: ‘NoneType‘ object has no attribute ‘data‘

    程序中有需要优化的参数未参与前向传播
  • 大白话谈谈ChatGPT:多点人工,多点智能

    对于NLP领域 xff0c 本人也是门外汉 xff0c 就是最近了看到的博文 xff0c 记录自己的一些体会 ChatGPT简介 ChatGPT的全称是 34 Conversational Generative Pre training T
  • GO如何查看变量大小和数据类型

    如何查看一个变量的大小和数据类型 如何查看一个变量的大小和数据类型 paceage main import 34 fmt 34 34 unsafe 34 var n2 int64 61 10 fmt Printf 34 n2的类型 T n2
  • GO语言百分号参数

    常用 参数 v 值的默认格式 T 值得类型的GO语法表示 t 单词true或者false b 表示为二进制 c 该值对应的unicode码值 d 表示十进制 o 表示八进制 f 有小数部分但无指数部分 q 双引号输出
  • java第八节-重复执行

    import java util Scanner public class hello public static void main String args for System out println 34 hello 34 impor
  • java基础第九节-跳转控制语句-数组

    continue用在循环中 xff0c 基于条件控制 xff0c 跳过某次循环体内容的执行 xff0c 继续下一次的执行 break用在循环中 xff0c 基于条件控制 xff0c 终止循环体内容的执行 xff0c 结束当前的整个循环 数组
  • JAVA基础-基本类型转换

    int 和string的相互转换 1 int转换String public static String valuesOf int i 返回int参数的字符串表示形式 xff0c 该方法是String类的方法 1 String转换int pu
  • ubuntu系统-查看系统版本信息

    cat etc issue
  • Ubuntu查看cpu使用情况

    top命令查看cpu等信息 id是 xff1a 空闲 CPU 占用的 CPU 百分比
  • Ubuntu系统查看内存信息

    free命令查看内存信息 h 选项会在数字后面加上适于可读的单位 free h total xff1a 总物理内存大小 used xff1a 内存使用量 free xff1a 剩余可用内存
  • 嘉立创打样的阻抗匹配

    一 适用条件 最好使用4层板以上 xff0c 2层做匹配没啥意义 xff0c 套用大佬的话 主要是中间层和表层的距离近 xff0c 表层和中间层的玻璃纤维厚度是0 2mm xff0c 双层板最少是0 6mm xff0c 这里的差距很大 xf
  • echo 命令总结

    echo命令的功能是在显示器上显示一段文字 xff0c 一般起到一个提示的作用 此外 xff0c 也可以直接在文件中写入要写的内容 也可以用于脚本编程时显示某一个变量的值 xff0c 或者直接输出指定的字符串 echo命令的语法是 xff1
  • Android音频子系统(十三)------audio音频测试工具

    你好 xff01 这里是风筝的博客 xff0c 欢迎和我一起交流 测试音频延时的话 xff0c 一般使用WALT来测试是最为准确的 xff0c 他是借助了外部硬件来捕获音频信号 xff0c 某宝上有卖 xff1a 就是有丢丢小贵 xff0c
  • 一位北邮信通硕士的求职历程,看看 或许有帮助

    序 xff1a 写在前面的话 这篇文章的适用对象为 xff1a 非技术类方向的同学 xff0c 如果你是技术大牛 xff0c 你可以跳过这篇文章了 如果你觉得自己不喜欢技术或者技术不适合你 xff0c 此文或许会给你些有用的东西 简单介绍一
  • [转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二)

    紧接着上一篇文章 xff0c 如何合理处理多个串口接收大量数据 此种方法 xff0c 很厉害 xff0c 很NB xff0c 首先 xff0c 利用DMA 可节省大量CUP资源 其次 xff0c 利用IDLE空闲中断来接收位置个数的数据 最
  • [转]FreeRTOS消息队列、信号量、事件标志组、任务通知

    功能及区别列表 消息队列 xff08 需要传递消息时使用 xff09 在任务与任务间 中断和任务间传递信息 xff0c 可以数据传输 事件标志组 xff08 多个事件同步 xff0c 不需要传递消息时使用 xff09 实现任务与任务间 中断
  • ubuntu 终端打不开解决办法

    由于ubuntu自带的是python3 5 在新安装了python3 6以后 xff0c 开机突然发现无论是点击图标还是使用快捷键终端都无法打开 xff0c 解决办法如下 xff1a xff11 xff0e 按Ctrl 43 Alt 43
  • Jack server already installed in "/***/.jack-server" 异常

    xff08 1 xff09 在新增新用户后 xff0c 进行android编译 xff0c 出现如下异常 xff1a Ensure Jack server is installed and started FAILED bin bash c
  • gstreamer移植qnx(二):交叉编译glib

    一 简介 这里以glib的2 63 0版本 xff0c QNX系统的版本是 xff1a 6 6 这里是为了编译gstreamer的依赖库 xff0c 也就是说最终目标 xff0c 是将gstreamer移植到QNX6 6系统上 我选择的是g