- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
gcc --version
g++ --version
gdb --version
sudo apt update
sudo apt install gcc g++ gdb
gcc -E hello.c -o hello.i # -E激活预处理,生成预处理后的文件
gcc -S hello.i -o hello.s # —S激活预处理和编译,生成汇编代码
gcc -c hello.s -o hello.o # -c激活预处理、编译和汇编,生成目标文件
gcc hello.o -o hello # 执行所有阶段,生成可执行程序
gcc -c hello.c # 生成目标文件,gcc会根据文件名hello.c生成hello.o
gcc hello.o -o hello # 生成可执行程序hello,这里我们需要指定可执行程序的名称,否则会默认生成a.out
gcc hello.c -o hello # 编译链接,生成可执行程序hello
gcc
和 g++
都是GNU(组织)
的一个编译器gcc
只能编译 c 代码,g++ 只能编译 c++ 代码
.c
的,gcc
把它当作是 C 程序,而 g++
当作是 c++
程序.cpp
的,两者都会认为是 C++
程序,C++
的语法规则更加严谨一些g++
会调用 gcc
,对于 C++
代码,两者是等价的,但是因为 gcc
命令不能自动和 C++
程序使用的库联接,所以通常用 g++
来完成链接,为了统一起见,干脆编译/链接统统用 g++
了,这就给人一种错觉,好像 cpp
程序只能用 g++
似的gcc
不会定义 __cplusplus
宏,而 g++
会
.c
,并且采用 gcc
编译器,则该宏就是未定义的,否则,就是已定义gcc
,链接只能用 g++
gcc/g++
,而链接可以用 g++
或者 gcc -lstdc++
gcc
命令不能自动和C++程序使用的库联接,所以通常使用 g++
来完成链接。但在编译阶段,g++
会自动调用 gcc
,二者等价1) #if [#elif] [#else] #endif
2) #ifdef [#elif] [#else] #endif
3) #ifndef [#elif] [#else] #endif
#if 常量表达式
...
#endif
当预处理器遇到 #if 指令时,会计算后面常量表达式的值。如果表达式的值为 0,则#if 与 #endif 之间的代码会在预处理阶段删除;否则,#if 与 #endif 之间的代码会被保留,交由编译器处理。 #if 指令常用于调试程序,如下所示:
#define DEBUG 1
...
#if DEBUG
printf("i = %d\n", i);
printf("j = %d\n", j);
#endif
是预处理器的一个运算符,它后面接标识符。如果标识符是一个定义过的宏则值为 1,否则值为 0。defined 运算符常和 #if 指令一起使用,比如:
#if defined(DEBUG)
...
#endif
仅当 DEBUG 被定义成宏时,#if 和 #endif 之间的代码会保留到程序中。defined 后面的括号不是必须的,因此可以写成这样: #if defined DEBUG defined 运算符仅检测 DEBUG 是否有被定义成宏,所以我们不需要给 DEBUG 赋值: #define DEBUG 。
#ifdef 标识符
...
#endif
当标识符有被定义成宏时,保留 #ifdef 与 #endif 之间的代码;否则,在预处理阶段删除 #ifdef 与 #endif 之间的代码。等价于:
#if defined(标识符)
...
#endif
#ifndef 标识符
...
#endif
它的作用恰恰与 #ifdef 相反:当标识符没有被定义成宏时,保留 #ifndef 与 #endif之间的代码.
下面的例子会根据 WIN32、MAC_OS 或 LINUX 是否被定义为宏,而将对应的代码包含到程序中:
#if defined(WIN32)
...
#elif defined(MAC_OS)
...
#elif defined(LINUX)
...
#endif
我们可以在程序的开头,定义这三个宏中的一个,从而选择一个特定的操作系统 。
我们可以检测一个宏是否被定义了,如果没有,则提供一个默认的定义:
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 1024
#endif
多次包含同一个头文件,可能会导致编译错误(比如,头文件中包含类型的定义)。因此,我们应该避免重复包含头文件。使用 #ifndef 和 #define 可以轻松实现这一点:
#ifndef __WD_FOO_H
#define __WD_FOO_H
typedef struct {
int id;
char name[25];
char gender;
int chinese;
int math;
int english;
} Student;
#endif
我们不能用 /.../ "注释掉" 已经包含 /.../注释的代码,即不能嵌套多行注释。但是我们可以用 #if 指令来实现:
#if 0
包含/*...*/注释的代码
#endif
注:这种屏蔽方式,我们称之为"条件屏蔽".
静态库
和动态库(共享库)
。区别是:
#include <stdio.h>
int add(int a, int b)
{
return a+b;
}
#include <stdio.h>
int sub(int a, int b)
{
return a-b;
}
#include <stdio.h>
int mul(int a, int b)
{
return a*b;
}
#include <stdio.h>
double div(int a, int b)
{
return (double)a/b;
}
#ifndef _HEAD_H
#define _HEAD_H
// 加法
int add(int a, int b);
// 减法
int sub(int a, int b);
// 乘法
int mul(int a, int b);
// 除法
double div(int a, int b);
#endif
#include <stdio.h>
#include "head.h"
int main()
{
int a = 20;
int b = 12;
printf("a = %d, b = %d\n", a, b);
printf("a + b = %d\n", add(a, b));
printf("a - b = %d\n", subtract(a, b));
printf("a * b = %d\n", multiply(a, b));
printf("a / b = %f\n", divide(a, b));
return 0;
}
tree
生成.o文件:gcc -c 文件名 。
将.o文件打包:ar rcs libxxx.a xx1.o xx2.o 。
需要提供静态库文件和相应的头文件 。
编译运行:gcc main.c -o app -I ./include -l calc -L ./lib 。
-I ./include:指定头文件目录,如果不指定,出现编译错误 。
-l calc:指定静态库名称,如果不指定,出现链接错误 。
-L ./lib:指定静态库位置,如果不指定,出现链接错误 。
正确执行(成功生成app可执行文件) 。
测试程序 。
规则 。
示例:有如下图所示文件(其中每个分文件用于实现四则运算),将其打包为动态库 。
生成.o文件:gcc -c -fpic 文件名 。
将.o文件打包:gcc -shared xx1.o xx2.o -o libxxx.so 。
需要提供动态库文件和相应的头文件 。
定位动态库(原因见工作原理->如何定位共享库文件,其中路径为动态库所在位置) 。
方法一:修改环境变量,当前终端生效,退出当前终端失效 。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib
方法二:修改环境变量,用户级别永久配置 。
# 修改~/.bashrc
vim ~/.bashrc
# 在~/.bashrc中添加下行,保存退出
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib
# 使修改生效
source ~/.bashrc
方法三:修改环境变量,系统级别永久配置 。
# 修改/etc/profile
sudo vim /etc/profile
# 在~/.bashrc中添加下行,保存退出
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/u/Desktop/Linux/calc/lib
# 使修改生效
source /etc/profile
方法四:修改/etc/ld.so.cache文件列表 。
# 修改/etc/ld.so.conf
sudo vim /etc/ld.so.conf
# 在/etc/ld.so.conf中添加下行,保存退出
/home/u/Desktop/Linux/calc/lib
# 更新配置
sudo ldconfig
有如下结构文件,其中main.c测试文件 。
配置环境变量 。
编译运行:gcc main.c -o app -I ./include -l calc -L ./lib 。
测试程序 。
如果不将动态库文件绝对路径加入环境变量,则会出现以下错误 。
静态库:GCC 进行链接时,会把静态库中代码打包到可执行程序中 。
动态库:GCC 进行链接时,动态库的代码不会被打包到可执行程序中 。
程序启动之后,动态库会被动态加载到内存中,通过 ldd (list dynamic dependencies)命令检查动态库依赖关系 。
如何定位共享库文件呢?
elf格式
的可执行程序,是由ld-linux.so
来完成的,它先后搜索elf文件
的 DT_RPATH
段 => 环境变量LD_LIBRARY_PATH
=> /etc/ld.so.cache文件列表
=> /lib/
,usr/lib
目录找到库文件后将其载入内存最后此篇关于gcc/g++编译的文章就讲到这里了,如果你想了解更多关于gcc/g++编译的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试在 Conda 环境中编译一些代码,在那里我 之前安装的编译包gcc_linux-64 . 然而,即使在停用和重新激活环境之后,gcc还在/usr/bin/gcc . 我该怎么做才能让 Co
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 7 年前。 Improve
这其实是两个问题: 1 - 在我的 debian amd64 系统上,我似乎无法构建与 gmp/mpfr/mpc 动态链接的交叉 GCC。即使我删除 --disable-shared,它也总是静态链接
研究ELF格式的结果,可以看到目标文件中有一个符号对应每个函数,对应的符号表项的值为st_size,表示大小的功能。 问题是,即使我更改了目标文件中特定函数的 st_size 并链接了它,但可执行文件
海湾合作委员会的 documentation for #line directives说他们是这样的: #line "myfile.cpp" 123 但是当我用 g++ 5.1 检查输出时,它们实际上
我正在使用 as 和 gcc 来汇编和创建 ARM 汇编程序的可执行文件,正如 this 所推荐的那样教程,如下: 给定一个汇编源文件,program.s,我运行: as -o program.o p
long long x; double n; x=long long(n); 这不起作用。什么是正确的方法? 最佳答案 显而易见的: x = (long long) n; 关于gcc - 转换为长长
我想知道用于 gcc 的原子内置函数的头文件是什么? 我想使用这 2 个函数为我当前创建的线程库实现互斥锁。 bool __sync_bool_compare_and_swap (type *ptr,
它出现在 another question :gcc调用的程序和部件是什么? (特别是在编译 C 或 C++ 时)以便有人可以设计一些拦截和更改流程的方案以用于各种自定义编码目的? 最佳答案 编译器二
可能吗?我想使用 gcc喜欢 assembler并在将其编译为 ubuntu 上的可执行文件后。 我尝试过这个: gcc a.asm -o out.o 来自 out.o文件编译成.out可执行文件。
我写了一个简单的 C 程序 test.c : #include #include int add(int a, int b); int main() { int i=5,j=10;
即。所以如果你使用任何八进制文字,它会给你一个警告。 微软编译器的同样问题。 如果没有,是否有任何其他工具可以检测八进制文字。 (vim 似乎有一个很酷的技巧,它突出了第一个领先的将不同的颜色归零,但
我在旧线程中搜索。但没有找到任何线程回答我的问题。 gcc 是否像 vc++ 一样支持函数级链接? 如果是,我应该提供什么选项来链接目标文件和库? 最佳答案 看起来 gcc 不直接支持函数级链接。您可
也许标题并没有把问题说得那么准确:我知道当我运行 gcc foo.c 时,GCC 会调用其他为它完成所有工作的子程序,从而生成主 gcc 程序只是一个界面。但这究竟是如何完成的呢? 它是否使用syst
我听说最近版本的 gcc 非常擅长将通过函数指针的调用转换为直接调用。但是,我在网上或快速浏览 gcc 的源代码上找不到任何关于它的信息。有谁知道这是否真的是真的,如果是这样,它使用什么算法来做到这一
gcc/g++ 链接器选项“-Map”生成的“.map”文件用于什么? 以及如何阅读它们? 最佳答案 我建议为您投入生产的任何软件生成一个映射文件并保留一份副本。 它可用于破译崩溃报告。根据系统的不同
gcc信息文件在有关x86-64特定标志的部分中说 其他事情: There is no `-march=generic' option because `-march' ind
我想知道 gcc 链接器选项(例如:-Wl,options)是否可以更改编译后的可执行文件中的汇编指令,因为如果您使用某些 gcc 优化选项会发生这种情况? 当您比较编译后的二进制文件(例如比较签名)
是否有GCC编译指示会停止,暂停或中止编译过程? 我正在使用gcc 4.1,但也希望在gcc 3.x版本上也可以使用该编译指示。 最佳答案 您可能需要#error: edd@ron:/tmp$ g++
当我使用gcc编译C程序时我通常使用 -g 将一些调试信息放入 elf 文件中这样 gdb 就可以在需要时帮助我。 但是,我注意到有些程序使用 -ggdb,因为它应该使调试信息对 gdb 更加友好。
我是一名优秀的程序员,十分优秀!