基于FS4412嵌入式系统移植(6) glib库的交叉编译与移植

今天和大家分享一下glib库的交叉编译过程和如何对程序进行编译以及运行。

glib库的移植资料比较少,比较零散,这里我就写一下亲自移植的过程,和大家分享一下。按照我的过程移植应该是不会有问题,如果遇到了问题可以留言联系我,一起讨论研究。

这里需要强调一下:libc、glibc、glib是不同的库!

glibc和 libc 都是 Linux 下的 C 函数库,而glib是GTK+的基础库

libc 是 Linux 下的 ANSI C 函数库;glibc 是 Linux 下的 GUN C 函数库。

具体的区分与概念可以参考:http://user.qzone.qq.com/452215612/2

先说一下我的上位机环境:

PC:XP sp3,深度完美 纯净标准版

虚拟机: VMware? Workstation,版本:9.0.2 build-1031769

ubuntu:12.04

在之前我已经在ubuntu上安装过glib2.0.6,并做了一些数据结构相关的教程,有兴趣的可以参考以下博文:http://blog.csdn.net/andylauren/article/category/6219334

开发板环境:

FS4412开发板:采用三星ARM Exynos 4412四核处理器,Linux3.14内核版本Uboot
2013.03
gcc-4.6.4交叉编译链

我们最终目的是在我们的开发板上能够执行使用了glib库的可执行文件。

要达到这个目的我们需要几个步骤:

1、需要使用交叉编译链交叉编译glib库;

2、将生成的动态库加入到文件系统的lib目录中;

3、使用交叉编译出来的glib库,交叉编译.c文件,然后在开发板中执行文件;

安装前准备:

glib源码包下载地址:http://ftp.gnome.org/pub/gnome/sources/glib/2.24/

这里我们使用的是glib-2.22.5.tar.gz

libffi源码包下载地址:https://www.sourceware.org/libffi/

libffi是glib的依赖库,所以需要先交叉编译这个库,我们使用的是libffi-3.2.1.tar.gz

pkg的安装:

pkg-config是一个很好的文本替换命令,主要用于编译命令上,用法下文会详细介绍

安装:apt-getinstall pkg-config

第一步:交叉编译glib库

在交叉编译glib前我们需要先交叉编译glib的依赖库libffi

1、libffi的安装

ffi是glib依赖的一个库,在交叉编译以前需要先交叉编译libffi

首先安装pc上的开发使用命令libffi-dev

键入:apt-getinstall libffi-dev    这一步为了解决configure时出现的问题,后文有介绍。

将libffi-3.2.1.tar.gz甩入ubuntu中

解压缩源码,并建立安装路径

这个没什么好看的,直接开始配置操作

键入:CC=arm-linux-gcc ./configure --prefix=/home/linux/glib/ffi/ --host=arm-linux

应该不会遇到任何问题,然后就会生成我们需要的Makefile文件。

然后就是三部曲中的

make

make insall

为了更好地在编译时使用自定义安装路径里的库,我们使用pkg-config来辅助我们编译glib,但要运行pkg-config,首先需要制作xx.pc文件:

我们先来到安装目录下的lib/pkgconfig目录下,里面有一个libffi.pc文件,由于这个库是给arm用的,所以我习惯在文件名后加上-arm:cp libffi.pc libffi-arm.pc

然后将libffi-arm.pc拷贝到/usr/local/lib/pkgconfig/下:cp libffi-arm.pc /usr/local/lib/pkgconfig/

这样pkg-config命令就可以识别到这个文件,大家可以先键入pkg-config --cflags libffi-arm看看会打印出什么呢?

-I/home/linux/glib/ffi/lib/libffi-3.2.1/include

这就是我们在交叉编译时需要用到的头文件路径。

2、交叉编译glib库

跟一般的安装一样,开始使用configure生成Makefile:

解压glib-2.22.5.tar.gz得到glib-2.22.5源码包目录。

先在glib-2.22.5目录下创建cache文件:gedit arm-linux.cache

然后在文件中输入:

glib_cv_stack_grows=no

glib_cv_uscore=no

ac_cv_func_posix_getpwuid_r=yes

ac_cv_func_posix_getgrgid_r=yes

glib_cv_have_qsort_r=no

运行configure的时候会从cache文件中读入配置,再将配置的log写入此文件

键入命令:CC=arm-linux-gcc ./configure --prefix=/home/linux/glib/glib-2.22/ --host=arm-linux --cache-file=arm-linux.cache

应该不会遇到任何问题,并生成了Makefile文件。

然后在glib目录下创建glib-2.22文件夹,用于保存生成的glib库文件。

然后就是三部曲中的

make

make insall

这个时候就会在glib-2.22文件夹下看到交叉编译好的glib库文件。里面会有bin,include,lib,share四个文件夹,分别有我们编译和运行时的文件和库。

第二步:将生成的动态库加入到文件系统的lib目录中

现在我们需要将编译好的glib动态库放到nfs文件系统的lib目录下,这样我们的程序在开发板上执行的时候就可以调用glib动态库了。

我们输入命令cp /home/linux/glib/glib-2.22/lib/libglib-2.0* /nfs/rootfs/lib/

这里我们将glib的所有库都拷贝到了nfs中,包括静态库,这是不必要的,我们只需要拷贝动态库就可以了。

其中文件libglib-2.0.so是一个硬链接,所以我们直接拷贝这个文件就会在nfs中得到一个库的副本文件。正确的做法是拷贝libglib-2.0.so.0.2200.5文件,并做两个硬链接到这个文件,连接文件分别是libglib-2.0.so.0和libglib-2.0.so。

其实正确的做法是使用cp -a命令,其中的-a参数相当于-dpR,保持文件的连接(d),保持原文件的属性(p)并作递归处理(R),所以应该输入:

cp -a /home/linux/glib/glib-2.22/lib/libglib-2.0* /nfs/rootfs/lib/

然后在删除静态编译库文件 libglib-2.0.la

rm  /home/linux/glib/glib-2.22/lib/libglib-2.0.la

第三步:使用交叉编译出来的glib库,交叉编译.c文件,然后在开发板中执行文件

我们现在拥有了glib的交叉编译库,而且在nfs文件系统中也有了动态库,我们需要使用一下这个库编译一个有glib函数的.C文件,并在开发板上运行起来。

我们从http://blog.csdn.net/andylauren/article/category/6219334中选择一个.c文件来作为我们的源程序,然后我们需要知道一些编译时的参数,比如头文件路径的设置,库文件路径的设置,在编译时使用
-I加上路径来表示头文件的路径,-L表示库文件的路径。

在ubuntu上我们编译glib库文件时使用的方法是gcc xxx.c -o xxx -lglib-2.0 这里的-o后面是生成的目标文件名,不是必须要的,如果不加会生成a.out文件,-l后面是我门使用的库文件名,是去掉了lib开头的库文件名,这里为什么我们没有使用-I -L呢,因为我们已经把这些文件放到了系统默认路径中,编译的时候会自动去默认路径下找相应的文件。交叉编译的时候我们也需要对应的书写编译命令,这里我先把命令写出来,然后在讲解,编译命令如下:

arm-linux-gcc GTree.c -o gtree-arm -I/home/linux/glib/glib-2.28/include/glib-2.0 -I/home/linux/glib/glib-2.28/lib/glib-2.0/include -L/home/linux/glib/glib-2.28/lib -lglib-2.0

其中arm-linux-gcc是交叉编译用的gcc,还有一个arm-none-linux-gnueabi-gcc命令,其实和它一模一样的,后边我们会对他进行讲解;

GTree.c 是我们要编译的源码文件,-o gtree-arm我们要生成的目标文件;

-I/home/linux/glib/glib-2.28/include/glib-2.0 -I/home/linux/glib/glib-2.28/lib/glib-2.0/include我们头文件路径;

-L/home/linux/glib/glib-2.28/lib我们库文件路径;

-lglib-2.0我们调用的库文件;

然后我们将生成的gtree-arm文件复制到nfs文件系统目录中,cp gtree-arm /nfs/rootfs

将开发板设置为nfs挂载,然后我们启动开发板,运行./gtree-arm,哈哈看到运行结果了,和电脑上的运行结果一样,表示我们移植成功了。

[[email protected] ]# ls
a.out              fs4412_led_app     mnt                sys
bin                fs4412_led_drv.ko  proc               tmp
dev                lib                root               usr
etc                linuxrc            sbin               var
[[email protected] ]# ./a.out
12345
[[email protected] ]# ls
a.out              fs4412_led_drv.ko  proc               usr
bin                gtree-arm          root               var
dev                lib                sbin
etc                linuxrc            sys
fs4412_led_app     mnt                tmp
[[email protected] ]# ./gtree-arm
BEGIN:
************************************************************
Now the tree:
Key:    0               Vaule:  zero
Key:    1               Vaule:  one
Key:    2               Vaule:  two
Key:    3               Vaule:  three
Key:    4               Vaule:  four
Key:    5               Vaule:  five
Key:    6               Vaule:  six
Key:    7               Vaule:  seven
Key:    8               Vaule:  eight
Key:    9               Vaule:  nine
The tree should have '10' items now.            Result: 10.
The height of tree is '4' now.
Now the vaule of '3' should be '3333' now.
Key:    0               Vaule:  zero
Key:    1               Vaule:  one
Key:    2               Vaule:  two
Key:    3               Vaule:  3333
Key:    4               Vaule:  four
Key:    5               Vaule:  five
Key:    6               Vaule:  six
Key:    7               Vaule:  seven
Key:    8               Vaule:  eight
Key:    9               Vaule:  nine
Now the vaule of '3' should be '3333' now[lookup].
The key '3' has been found and removed now.
Now the vaule which should be removed of '3' should be '(null)' now[search].
Now the tree look like:
Key:    0               Vaule:  zero
Key:    1               Vaule:  one
Key:    2               Vaule:  two
Key:    4               Vaule:  four
Key:    5               Vaule:  five
Key:    6               Vaule:  six
Key:    7               Vaule:  seven
Key:    8               Vaule:  eight
Key:    9               Vaule:  nine

************************************************************
DONE
[[email protected] ]# 

第一次移植血泪史:

下面我来讲一下我这次移植的过程中遇到的问题,可以说是一步一个砍,十步一个坑,坑里还有水,水里还有丁,进去就没影。感觉就像是体验了一次西天取经的99,81难一样。

首先在网上根本就找不到一个完整的glib移植的教程,有的也只是只言片语,我就这里摸索着前进。

第一劫:版本选择

首先我想我的ubuntu上安装的是glib2.0.6,那么我也是用这个进行移植吧,然后我就开始解压,配置./configure,然后遇到了根本找不到答案的问题,

checking for extra flags to get ANSI library prototypes... configure: error: cannot run test program while cross compiling

在网上根本找不到相应的解决办法,甚至于帖子都没有,没办法,我就换了版本,glib2.0.7,glib2.12,都是这样,都来我试着读了一下,意思是某个测试文件不能在交叉编译环境中运行,真的不知道是什么情况,我觉得应该,glib低版本和交叉编译链或者编译环境不匹配,或者低版本不支持交叉编译。

好,我换了最新版的glib2.48,报错缺少zlib的lib和头文件,换了多个版本,从glib2.32到glib2.28都是这样,最后我在网上找到一个帖子说glib-2.23开始就需要zlib,也就是我还需要交叉编译zlib,我想了想,这个zlib还不知道会遇到什么险阻,放弃最新版,反正我不是处女座,只要有个好用的库就可以了,不需要是最新的。然后就在2.23之后的版本选择了2.22.5版本。

这里我只是写了不到100字,但是应该能想象到我在做的时候一次次地下载,然后倒入ubuntu虚拟机,然后xvf解压,然后./configure,然后看着各种错误是的心情,我下载实验的版本不少于20个,很是崩溃。

第二劫:下载网址与autoconf

在开始的时候我通过他们提供的官方下载网址下载源码包,但是有的源码包中有configure文件,而有的只有configure.ac文件,这个configure.ac文件是需要autoconf工具去生成configure的,我怕我选择的版本有问题,所有特意安装了autoconf工具去生成configure。

这个时候问题又来了,autoconf工具生成configure过程中有报错,我的天啊,真是一波未平一波又起,但是我不打算进行问题嵌套处理,我就放弃了使用autoconf,然后我去找其他的下载源码包网站,终于我找到了一个网站,提供所有都带有configure文件的源码包,也就是我上面贴出来的那个网址。

当我遇到为了解决一个问题而去解决另一个问题的时候,我在想cpu进行中断嵌套的时候是一种什么心情呢?一定很崩溃,怪不得A9以后就不支持中断嵌套了呢。

第三劫:交叉编译参数

其实我也只是一个初学者,在学习的时候就使用的都是老师给配置好的环境,只要一个gcc都搞定,哪里用自己去找头文件,库文件。接触到了交叉编译之后这是一个过不去的坎,必须要能够自己指定头文件和库文件路径,这一劫还算是比较好过的,毕竟是基础知识,网上资料教程很多。

最后我在补充一个我自己发现的知识,那就是arm-linux-gcc和arm-none-linux-guneabi-gcc其实是同一个东西。

我们使用which arm-linux-gcc

看到/home/linux/sys/gcc-4.6.4/bin/arm-linux-gcc

说明arm-linux-gcc指向交叉编译链里的bin文件夹下的arm-linux-gcc

然后我们使用arm-linux-gcc -v

[email protected]:~/16021/glibDemo$ arm-linux-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gcc
COLLECT_LTO_WRAPPER=/home/linux/sys/gcc-4.6.4/bin/../libexec/gcc/arm-arm1176jzfssf-linux-gnueabi/4.6.4/lto-wrapper
Target: arm-arm1176jzfssf-linux-gnueabi
Configured with: /work/builddir/src/gcc-4.6.4/configure
--build=i686-build_pc-linux-gnu
--host=i686-build_pc-linux-gnu
--target=arm-arm1176jzfssf-linux-gnueabi
--prefix=/opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4
--with-sysroot=/opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/sysroot
--enable-languages=c,c++
--with-arch=armv6zk
--with-cpu=arm1176jzf-s
--with-tune=arm1176jzf-s
--with-fpu=vfp
--with-float=softfp
--with-pkgversion='crosstool-NG hg+default-2685dfa9de14 - tc0002'
--disable-sjlj-exceptions
--enable-__cxa_atexit
--disable-libmudflap
--disable-libgomp
--disable-libssp
--disable-libquadmath
--disable-libquadmath-support
--with-gmp=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-mpfr=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-mpc=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-ppl=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-cloog=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-libelf=/work/builddir/arm-arm1176jzfssf-linux-gnueabi/buildtools
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm'
--enable-threads=posix
--enable-target-optspace
--without-long-double-128
--disable-nls
--disable-multilib
--with-local-prefix=/opt/TuxamitoSoftToolchains/arm-arm1176jzfssf-linux-gnueabi/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/sysroot
--enable-c99
--enable-long-long
Thread model: posix
gcc version 4.6.4 (crosstool-NG hg+default-2685dfa9de14 - tc0002)

好了我们使用arm-none-linux-guneabi-gcc -v

与上面的返回一样,所有的路径都是一样的,最主要的是Target: arm-arm1176jzfssf-linux-gnueabi,目标都是一模一样的,所以以后我们在需要使用arm-none-linux-guneabi-的时候我们只需要使用arm-linux-就可以。

时间: 2024-10-31 20:01:57

基于FS4412嵌入式系统移植(6) glib库的交叉编译与移植的相关文章

基于FS4412嵌入式系统移植(8) linux内核调试之printk

以下内容主要摘录自<Linux安全体系分析与编程> 1.基本原理 (1)在UBOOT里设置console=ttySAC0或者console=tty1 这里是设置控制终端,tySAC0 表示串口, tty1 表示lcd (2)内核用printk打印 内核就会根据命令行参数来找到对应的硬件操作函数,并将信息通过对应的硬件终端打印出来! 2.printk及控制台的日志级别 函数printk的使用方法和printf相似,用于内核打印消息.printk根据日志级别(loglevel)对消息进行分类. 相

系列篇|编译可在Android上运行的依赖库(一):glib库

前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在“编译依赖库”一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库交叉编译到Android平台上才能成功的编译glib库,系列文章中除<编译可在Android上运行的glib库>外的其他交叉编译文章均是介绍如何对glib依赖库进行交叉编译.以上,所以叫系列文章,因为这些文章完整的介绍了如何编译可在Android上运行的glib库. 文章价值 这些文章的核心价值是

【课程分享】深入浅出嵌入式linux系统移植开发 (环境搭建、uboot的移植、嵌入式内核的配置与编译)

深入浅出嵌入式linux系统移植开发 (环境搭建.uboot的移植.嵌入式内核的配置与编译) 亲爱的网友,我这里有套课程想和大家分享,如果对这个课程有兴趣的,可以加我的QQ2059055336和我联系. 课程内容简介 本课程重点是给大家讲解嵌入式linux系统移植的开发方法,采用理论与实践,硬件与软件相结合的方法. 1.在每节开始之前先简单回顾上一节所讲的主要内容,并对本节所讲的内容先进行概述,讲解概念.技术要点,设计实现思路等内容,最后总结本次课程的要掌握的要点. 2.在讲课的过程中对关键技术

嵌入式系统移植三部曲 李炎朔

嵌入式系统移植三部曲                            李炎朔 09机应一班 学号0906041053 三部曲<bootloader的移植><linux的移植><根文件系统的移植> 一 bootloader的移植(1)安装skyeye-1.2.6_rc1 [[email protected] Desktop]# tar -xjvf skyeye-1.2.6_rc1.tar.bz2 -C ./[[email protected] Desktop]# c

嵌入式系统移植三部曲 吴素芬

计算机与信息工程学院  09级嵌入式  吴素芬 嵌入式系统移植三部曲 一.BootLoader的移植 二.linux的移植 三.根文件系统的移植 一.准备工作 (1).创建交叉编译环境 1.[[email protected] opt]# ll arm-linux-* -rwxr-xr-x 1 root root 36273634 06-13 12:21 arm-linux-gcc-2.95.3.tar.bz2 -rwxr-xr-x 1 root root 42745480 06-13 12:2

利用qemu模拟嵌入式系统制作全过程

http://www.tinylab.org/using-qemu-simulation-inserts-the-type-system-to-produce-the-whole-process/ 利用qemu模拟嵌入式系统制作全过程 by Pingbo Wen of TinyLab.org 2013/08/31 这篇文章,将介绍如何用qemu来搭建一个基于ARM的嵌入式linux系统.通过该文章,你可以学习到如何配置kernel,如何交叉编译 kernel,如何配置busybox并编译,如何制

嵌入式系统开发——开篇

嵌入式系统开发中,C语言的地位是无法取代的,所以我用C语言为自己建立一个常用功能函数库.在基于单片机的开发中,经常会遇到“以时间换空间”或者“以空间换时间”的抉择.因为单片机不是运算能力有限,就是存储空间有限! 尽管现如今基于ARM核的微处理器已经普及,其运算能力和存储能力相对于以前8位时代,可谓是翻天覆地!但作为软件开发者,希望自己所写代码能具备移植性的同时还要尽量高效,是一种境界.这对于提升自己的编程水平.对C语言的应用能力,不失为一个好方法. 我在这里记录下我常用的程序库,方便自己和他人查

利用 qemu 模拟嵌入式系统制作全过程

利用qemu模拟嵌入式系统制作全过程 by Pingbo Wen of TinyLab.org 2013/08/31 这篇文章将介绍如何用 Qemu 来搭建一个基于 ARM 的嵌入式 Linux 系统.通过该文章可以学习到如何配置和交叉编译 Kernel,如何配置 Busybox 并编译,如何制作 Initramfs,如何制作根文件系统,如何定制自己的 Uboot,如何通过 Uboot 向 Kernel 传递参数等.开始干活! 零.环境搭建 在实现我们的目标之前,我们需要搭建自己的工作环境.在这

热烈庆祝华清远见2014嵌入式系统(Linux&amp;Android)开发就业培训课程全面升级

近日,华清远见公开宣布:2014嵌入式系统 (Linux&Android)开发就业培训课程再次升级!据悉,华清远见如今已经持续10年,一直保持课程每年2次的更新的频率.华清远见的每 次课程更新都能够带给行业一些新的思路和方向,这次也不例外.通过知情人,我们了解到华清远见此次针对嵌入式培训和Anrdoid培训两个方向均有重大变 革. 首先,华清远见嵌入式系统 (Linux&Android)开发就业培训课程升级后主课程中全面采用自主研发的Cortex-A9 四核ARM硬件平台.这也是目前在嵌入