Linux系统编程入门(上)

基本配置

安装必要包

# 更新软件源
sudo apt-get update

# 安装opengl
sudo apt-get install build-essential    
sudo apt-get install libgl1-mesa-dev   
sudo apt-get install libglu1-mesa-dev 
sudo apt-get install freeglut3-dev

# 安装vim
sudo apt-get install vim

# 安装minicom
sudo apt-get install minicom

# 安裝配置ssh
sudo apt-get install openssh-client
sudo apt-get install openssh-server
sudo  /etc/init.d/ssh restart

# 安裝ncurses
sudo apt-get install ncurse*

# 安裝git
sudo apt-get install git

# 安裝makeinfo
sudo apt-get install texinfo

# 安裝bison
sudo apt-get install bison
sudo apt-get install flex 

# 安装gimp图形处理软件
sudo apt-get install gimp

# 安装配置tftp服务
sudo apt-get install tftpd-hpa
sudo /etc/init.d/tftpd-hpa restart

# 安装c++库
sudo apt-get install lib32stdc++6

# 安装fastboot
sudo apt-get install android-tools-fastboot

# 安装配置nfs
sudo apt-get install nfs-kernel-server
sudo /etc/init.d/nfs-kernel-server start

安装vmware加强包

把CD的iso映像弹出来,然后下载加强包tool.tar

$ tar -zxvf tool.tar
$ cd vmware-tools-distrib
$ sudo ./...pl

# 或者可采用下面的方法直接安装,记得重启才能生效
$ sudo vmware-uninstall-tools.pl #完全卸载掉安装好的不能用的vmtools
$ sudo apt-get install open-vm-tools-desktop #安装vmware-tools

配置网络源

$ sudo vim /etc/apt/source.list

之后在文件后追加

deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse

samba

$ sudo apt install samba
$ sudo passwd root #ubuntu重置密码
$ sudo apt-get install openssh-server # 使用MobaXtem连接ssh前先装这个包
$ pwd
/home/chan
$ mkdir /share
$ sudo chmod 777 /share/ -R
$ cd /etc/samba
$ vim smb.conf
[share]
   comment = My Samba
   path = /home/chan/share
   browseable = yes
   writeable = yes
$ sudo smbpasswd -a chan #添加chan这个用户,并且键盘输入设置密码

ssh配置远程登陆验证

$ ssh-keygen -t rsa
# 把本机windows的pub_key复制到虚拟机的authorized_keys, 这样就不用输入密码远程登录
$ cd ~/.ssh
$ vim authorized_keys

GCC

GCC 原名为 GNU C语言编译器(GNU C Compiler)
GCC(GNU Compiler Collection,GNU编译器套件)是由 GNU 开发的编程语言译器。GNU 编译
器套件包括 C、C++、Objective-C、Java、Ada 和 Go 语言前端,也包括了这些语言的库(如
libstdc++,libgcj等)
image

gcc test.c -E -o test.i
gcc test.i -S -o test.s
gcc test.s -s -o test.o

常用参数介绍

image

什么是库

image

静态库

命名规则

  • Linux下: libxxx.a
    其中
    lib:固定前缀
    xxx:自定义库的名字
    .a:固定后缀
  • Windows下:libxxx.lib

静态库的制作

image

gcc -c add.c div.c mult.c sub.c 
ar rcs libcalc.a add.o div.o mult.o sub.o
mv libcalc.a ../lib/
gcc main.c -o app -I ./include/

1.使用gcc -c以只汇编但不链接的方式来生成.o目标文件
gcc -c add.c div.c mult.c sub.c
2.将.o文件进行打包,使用ar工具(archive)
ar rcs libcalc.a add.o div.o mult.o sub.o
其中rcs含义:r插入 c创建 s索引
3.

tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.a
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

A.如果此时直接gcc main.c,由于main.c与head.h不在同一目录会报错

    chan@chan-virtual-machine:~/Linux/lesson05/library$ gcc main.c -o app
    main.c:2:10: fatal error: head.h: No such file or directory
        2 | #include "head.h"
        |          ^~~~~~~~
    compilation terminated.

解决方法有两个 (1)移动main.c到include (2)使用 -I来指定库目录位置
B.采用 -I解决上述问题,但会遇到下面的报错提示,原因是main中调用函数未引用

    chan@chan-virtual-machine:~/Linux/lesson05/library$ gcc main.c -o app -I ./include/ 
    /usr/bin/ld: /tmp/ccW9805c.o: in function `main':
    main.c:(.text+0x41): undefined reference to `add'
    /usr/bin/ld: main.c:(.text+0x66): undefined reference to `subtract'
    /usr/bin/ld: main.c:(.text+0x8b): undefined reference to `multiply'
    /usr/bin/ld: main.c:(.text+0xb0): undefined reference to `divide'
    collect2: error: ld returned 1 exit status

C.采用 -l指定库文件名称,但是库还是找不到可以再加一个 -L去指定库位置
gcc main.c -o app -I ./include/ -l calc -L ./lib/

动态库

动态库也成为共享库

命名规则

  • Linux下: libxxx.so
    其中
    lib:固定前缀
    xxx:自定义库的名字
    .so:固定后缀
  • Windows下:libxxx.dll

动态库的制作

image
gcc -c -fpic add.c sub.c mult.c div.c
-fpic表示得到与位置无关的目标文件
gcc -shared add.o sub.o mult.o div.o -o libcalc.so
-shared生成动态库libcalc.iso
但是如果此时直接使用 gcc main.c -o main -I ./include/ -L ./lib/ -l calc,然后执行main会报错

    chan@chan-virtual-machine:~/Linux/lesson06/library$ ./main
    ./main: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory

加载动态库的时候找不到该动态库libcalc.so文件,使用ldd(list dynamic dependencies)命令检查动态库依赖关系

    chan@chan-virtual-machine:~/Linux/lesson06/library$ ldd main
            linux-vdso.so.1 (0x00007ffc96fb0000)
            libcalc.so => not found
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000752f43400000)
            /lib64/ld-linux-x86-64.so.2 (0x0000752f43839000)

发现libcalc.so并没有被找到,这就要知道动态库工作原理。

动态库工作原理

1752831717887

那如何定位共享库文件呢?
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。
对于e1f格式的可执行程序,是由ld-linux.so来完成的。
它先后搜索elf文件的DT_RPATH段 -> 环境变量LD_LIBRARY_PATH -> /etc/ld.so.cache文件列表 -> /lib//usr/lib目录找到库文件后将其载入内存。

  • DT_RPATH段:修改不了的,不常用,了解
  • 环境变量
    将库文件目录导入环境变量LD_LIBRARY_PATH,有下面三种方法:
    1.export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/chan/Linux/lesson06/library/lib
    其中,$LD_LIBRARY_PATH表示获取原先的LD_LIBRARY_PATH值,然后使用':',进行分隔指定目录。
    此时,我们ldd main,发现检测到so库文件了,此时是可以运行 main 程序的
    image
    但是这种方法是临时的,一旦我们关掉这个终端窗口,还需要重新配置。
    2.编辑当前用户下的.bashrc文件,将环境变量LD_LIBRARY_PATH写入,然后记得 source ~/.bashrc 或者 . ~/.bashrc。
    3.修改系统配置 /etc/profile,,将环境变量LD_LIBRARY_PATH写入.
  • etc/ld.so.cache
    直接vim etc/ld.so.cache是修改不了的,打开是乱码。
    image
    可以vim etc/ld.so.conf进行间接修改,将库文件目录位置写进去保存退出就行,然后sudo ldconfig 使配置更新。
    image
  • /lib//usr/lib目录不推荐进行修改,如果名字重复,会引起一些问题。

静态库和动态库的区别

  • 区别为在链接阶段如何处理,链接成可执行程序
    image

  • 静态库制作过程
    image

1.使用gcc -c以只汇编但不链接的方式来生成.o目标文件
gcc -c add.c div.c mult.c sub.c 
2.将.o文件进行打包,使用ar工具(archive)
ar rcs libcalc.a add.o div.o mult.o sub.o
3.采用 -l指定库文件名称,但是库还是找不到可以再加一个 -L去指定库位置
gcc main.c -o app -I ./include/ -l calc -L ./lib/
  • 动态库制作过程
    image
1.-fpic表示得到与位置无关的目标文件
gcc -c -fpic add.c sub.c mult.c div.c 
2.-shared生成动态库libcalc.iso生成
gcc -shared add.o sub.o mult.o div.o -o libcalc.so
3.当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径(ldd main)。此时就需要系统的动态载入器来获取该绝对路径。
    对于e1f格式的可执行程序,是由ld-linux.so来完成的。
它先后搜索elf文件的DT_RPATH段 -> 环境变量LD_LIBRARY_PATH -> /etc/ld.so.cache文件列表 -> /lib/,/usr/lib目录找到库文件后将其载入内存。
4.gcc main.c -o main -I ./include/ -L ./lib/ -l calc
  • 静态库的优缺点
    image

  • 动态库的优缺点
    image

posted @ 2025-07-18 17:33  Xiaomostream  阅读(23)  评论(0)    收藏  举报