運行軟件的目標機器報錯:
./qt_cef_poc --no-sandbox --url=http://www.baidu.com ./qt_cef_poc: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./libstdc++.so.6)
$ strings /lib64/libc.so.6 | grep LIBCXX
GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 …
在目標機器上看他的libc.so.6支持的版本。或者grep libc。 發現最高支持到GLIBC 2.17
查看自己機器上的版本庫stackoverflow回答
1 libstdc++.so 版本
To find which library is being used you could run
(1) 方式一
$ /sbin/ldconfig -p | grep stdc++
libstdc++.so.6 (libc6) => /usr/lib/libstdc++.so.6
(2) 方式二
$ locate libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/3.4.6/libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/3.4.6/32/libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/32/libstdc++.so
/usr/lib64/libstdc++.so.5
/usr/lib64/libstdc++.so.5.0.7
/usr/lib64/libstdc++.so.6
/usr/lib64/libstdc++.so.6.0.13
其中,如果用 ll 仔細看,有些是軟鏈接,指向一個具體的版本,如 /usr/libstdc++.so.6 ( libstdc++.so.6 -> libstdc++.so.6.0.13 ),這個軟鏈接搜索過程是:鏈接程序ld-linux.so 先后搜索elf文件的 DT_RPATH段—環境變量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/, /usr/lib, /usr/lib64 …。
7.12 這個 libstdc++.so 版本所兼容的 GLIBC 版本
$ strings /usr/lib/libstdc++.so.6 | grep LIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
…
GLIBCXX_3.4.19
7.2 版本兼容
很多時候,我們在自己機器上編譯完成了 C/C++ 程序,但是放在其他機器上會出現類似 /usr/lib/libstdc++.so.6: version GLIBCXX_3.4.9' not found 這個錯誤。
[stackoverflow回答](https://stackoverflow.com/questions/4133674/glibcxx-versions)
就是說,GLIBCXX_3.4.* 這一系列版本都是想下兼容,高的版本可能做了 一些改動。那么 c 程序 link 的時候,會用到新版本的東西,就出現了這個錯誤。
用
readelf -a
對於c++ : readelf -aW <file> | c++filt
objdump -x
可以查看 c 程序里哪里用到了哪個版本的庫函數。
注: objdump命令的使用objdump命令是Linux下的反匯編目標文件或者可執行文件的命令。
在自己的編譯機器上查看:
程序引用的動態庫需要的libc版本:
ldd qt_cef_poc|grep libc.so.6
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb759fcf000)
程序自身elf文件需要的ligc版本
readelf -s qt_cef_poc | grep -oP "GLIBC_[\d\.]*" | sort | uniq GLIBC_ GLIBC_2 GLIBC_2.14 GLIBC_2.2.5 GLIBC_2.4
自己編譯機器上支持的libc到什么版本
strings /lib/x86_64-linux-gnu/libc.so.6 | grep libc
libc-2.23.so
用
readelf -a and
objdump -x` 可以查看 c 程序里哪里用到了哪個版本的庫函數。
注: objdump命令的使用objdump命令是Linux下的反匯編目標文件或者可執行文件的命令。
解決方法:
1, 鏈接靜態庫解決
1.在linux中用yum下載安裝glibc和libstdc++的靜態庫 sudo yum install glibc-static libstdc++-static 2.在編譯選項LDFLAGS中添加-static即可正常編譯運行。-satic會將所有庫都變成靜態的。gcc有內置加入libc的。參考:https://www.cnblogs.com/bigben0123/p/3304863.html
2,指定版本編譯: GLIBC GLIBC++庫。
這種情況,只有自己的代碼真的沒使用這些庫(不可能吧,如果沒使用,gcc也不會打包到最新版本???? )
有過這種情況,同樣的代碼,在低版本gcc編譯通過。在高版本也編譯通過。結果高版本的依賴的庫就是高版本。
3,在高級版本上,指定低級版本編譯。降級編譯。
-
查看libc/libc++庫的版本
`strings "/lib/libc.so.6" | grep LIBC` `strings "/lib/libstdc++.so.6" | grep LIBC` 把庫的路徑換成你機器的路徑即可
-
查看elf文件需要的庫的版本
`readelf -s ltrace | grep -oP "GLIBC_[\d\.]*" | sort | uniq` 把`-s`后面的文件換成你的程序
我是通過vs2015安裝的visualGDB遠程連接centos的linux系統作為開發環境的,因為正式服務器中glibc版本為2.12,而開發環境中的glibc版本為2.17,所以當編譯好的程序放到正式服中會報版本錯誤,一種解決方式是把正式服的glibc版本升級到最新版,但因為怕升級會引起其他問題,所以只能通過連接靜態庫增加程序大小的方式解決。
1.在linux中用yum下載安裝glibc和libstdc++的靜態庫
sudo yum install glibc-static libstdc++-static
2.在編譯選項LDFLAGS中添加-static即可正常編譯運行
CMake 指定gcc編譯版本
修改 CMakeLists.txt 文件,添加如下命令
SET(CMAKE_C_COMPILER “/home/hhb/gcc-5.2.0/bin/gcc”)
SET(CMAKE_CXX_COMPILER “/home/hhb/gcc-5.2.0/bin/g++”)
參考:
http://blog.csdn.net/amds123/article/details/53812133
更新:上面那個方法經實踐發現不行
使用下面的方法搞定了!
Do not overwrite CMAKE_C_COMPILER, but export CC (and CXX) before calling cmake:
export CC=/usr/local/bin/gcc export CXX=/usr/local/bin/g++ cmake /path/to/your/project make
參考:
https://stackoverflow.com/questions/17275348/how-to-specify-new-gcc-path-for-cmake
glibc、libc、gcc、g++
1、libc
C standard library
The C standard library or libc is the standard library for the C programming language, as specified in the ANSI C standard.[1] It was developed at the same time as the C library POSIX specification, which is a superset of it.[2][3] Since ANSI C was adopted by the International Organization for Standardization,[4] the C standard library is also called the ISO C library.
The C standard library provides macros, type definitions and functions for tasks such as string handling, mathematical computations, input/output processing, memory management, and several other operating system services.
ANSI
ANSI C, ISO C and Standard C refer to the successive standards for the C programming language published by the American National Standards Institute (ANSI) and the International Organization for Standardization (ISO). Historically, the names referred specifically to the original and best-supported version of the standard (known as C89 or C90). Software developers writing in C are encouraged to conform to the standards, as doing so helps portability between compilers.
2、glibc
2.1、wiki解釋
GNU C Library
“glibc” redirects here. It is not to be confused with GLib or Gnulib.
The GNU C Library, commonly known as glibc, is the GNU Project’s implementation of the C standard library. Despite its name, it now also directly supports C++ (and, indirectly, other programming languages). It was started in the early 1990s by the Free Software Foundation (FSF) for their GNU operating system.
Released under the GNU Lesser General Public License[3], glibc is free software.
GNU
GNU /ɡnuː/ (About this sound listen)[3][4] is an operating system[5][6][7] and an extensive collection of computer software. GNU is composed wholly of free software,[8][9][10] most of which is licensed under the GNU Project’s own GPL.
GNU is a recursive acronym for “GNU’s Not Unix!”,[8][11] chosen because GNU’s design is Unix-like, but differs from Unix by being free software and containing no Unix code.[8][12][13] The GNU project includes an operating system kernel, GNU HURD, which was the original focus of the Free Software Foundation (FSF).[8][14][15][16] However, non-GNU kernels, most famously Linux, can also be used with GNU software; as the Hurd kernel is not yet production-ready,[17] this is how the GNU system is usually used.[18][19] The combination of GNU software and the Linux kernel is commonly known as Linux (or less frequently GNU/Linux; see GNU/Linux naming controversy).
Richard Stallman, the founder of the project, views GNU as a “technical means to a social end”.[20] Relatedly Lawrence Lessig states in his introduction to the second edition of Stallman’s book Free Software, Free Society that in it Stallman has written about “the social aspects of software and how Free Software can create community and social justice.”[21]GNU Project
he GNU Project /ɡnuː/ (About this sound listen)[3] is a free-software, mass-collaboration project, first announced on September 27, 1983 by Richard Stallman at MIT. Its aim is to give computer users freedom and control in their use of their computers and computing devices, by collaboratively developing and providing software that is based on the following freedom rights: users are free to run the software, share it (copy, distribute), study it and modify it. GNU software guarantees these freedom-rights legally (via its license), and is therefore free software; the use of the word “free” always being taken to refer to freedom.
In order to ensure that the entire software of a computer grants its users all freedom rights (use, share, study, modify), even the most fundamental and important part, the operating system (including all its numerous utility programs), needed to be free software. According to its manifesto, the founding goal of the project was to build a free operating system and, if possible, “everything useful that normally comes with a Unix system so that one could get along without any software that is not free.” Stallman decided to call this operating system GNU (a recursive acronym meaning “GNU’s not Unix”), basing its design on that of Unix, a proprietary operating system.[4] Development was initiated in January 1984. In 1991, the kernel Linux appeared, developed outside the GNU project by Linus Torvalds,[5] and in December 1992 it was made available under version 2 of the GNU General Public License.[6] Combined with the operating system utilities already developed by the GNU project, it allowed for the first operating system that was free software, known as Linux or GNU/Linux.[7][8]
The project’s current work includes software development, awareness building, political campaigning and sharing of the new material.
2.2、gnu.org解釋
鏈接戳我
What is glibc?
The GNU C Library project provides the core libraries for the GNU system and GNU/Linux systems, as well as many other systems that use Linux as the kernel. These libraries provide critical APIs including ISO C11, POSIX.1-2008, BSD, OS-specific APIs and more. These APIs include such foundational facilities as open, read, write, malloc, printf, getaddrinfo, dlopen, pthread_create, crypt, login, exit and more.
The GNU C Library is designed to be a backwards compatible, portable, and high performance ISO C library. It aims to follow all relevant standards including ISO C11, POSIX.1-2008, and IEEE 754-2008.
The project was started circa 1988 and is almost 30 years old. You can see the complete project release history on the wiki.
Despite the project’s age there is still a lot to do so please Get Started and Get Involved!
Current Status
The GNU C Library releases every 6 months. See the NEWS file in the glibc sources for more information.
The current stable version of glibc is 2.26, released on August 2, 2017.
The current development version of glibc 2.27, releasing on or around February 1, 2018.
3、What’s the difference between glibc and libc6?
原鏈接
libc is the C library; basically, it contains all of the system functions that most (if not all) programs need to run on Linux. It’s similar to a combination of dos.library and exec.library on Amigas, but it also contains a lot of things that are in the C runtime library (like, for example, ixemul.library or the .lib files included with SAS/C and other compilers for AmigaOS).
libc6 and glibc are the same version of libc; officially, it’s version 2 of the GNU C Library (but it’s the sixth major version of the Linux C library). You can read more about glibc at the GNU C Library pages.
The major versions of libc for Linux/m68k are:
libc4: Version 4 of the C library is based on the a.out binary format; it was the first version to support dynamic linking (shared libraries). However, a.out dynamic linking had a lot of problems (for example, you had to build the library twice, so you could add a jump table to the library on the second pass, and the library was non-relocatable, so every library had to be allocated a block of space to load into), so it was abandoned (at least on m68k; Intel users may still need it for some esoteric applications). You should not be using libc4 for anything any more. If you do use it, we will hunt you down and execute you as an example to others. (Not really, but you get the point…)
libc5: Version 5 of the C library was a fairly big improvement over version 4. However, it still had some problems (adding new functions or changing structure sizes introduced subtle bugs) so it is no longer being actively developed. It was the first version of the Linux C Library based on ELF, a different file format that made programs loadable in more flexible ways (it uses hunks, similar to the AmigaOS executable file format). libc5 is officially deprecated on m68k; use libc6 for new compilations.
libc6: Version 6 of the Linux C Library is version 2 of the GNU C Library; the confusion is because Linux has had multiple C library versions. This is the newest technology available, and includes features (like “weak symbols”) that theoretically allow new functions and modified structures in the library without breaking existing code that uses version 6, and avoid kernel version dependency problems. You should be coding and compiling all code against this version.
4、What the role of libc(glibc) in our linux app?
原鏈接
libc implements both standard C functions like strcpy() and POSIX functions (which may be system calls) like getpid(). Note that not all standard C functions are in libc - most math functions are in libm.
You cannot directly make system calls in the same way that you call normal functions because calls to the kernel aren’t normal function calls, so they can’t be resolved by the linker. Instead, architecture-specific assembly language thunks are used to call into the kernel - you can of course write these directly in your own program too, but you don’t need to because libc provides them for you.
Note that in Linux it is the combination of the kernel and libc that provides the POSIX API. libc adds a decent amount of value - not every POSIX function is necessarily a system call, and for the ones that are, the kernel behaviour isn’t always POSIX conforming.
libc is a single library file (both .so and .a versions are available) and in most cases resides in /usr/lib. However, the glibc (GNU libc) project provides more than just libc - it also provides the libm mentioned earlier, and other core libraries like libpthread. So libc is just one of the libraries provided by glibc - and there are other alternate implementations of libc other than glibc.
5、GCC
5.1、wiki解釋
the GNU Compiler Collection
GNU編譯器套裝(英語:GNU Compiler Collection,縮寫為GCC),指一套編程語言編譯器,以GPL及LGPL許可證所發行的自由軟件,也是GNU項目的關鍵部分,也是GNU工具鏈的主要組成部分之一。GCC(特別是其中的C語言編譯器)也常被認為是跨平台編譯器的事實標准。1985年由理查德·馬修·斯托曼開始發展,現在由自由軟件基金會負責維護工作。
原名為GNU C語言編譯器(GNU C Compiler),因為它原本只能處理C語言。GCC在發布后很快地得到擴展,變得可處理C++。之后也變得可處理Fortran、Pascal、Objective-C、Java、Ada,Go與其他語言。
許多操作系統,包括許多類Unix系統,如Linux及BSD家族都采用GCC作為標准編譯器。蘋果電腦預裝的Mac OS X操作系統也采用這個編譯器。
GCC原本用C開發,后來因為LLVM、Clang的崛起,它更快地將開發語言轉換為C++。許多C的愛好者在對C++一知半解的情況下主觀認定C++的性能一定會輸給C,但是Taylor給出了不同的意見,並表明C++不但性能不輸給C,而且能設計出更好,更容易維護的程序(GCC’s move to C++)
5.2、gnu解釋
鏈接戳我
The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, and Go, as well as libraries for these languages (libstdc++,…). GCC was originally written as the compiler for the GNU operating system. The GNU system was developed to be 100% free software, free in the sense that it respects the user’s freedom.
We strive to provide regular, high quality releases, which we want to work well on a variety of native and cross targets (including GNU/Linux), and encourage everyone to contribute changes or help testing GCC. Our sources are readily and freely available via SVN and weekly snapshots.
Major decisions about GCC are made by the steering committee, guided by the mission statement.
6、gcc and g++
6.1stackoverflow回答
6.1.1 回答1
gcc and g++ are compiler-drivers of the ‘Gnu Compiler Collection’ (which was once upon a time just the ‘Gnu C Compiler’).
Even though they automatically determine which backends (cc1 cc1plus …) to call depending on the file-type, unless overridden with -x language, they have some differences.
The probably most important difference in their defaults is which libraries they link against automatically.
According to 1 and 2, g++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc (the 1st is a compiler option, the 2nd two are linker options). This can be checked by running both with the -v option (it displays the backend toolchain commands being run).
6.1.2 回答2
6.2 知乎回答
6.2.1 回答1
gcc 最開始的時候是 GNU C Compiler, 如你所知,就是一個c編譯器。但是后來因為這個項目里邊集成了更多其他不同語言的編譯器,GCC就代表 the GNU Compiler Collection,所以表示一堆編譯器的合集。 g++則是GCC的c++編譯器。現在你在編譯代碼時調用的gcc,已經不是當初那個c語言編譯器了,更確切的說他是一個驅動程序,根據代碼的后綴名來判斷調用c編譯器還是c++編譯器 (g++)。比如你的代碼后綴是*.c,他會調用c編譯器還有linker去鏈接c的library。如果你的代碼后綴是cpp, 他會調用g++編譯器,當然library call也是c++版本的。當然我說了這么多你可能感到有些混亂,沒關系,你就把gcc當成c語言編譯器,g++當成c++語言編譯器用就是了。
作者:李鋒
鏈接:https://www.zhihu.com/question/20940822/answer/16667772
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
6.2.2 回答2
一:gcc與g++比較
編譯c/c++代碼的時候,有人用gcc,有人用g++,於是各種說法都來了,譬如c代碼用gcc,而 c++代碼用g++,或者說編譯用gcc,鏈接用g++,一時也不知哪個說法正確,如果再遇上個extern “C”,分歧就更多了,這里我想作個了結,畢竟知識的目的是令人更清醒,而不是更糊塗。
誤區一:gcc只能編譯c代碼,g++只能編譯c++代碼兩者都可以,但是請注意:
1.后綴為.c的,gcc把它當作是C程序,而g++當作是c++程序;后綴為.cpp的,兩者都會認為是c++程序,注意,雖然c++是c的超集,但是兩者對語法的要求是有區別的,例如
<C++>
#include<stdio.h>
int main(int argc, char* argv[]) {
if(argv == 0) return;
printString(argv);
return 0;
}
int printString(char* string) {
sprintf(string, "This is a test.\n")
}
</C++>
如果按照C的語法規則,OK,沒問題,但是,一旦把后綴改為cpp,立刻報三個錯:
“printString未定義”;
“cannot convert char**' to
char*”;
”return-statement with no value“;
分別對應前面紅色標注的部分。可見C++的語法規則更加嚴謹一些。
2.編譯階段,g++會調用gcc,對於c++代碼,兩者是等價的,但是因為gcc命令不能自動和C++程序使用的庫聯接,所以通常用g++來完成鏈接,為了統一起見,干脆編譯/鏈接統統用g++了,這就給人一種錯覺,好像cpp程序只能用g++似的。
誤區二:gcc不會定義__cplusplus宏,而g++會
實際上,這個宏只是標志着編譯器將會把代碼按C還是C++語法來解釋,如上所述,如果后綴為.c,並且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。
誤區三:編譯只能用gcc,鏈接只能用g++
嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因為gcc命令不能自動和C++程序使用的庫聯接,所以通常使用g++來完成聯接。但在編譯階段,g++會自動調用gcc,二者等價。
誤區四:extern “C”與gcc/g++有關系
實際上並無關系,無論是gcc還是g++,用extern “c”時,都是以C的命名方式來為symbol命名,否則,都以c++方式命名。
二:gcc和g++的包含頭文件庫文件方法
-l參數就是用來指定程序要鏈接的庫,-l參數緊接着就是庫名,那么庫名跟真正的庫文件名有什么關系呢?就拿數學庫來說,他的庫名是m,他的庫文件名是libm.so,很容易看出,把庫文件名的頭lib和尾.so去掉就是庫名了。
好了現在我們知道怎么得到庫名,當我們自已要用到一個第三方提供的庫名字libtest.so,那么我們只要把 libtest.so拷貝到/usr/lib里,編譯時加上-ltest參數,我們就能用上libtest.so庫了(當然要用libtest.so庫里 的函數,我們還需要與libtest.so配套的頭文件)
放在/lib和/usr/lib和/usr/local/lib里的庫直接用-l參數就能鏈接了,但如果庫文件沒放 在這三個目錄里,而是放在其他目錄里,這時我們只用-l參數的話,鏈接還是會出錯,出錯信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是鏈接程序ld在那3個目錄里找不到libxxx.so,這時另外一個參數-L就派上用場了,比如常用的X11的庫,它在/usr /X11R6/lib目錄下,我們編譯時就要用-L/usr/X11R6/lib -lX11參數,-L參數跟着的是庫文件所在的目錄名。再比如我們把libtest.so放在/aaa/bbb/ccc目錄下,
那鏈接參數就是-L /aaa/bbb/ccc -ltest另外,大部分libxxxx.so只是一個鏈接,以RH9為例,比如libm.so它鏈接到/lib/libm.so.x,/lib/libm.so.6又鏈接到/lib/libm-2.3.2.so,如果沒有這樣的鏈接,還是會出錯,因為ld只會找libxxxx.so,所以如果你要用到xxxx庫,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一個鏈接就可以了ln -s libxxxx-x.x.x.so libxxxx.so
手工來寫鏈接參數總是很麻煩的,還好很多庫開發包提供了生成鏈接參數的程序,名字一般叫xxxx-config,一般放在/usr/bin目錄下,比如gtk1.2的鏈接參數生成程序是gtk-config,執行gtk-config –libs就能得到以下輸出”-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic-lgmodule -lglib -ldl -lXi -lXext -lX11 -lm”,這就是編譯一個gtk1.2程序所需的gtk鏈接參數,xxx-config除了–libs參數外還有一個參數是–cflags用來生成頭 文件包含目錄的,也就是-I參數,在下面我們將會講到。
你可以試試執行gtk-config –libs –cflags,看看輸出結果現在的問題就是怎樣用這些輸出結果了,最笨的方法就是復制粘貼或者照抄,聰明的辦法是在編譯命令行里加入這個 xxxx-config --libs --cflags
,比如編譯一個gtk程序:gcc gtktest.c gtk-config --libs --cflags
這樣就差不多了。注意`不是單引號,而是1鍵左邊那個鍵。
5、-include和-I參數
-include用來包含頭文件,但一般情況下包含頭文件都在源碼里用#include xxxxxx實現,-include參數很少用。-I參數是用來指定頭文件目錄,/usr/include目錄一般是不用指定的,gcc知道去那里找,但 是如果頭文件不在/usr/include里我們就要用-I參數指定了,比如頭文件放在/myinclude目錄里,那編譯命令行就要加上-I /myinclude參數了,如果不加你會得到一個”xxxx.h: No such file or directory”的錯誤。-I參數可以用相對路徑,比如頭文件在當前目錄,可以用-I.來指定。
結論例子: g++ curltest.cpp -o curltest -L/mnt/hgfs/windows/curl-7.19.5/lib/.libs -lcurl -I/mnt/hgfs/windows/curl-7.19.5/include
7、 版本兼容問題
Linux編譯不同版本glibc
方法步驟
- 在http://ftp.gnu.org/gnu/glibc/網站下載你需要的glibc版本
- 解壓下載的文件,同時在本目錄下創建一個bulid文件夾,在其他目錄下建立一個glibc-x.xx目錄:
tar -zxvf glibc-2.23.tar.gz cd glibc-2.23 mkdir build
- 進入build目錄,然后輸入下面的命令,文件的路徑自己確定:
cd build CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error=maybe-uninitialized" \ CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error=maybe-uninitialized" \ ../configure --prefix=/home/sir/cc-sir/glibc/glibc-2.23/ make make install
- 最后進行軟鏈接就可以:
sudo ln -s /home/sir/cc-sir/glibc-2.23/lib/ld-2.23.so 23-linux-x86-64.so.2
然后檢查/lib64目錄可以看到新增加的libc:
sir@sir-PC:~/desktop$ ls -l /lib64 總用量 0 lrwxrwxrwx 1 root root 42 4月 14 12:54 23-linux-x86-64.so.2 -> /home/sir/cc-sir/glibc-2.23/lib/ld-2.23.so lrwxrwxrwx 1 root root 42 4月 14 10:12 26-linux-x86-64.so.2 -> /home/sir/cc-sir/glibc-2.26/lib/ld-2.26.so lrwxrwxrwx 1 root root 32 11月 3 19:49 ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.27.so
如果編譯的glibc版本太低,在make的時候可能會出現一些問題,可能需要自己根據報錯的信息,修改源代碼;
報錯例子
nis_call.c: In function ‘nis_server_cache_add’: nis_call.c:682:6: error: suggest explicit braces to avoid ambiguous ‘else’ [-Werror=dangling-else] if (*loc != NULL) ^ cc1: all warnings being treated as errors make[2]: *** [../o-iterator.mk:9:/home/sir/cc-sir/glibc-2.23/nis/nis_call.o] 錯誤 1 make[2]: 離開目錄“/home/sir/tools/glibc-2.23/nis” make[1]: *** [Makefile:214:nis/others] 錯誤 2 make[1]: 離開目錄“/home/sir/tools/glibc-2.23” make: *** [Makefile:9:all] 錯誤 2
nis_call.cer文件中第682行的if語句沒有加‘{ }’,導致語義不明報錯,自行補上{ }就可以;
-o /home/sir/cc-sir/glibc-2.23/misc/regexp.os -MD -MP -MF /home/sir/cc-sir/glibc-2.23/misc/regexp.os.dt -MT /home/sir/cc-sir/glibc-2.23/misc/regexp.os
/tmp/cc2dus00.s: Assembler messages:
/tmp/cc2dus00.s: 錯誤:`loc1@GLIBC_2.2.5' can't be versioned to common symbol 'loc1' /tmp/cc2dus00.s: 錯誤:`loc2@GLIBC_2.2.5' can't be versioned to common symbol 'loc2' /tmp/cc2dus00.s: 錯誤:`locs@GLIBC_2.2.5' can't be versioned to common symbol 'locs' make[2]: *** [../o-iterator.mk:9:/home/sir/cc-sir/glibc-2.23/misc/regexp.os] 錯誤 1 make[2]: 離開目錄“/home/sir/tools/glibc-2.23/misc” make[1]: *** [Makefile:214:misc/subdir_lib] 錯誤 2 make[1]: 離開目錄“/home/sir/tools/glibc-2.23” make: *** [Makefile:9:all] 錯誤 2
將regexp.c源文件中的:
char *loc1 char *loc2 char *locs
修改為:
char *loc1 __attribute__ ((nocommon)); char *loc2 __attribute__ ((nocommon)); char *locs __attribute__ ((nocommon));
還有其他的報錯都大同小異,修改一下源代碼基本都可以解決…
我有已經修改好了的libc, 需要的可以私信…
有時候我們需要測試不同的glibc的性能,此時可以使用如下命令來指定動態庫加載器和glibc,
g++ test_log.c -Wl,--rpath=/usr/local/lib -Wl,--dynamic-linker=/usr/local/lib/ld-linux-x86-64.so.2
其中/usr/local/lib為glibc動態庫的路徑,linker為動態裝載器
以下test_log.c代碼為例
/* * learn for syslog/openlog * * * */ #include <syslog.h> #include <stdio.h> #include <stdlib.h> int main(int argc,char **argv) { //check the argc,usage e.g. ./a.out filename if(argc != 2){ perror("argc != 2"); exit(1); } openlog(argv[0],LOG_PID | LOG_NOWAIT | LOG_NDELAY,LOG_USER); syslog(LOG_INFO,"%s","hello,world"); closelog(); }
使用上述命令編譯后,可以用/usr/bin/ldd查看a.out依賴的動態庫
[jefby@localhost work]$ /usr/bin/ldd a.out linux-vdso.so.1 => (0x00007fff3d9ff000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003c67400000) libm.so.6 => /usr/local/lib/libm.so.6 (0x00007fdf9bc5c000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003c67000000) libc.so.6 => /usr/local/lib/libc.so.6 (0x00007fdf9b8b8000) /usr/local/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003c5a000000)
說明已經替換成功,運行
./a.out jefby
然后使用tail來查看是否成功寫入系統日志中
sudo tail /var/log/messages
如下所示,可以看到已經成功寫入:
[jefby@localhost work]$ ./a.out jefby [jefby@localhost work]$ sudo tail /var/log/messages -n 1 Aug 22 14:30:02 localhost ./a.out[12965]: hello,world