libc++是什么? 

libc++是C++标准库的实现!

libc++ is an implementation of the C++ standard library, targeting C++11, C++14 and above.

https://libcxx.llvm.org/

gcc、libc、libstdc++的关系:

当你在linux下写C/C++代码的时候,是不是会遇到许多编译链接的问题? 时不时报个glibc,gcc,g++等相关的错误? 很多时候都无从下手,而且比较混乱。 这也是编译链接过程中经常出现的问题。

这篇文章不是去介绍如何编译链接,而是理清编译链接过程中碰到的一些概念和出现的问题。尤其是,libc,glib,glibc,eglibc,libc++,libstdc++,gcc,g++。

从libc说起。
libc是Linux下原来的标准C库,也就是当初写hello world时包含的头文件#include < stdio.h> 定义的地方。

后来逐渐被glibc取代,也就是传说中的GNU C Library,在此之前除了有libc,还有klibc,uclibc。现在只要知道用的最多的是glibc就行了,主流的一些linux操作系统如 Debian, Ubuntu,Redhat等用的都是glibc(或者其变种,下面会说到).

那glibc都做了些什么呢? glibc是Linux系统中最底层的API,几乎其它任何的运行库都要依赖glibc。 glibc最主要的功能就是对系统调用的封装,你想想看,你怎么能在C代码中直接用fopen函数就能打开文件? 打开文件最终还是要触发系统中的sys_open系统调用,而这中间的处理过程都是glibc来完成的。这篇文章详细介绍了glibc是如何与上层应用程序和系统调用交互的。除了封装系统调用,glibc自身也提供了一些上层应用函数必要的功能,如string,malloc,stdlib,linuxthreads,locale,signal等等。

好了,那eglibc又是什么? 这里的e是Embedded的意思,也就是前面说到的变种glibc。eglibc的主要特性是为了更好的支持嵌入式架构,可以支持不同的shell(包括嵌入式),但它是二进制兼容glibc的,就是说如果你的代码之前依赖eglibc库,那么换成glibc后也不需要重新编译。ubuntu系统用的就是eglibc(而不是glibc),不信,你执行 ldd –version 或者 /lib/i386-linux-gnu/libc.so.6
(64位系统运行/lib/x86_64-linux-gnu)看看,便会显示你系统中eglibc/glibc的版本信息。 这里提到了libc.so.6,这个文件就是eglibc/glibc编译后的生成库文件。

还有一个glib看起来也很相似,那它又是什么呢?glib也是个c程序库,不过比较轻量级,glib将C语言中的数据类型统一封装成自己的数据类型,提供了C语言常用的数据结构的定义以及处理函数,有趣的宏以及可移植的封装等(注:glib是可移植的,说明你可以在linux下,也可以在windows下使用它)。那它跟glibc有什么关系吗?其实并没有,除非你的程序代码会用到glib库中的数据结构或者函数,glib库在ubuntu系统中并不会默认安装(可以通过apt-get install libglib2.0-dev手动安装),著名的GTK+和Gnome底层用的都是glib库。想更详细了解glib? 可以参考这里

看到这里,你应该知道这些库有多重要了吧? 你写的C代码在编译的过程中有可能出现明明是这些库里面定义的变,却量还会出现’Undefined’, ‘Unreference’等错误,这时候你可能会怀疑是不是这些库出问题了? 是不是该动手换个gilbc/eglibc了? 这里强调一点,在你准备更换/升级这些库之前,你应该好好思考一下,你真的要更换/升级吗?你要知道你自己在做什么!你要时刻知道glibc/eglibc的影响有多大,不管你之前部署的什么程序,linux系统的ls,cd,mv,ps等等全都得依赖它,很多人在更换/升级都有过惨痛的教训,甚至让整个系统奔溃无法启动。所以,强烈不建议更换/升级这些库!

当然如果你写的是C++代码,还有两个库也要非常重视了,libc++/libstdc++,这两个库有关系吗?有。两个都是C++标准库。libc++是针对clang编译器特别重写的C++标准库,那libstdc++自然就是gcc的事儿了。libstdc++与gcc的关系就像clang与libc++. 其中的区别这里不作详细介绍了。

再说说libstdc++,glibc的关系。 libstdc++与gcc是捆绑在一起的,也就是说安装gcc的时候会把libstdc++装上。 那为什么glibc和gcc没有捆绑在一起呢?
相比glibc,libstdc++虽然提供了c++程序的标准库,但它并不与内核打交道。对于系统级别的事件,libstdc++首先是会与glibc交互,才能和内核通信。相比glibc来说,libstdc++就显得没那么基础了。

说完了这些库,这些库最终都是拿来干嘛的?当然是要将它们与你的程序链接在一起! 这时候就不得不说说gcc了(当然还有前文提到的clang以及llvm等编译器,本文就不细说它们的区别了)。

你写的C代码.c文件通过gcc首先转化为汇编.S文件,之后汇编器as将.S文件转化为机器代码.o文件,生成的.o文件再与其它.o文件,或者之前提到的libc.so.6库文件通过ld链接器链接在一块生成可执行文件。当然,在你编译代码使用gcc的时候,gcc命令已经帮你把这些细节全部做好了。

那g++是做什么的? 慢慢说来,不要以为gcc只能编译C代码,g++只能编译c++代码。 后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序;后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的。在编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,需要这样,gcc -lstdc++, 所以如果你的Makefile文件并没有手动加上libstdc++库,一般就会提示错误,要求你安装g++编译器了。

好了,就说到这,理清这些库与编译器之间的关系,相信会对你解决编译链接过程中遇到的错误起到一点帮助。

如果你的编译器不支持一些新的C/C++特性,想升级gcc/g++, 这里也给出一个基于ubuntu系统的参考方法。

添加ppa

  1. sudo add-apt-repository ppa:ubuntu-toolchain-r/test
  2. sudo apt-get update

添加ppa,是因为你所用的ubuntu版本的更新源中可能并没有你想要的gcc/g++版本。

安装新版gcc/g++

  1. sudo apt-get install gcc-4.8
  2. sudo apt-get install g++-4.8

可以到/usr/bin/gcc查看新安装的gcc,g++

配置系统gcc/g++

使用update-alternatives,统一更新gcc/g++

  1. sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6
  2. sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
  3. sudo update-alternatives --config gcc

数字优先级(如60,80)高的会被系统选择为默认的编译器,也可以执行第三条命令就是来手动配置系统的gcc,此处按照提示,选择4.8版本的即可。

原文地址:

https://blog.csdn.net/haibosdu/article/details/77094833

OSX - libc++究竟是啥?的更多相关文章

  1. IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

    1.前言 IM的群聊消息,究竟存1份(即扩散读方式)还是存多份(即扩散写方式)? 上一篇文章<IM群聊消息的已读回执功能该怎么实现?>是说,“很容易想到,是存一份”,被网友们骂了,大家争论 ...

  2. 熟悉的“if __name__ == '__main__':”究竟是啥?

    print(__name__) # 直接手动运行,打印"__main__",当做模块导入(别处import)时打印脚本名字即"name_main" if __n ...

  3. Java中数组和集合的foreach操作编译后究竟是啥

    今天和同事在关于foreach编译后是for循环还是迭代器有了不同意见,特做了个Demo,了解一下. 是啥自己来看吧! public class Demo { public static void m ...

  4. feed流拉取,读扩散,究竟是啥?

    from:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651961214&idx=1&sn=5e80ad6f2 ...

  5. Kafka无法消费!?究竟是bug的“沦陷”还是配置的“扭曲”?

    在一个月黑风高的夜晚,突然收到现网生产环境Kafka消息积压的告警,梦中惊醒啊,马上起来排查日志. 问题现象 消费请求卡死在查找Coordinator Coordinator为何物?Coordinat ...

  6. 究竟是.NET淹没在汪洋大海,还是人心的浮躁、见识的短浅?

    这些年来有相当多的.net开发者转了其他语言,也有一部分是迫不得已因为公司的转型而转,其中也有一大部分觉得.net没前途性能不好比某些语言性能差.还有一部分会说出一些名词去指责.net说他做不到,其实 ...

  7. 学了那么多 NoSQL 数据库 NoSQL 究竟是啥

    NoSQL 简史 NoSQL 一词最早出现于 1998 年,是 Carlo Strozzi 开发的一个轻量.开源.不提供 SQL 功能的关系数据库. 2009 年,Last.fm 的 Johan Os ...

  8. CPU被挖矿,Redis竟是内鬼!

    却说这一日,Redis正如往常一般工作,不久便收到了一条SAVE命令. 虽说这Redis常被用来当做缓存,数据只存在于内存中,却也能通过SAVE命令将内存中的数据保存到磁盘文件中以便持久化存储. 只见 ...

  9. 升级到iOS9之后的相关适配

    iOS9AdaptationTips(iOS9开发学习交流群:458884057) iOS9适配系列教程[中文在页面下方]转自@iOS程序犭袁 (截至2015年9月26日共有10篇,后续还将持续更新. ...

随机推荐

  1. dede中arcurl的解析

    有时候我们需要在dede中通过$dsql查询出文章数据,并生成文章的地址. 但是dede默认的dede_archives和附加表dede_addonarticle都没有存放arcurl的字段. 说明a ...

  2. 【SQL模板】一.修改/新增存储过程TSQL

    ---Name: 创建存储过程模板.sql ---Purpose: 用于创建 数据库中 新的存储过程 ---Author: xx ---Time: 2015-12-18 10:26:06 ---Rem ...

  3. Scrum使用心得 【转】

    原文链接: http://blog.sina.com.cn/s/blog_58db96bc0100ymuk.html 1      Scrum管理模式和传统管理模式的区别 这些管理模式本质上目的相同: ...

  4. Loadrunner12.5-同一个网址通过vugen不能打开,但是直接在ie11中就可以打开

    一:录制选项修改成“WinINet级别数据”,重新录制就可以成功打开网页了. 注:运行时设置--首选项--高级--“使用WinINet回放而非套接字(仅限Windows)”需要勾选上:否则录制脚本结束 ...

  5. geoserver 开发1

    打开项目,会看见下面这些包(其实还有很多插件之类的包,我都删除了) 5)可以从Eclipse启动GeoServer了. 如果你已经安装了GeoServer,现在也可以打开它的登陆页面进行操作. 三 结 ...

  6. laravel增删改查(查询构建器)

    1.增 $data = [ 'username' => 'xiaohong', 'nickname' => '小红红', 'email' => '12356788@qq.com', ...

  7. 数据帮助类DBhelper的定义

    数据库帮助类的使用DBhelperusing System;using System.Collections.Generic;using System.Text;using System.Data;u ...

  8. part1:1-embeded学习心态

    遇到问题,要冷静分析问题,采用排除法,个个排除查找问题之所在!切记!在没分析完自己问题之前,别把问题所在指向他人!

  9. Android 编译参数 LOCAL_MODULE_TAGS

    此参数会影响到库生成后的存放位置,影响生成位置的应该是相关平台下的变量PRODUCT_PACKAGES http://blog.csdn.net/evilcode/article/details/64 ...

  10. 2018.07.23 codeforces 438D. The Child and Sequence(线段树)

    传送门 线段树维护区间取模,单点修改,区间求和. 这题老套路了,对一个数来说,每次取模至少让它减少一半,这样每次单点修改对时间复杂度的贡献就是一个log" role="presen ...