在CentOS系统下编写GCC编译脚本可以帮助自动化编译过程,提高开发效率。以下是编写GCC编译脚本的基本步骤和示例:
使用文本编辑器(如vim, nano等)创建一个新的脚本文件。例如,创建一个名为build.sh的脚本:
#!/bin/bash
# 编译脚本示例
赋予脚本执行权限:
chmod +x build.sh
在脚本中添加GCC编译所需的命令。例如:
#!/bin/bash
# 设置编译器选项
CFLAGS="-Wall -g"
# 源文件
SOURCES="main.c foo.c bar.c"
# 目标文件
OBJECTS=${SOURCES%.c}.o
# 可执行文件名
EXECUTABLE=myapp
# 清理生成的文件
clean:
rm -f ${OBJECTS} ${EXECUTABLE}
# 编译规则
all: ${EXECUTABLE}
${EXECUTABLE}: ${OBJECTS}
${CC} ${CFLAGS} -o ${EXECUTABLE} ${OBJECTS}
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
.PHONY: all clean
执行编译脚本:
./build.sh
CFLAGS="-Wall -g"
-Wall:开启所有常用警告。-g:生成调试信息,便于使用调试器(如gdb)调试程序。SOURCES="main.c foo.c bar.c"
OBJECTS=${SOURCES%.c}.o
SOURCES:列出所有需要编译的源文件。OBJECTS:通过参数替换去除.c后缀,并添加.o生成目标文件列表。EXECUTABLE=myapp
clean:
rm -f ${OBJECTS} ${EXECUTABLE}
clean目标,用于删除生成的目标文件和可执行文件,方便重新编译。all: ${EXECUTABLE}
${EXECUTABLE}: ${OBJECTS}
${CC} ${CFLAGS} -o ${EXECUTABLE} ${OBJECTS}
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
all:默认目标,生成可执行文件。${EXECUTABLE}: ${OBJECTS}:指定如何生成可执行文件,依赖于所有目标文件。%.o: %.c:模式规则,指定如何从.c文件生成.o文件。.PHONY: all clean
all和clean为伪目标,确保即使存在同名文件也会执行相应命令。可以使用wildcard函数自动检测源文件,避免手动维护源文件列表:
SOURCES=$(wildcard *.c)
OBJECTS=${SOURCES%.c}.o
如果项目中有多个可执行文件,可以修改编译规则。例如:
EXECUTABLES="myapp utils"
all: ${EXECUTABLES}
${EXECUTABLES}: %: %.o
${CC} ${CFLAGS} -o $@ $<
%.o: %.c
${CC} ${CFLAGS} -c $< -o $@
clean:
rm -f ${OBJECTS} ${EXECUTABLES}
手动管理依赖关系可能繁琐,可以使用gcc -M生成依赖文件,并在编译脚本中包含这些依赖:
DEPENDS=$(SOURCES:.c=.d)
-include ${DEPENDS}
%.d: %.c
${CC} -MM ${CFLAGS} $< > $@
以下是一个功能较为完整的GCC编译脚本示例:
#!/bin/bash
# 编译器
CC=gcc
# 编译器选项
CFLAGS="-Wall -g -O2"
# 源文件目录
SRC_DIR=src
# 头文件目录
INC_DIR=include
# 目标文件目录
OBJ_DIR=obj
# 可执行文件目录
BIN_DIR=bin
# 源文件
SOURCES=$(wildcard ${SRC_DIR}/*.c)
# 头文件
HEADERS=$(wildcard ${INC_DIR}/*.h)
# 目标文件
OBJECTS=${SOURCES:${SRC_DIR}=${OBJ_DIR}}.o
# 可执行文件
EXECUTABLE=${BIN_DIR}/myapp
# 创建目标目录
mkdir -p ${OBJ_DIR} ${BIN_DIR}
# 编译规则
all: ${EXECUTABLE}
${EXECUTABLE}: ${OBJECTS}
${CC} ${CFLAGS} -o $@ $^
${OBJ_DIR}/%.o: ${SRC_DIR}/%.c | ${OBJ_DIR}
${CC} ${CFLAGS} -I${INC_DIR} -c $< -o $@
${OBJ_DIR}:
mkdir -p ${OBJ_DIR}
clean:
rm -rf ${OBJ_DIR} ${BIN_DIR}
.PHONY: all clean
目录结构:
project/
├── bin/
├── include/
│ └── header.h
├── obj/
├── src/
│ ├── main.c
│ ├── foo.c
│ └── bar.c
└── build.sh
功能:
src目录下的所有.c文件,并编译生成obj目录下的.o文件。bin目录下。虽然Shell脚本可以实现编译自动化,但Makefile更为强大和灵活,特别适用于大型项目。以下是一个简单的Makefile示例:
# 编译器
CC=gcc
# 编译器选项
CFLAGS=-Wall -g -O2
# 源文件目录
SRC_DIR=src
# 头文件目录
INC_DIR=include
# 目标文件目录
OBJ_DIR=obj
# 可执行文件目录
BIN_DIR=bin
# 源文件
SOURCES=$(wildcard $(SRC_DIR)/*.c)
# 头文件
HEADERS=$(wildcard $(INC_DIR)/*.h)
# 目标文件
OBJECTS=$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SOURCES))
# 可执行文件
EXECUTABLE=$(BIN_DIR)/myapp
# 默认目标
all: $(EXECUTABLE)
# 链接生成可执行文件
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
# 编译生成目标文件
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) $(CFLAGS) -I$(INC_DIR) -c $< -o $@
# 创建目标目录
$(OBJ_DIR):
mkdir -p $(OBJ_DIR)
# 清理
clean:
rm -rf $(OBJ_DIR) $(BIN_DIR)
.PHONY: all clean
Makefile,放在项目根目录。make
make clean
编写GCC编译脚本可以显著提高编译效率,尤其是在处理大型项目时。根据项目需求,可以选择使用Shell脚本或Makefile来实现自动化编译。Makefile提供了更强大的依赖管理和构建规则,适合复杂的项目结构。掌握这些工具的使用,将有助于提升开发体验和项目管理能力。