查看原文
其他

Java 程序员眼里的 gcc

IT服务圈儿 2023-02-06

The following article is from 低并发编程 Author 闪客

来源丨经授权转自 低并发编程(ID:dibingfa)

作者丨闪客


作为一名 Java 程序员,对 gcc 的基本使用总是记不住,很不熟练,今天写篇文章用最简单的方式记录下。



编译的过程



写个 hello.c 代码

#include <stdio.h>
#define STR "hello world\n"

void main() {
    printf(STR);
}


第一步:预处理(preprocess)

其实就是以下三个动作

1. 头文件展开2. 宏定义直接替换3. 条件编译不成立就去掉gcc -E hello.c -o hello.i


第二步:编译(compile)

转换成汇编语言

gcc -S hello.i -o hello.s


第三步:汇编(assemble)

转换成二进制(ELF relocatable)

gcc -c hello.s -o hello.o


第四步:链接(link)

具体分为动态链接和静态链接

# 动态链接
gcc hello.o -o hello
# 静态链接
gcc hello.o -o hello -static

 


静态库制作



写一个加法函数。

int add(int a, int b) {
    return a+b;
}

编译成 .o

gcc -c add.c -o add.o

制作成静态库

ar rcs libadd.a add.o

编写测试代码

#include <stdio.h>
void main(){
    printf("%d", add(1,2));
}

编译成可执行文件

#写法一
gcc test.c -o test libadd.a
#写法二
gcc test.c -o test -static -ladd -L ./

执行

./test
3


 

动态库制作



写一个加法函数。

int add(int a, int b) {
    return a+b;
}

编译成 .o

gcc -c add.c -o add.o -fPIC

制作成动态库

gcc -shared -o libadd.so add.o

上面两步也可以直接从源文件一步到位

gcc -fPIC -shared -o libadd.so add.c

编写测试代码

#include <stdio.h>
void main(){
    printf("%d", add(1,2));
}

编译成可执行文件

gcc test.c -o test -ladd -L ./

执行发现报错

./test
error while loading shared libraries: libadd.so: 
cannot open shared object file: No such file or directory

因为执行的时候找不到指定的动态库。


那我们把 libadd.so 放在执行时的动态库默认搜索路径下,比如 /lib64

cp libadd.so /lib64

再次执行就成功了

./test
3

查看二进制文件的链接信息,也可以发现我们的 libadd.so 生效了。

ldd test
   linux-vdso.so.1 =>  (0x00007ffe0f597000)
   libadd.so => /lib64/libadd.so (0x00007fa5ab29f000)
   libc.so.6 => /lib64/libc.so.6 (0x00007fa5aaed1000)
   /lib64/ld-linux-x86-64.so.2 (0x00007fa5ab4a1000)


好了,以上就是编译、静态库制作、动态库制作的过程,先记住这些 gcc 的基本常识,再去研究原理吧~




‍‍‍‍‍‍‍‍1、“我将 20 年前开发的操作系统迁移到 .NET 6,竟然成功了!”

2、面试官:请用Java实现一个HTTP请求

3、如何在编码阶段减少代码中的bug?

4、被唱衰的PHP,在这份排行榜一直稳坐第四

5、如何保证数据库和缓存双写一致性?

点分享

点点赞

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存