linux文件编译与调试

声明:这里实际用的是g++不过2者一样参数差不多,亲测可用。
编译过程
源代码–>预处理–>编译–>汇编–>链接–>可执行文件
源代码不用多说,保证没有错就行。
预处理

#include<iostream>
using namespace std;
int main()
{
    int a[100];
    int n = 0;
    int max;
    int num=0;
    cin >> n;
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
    }
    cin >> max;
    max += 30;
    for (int i = 0; i < n; ++i)
    {
        if (a[i] <= max)
            num++;
    }
    cout << num;
    return 0;
}

这是自己写的源码,有点粗糙,文件名叫main1.c

g++ main1.c -o main1.i -E

-o为output,-E表示只进行预处理 输出为main1.i文件(.i文件为预处理后的文件)

# 2 "main1.c"
using namespace std;
int main()
{
 int a[100];
 int n = 0;
 int max;
 int num=0;
 cin >> n;
 for (int i = 0; i < n; ++i)
 {
  cin >> a[i];
 }
 cin >> max;
 max += 30;
 for (int i = 0; i < n; ++i)
 {
  if (a[i] <= max)
   num++;
 }
 cout << num;
 return 0;
}

前面省去了一大堆不懂得东西,其实这一步骤就是做一些替换。把头文件替换掉,声明之类的替换掉。
编译

g++ main1.i -o main1.s -S

输出文件为

    .file   "main1.c"
    .section    .rodata
    .type   _ZStL19piecewise_construct, @object
    .size   _ZStL19piecewise_construct, 1
_ZStL19piecewise_construct:
    .zero   1
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .text
    .globl  main
    .type   main, @function
main:
.LFB1455:
    .cfi_startproc
    leal    4(%esp), %ecx
    .cfi_def_cfa 1, 0
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    .cfi_escape 0x10,0x5,0x2,0x75,0
    movl    %esp, %ebp
    pushl   %ebx
    pushl   %ecx
    .cfi_escape 0xf,0x3,0x75,0x78,0x6
    .cfi_escape 0x10,0x3,0x2,0x75,0x7c
    subl    $432, %esp
    call    __x86.get_pc_thunk.bx
    addl    $_GLOBAL_OFFSET_TABLE_, %ebx
    movl    $0, -424(%ebp)
    movl    $0, -12(%ebp)
    subl    $8, %esp
    leal    -424(%ebp), %eax
    pushl   %eax
    movl    _ZSt3cin@GOT(%ebx), %eax
    pushl   %eax
    call    _ZNSirsERi@PLT
    addl    $16, %esp
    movl    $0, -16(%ebp)
.L3:
    movl    -424(%ebp), %eax

这一步其实就是把原本的语言替换为汇编语言。
汇编

g++ main1.s -o main1.o -c

用-c参数输出为.o文件
这里写图片描述
很显然到这一步已经变成二进制文件了不过这一步的二进制文件不能执行

root@kali:~/桌面# g++ main1.o -o main1
root@kali:~/桌面# ./main1

就能执行了


函数库
linux存在好多苦存放在/usr/lib目录下。不过想要你的库能被查找到还要按照格式命名。
库名字以lib开头,随后指明是什么库,最后加.a或.so (.a表示静态库,.so表示共享库)
libm.so表示数学的共享库。

gcc -o hello hello.c /usr/lib/libm.a

除搜索标准c语言函数库外还搜索数学库已解决引用问题跟下面命令作用相同

gcc -o hello hello.c -lm

/usr/lib/libm.a可以简写为-lm
另外,-L可以增加搜索路径

gcc -o hello hello.c -L/usr/openwin/lib -lx11

更改了搜索目录,从原本的/usr/lib改成了/usr/openwin/lib


建立小型函数库
首先建立.c文件 分别为pro1.c pro2.c分别包含一个函数

root@kali:~/桌面# cat pro1.c
#include<stdio.h>
void pro1(int arg)
{
    printf("hello:%d\n",arg);
}
root@kali:~/桌面# cat pro2.c
#include<stdio.h>
void pro2(char *arg)
{
    printf("OK:%s\n",arg);
}

步骤2:
把.c文件编译到汇编阶段生成.o文件。

root@kali:~/桌面# gcc pro1.c -o pro1.o -c
root@kali:~/桌面# gcc pro2.c -o pro2.o -c

步骤3:
为库文件创建一个头文件lib.h文件,声明库文件中的函数,它应该被希望使用库文件的应用程序包含

root@kali:~/桌面# cat lib.h
void pro1(int);
void pro2(char *);

步骤4:创建并使用一个库文件。用ar命令将单独文件归并到一个大的文件中。

root@kali:~/桌面# ar crv libfoo.a pro1.c pro2.c
a - pro1.c
a - pro2.c

输出为libfoo.a文件,一个静态库就完成了(还记得这个名字的含义吗,之前说过)
步骤5:
主程序

root@kali:~/桌面# cat main.c
#include"lib.h"
int main()
{
    pro2("Linux world");
    exit(0);
}

步骤6:编译这个程序

root@kali:~/桌面# gcc -o proc main.c -L. -lfoo

proc是输出文件,还记得-L吗是更改默认查找库的目录改为’.’也就是你的工作目录,我这里是桌面 -lfoo就是libfoo.a文件了。

root@kali:~/桌面# ./proc
OK:Linux world

有时候我们不知道某个函数在什么库中可以用下面这条很实用的命令
查找sin函数所在的库

root@kali:~/桌面# nm -o /lib/*.so|grep sin
nm: /lib/klibc-rBb4n9zs2Ri-TucnLVZwCHjM8M4.so:无符号

用make命令来编译工程
写make文件

proc: main.o pro1.o pro2.o
    gcc main.o pro1.o pro2.o -o proc
main.o: main.c pro.h
    gcc main.c -c
pro1.o: pro1.c
    gcc pro1.c -c
pro2.o: pro2.c
    gcc pro2.c -c

依赖关系图如下
这里写图片描述
用make命令生成文件

root@kali:~/桌面# make -f makefile
gcc main.c -c
main.c: In function ‘main’:
main.c:5:2: warning: implicit declaration of functionexit’ [-Wimplicit-function-declaration]
  exit(0);
  ^~~~
main.c:5:2: warning: incompatible implicit declaration of built-in functionexit’
main.c:5:2: note: include ‘<stdlib.h>’ or provide a declaration ofexit’
gcc pro1.c -c
gcc pro2.c -c
gcc main.o pro1.o pro2.o -o proc

除了生成了可执行文件还生成了.o的2个临时文件
简单调试
想要调试,编译时要加入调试信息

gcc -g main.c -o proc

l列出前10行
b 3 下断点于第三行
info b 查看断点信息
run 运行程序
n 步过
s 步入
c 继续运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值