基于嵌入式Linux下GCC编译器__sync_sub_and_fetch_4错误的解决心得

*******************************************************************************************************************************************************

作者:EasyWave                                                                                                                      时间:2015.02.21

类别:Linux应用-嵌入式Linux下GCC编译器__sync_sub_and_fetch_4错误的解决心得    声明:转载,请保留链接

注意:如有错误,欢迎指正。这些是我学习的日志文章......

*******************************************************************************************************************************************************

一:多线程下变量的GCC原子操作

       原子操作就是不可再分的操作,在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制。在Linux系统中的GCC或者嵌入式Linux的交叉编译GCC中从4.1.2提供了__sync_*系列的built-in函数,用于提供加减和逻辑运算的原子操作。其声明如下所示:

这两组函数的区别在于第一组返回更新前的值,第二组返回更新后的值。注意:type可以是1,2,4或8字节长度的int类型,即:

int8_t        /      uint8_t

int16_t      /      uint16_t

int32_t      /      uint32_t

int64_t      /      uint64_t

这两组函数的后面的可扩展参数(...)用来指出哪些变量需要memory barrier,因为目前GCC实现的是full barrier(类似于linux
kernel 中的mb(),表示这个操作之前的所有内存操作不会被重排序到这个操作之后),所以可以略掉这个参数。

二:undefined reference to ‘__sync_sub_and_fetch_4‘ problem如何解决

在有些嵌入式Linux的交叉编译GCC环境中可能并没有这类进程下的原子操作函数,也有可能是uClibc库比较老的原因导致的,我在编译BlueZ时,就发现了当uClibc和GCC编译器版本太老时,有很多的系统函数是没有的,在编译BlueZ时会出现很多没有见过的错误。最难搞定就是undefined
reference to ‘__sync_sub_and_fetch_4‘ problem的错误,后来在国外的网站上发现一个解决方式,那就是到高版本中的GCC中下载一个linux_atomic.c文件,将其编译为一个静态库链接到你的具体编译的项目代码中可以解决这个错误。由于我的嵌入式Linux的GCC交叉编译工具比较低,还是4.3 的版本,也许在做交叉编译工具时并没有将线程下原子操作函数做进来而导致undefined
reference to ‘__sync_sub_and_fetch_4‘ problem的问题发生,在ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-4.6.0/下载一个4.6版本的GCC下来,如下所示:

对于相应的嵌入式Linux的线程下原子操作函数,一般是放在gcc/config/xxxx/linux-atomic.c下,xxxx就是不同的架构的目录,比如:ARM的平台,就是在gcc/config/arm/linux-atomic.c,如下所示:

采用libtool工具来编译linux-atomic.c文件,可以得到一个静态库,将这个静态库加入到你的实际项目中就可以解决这个问题,具体的做法如下:

#!/bin/bash

AR="arm-linux-uclibcgnueabi-ar"
RANLIB="arm-linux-uclibcgnueabi-ranlib"
CC="arm-linux-uclibcgnueabi-gcc"

libtool --tag=CC --mode=compile arm-linux-uclibcgnueabi-gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atmoic.lo linux-atomic.c
libtool --tag=CC --mode=link arm-linux-uclibcgnueabi-gcc -module -avoid-version -g -O2 -o liblinux-atmoic.la linux-atmoic.lo

我这里做了一个脚本,将其命名为:build.sh就可以了,将linux-atomic.c和build.sh放在同一目录下,然后执行./build.sh即可。具体的操作见下图所示:

最后将liblinux-atmoic.a加入到你的实际要编译的程序LIBS中即可。具体可以自己在LIBS="-llinux-atmoic"加入这选项。重新编译linux-atomic.c并且将其加入到要编译的项目中就可以解决undefined
reference to ‘__sync_sub_and_fetch_4‘ problem这类的错误。

时间: 2024-08-24 07:42:22

基于嵌入式Linux下GCC编译器__sync_sub_and_fetch_4错误的解决心得的相关文章

Linux下编译PHP常见错误及解决方法

1.configure: error: xml2-config not found. Please check your libxml2 installation.yum install libxml2-devel -y openssl-devel bzip2-devel curl-devel 2.configure: error: Cannot find OpenSSL's <evp.h> yum install openssl-devel 3.configure: error: Pleas

SOAP嵌入式linux下的应用(一)

作者:华清远见讲师 Simple Object Access Protocol(SOAP)简单对象访问协议,是交换数据的一种协议规范,是一种轻量的.简单的.基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息. 这里介绍soap嵌入式linux下的使用. 一.gSOAP 选择gSOAP的原因: gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多.绝大多数的C++we

嵌入式开发之GCC编译器使用

嵌入式开发之GCC编译器使用 Linux系统下GCC是GNU推出的功能强大的性能优越的多平台编译器,是GNU的代表作之一.GCC 可以在多种硬件平台上编译出可执行程序,其执行效率一般比其他编译器高%20到%30.GCC编译器能将C C++语言程序汇编程序编译,链接成可执行程序.在linux文件没有统一的后缀,系统从文件的属性来区分可执行程序和不可执行程序.  1.1GCC编译程序的四个阶段 预处理(Pre-Processing) 编译(Comping) 汇编(Assembing) 连接(Link

基于嵌入式Linux的千兆以太网卡驱动程序设计及测试

一. 引言 千兆以太网是一种具有高带宽和高响应的新网络技术,相关协议遵循IEEE 802.3规范标准.采用和10M以太网相似的帧格式.网络协议和布线系统,基于光纤和短距离同轴电缆的物理层介质,更适用于交换机.服务器等数据吞吐率大的设备.本文设计实现一种基于嵌入式Linux千兆以太网卡的驱动程序,并完成后续的测试工作和代码移植. 千兆以太网网卡工作在OSI网络架构的物理层和数据链路层,其中物理层由PHY芯片管理,数据链路层由千兆以太网控制器(GMAC)管理.硬件构架上,GMAC控制器由核心层.MT

linux下交叉编译器制作

目前我用的交叉编译器是TQ2440配套光盘中制作好了的,解压后需要如下配置: 1.对于Fedora系统:修改/etc/profile文件,在其中添加交叉编译器的环境变量的设置. 对于Ubuntu系统,修改/etc/enviroment文件 2.我用的是Fedora系统,修改PATH值,在其后添加上交叉编译器的路径,添加pathmunge /opt/EmbedSky/4.3.3/bin 对于Ubuntu系统,修改PATH="/usr/local/sbin:/usr/local/bin:/usr/s

Linux下gcc编译生成动态链接库*.so文件并调用它 是转载的

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助.1.动态库的编译 下面通过一个例子来介绍如何生成一个动态库.这里有一个头文件:so_test.h,三个.c文件:test_a.c.test_b.c.test_c.c,我们将这几个文件编译成一个动态库:libtest.so. //so_test.h:#include "stdio.h"

linux下gcc升级

由于最近公司老大安排对gcc进行升级,所以就整理下这篇文档,希望对有些盆友有些许帮助 1 安装gmp4.3.2 tar jxvf gmp-4.3.2.tar.bz2 mkdir /usr/local/gmp-4.3.2 cd /usr/local/gmp-4.3.2 /opt/gmp-4.3.2/configure --prefix=/usr/local/gmp-4.3.2 make  && make install 2 安装mpfr2.4.2 tar jxvf mpfr2.4.2.tar

Linux中gcc编译器的用法

在Linux环境下进行开发,gcc是非常重要的编译工具,所以学习gcc的基本常见用法时非常有必要的. 一.首先我们先说明下gcc编译源文件的后缀名类型 .c为后缀的文件,C语言源代码文件:  .a为后缀的文件,是由目标文件构成的档案库文件:  .C,.cc或.cxx 为后缀的文件,是C++源代码文件:  .h为后缀的文件,是程序所包含的头文件:  .i 为后缀的文件,是已经预处理过的C源代码文件:  .ii为后缀的文件,是已经预处理过的C++源代码文件:  .m为后缀的文件,是Objective

linux下挂载NTFS分区错误修复

今天在linux下打开win的NTFS硬盘总是提示出错了,而且是全部的NTFS盘都出错,其中sda1错误显示如下: Error mounting /dev/sda1 at /media/wangbo/24F02EECF02EC3C0: Command-line `mount -t "ntfs" -o "uhelper=udisks2,nodev,nosuid,uid=1000,gid=1000,dmask=0077,fmask=0177" "/dev/sd