甘肃省长城建设集团网站,推广代理公司,前端网站开发,百度指数热度榜1.写在前面对于Windows下开发#xff0c;很多IDE都集成了编译器#xff0c;如Visual Studio#xff0c;提供了“一键编译”#xff0c;编码完成后只需一个操作即可完成编译、链接、生成目标文件。Linux开发与Windows不同#xff0c;Linux下一般用的的gcc/g编译器#xff… 1.写在前面对于Windows下开发很多IDE都集成了编译器如Visual Studio提供了“一键编译”编码完成后只需一个操作即可完成编译、链接、生成目标文件。Linux开发与Windows不同Linux下一般用的的gcc/g编译器如果是开发ARM下的Linux程序还需用到arm-linux-gcc/arm-linux-g交叉编译器。Linux下也可以实现“一键编译”功能此时需要一个编译脚本“Makefile”Makefile可以手动编写也可以借助自动化构建工具如scons、CMake生成。手动编写Makefile是Linux和Windows程序员的区别之一一般地一个通用的Makefile能够适合大部分Linux项目程序。2.通用Makefile模板2.1 编译可执行文件MakefileVERSION 1.00
CC gcc
DEBUG -DUSE_DEBUG
CFLAGS -Wall
SOURCES $(wildcard ./source/*.c)
INCLUDES -I./include
LIB_NAMES -lfun_a -lfun_so
LIB_PATH -L./lib
OBJ $(patsubst %.c, %.o, $(SOURCES))
TARGET app#links
$(TARGET):$(OBJ)mkdir -p output$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)rm -rf $(OBJ)#compile
%.o: %.c$(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $ -o $.PHONY:clean
clean:echo Remove linked and compiled files......rm -rf $(OBJ) $(TARGET) output【要点说明】【1】程序版本 开发调试过程可能产生多个程序版本可以在目标文件后前增加版本号标识。VERSION 1.00
$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET)$(VERSION)【2】编译器选择 Linux下为gcc/garm下为arm-linux-gcc不同CPU厂商提供的定制交叉编译器名称可能不同如Hisilicon“arm-hisiv300-linux-gcc”。CC gcc【3】宏定义 开发过程特殊代码一般增加宏条件来选择是否编译如调试打印输出代码。-D是标识后面接着的是“宏”。DEBUG -DUSE_DEBUG【4】编译选项 可以指定编译条件如显示警告-Wall优化等级-O。CFLAGS -Wall -O【5】源文件 指定源文件目的路径利用“wildcard”获取路径下所有依赖源文件。SOURCES $(wildcard ./source/*.c)【6】头文件 包含依赖的头文件包括源码文件和库文件的头文件。INCLUDES -I./include【7】库文件名称 指定库文件名称库文件有固定格式静态库为libxxx.a;动态库为libxxx.so指定库文件名称只需写“xxx”部分LIB_NAMES -lfun_a -lfun_so【8】库文件路径 指定依赖库文件的存放路径。注意如果引用的是动态库动态库也许拷贝到“/lib”或者“/usr/lib”目录下执行应用程序时系统默认在该文件下索引动态库。LIB_PATH -L./lib【9】目标文件 调用“patsubst”将源文件.c编译为目标文件.o。OBJ $(patsubst %.c, %.o, $(SOURCES))【10】执行文件 执行文件名称TARGET app【11】编译%.o: %.c$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $ -o $【12】链接 可创建一个“output”文件夹存放目标执行文件。链接完输出目标执行文件可以删除编译产生的临时文件.o。$(TARGET):$(OBJ)mkdir -p output$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) -o output/$(TARGET).$(VERSION)rm -rf $(OBJ)【13】清除编译信息 执行“make clean”清除编译产生的临时文件。.PHONY:clean
clean:echo Remove linked and compiled files......rm -rf $(OBJ) $(TARGET) output2.2 编译静态库MakefileVERSION
CC gcc
DEBUG
CFLAGS -Wall
AR ar
ARFLAGS rv
SOURCES $(wildcard *.c)
INCLUDES -I.
LIB_NAMES
LIB_PATH
OBJ $(patsubst %.c, %.o, $(SOURCES))
TARGET libfun_a#link
$(TARGET):$(OBJ)mkdir -p output$(AR) $(ARFLAGS) output/$(TARGET)$(VERSION).a $(OBJ)rm -rf $(OBJ)#compile
%.o: %.c$(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $ -o $.PHONY:clean
clean:echo Remove linked and compiled files......rm -rf $(OBJ) $(TARGET) output【要点说明】 基本格式与“编译可执行Makefile”一致不同点包括以下。【1】使用到“ar”命令将目标文件.o链接成静态库文件.a。静态库文件固定命名格式为libxxx.a。2.3 编译动态库MakefileVERSION
CC gcc
DEBUG
CFLAGS -fPIC -shared
LFLAGS -fPIC -shared
SOURCES $(wildcard *.c)
INCLUDES -I.
LIB_NAMES
LIB_PATH
OBJ $(patsubst %.c, %.o, $(SOURCES))
TARGET libfun_so#link
$(TARGET):$(OBJ)mkdir -p output$(CC) $(OBJ) $(LIB_PATH) $(LIB_NAMES) $(LFLAGS) -o output/$(TARGET)$(VERSION).sorm -rf $(OBJ)#compile
%.o: %.c$(CC) $(INCLUDES) $(DEBUG) -c $(CFLAGS) $ -o $.PHONY:clean
clean:echo Remove linked and compiled files......rm -rf $(OBJ) $(TARGET) output【要点说明】 基本格式与“编译可执行Makefile”一致不同点包括以下。【1】编译选项和链接选项增加“-fPIC -shared ”选项。动态库文件固定命名格式为libxxx.so。3.Demo3.1 应用程序编写测试例程文件存放目录结构如下头文件存放在“include”目录库文件存放在“lib”目录源文件存放在“source”目录Makefile在当前目录下。源码1/*头文件*/
#ifndef _FUN0_H_
#define _FUN0_H_
#endifextern void fun0_printf(void);
extern void fun1_printf(void);/*源文件*/
#include stdio.h
#include fun0.hvoid fun0_printf(void)
{printf(Call \fun0\. \r\n);
}源码2/*头文件*/
#ifndef _FUN1_H_
#define _FUN1_H_
#endifextern void fun1_printf(void);/*源文件*/
#include stdio.h
#include fun1.hvoid fun1_printf(void)
{printf(Call \fun1\.\r\n);
}主函数源码/*源文件*/
#include stdio.h
#include fun0.h
#include fun1.h
#include fun_lib_a.h
#include fun_lib_so.hint main(void)
{#ifdef USE_DEBUGprintf(Debug Application startup.\r\n);#endiffun0_printf();fun1_printf();fun_lib_a_printf();fun_lib_so_printf();return 0;
}库文件“./lib”目录下存放两个库文件一个静态库libfun_a.a一个动态库libfun_so.so。Makefile文件即为“2.1节”的Makefile模板。测试运行【如果执行文件提示无“libfun_so.so”,则需拷贝“libfun_so.so”到根目录下的“/lib”或者“/usr/lib”目录下因为系统执行程序默认从该路径引脚动态库】3. 2 生成静态库编写测试例程生产的库文件即为“3.1节”调用的库文件libfun_a.a。文件存放目录结构如下源文件/*头文件*/
#ifndef _FUN_LIB_A_H_
#define _FUN_LIB_A_H_
#endifextern void fun_lib_a_printf(void);/*源文件*/
#include stdio.h
#include fun_lib_a.hvoid fun_lib_a_printf(void)
{printf(Call \fun_lib_a\.\r\n);
}Makefile文件即为“2.2节”的Makefile模板。编译生成静态库3. 3 生成静态库编写测试例程生产的库文件即为“3.1节”调用的库文件libfun_so.so。文件存放目录结构如下源文件/*头文件*/
#ifndef _FUN_LIB_SO_H_
#define _FUN_LIB_SO_H_
#endifextern void fun_lib_so_printf(void);/*头文件*/#include stdio.h
#include fun_lib_so.hvoid fun_lib_so_printf(void)
{printf(Call \fun_lib_so\.\r\n);
}编译生成动态库