linux c 编程方法概述,Linux C编程初探

之前一直都是在Windows下享受IDE带来的各种便利,但对于程序到底是怎么从源代码变成可执行文件的,一直不甚明了。听了舒大师的Linux入门课后,研究一下在Linux下如何进行C语言程序开发。

主要从三个方面来展开:

GCC的基本使用

静态库和动态库的编译和链接

Makefile的编写

1. 任务概述

为了涵盖前面提出的三个主题,设置了如下的任务:

在4个c文件中分别实现4个函数,将其中两个文件编译为静态链接库,另两个文件编译为动态链接库,最后在主程序中分别调用这4个函数进行输出。

文件目录定义:

./bin //生成的可执行文件

./inc //头文件

func.h

./lib //生成的库文件

./obj //中间目标文件

./src //源文件

func_d1.c

func_d2.c

func_s1.c

func_s2.c

main.c

Makefile

2. GCC基本使用

不考虑库文件和makefile的使用,直接用GCC进行编译。

生成中间目标文件:

$ gcc -c src/func_d1.c

$ gcc -c src/func_d2.c

$ gcc -c src/func_s1.c

$ gcc -c src/func_s2.c

$ gcc -c src/main.c -I inc

链接文件:

$ gcc -o main func_d1.o func_d2.o func_s1.o func_s2.o main.o

结果测试:

$ ./main

结果输出:

hello world!

Using the static library.

Input number is: 1.

Using the dynamic library.

Input string is: hello.

当然,这里还并没有static library和dynamic library什么事,只是单纯地输出一些字符串而已。

3. 静态库和动态库

先删除之前生成的可执行文件,重新采用库文件的方式来实现。

$ rm main

3.1 静态链接库

将func_s1.c和func_s2.c这两个文件编译为静态链接库,生成libfunc_s.a。

$ ar rc libfunc_s.a func_s1.o func_s2.o

3.2 动态链接库

将func_d1.c和func_d2.c这两个文件编译为动态链接库,生成libfunc_d.so。

其中,需要以-fpic方式,重新编译func_d1.o和func_d2.o,使其适应共享库的调用方式。

$ gcc -c -fpic src/func_d1.c src/func_d2.c

$ gcc -shared func_d1.o func_d2.o -o libfunc_d.so

3.3 程序调用

同时调用这两个库文件,生成最终的可执行文件。

gcc src/main.c -I inc -L . -lfunc_s -Wl,-rpath lib -lfunc_d -o main

执行生成的main文件,结果与刚才相同,但此时才是真正地分别通过静态库和动态库的方式来实现函数调用的。

4. Makefile编写

通过编写Makefile文件,可以实现程序的自动化编译和链接,并且对于大型的程序,能够将文件组织得更加合理和有序。

Makefile文件如下所示:

SHELL = /bin/bash

CC = gcc

AR = ar rc

RM = rm -rf

MV = mv

MK = mkdir -p

INC_DIR = ./inc/

SRC_DIR = ./src/

OBJ_DIR = ./obj/

LIB_DIR = ./lib/

BIN_DIR = ./bin/

BIN_FILE = $(BIN_DIR)main

INC = $(INC_DIR)func.h

SRC_M = $(SRC_DIR)main.c

SRC_S = $(SRC_DIR)func_s1.c $(SRC_DIR)func_s2.c

SRC_D = $(SRC_DIR)func_d1.c $(SRC_DIR)func_d2.c

OBJ_M = main.o

OBJ_S = func_s1.o func_s2.o

OBJ_D = func_d1.o func_d2.o

LIB_S = $(LIB_DIR)libfunc_s.a

LIB_D = $(LIB_DIR)libfunc_d.so

all: init $(LIB_S) $(LIB_D) $(BIN_FILE)

init:

$(MK) $(OBJ_DIR)

$(MK) $(LIB_DIR)

$(MK) $(BIN_DIR)

$(LIB_S): $(OBJ_S)

$(AR) $(LIB_S) $(OBJ_S)

$(MV) $(OBJ_S) $(OBJ_DIR)

$(OBJ_S): $(SRC_S)

$(CC) -c $(SRC_S)

$(LIB_D): $(OBJ_D)

$(CC) -shared $(OBJ_D) -o $(LIB_D)

$(MV) $(OBJ_D) $(OBJ_DIR)

$(OBJ_D): $(SRC_D)

$(CC) -c -fpic $(SRC_D)

$(BIN_FILE): $(OBJ_M)

$(CC) $(OBJ_M) $(LIB_S) $(LIB_D) -o $(BIN_FILE)

$(MV) $(OBJ_M) $(OBJ_DIR)

$(OBJ_M): $(SRC_M)

$(CC) -c $(SRC_M) -I $(INC_DIR) -o $(OBJ_M)

clean:

$(RM) $(OBJ_DIR) $(LIB_DIR) $(BIN_DIR)

$(RM) *.o

其中:

执行make clean命令清除之前的编译结果。

执行make命令进行整个程序的编译链接。

结果测试:

$ bin/main

最终输出结果也和预想的一致。

至此,已经打通了在Linux下进行C语言程序开发的必要路径。

5. 附程序源文件

main.c

#include

#include "func.h"

void main(void)

{

printf("hello world!\n");

func_s1();

func_s2(1);

func_d1();

func_d2("hello");

return;

}

func.h

void func_s1(void);

void func_s2(int a);

void func_d1(void);

void func_d2(char *s);

func_s1.c

#include

void func_s1(void)

{

printf("Using the static library.\n");

return;

}

func_s2.c

#include

void func_s2(int a)

{

printf("Input number is: %d.\n", a);

return;

}

func_d1.c

#include

void func_d1(void)

{

printf("Using the dynamic library.\n");

return;

}

func_d2.c

#include

void func_d2(char *s)

{

printf("Input string is: %s.\n", s);

return;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值