gcc学习总结

gcc学习总结—詹坤林

2010 年 10 月


(一) gcc编译命令     
(1) 简单命令
    gcc  源代码文件xxx.c -o 可执行目标文件名
(2) 编译时链接动态、静态库命令
    C语言中有一些函数不需要进行编译,有一些函数也可以在多个文凭中使用。一般来说,这些函数都会执行一些标准任务,如数据库输入/输出操作或屏幕控制等。可以事先对这些函数进行编译,然后将它们放置在一些特殊的目标代码文件中,这些目标代码文件就称为库。库文件中的函数可以通过连接程序与应用程序进行连接。这样就不必在每次开发程序时都对这些通用的函数进行编译了。 
    库可以有三种使用的形式:静态、共享和动态。静态库的代码在编译时就已连接到开发人员开发的应用程序中,而共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。动态库则是共享库的另一种变化形式。动态库也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其它程序使用。由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。
    系统中可用的库都存放在/usr/lib和/lib目录中。库文件名由前缀lib和库名以及后缀组成。根据库的类型不同,后缀名也不一样。共享库的后缀名由.so和版本号组成,静态库的后缀名为.a。采用旧的a.out格式的共享库的后缀名为.sa。 
    libname.so.major.minor 
    libname.a 
    这里的name可以是任何字符串,用来唯一标识某个库。该字符串可以是一个单字、几个字符、甚至一个字母。数学共享库的库名为libm.so.5,这里的标识字符为m,版本号为5。libm.a则是静态数学库。X-Windows库名为libX11.so.6,这里使用X11作为库的标识,版本号为6。
    在gcc编译器中引用可搜索到的目录中的库文件时,需要使用-l选项和库名。例如在gcc命令行上输入-lm可以在程序中连接标准算术库, -l将首先使用libname.so进行搜索,这里是libm.so。下面的例子将使用算术库创建bookrecs程序,请注意这里的-lm选项。 
    
    gcc main.c io.c -o bookrecs -lm 
 
    放在/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。


    gcc main.c -L. -ltest -o main  该命令将链接当前目录.下的test库。


    注意:假若当前目录有一个test动态库,假如是文件libtest.so,编译时应该使用gcc main.c -L. -ltest -o main
          但是使用命令 gcc main.c libtest.so -o main 编译也不会出错,但是在运行./main时会出错,因为程序运行时
          是到/usr/lib和/lib中找库文件,而不到当前目录下寻找。此时就需要将库文件复制到/usr/lib中,这也说明程序
          运行时是需要动态库文件的。而假若是静态库,则不会出现此问题,因为编译时链接静态库会将静态库的代码链接
          到程序中。


(3)编译时指定头文件 


    -Ixxx 的意思是除了默认的头文件搜索路径(比如/usr/include,/usr/local/include等)外,同时还在路径xxx下搜索需要被引用的头文件。


    例如 gcc -I.  在当前目录下搜索头文件。 


例如:
[root@hdfs05 Cprograms]# ls
lib  main.c  Makefile  src
[root@hdfs05 Cprograms]# ls src
compute.c  compute.h {compute.h中声明了函数,compute.c是函数的具体定义}
[root@hdfs05 Cprograms]# gcc main.c src/compute.c -Isrc/ -o main
[root@hdfs05 Cprograms]# ./main
8+4=12.000000
8/4=2.000000


(4).gch文件
    头文件过大时,可以预编译头文件,加快编译速度,程序编译时首先找.gch文件
    gcc -c  compute.h
    将生成compute.h.gch


(5) 也可以Include ".c文件"


(6) 动态库(动态链接库)、静态库(静态链接)生成


实例:当前目录Cprograms下有一系列目录
include目录下放了头文件compute.h
src目录下放了compute.h中定义的函数的实现compute.c。其中可以include "compute.h",建议包含,因为可能用到声明的变量。也可以不用include "compute.h",这是因为函数的实现编译成库,在main.c程序中include "compute.h",调用头文件中标示的函数,只是起到一个指示作用,链接时会直接根据该指示载入库中的函数代码。
main中放了测试程序main.c,其中include "compute.h",调用了其中的函数
lib用于存放生成的库文件


[root@hdfs05 Cprograms]# gcc -c ./src/compute.c 
./src/compute.c:2:21: 错误:compute.h:没有那个文件或目录
[root@hdfs05 Cprograms]# gcc -c ./src/compute.c -I./include   生成.o文件
[root@hdfs05 Cprograms]# ar cr lib/libcom.a compute.o  在lib目录下生成静态库libcompute.a
[root@hdfs05 Cprograms]# gcc main/main.c -Llib -lcom -Iinclude -o x 编译Main.c为可执行文件x,注意一定要使用-I参数,否则编译不通过,或者可以将头文件复制到/usr/local/include下,gcc会自动搜索头文件


或者可以不使用库直接编译


gcc main/main.c src/compute.c -Iinclude -o main


以下内容摘自《An Introduction to GCC》


推荐如下使用


(1) 打开编译器警告选项“-Wall”可以捕捉到许多在C编程中最常发生的错误(waring all)。


  gcc -Wall *.c -o test  -Wall选项将打开常用的编译器警告,会打印程序警告。


(2) gcc中使用 -I 和 -L 控制头文件和库文件的搜索路径时的搜索次序


默认情况下,gcc在下面目录中搜索头文件:
/usr/local/include/
/usr/include/
在下面目录中搜索库:
/usr/local/lib/
/usr/lib/
搜索头文件的目录列表常被称为include路径,而搜索库的目录列表被称为搜索路径或链接路径。
在这些路径中的目录是按次序搜索的,在上面的两个列表中从第一个到最后一个。例如,“/usr/local/include”中找到的头文件优先于“/usr/include”中的同名文件。类似的,“/usr/local/lib”中找到的库优先于“/usr/lib”中的同名库。
当有其他库被安装到另外的目录中,为了能按序找到这些库,需要扩展搜索路径。编译器选项“-I”和“-L”用于把新目录添加到各自的include路径和库搜索路径的头上。


通过shell中的环境可以控制头文件和库的搜索路径。可以在每次开始shell会话的相应登录文件中,比如“.bash_profile”,自动地设置它们。
可以使用环境变量C_INCLUDE_PATH(针对C的头文件)或CPP_INCLUDE_PATH(针对C++的头文件)把其他目录添加到include路径中。
例如,当编译C程序时,下面的命令会把“/opt/gdbm-1.8.3/include”添加到include路径中:
$ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include
$ export C_INCLUDE_PATH
该目录将在命令行上用选项“-I”指定的任何目录之后,但在标准默认目录“/usr/local/include”和“/usr/include”之前被搜索。
Shell命令export是必要的,以便shell以外的程序也能获得该环境变量,比如象编译器----对每一次shell会话的每一个变量来说,只需要设一次,也可以在相应的登录文件中设置。
类似的,使用环境变量LIBRARY_PATH可以把另外的目录添加到链接路径中去。例如,下面的命令会把“/opt/gdbm-1.8.3/lib”添加到链接路径中:
$ LIBRARY_PATH=/opt/gdbm-1.8.3/lib
$ export LIBRARY_PATH
该目录将在命令行上用选项“-L”指定的任何目录之后,但在标准默认目录“/usr/local/lib”和“/usr/lib”之前被搜索。
环境变量被设置好以后,程序可以不用带“-I”和“-L”选项就能成功被编译,
$ gcc -Wall dbmain.c -lgdbm
因为现在默认路径包括了在环境变量C_INCLUDE_PATH和LIBRARY_PATH中指定的目录。


遵循标准Unix搜索路径的规范,搜索目录可以在环境变量中用冒号分隔的列表形式一起指定:
DIR1:DIR2:DIR3:...
这些目录被依次从左到右搜索。单个点“.”可以用来指示当前目录。7
例如,下面的设置把安装软件包的当前目录,及在“/optgdbm-1.8.3”和“/net”目录下各自的“include”,“lib”目录放到默认的include和链接路径中去:
$ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include
$ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib
在命令行上可以重复使用“-I”和“-L”选项来指定多个搜索路径的目录。例如,下面的命令,
$ gcc -I. -I/opt/gdbm-1.8.3/include -I/net/include -L. -L/opt/gdbm-1.8.3/lib -L/net/lib .....
等同于上面在环境变量中设置的。
当环境变量和命令行选项被同时使用时,编译器按下面的次序搜索目录:
1. 从左到右搜索由命令行“-I”和“-L”指定的目录
2. 由环境变量,比如C_INCLUDE_PATH和LIBRARY_PATH指定的目录
3. 默认的系统目录


(3) 使用“-static”选项可以迫使gcc静态链接,避免使用共享库,因为名字相同时,gcc首先是链接动态库


(4) 动态链接库的载入 


程序链接阶段链接了共享库的程序在运行的时候依赖于该共享库,在程序执行之前必须保证共享库已经载入了内存。
默认情况下,载入器仅在一些预定义的系统目录中查找共享库,比如“/usr/local/lib”和“/usr/lib”。如果库不在这些目录中,那它必须被添加到载入路径(load path)中去。
设置载入路径的最简单方法是通过环境变量LD_LIBRARY_PATH来设置需要载入的动态库的路径。
系统管理员可以为所有用户设置LD_LIBRARY_PATH变量,只要把它添加到默认的登录脚本中,比如象“/etc/profile”。
在GNU系统上,系统范围的路径也可以被定义在载入器配置文件“/etc/ld.so.conf”中,配置完毕执行命令ldconfig命令。


(5) gcc与ansi/iso标准


默认情况下,gcc编译程序用的是C语言的GNU“方言”(一种C语言的GNU实现),被称为GNU C。
该实现集成了C语言官方ANSI/ISO标准和一些有用的GNU对C语言的扩展。
gcc提供了一些控制该种C的“方言”的选项,最常用的选项有“-ansi”和“-pedantic”,并且“-std”命令能够指定程序遵循哪一个标准。


“-ansi”禁止那些与ANSI/ISO标准冲突的GNU扩展特性,如果GNU的扩展与ANSI/ISO标准不冲突,则不会被禁止。


有时候,一个合法的ANSI/ISO程序可能并不兼容于GNU C中的扩展特性。为了处理这种情况,编译器选项“-ansi”禁止那些与ANSI/ISO标准冲突的GNU扩展特性。在使用GNU C库(glibc)的系统上,该选项也禁止了对C标准库的扩展。这样就允许那些基于ANSI/ISO C编写的程序在没有任何来自GNU扩展的情况下编译。
例如,下面是一个合法的ANSI/ISO C程序,它用到一个名为asm的变量:
#include <stdio.h>
int
main (void)
{
const char asm[] = "6502";
printf ("the string asm is ’%s’\n", asm);
return 0;
}
变量名asm在ANSI/ISO标准中是合法的,但asm是GNU扩展的关键字(它允许C函数中使用本地汇编指令),所以该程序在GNU C下不能编译。因此,它不能用作变量名,会产生编译错。


“严格的ANSI/ISO标准”


同时使用命令行选项“-pedantic”和“-ansi”会导致gcc拒绝所有的GNU C扩展,而不单单是那些不兼容于ANSI/ISO标准的。


这有助于你写出遵循ANSI/ISO标准的可移植的程序。
下面是一个用到变长数组(一种GNU C扩展)的程序。数组x[n]被声明成具有整数变量n指定的长度。
int
main (int argc, char *argv[])
{
int i, n = argc;
double x[n];
for (i = 0; i < n; i++)
x[i] = i;
return 0;
}
由于GNU C支持变长数组并不会妨碍合法的ANSI/ISO程序的编译(这是一种向后兼容的扩展),该程序可以用“-ansi”编译,因为不冲突的扩展不会被禁止:
$ gcc -Wall -ansi gnuarray.c
但是,如果用“-ansi -pedantic”来编译,就会报有关违反了ANSI/ISO标准的警告,因为GNU C扩展部分并不是ANSI/ISO标准所规定的:
$ gcc -Wall -ansi -pedantic gnuarray.c
gnuarray.c: In function ‘main’:
gnuarray.c:5: warning: ISO C90 forbids variable-size


“选择指定标准”


可以用“-std”选项来控制GCC编译时采用的某个C语言标准。有下列C语言标准被支持:
‘-std=c89’ or ‘-std=iso9899:1990’
原来的ANSI/ISO语言标准(ANSI X3.159-1989,ISO/IEC 9899:1990)。GCC把两份ISO技术勘误表中的修正集成到这两份标准中。
‘-std=iso9899:199409’
1994年发布的ISO C语言标准的第一次修正版。该修正版主要涉及到国际化方面,比如为C库添加了多字节字符的支持。
‘-std=c99’ or ‘-std=iso9899:1999’
1999年发布的修正过的ISO C语言标准(ISO/IEC 9899:1999)。
附带GNU扩展的C语言标准可以用选项“-std=gnu89”和“-std=gnu99”来选择。






































        
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PyTorch 是一个用于科学计算和深度学习的 Python 库,它能够在 CPU 和 GPU 上高效地运行。PyTorch 通过使用类似 NumPy 的语法和动态计算图来简化了深度学习模型的实现。 CUDA 是 NVIDIA 开发的用于高性能计算的并行计算平台和编程模型,它使得程序能够在 NVIDIA GPU 上并行执行。CUDA 能够显著提高深度学习模型的训练速度。 GCC 是 GNU Compiler Collection 的缩写,它是一款优秀的开源编译器,支持多种编程语言,如 C、C++、Objective-C、Java、Ada 和 Fortran 等。在 Linux 上,GCC 通常是默认的 C/C++ 编译器。 PyTorch 可以与 CUDA 和 GCC 一起使用,以便在 GPU 上加速深度学习模型的训练和推断。要在 PyTorch 中使用 CUDA,您需要安装适当的 CUDA 版本和 CuDNN 库。要在 PyTorch 中使用 GCC,您需要确保安装了合适的版本,并且将其配置为默认编译器。 ### 回答2: PyTorch和CUDA GCC是不同的软件工具。PyTorch是一个用于深度学习的开源框架,而CUDA GCC是用于编译和优化CUDA代码的编译器工具。 PyTorch的版本与CUDA GCC的版本之间没有直接的对应关系。PyTorch有自己的版本号体系,用于区分不同的发布版本。每个PyTorch发布版本都可以兼容一定范围内的CUDA运行时版本。 而CUDA GCC的版本则与NVIDIA的CUDA Toolkit版本相关联。CUDA Toolkit提供了用于开发和运行CUDA应用程序的一系列工具和库。每个CUDA Toolkit版本都包含了特定的CUDA GCC版本,用于编译CUDA代码。 在选择PyTorch和CUDA GCC版本时,应该首先了解两者的兼容性。一般来说,PyTorch的官方文档会明确指出支持的CUDA版本范围。同时,NVIDIA官方也会在CUDA Toolkit的文档中列出支持的CUDA GCC版本。 为了确保PyTorch与CUDA GCC的兼容性,应该选择满足两者要求的版本。在安装PyTorch时,可以通过指定合适的CUDA版本来确保PyTorch与CUDA GCC的兼容性。 总结而言,PyTorch和CUDA GCC是两个相互独立的工具,没有直接的版本对应关系。在选择版本时,要注意PyTorch和CUDA GCC的兼容性,以确保代码的正常运行。 ### 回答3: PyTorch和CUDA的版本之间是有对应关系的。PyTorch是一个使用GPU加速的深度学习框架,而CUDA是NVIDIA公司提供的GPU并行计算平台和编程模型。 PyTorch的版本通常会与其所支持的CUDA版本相对应。PyTorch的每个主要版本都会明确声明其所需要的最低CUDA版本。比如,PyTorch 1.8版本需要CUDA 10.2及以上的版本。也就是说,如果想要使用PyTorch 1.8,必须安装CUDA 10.2或更高版本的驱动和库。 需要注意的是,CUDA版本与GPU型号是一一对应的,并非所有老旧的GPU都支持最新的CUDA版本。因此,在选择PyTorch和CUDA版本时,还要考虑自己的GPU型号是否与目标CUDA版本兼容。 另外,GCC(GNU Compiler Collection)是一套开源的编程语言编译器集合,其中包含了C、C++等语言的编译器。与PyTorch和CUDA的版本对应无关,GCC版本的选择主要取决于操作系统和具体的代码编译要求。通常情况下,PyTorch和CUDA的版本并不要求特定的GCC版本。 总结而言,PyTorch和CUDA的版本有对应关系,PyTorch会明确声明所需的最低CUDA版本。而GCC编译器的版本选择与PyTorch和CUDA的版本无关,主要依赖于操作系统和编译需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值