Linux篇【3】:Linux环境基础开发工具使用(中)

news2025/4/19 1:52:15


目录

一、Linux 编译器:gcc/g++ 的使用

1.1、知识拓展:

1.2、如何安装 C/C++ 标准静态库:

1.3、头文件与库文件:

1.4、静态库,静态链接,动态库,动态链接:

二、简单 vim 配置

2.1、配置文件的位置

2.2、常用配置选项,用来测试

2.3、使用插件

2.4、参考资料


一、Linux 编译器:gcc/g++ 的使用

1.1、知识拓展:

1、在 Linux 系统中,不仅可以编写 C 和 C++ 的程序,还可以编写 Python,PHP,Shell,Java 的程序、

2、函数库一般分为静态库和动态库,在基础 IO 部分会讲解如何去制作静态库和动态库,以及如何去使用他们、

3、程序(代码)本质上是文本的形式,在经过预处理,编译,汇编之后将会转化为机器语言(二进制指令),转换为机器语言(二进制指令)的原因是因为,计算机只认识二进制,那么计算机为什么只认识二进制呢,这是因为,本质上并不是计算机只认识二进制,而是计算机中的各种硬件/组件只认识二进制,计算机在最初被设计时,无论是CPU,磁盘,触发器还是内存等硬件/组件,他们在设计的时候只是用来存储两态信息,其实,除了二进制计算机外,还存在其他进制的计算机,但是二进制计算机比较主流,因为二进制计算机更简单,二进制在硬件电路设计上比较简单,所以,最好也要将程序(代码)转换为二进制指令(机器语言),使得两者统一起来,从而更加方便的使用、

4、gcc 编译器和 g++ 编译器的编译过程和选项是完全一样的、

[HJM@hjmlcc ~]$ whoami
HJM
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp
[HJM@hjmlcc ~]$ vim lcc.c  // vim编辑器不会根据文件名的后缀来区分文件的类型、
[HJM@hjmlcc ~]$ cat lcc.c
#include<stdio.h>
int main()
{
  printf("%d\n",100);
  return 0;
}
[HJM@hjmlcc ~]$ gcc lcc.c 
//C语言代码需要使用gcc编译器来编译,gcc编译器会根据文件名的后缀来区分文件的类型、
[HJM@hjmlcc ~]$ ls
a.out  lcc.c  lcc.cpp    // Linux 系统下默认生成的可执行程序的名字为:a.out、
[HJM@hjmlcc ~]$ ./a.out
100
[HJM@hjmlcc ~]$ vim lcc.cpp  // vim编辑器不会根据文件名的后缀来区分文件的类型、
[HJM@hjmlcc ~]$ cat lcc.cpp
#include<iostream>
using namespace std;
int main()
{
  cout<<"hello,c++\n"<<endl;
  return 0;
}
[HJM@hjmlcc ~]$ g++ lcc.cpp
//C++代码需要使用g++编译器来编译,g++编译器会根据文件名的后缀来区分文件的类型、
[HJM@hjmlcc ~]$ ls
a.out  lcc.c  lcc.cpp
[HJM@hjmlcc ~]$ ./a.out
hello,c++

[HJM@hjmlcc ~]$ 


//注意1:
//若root用户和普通用户均未安装g++编译器,可以通过sudo的方法进行安装,也可以切换到root用户,输入指令:yum install -y gcc-c++ 的方法来安装、

//注意2:
//gcc编译器只能用来编译C语言代码,而g++编译器不仅可以编译C++代码,也可以编译C语言代码,因为C++兼容C语言、
[HJM@hjmlcc ~]$ whoami
HJM
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp
[HJM@hjmlcc ~]$ vim lcc.c
[HJM@hjmlcc ~]$ cat lcc.c
#include<stdio.h>
int main()
{
  printf("%d\n",100);       //预处理指令是以#号开头的代码行、
  return 0;
}
[HJM@hjmlcc ~]$ gcc lcc.c -o mylcc  
//Linux系统下默认生成的可执行程序的名字为:a.out,而上述指令代表:不使用Linux系统下默认生成的可
//执行程序名字:a.out,而是指定生成的可执行程序名字为:mylcc、
lcc.c  lcc.cpp  mylcc
[HJM@hjmlcc ~]$ gcc -E lcc.c -o lcc.i
//其中:
//-E:从当前开始,当预处理阶段完成,就停止、
//-o lcc.i:把预处理得到的结果写到临时普通文件lcc.i中、
//不管是在Linux还是Wiondows中,当使用gcc或g++编译器编译完代码后,源代码不受任何影响、
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  mylcc
[HJM@hjmlcc ~]$ vim lcc.c
//如下图所示:

[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  mylcc
[HJM@hjmlcc ~]$ cat lcc.c
#include<stdio.h>
#define M 10
#define DEBUG  //定义宏的时候不一定非要赋值、
int main()
{
  printf("%d\n",100);
  printf("%d\n",M);
  //printf("%d\n",M);
  //printf("%d\n",M);
  //printf("%d\n",M);
#ifdef DEBUG
  printf("hello, debug\n");
#else
  printf("hello,release\n");
#endif
  return 0;
}
[HJM@hjmlcc ~]$ gcc -E lcc.c -o lcc.i
[HJM@hjmlcc ~]$ vim lcc.c

    如上图所示,在分屏状态下,若普通文件 lcc.i 和普通文件 lcc.c 均处于命令模式下,ctrl+快速两次w,便可实现在两个屏幕之间的切换、

[HJM@hjmlcc ~]$ ls /usr/include  
//在Linux系统中,C语言的头文件库(C语言自带的头文件)基本上都在这个路径下,不排除它们将来会安装
//在其他路径下,具体在后面进行阐述、
aio.h        dlfcn.h        gconv.h         krad.h      mcheck.h    nfs                 python2.7      stdint.h     ucs
aliases.h    drm            gelf.h          krb5        mellanox    nlist.h             python3.6m     stdio_ext.h  uct
alloca.h     dwarf.h        getopt.h        krb5.h      memory.h    nl_types.h          rdma           stdio.h      ulimit.h
a.out.h      elf.h          gio-unix-2.0    langinfo.h  mft         nss.h               re_comp.h      stdlib.h     unistd.h
argp.h       elfutils       glib-2.0        lastlog.h   misc        numacompat1.h       regex.h        string.h     ustat.h
argz.h       endian.h       glob.h          libdb       mntent.h    numa.h              regexp.h       strings.h    utime.h
ar.h         envz.h         gnu             libelf.h    monetary.h  numaif.h            resolv.h       sys          utmp.h
arpa         err.h          gnu-versions.h  libgen.h    mqueue.h    obstack.h           rpc            syscall.h    utmpx.h
asm          errno.h        grp.h           libintl.h   mstflint    openssl             rpcsvc         sysexits.h   valgrind
asm-generic  error.h        gshadow.h       libio.h     mtcr_ul     paths.h             sched.h        syslog.h     values.h
assert.h     et             gssapi          libiptc     mtd         pcrecpparg.h        scsi           systemd      verto.h
bits         execinfo.h     gssapi.h        libipulog   net         pcrecpp.h           search.h       tar.h        verto-module.h
byteswap.h   fcntl.h        gssrpc          libmnl      netash      pcre.h              selinux        termio.h     video
c++          features.h     iconv.h         libnl3      netatalk    pcreposix.h         semaphore.h    termios.h    wait.h
com_err.h    fenv.h         ieee754.h       libudev.h   netax25     pcre_scanner.h      sepol          tgmath.h     wchar.h
complex.h    FlexLexer.h    ifaddrs.h       limits.h    netdb.h     pcre_stringpiece.h  setjmp.h       thread_db.h  wctype.h
cpio.h       fmtmsg.h       inttypes.h      link.h      neteconet   poll.h              sgtty.h        time.h       wordexp.h
cpufreq.h    fnmatch.h      ip6tables.h     linux       netinet     printf.h            shadow.h       ttyent.h     xen
crypt.h      fpu_control.h  iptables        locale.h    netipx      profile.h           signal.h       uapi         xlocale.h
ctype.h      fstab.h        iptables.h      lzma        netiucv     protocols           sound          uchar.h      xtables.h
db_185.h     fts.h          kadm5           lzma.h      netpacket   pthread.h           spawn.h        ucm          xtables-version.h
db.h         ftw.h          kdb.h           malloc.h    netrom      pty.h               stab.h         ucontext.h   zconf.h
dirent.h     _G_config.h    keyutils.h      math.h      netrose     pwd.h               stdc-predef.h  ucp          zlib.h
[HJM@hjmlcc ~]$ 

//任何一款编译器,其内部都必须能通过一定的方式知道所包含的头文件所在的路径,而在Linux系统下,
//gcc编译器默认有自己的头文件(C语言自带的头文件)搜索路径,即: /usr/include 和 当前路径下(一
//般用来搜索我们自定义的头文件)、

    语言特性越新,老的编译器就无法支持,本质原因并不是老的编译器不支持,而是老的编译器缺少部分配套的头文件和库、

[HJM@hjmlcc ~]$ whoami
HJM
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  mylcc
[HJM@hjmlcc ~]$ gcc -S lcc.i -o lcc.s //也可以写成:gcc -S lcc.c -o lcc.s ,但最好不要这样写、
//其中:
//-S:从当前开始,当编译阶段完成,就停止、
//-o lcc.s:把编译得到的结果写到临时普通文件lcc.s中,一般来说,后缀为.s或.asm的文件(普通文件)一
//般用来存放汇编语言、
//不管是在Linux还是Wiondows中,当使用gcc或g++编译器编译完代码后,源代码不受任何影响、
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.s  mylcc
[HJM@hjmlcc ~]$ vim lcc.s

[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.s  mylcc
[HJM@hjmlcc ~]$ gcc -c lcc.s -o lcc.o
//其中:
//-c:从当前开始,当汇编阶段完成,就停止、
//-o lcc.o:把汇编得到的结果写到临时普通文件lcc.o中、
//不管是在Linux还是Wiondows中,当使用gcc或g++编译器编译完代码后,源代码不受任何影响、
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ vim lcc.o
[HJM@hjmlcc ~]$ od lcc.o     //二进制文件(普通)查看工具、
0000000 042577 043114 000402 000001 000000 000000 000000 000000
0000020 000001 000076 000001 000000 000000 000000 000000 000000
0000040 000000 000000 000000 000000 001500 000000 000000 000000
0000060 000000 000000 000100 000000 000000 000100 000015 000014
0000100 044125 162611 062276 000000 137400 000000 000000 000270
0000120 000000 164000 000000 000000 005276 000000 137400 000000
...
...
0003020 000000 000000 000000 000000 001030 000000 000000 000000
0003040 000030 000000 000000 000000 000000 000000 000000 000000
0003060 000001 000000 000000 000000 000000 000000 000000 000000
0003100 000021 000000 000003 000000 000000 000000 000000 000000
0003120 000000 000000 000000 000000 001330 000000 000000 000000
0003140 000141 000000 000000 000000 000000 000000 000000 000000
0003160 000001 000000 000000 000000 000000 000000 000000 000000
0003200
[HJM@hjmlcc ~]$ 

//二进制普通文件,即lcc.o目标文件并不是可执行程序,没有办法运行,因为在源文件lcc.c中,我们使用了
//库函数,但是截至目前,虽然我们包含了对应的头文件,只是对使用的这些库函数进行了声明,但是我们还
//找不到使用的这些库函数的定义,即:生成的二进制普通目标文件还未与链接库(C标准库,主要指C标准动
//态库)关联(链接)起来、

[HJM@hjmlcc ~]$ clear
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ ./lcc.o
-bash: ./lcc.o: Permission denied
[HJM@hjmlcc ~]$ ll
total 48
-rw-rw-r-- 1 HJM HJM   309 Nov  2 10:15 lcc.c
-rw-rw-r-- 1 HJM HJM    96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM 16921 Nov  2 10:15 lcc.i
-rw-rw-r-- 1 HJM HJM  1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM   594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM  8360 Nov  2 09:24 mylcc
[HJM@hjmlcc ~]$ chmod u+x lcc.o
[HJM@hjmlcc ~]$ ll
total 48
-rw-rw-r-- 1 HJM HJM   309 Nov  2 10:15 lcc.c
-rw-rw-r-- 1 HJM HJM    96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM 16921 Nov  2 10:15 lcc.i
-rwxrw-r-- 1 HJM HJM  1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM   594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM  8360 Nov  2 09:24 mylcc
[HJM@hjmlcc ~]$ ./lcc.o
-bash: ./lcc.o: cannot execute binary file  //不是可执行文件(普通文件)、
[HJM@hjmlcc ~]$ ldd lcc.o
	not a dynamic executable
[HJM@hjmlcc ~]$ chmod u-x lcc.o
[HJM@hjmlcc ~]$ ll
total 48
-rw-rw-r-- 1 HJM HJM   309 Nov  2 10:15 lcc.c
-rw-rw-r-- 1 HJM HJM    96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM 16921 Nov  2 10:15 lcc.i
-rw-rw-r-- 1 HJM HJM  1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM   594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM  8360 Nov  2 09:24 mylcc
[HJM@hjmlcc ~]$ 



//拓展:
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ll
total 76
-rwxrwxr-x 1 HJM HJM  8304 Nov  2 15:08 a.out
-rw-rw-r-- 1 HJM HJM    27 Nov  2 15:08 hjm.c
-rw-rw-r-- 1 HJM HJM   151 Nov  2 15:36 hjm.i
-rw-rw-r-- 1 HJM HJM  1232 Nov  2 15:37 hjm.o
-rw-rw-r-- 1 HJM HJM   370 Nov  2 15:36 hjm.s
-rw-rw-r-- 1 HJM HJM   309 Nov  2 10:15 lcc.c
-rw-rw-r-- 1 HJM HJM    96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM 16921 Nov  2 10:15 lcc.i
-rw-rw-r-- 1 HJM HJM  1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM   594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM  8360 Nov  2 09:24 mylcc
[HJM@hjmlcc ~]$ cat hjm.c
//假设下面是C语言代码,此时可以不包含任何头文件,也可以不包含头文件<stdio.h>,因为我们未使用C语
//言的任何库函数,所以我们不需要对这些库函数包含头文件<stdio.h>来进行声明、
int main()
{
  return 0;
}
//由上可知我们并没有使用C语言的任何库函数,所以我们也不需要找到关于任何C语言库函数的实现,按道
//理说,当我们生成的二进制普通目标文件即使不与C标准库(主要指C标准动态库)进行链接也是可以的,直
//接运行 ./hjm.o 应该也是可以的,但是发现会报错说是: hjm.o普通文件不是可执行程序,这是因为,当
//我们生成的二进制普通目标文件与C标准库(主要指C标准动态库)进行链接时,并不只是为了C标准库(主要
//指C标准动态库)中有关C语言库函数的定义,除了这一方面外,还会进行其他的一些操作,所以,即使我们
//不需要找到有关C语言的任何库函数的定义,我们也必须让二进制普通目标文件与C标准库(主要是指C标
//准动态库)进行链接才可以,由此可知,当我们写了一段C语言代码,不管该代码中是否使用了C语言的任何
//库函数,其生成的二进制普通目标文件都必须要与C标准库(C标准动态库)进行链接,只有二进制普通目标
//文件是无法直接运行的,只要不是可执行普通文件,则都会报错说是:cannot execute binary file、
[HJM@hjmlcc ~]$ ./hjm.o
-bash: ./hjm.o: Permission denied
[HJM@hjmlcc ~]$ chmod u+x hjm.o
[HJM@hjmlcc ~]$ ./hjm.o
-bash: ./hjm.o: cannot execute binary file
[HJM@hjmlcc ~]$ chmod u-x hjm.o
[HJM@hjmlcc ~]$ ll
total 76
-rwxrwxr-x 1 HJM HJM  8304 Nov  2 15:08 a.out
-rw-rw-r-- 1 HJM HJM    27 Nov  2 15:08 hjm.c
-rw-rw-r-- 1 HJM HJM   151 Nov  2 15:36 hjm.i
-rw-rw-r-- 1 HJM HJM  1232 Nov  2 15:37 hjm.o
-rw-rw-r-- 1 HJM HJM   370 Nov  2 15:36 hjm.s
-rw-rw-r-- 1 HJM HJM   309 Nov  2 10:15 lcc.c
-rw-rw-r-- 1 HJM HJM    96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM 16921 Nov  2 10:15 lcc.i
-rw-rw-r-- 1 HJM HJM  1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM   594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM  8360 Nov  2 09:24 mylcc
[HJM@hjmlcc ~]$ 
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ touch hjm.c
[HJM@hjmlcc ~]$ vim hjm.c
[HJM@hjmlcc ~]$ cat hjm.c

//包含头文件这一操作并不是必须的,所有的包含头文件的操作,本质上是因为想使用头文件所声明的方法,
//即能够让我们写的代码中能够使用所包含的头文件中所声明的方法,我们在写C语言代码时,经常包含头
//文件:#include<stdio.h>,这是因为,我们经常使用库函数:scanf,printf等等,都是库函数,都需要我
//们将<stdio.h>头文件包含进来用来对这些库函数进行声明,但是除了包含对应的头文件外还不够,头文
//件只是用来对这些库函数进行声明的,我们还需要找到这些库函数的实现,所以我们还需要这些库函数的
//链接库(C标准库,主要指C标准动态库),若只针对于C语言而言,链接库就是所谓的C标准库(主要指:C标准
//动态库)、
//如果我们在写C语言代码时,用不到<stdio.h>头文件中所声明的方法,那我们就可以不包含这个头文件,
//此时也能够成功编译、
int main() 
{
  return 0;
}
[HJM@hjmlcc ~]$ gcc hjm.c //可以成功编译、
[HJM@hjmlcc ~]$ ls
a.out  hjm.c  lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ ./a.out   //可以成功运行、
[HJM@hjmlcc ~]$ 
//注意:要指定lib64平台,不同的平台会有一定的差别、
//C标准库所在的路径如下所示,主要是指:/lib64/libc-2.17.so 和 /lib64/libc.a,分别是C标准动态
//库和C标准静态库,若只针对于C语言而言,其中的库函数的实现一般都在C标准动态库中,C标准库有自己
//的命名规则,在Linux系统中, .so对应的一般是动态库, .a对应的一般是静态库、 
//当前为止,我们的Linux系统(不管是云服务器还是虚拟机等等环境)中一般都默认只安装了动态库,未安装静态库,包括C标准库和C++标准库、
[HJM@hjmlcc ~]$ ls /lib64/libc*  
/lib64/libc-2.17.so                              /lib64/libcmdif.a            /lib64/libcrack.so.2.9.0        /lib64/libcrypt.so.1
/lib64/libcairo-script-interpreter.so.2          /lib64/libc_nonshared.a      /lib64/libcroco-0.6.so.3        /lib64/libc.so
/lib64/libcairo-script-interpreter.so.2.11512.0  /lib64/libcom_err.so         /lib64/libcroco-0.6.so.3.0.1    /lib64/libc.so.6
/lib64/libcairo.so.2                             /lib64/libcom_err.so.2       /lib64/libcrypt-2.17.so         /lib64/libcupscgi.so.1
/lib64/libcairo.so.2.11512.0                     /lib64/libcom_err.so.2.1     /lib64/libcrypto.so             /lib64/libcupsimage.so.2
/lib64/libcap-ng.so.0                            /lib64/libconfig.so.9        /lib64/libcrypto.so.10          /lib64/libcupsmime.so.1
/lib64/libcap-ng.so.0.0.0                        /lib64/libconfig++.so.9      /lib64/libcrypto.so.1.0.2k      /lib64/libcupsppdc.so.1
/lib64/libcap.so.2                               /lib64/libconfig.so.9.1.3    /lib64/libcryptsetup.so.12      /lib64/libcups.so.2
/lib64/libcap.so.2.22                            /lib64/libconfig++.so.9.1.3  /lib64/libcryptsetup.so.12.3.0  /lib64/libcurl.so.4
/lib64/libcidn-2.17.so                           /lib64/libcpupower.so.0      /lib64/libcryptsetup.so.4       /lib64/libcurl.so.4.3.0
/lib64/libcidn.so                                /lib64/libcpupower.so.0.0.0  /lib64/libcryptsetup.so.4.7.0
/lib64/libcidn.so.1                              /lib64/libcrack.so.2         /lib64/libcrypt.so
[HJM@hjmlcc ~]$ 
[HJM@hjmlcc ~]$ pwd
/home/HJM
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s
[HJM@hjmlcc ~]$ gcc lcc.o -o mylcc

//gcc编译器不加任何选项,默认会在系统特定的路径(该例子下,主要是指:/lib64/libc*或/usr/lib)下自动
//去寻找我们所要使用的链接库(该例子下,此处链接库指的就是C标准库,主要是C标准动态库),在预处理阶
//段,gcc编译器也会自动去系统特定的路径(该例子下,此处的路径是:/usr/include,主要是指头文件
//<stdio.h>,自动找到该头文件,将其其中的内容拷贝一份,在预处理阶段,将包含的头文件展开)下自动寻找
//所需要的所有头文件,将找到的所有的对应的头文件中的具体内容拷贝一份,在预处理阶段完成头文件的展
//开操作,g++编译器的功能也是类似的、
//不使用Linux系统下默认的可执行程序名:a.out,而是指定可执行程序名为:mylcc、

[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ ./mylcc
100
10
hello, debug
[HJM@hjmlcc ~]$ 

1.2、如何安装 C/C++ 标准静态库:

[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ ldd mylcc  //查看某一个可执行程序所依赖的库,查看当前的链接状态、
	linux-vdso.so.1 =>  (0x00007ffea3f35000)
	/$LIB/libonion.so => /lib64/libonion.so (0x00007fe3e6f09000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fe3e6a22000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fe3e681e000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fe3e6df0000)
[HJM@hjmlcc ~]$ ls /lib64/libc.so.6
/lib64/libc.so.6
[HJM@hjmlcc ~]$ ls /lib64/libc.so.6 -al
lrwxrwxrwx 1 root root 12 Oct 30 10:56 /lib64/libc.so.6 -> libc-2.17.so   //C标准动态库、
[HJM@hjmlcc ~]$ file mylcc  //查看某一个可执行程序的构成、
mylcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=c85dc0a29837d6c3f34928dc00025635a5aa6b24, not stripped
//由executable可知,这是一个可执行程序,dynamically linked代表动态链接,uses shared libs代表共
//享库,默认情况下,(gcc编译器下)形成的可执行程序就是动态链接的,默认情况下,(g++编译器下)形成的
//可执行程序也是动态链接的,如果想进行静态链接,必须要手动进行操作,如下所示、
[HJM@hjmlcc ~]$ gcc lcc.c -o mylcc2 -static 
//注意:在安装(可能不需要安装,不需要安装时,就是使用)指令 static 之前,必须保证当前Linux系统下
//已经安装了静态库,由于此时我当前的Linux系统中未安装静态库,因此此时执行上述指令会报错,具体的
//静态库的安装会在后面再进行阐述、


//拓展:
//可以在普通用户下通过指令:sudo yum install -y glibc-static 来安装C标准静态库,也可以切换到
//root用户下,通过指令:yum install -y glibc-static 来安装C标准静态库、
//可以在普通用户下通过指令:sudo yum install -y libstdc++-static 来安装C++标准静态库,也可以
//切换到root用户下,通过指令:yum install -y libstdc++-static 来安装C++静态库、

[root@hjmlcc ~]# whoami
root
[root@hjmlcc ~]# pwd
/root
[root@hjmlcc ~]# yum install -y glibc-static
Loaded plugins: fastestmirror, langpacks
Repository cr is listed more than once in the configuration
Repository fasttrack is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package glibc-static.x86_64 0:2.17-326.el7_9 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================================================
 Package                             Arch                          Version                               Repository                      Size
==============================================================================================================================================
Installing:
 glibc-static                        x86_64                        2.17-326.el7_9                        updates                        1.6 M

Transaction Summary
==============================================================================================================================================
Install  1 Package

Total download size: 1.6 M
Installed size: 7.6 M
Downloading packages:
glibc-static-2.17-326.el7_9.x86_64.rpm                                                                                 | 1.6 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : glibc-static-2.17-326.el7_9.x86_64                                                                                         1/1 
  Verifying  : glibc-static-2.17-326.el7_9.x86_64                                                                                         1/1 

Installed:
  glibc-static.x86_64 0:2.17-326.el7_9                                                                                                        

Complete!
[root@hjmlcc ~]# logout
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc
[HJM@hjmlcc ~]$ gcc lcc.c -o mylcc2 -static
[HJM@hjmlcc ~]$ ls
lcc.c  lcc.cpp  lcc.i  lcc.o  lcc.s  mylcc  mylcc2
[HJM@hjmlcc ~]$ ll
total 892
-rw-rw-r-- 1 HJM HJM    309 Nov  2 20:36 lcc.c
-rw-rw-r-- 1 HJM HJM     96 Nov  2 10:33 lcc.cpp
-rw-rw-r-- 1 HJM HJM  16921 Nov  2 10:15 lcc.i
-rw-rw-r-- 1 HJM HJM   1664 Nov  2 14:53 lcc.o
-rw-rw-r-- 1 HJM HJM    594 Nov  2 10:49 lcc.s
-rwxrwxr-x 1 HJM HJM   8408 Nov  2 20:57 mylcc    //8408byte
-rwxrwxr-x 1 HJM HJM 861384 Nov  2 21:48 mylcc2   //861384byte
[HJM@hjmlcc ~]$ 
[HJM@hjmlcc ~]$ which ls
alias ls='ls --color=auto'
	/usr/bin/ls
[HJM@hjmlcc ~]$ ldd /usr/bin/ls
	linux-vdso.so.1 =>  (0x00007fff195ec000)
	/$LIB/libonion.so => /lib64/libonion.so (0x00007fc55c5c6000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fc55c286000)
	libcap.so.2 => /lib64/libcap.so.2 (0x00007fc55c081000)
	libacl.so.1 => /lib64/libacl.so.1 (0x00007fc55be78000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fc55baaa000)
//由此可知,指令 ls ,就是使用C语言来写的、
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fc55b8a6000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fc55b644000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fc55c4ad000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007fc55b43f000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc55b223000)
[HJM@hjmlcc ~]$ 

//Linux系统中,很多的指令都是使用C语言写的,都会使用C标准库(主要是指C标准动态库)、
//所以,若在Linux系统下将C标准库(包括C标准动态库和静态库(主要指C标准动态库))删除,则许多指令都将不能再使用、

//拓展:
//以后缀为 .iso 结尾的文件(普通文件)一般是镜像文件、

1.3、头文件与库文件:


1、头文件:

     不管是自己写的头文件还是系统默认自带的头文件,其中包含的一般都是声明(主要指的是函数的声明,自己写的头文件主要包含自己实现的函数的声明,系统默认自带的头文件主要包含的是各种库函数的声明),头文件给我们提供了可以使用的方法的声明,所有的开发环境,具有的语法提示功能,本质上是通过头文件帮我们搜索的,语法提示如下所示:

     当输入 printf 时,Linux系统会自动在全部的头文件中搜索所有与 printf 有关的内容,这个过程是自动的,这就是语法提示、


2、库文件: 

      给我们提供了可以使用的方法的具体实现,以供链接,形成我们自己的可执行程序、


总结:

      头文件与库文件之间的关系就类似于我们写的 .h 头文件与 .c 或 .cpp 源文件之间的关系,当我们自己写代码时,包含头文件,链接库文件,就可以形成可执行程序、

      当我们自己在写代码时,包含了对应的头文件这一过程就已经可以称为链接过程了,等到寻找库函数的具体实现(定义)时,直接跳转到对应的库中即可,链接不是执行,链接是产生关系、   


1.4、静态库,静态链接,动态库,动态链接:

    我们的计算机,我们自己的系统中,或在链接库中,会存在两种库,分别为:静态库和动态库,在 Linux 系统中,所有的动态库都是以 .so 结尾的,而在 Windows 系统下,所有的动态库则都是以 .dll 结尾的,在 Linux 系统中,所有的静态库都是以 .a 结尾的,而在 Windows 系统下,所有的静态库都是以 .lib 结尾的,与这两种库相对应的就会存在两种链接方式,分别为:静态链接和动态链接,本章内容中,主要研究的是,我们的二进制普通目标文件是怎么和动态库或静态库链接起来的,也就是主要研究的是:动态链接和静态链接、

静态链接:将库中的相关代码直接拷贝到自己的二进制普通目标文件中,形成可执行程序,也就是说:在静态链接中,在链接阶段,查找对应模块的静态库,而不是动态库,在链接时会依赖一次静态库,当运行时,就不再依赖任何库(包括静态库和动态库),程序或指令可以独立的执行,我们之前使用的程序(指令)几乎都是动态链接(动态库),不发生拷贝,只发生关联、

静态链接和动态链接分别形成的可执行程序的优缺点:

1、动态链接:

优点:该动态库是大家共享的,可以节省资源,在 Linux 系统下,命令会加载到内存里,所以会节省内存资源,除此之外还可以节省磁盘资源、

缺点:一旦该动态库缺失,会导致几乎所有的程序(指令)失效、

2、静态链接:

优点:在链接阶段,查找对应模块的静态库,而不是动态库,在链接时会依赖一次静态库,当运行时,就不再依赖任何库(包括静态库和动态库),程序或指令可以独立的执行、

缺点:浪费资源,导致我们的系统里可能会存在很多重复的代码,导致内存,磁盘等资源被浪费、

在编译器(以 gcc 为例)中,怎么查看生成的可执行程序中到底是静态链接还是动态链接呢?

答:

    可以通过形成的可执行程序的体积来进行分辨,静态链接形成的可执行程序的体积一定比动态链接形成的可执行程序的体积要大、

gcc编译器常见的选项:

-E:只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面、

-S:编译到汇编语言不进行汇编和链接、
-c: 编译到目标代码、
-o: 文件输出到文件、
-static:   此选项对生成的文件采用静态链接、
-g:         生成调试信息,GNU 调试器可利用该信息、
-shared:此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库,在后期讲解动静态库时再进行具体阐述、
-O0
-O1
-O2
-O3:  编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高,优化级别在讲解信号时再进行具体阐述、
-w:    不生成任何警告信息、
-Wall:生成所有警告信息、

二、简单 vim 配置

2.1、配置文件的位置

1、
    在目录 /etc 下面,有个名为 vimrc 的文件,这是系统中公共的vim配置文件,对所有用户都有效、
2、
    而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为:".vimrc" ,例如,/root 目录下, 通常已经存在一个 .vimrc 文件,如果不存在,则创建之、
3、切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~  、
4、打开自己目录下的 .vimrc 文件,执行 vim .vimrc  、

2.2、常用配置选项,用来测试

1、设置语法高亮: syntax on
2、显示行号: set nu
3、设置缩进的空格数为4: set shiftwidth=4

2.3、使用插件

    要配置好看的 vim,原生的配置可能功能不全,可以选择安装插件来完善配置,保证用户是你要配置的用户,接下来:
1、安装 TagList 插件,下载 taglist_xx.zip ,解压完成,将解压出来的 doc 的内容放到~/.vim/doc ,将解压出来的 plugin 下的内容拷贝到 ~/.vim/plugin 、
2、在 ~/.vimrc 中添加: let Tlist_Show_One_File=1 let Tlist_Exit_OnlyWindow=1 let
Tlist_Use_Right_Window=1 、
3、安装文件浏览器和窗口管理器插件: WinManager 、
4、下载 winmanager.zip,2.X版本以上的、
5、解压 winmanager.zip,将解压出来的 doc 的内容放到 ~/.vim/doc,将解压出来的 plugin下的内容拷贝到 ~/.vim/plugin 、
6、在 ~/.vimrc 中添加 let g:winManagerWindowLayout=‘FileExplorer|TagList nmap wm :WMToggle<cr> 、
7、然后重启vim,打开 ~/XXX.c 或 ~/XXX.cpp , 在 normal 状态下输入 "wm" , 你将看到上图的效果更具体移步: 手把手教你把Vim改装成一个IDE编程环境(图文)_wooin的博客-CSDN博客 , 
其他手册,请执行 vimtutor 命令、

2.4、参考资料

https://github.com/wsdjeg/vim-galore-zh_cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3317.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringBoot】一文了解SpringBoot热部署

文章目录前言手动启动热部署热部署种类手动进行热部署自动启动热部署热部署范围配置热部署的关闭总结&#x1f315;博客x主页&#xff1a;己不由心王道长&#x1f315;! &#x1f30e;文章说明&#xff1a;一文彻底搞懂SpringBoot热部署&#x1f30e; ✅系列专栏&#xff1a;Sp…

深入理解Java虚拟机:Java类的加载机制

本篇内容包括&#xff1a;Java 类的加载机制&#xff08;Jvm 结构组成、Java 类的加载&#xff09;、类的生命周期&#xff08;加载-验证-准备-解析-初始化-使用-卸载&#xff09;、类加载器 以及 双亲委派模型。 一、Java 类的加载机制 1、 Jvm 结构组成 Jvm 整体组成可分为…

坤坤音效键盘(Python实现)

文章目录坤坤音效键盘说明坤坤音效键盘效果展示代码实现安装第三方库准备音频监听键盘播放音频编写逻辑引入线程打包成exe程序坤坤音效键盘说明 坤坤音效键盘说明&#xff1a; 单独按下 j、n、t、mj、n、t、mj、n、t、m 按键&#xff0c;会对应触发 “鸡”、“你”、“太”、…

科技视界杂志科技视界杂志社科技视界编辑部2022年第21期目录

科技视界杂志科技视界杂志社科技视界编辑部2022年第21期目录 科普论坛《科技视界》投稿&#xff1a;cnqikantg126.com 天敌昆虫——让农业生产更安全 季香云; 1-3 储粮昆虫三维模型Web可视化技术研究与应用 阎磊;马宏琳;李亮;李鹏翔;王义超; 4-6 科学实验 非均匀催…

wy的leetcode刷题记录_Day33

wy的leetcode刷题记录_Day33 时间&#xff1a;2022-11-4 目录wy的leetcode刷题记录_Day33754. 到达终点数字题目介绍思路代码收获199. 二叉树的右视图题目介绍思路代码收获754. 到达终点数字 今天的每日一题是&#xff1a;754. 到达终点数字 题目介绍 在一根无限长的数轴上…

CSS:变量函数var和自定义属性

文章目录CSS变量var()函数CSS变量 CSS变量分为两部分&#xff1a;变量声明和变量使用。 变量的声明是由CSS自定义属性和对应的属性朱组成的&#xff0c;比如&#xff1a; :root {--custom-color: deepskyblue;}在这段代码中&#xff0c;–custom-color是属于css的自定义属性名…

方法的使用

目录 1. 举例说明什么叫方法 2. 方法概念及使用 2.1 什么是方法(method) 1.2 方法定义 1.3 方法调用的执行过程 1.4 实参和形参的关系(重要) 2. 方法重载 2.1 为什么需要方法重载 2.3 方法签名 3. 递归 递归执行过程分析 1. 举例说明什么叫方法 我们利用面向对象的方…

2022年特色小镇行业研究报告

第一章 行业概况 特色小镇是在几平方公里土地上集聚特色产业、生产生活生态科技相融合、不同于行政建制镇和产业园区的创新创业平台。根据类型的不同&#xff0c;特色小镇可以分为三类&#xff0c;即产业类、社区类和旅游类。 产业类&#xff1a;通过招商引资吸引企业进入&…

门控循环单元(GRU)【动手学深度学习v2】

理论 候选隐藏状态。 圆圈 表示 按元素乘法。 这里面的 这个符号值得是 按元素相乘。 Rt理解为 和Ht 长度一样的一维向量。&#xff08;这么理解&#xff09; 这里如果Rt长的像0的话&#xff0c;那么乘出来的结果&#xff0c;就也像0。 要是像0 的话&#xff0c;相当于是说…

文件操作之文件系统

目录 一 磁盘 1 磁盘的物理结构 2 磁盘在物理结构上如何存储数据 CHS寻址 3 从物理结构到抽象结构 LBA寻址 4管理 二 块组 boot block super block inode table data blocks block bitmap GDT&#xff1a;Global Descriptor Table 块组描述符 三 文件名和目录之…

网课查题接口搭建

网课查题接口搭建 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击跳…

字符串匹配算法(C/Java实现)

目录BF算法C语言实现Java实现KMP算法Java实现C语言实现next[]数组的优化BF算法 BF算法&#xff0c;即暴力(Brute Force)算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配&#xff0c;若相等&#xff0c;…

R语言代做实现:混合正态分布EM最大期望估计法

全文链接&#xff1a;http://tecdat.cn/?p4815 原文出处&#xff1a;拓端数据部落公众号 因为近期在分析数据时用到了EM最大期望估计法这个算法&#xff0c;在参数估计中也用到的比较多。然而&#xff0c;发现国内在R软件上实现高斯混合分布的EM的实例并不多&#xff0c;大多…

Linux系统下实现开机自动加载驱动模块

在使用模块化加载驱动时&#xff0c;若系统内部存在同类别设备驱动&#xff0c;可能会出现无法加载我们添加的动态模块&#xff0c;比如Linux系统内置了CDC驱动&#xff0c;当我们使用兼容CDC和VCP驱动USB转串口芯片时&#xff0c;就会出现上电出现的是CDC串口&#xff0c;从而…

vue3 组件响应式v-model 失效,实践踩坑,一文搞懂组件响应式原理,对初学者友好

文章目录前情提要实战解析最后前情提要 vue3的v-model已经有了变化&#xff0c;假如你还不知道其中细节&#xff0c;看完这篇文章你就完全明白了&#xff0c;我以踩坑的场景来进行解析。起因是在我的项目中需要一个输入框组件&#xff0c;这个组件用来根据输入异步查询系统内已…

Python编程 基础数据类型

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言&#xff1a; 一.Python基础数据类型 1.为什么会有数据类型&#xff1f;&am…

公共云和私有云之间的区别

目前&#xff0c;越来越多的公司正在调整云服务来运行他们的应用程序。其实&#xff0c;有不同类型的云部署模型来满足客户的不同需求。云部署模型分为三种类型&#xff1a;公有云、私有云和混合云(公有云和私有云的混合)。在本文中&#xff0c;我们将对公共云和私有云之间的区…

【数据结构】单链表——单链表的定义及基本操作的实现(头插、尾插、头删、尾删、任意位置的插入与删除)

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《数据结构》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 单链表前言…

分享30个PHP源码,总有一款适合你

链接&#xff1a;https://pan.baidu.com/s/1dVbUn5YFMOze4J-K8sCAXQ?pwdeinu 提取码&#xff1a;einu 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后可以看到。 Emlog for SAE 适合新浪sae使用的个人博客…

网关Gateway-快速上手

gateway网关官方文档: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/# 网关的概念 网关作为流量的入口&#xff0c;常用的功能包括路由转发&#xff0c;权限校验&#xff0c;限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关…