nginx编译安装(ubuntu+rocky+openeuler)
apt install build-essential gcc g++ libc6 libc6-dev libpcre3 libpcre3-dev libssldev libsystemd-dev zlib1g-dev libssl-dev
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get update
# 安装 openssl 开发包
sudo apt-get install libssl-dev
apt install libxml2 libxml2-dev libxslt1-dev php-gd libgd-dev geoip-database libgeoip-dev
创建运行用户
root@ubuntu24:~# useradd -r -s /usr/sbin/nologin nginx
下载最新版源码并解压
root@ubuntu24:~# wget https://nginx.org/download/nginx-1.22.1.tar.gz
注意:
如果出现 “无法解析主机地址 ‘nginx.org’”,重新尝试下载即可root@ubuntu24:~# tar xf nginx-1.22.1.tar.gz
root@ubuntu24:~# cd nginx-1.22.1/
root@ubuntu24:nginx-1.22.1# ./configure --prefix=/data/server/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --withhttp_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
好的,这是一个关于 Makefile 的详细解释。它是理解 Linux/Unix 下软件编译流程的核心。
一、Makefile 是什么?
Makefile 是一个文本文件,它包含了构建(build)和管理软件项目的一系列规则。它被 make 工具读取并使用。
-
核心思想:定义源文件和目标文件之间的依赖关系,以及从源文件生成目标文件所需的命令。
-
主要优势:自动化且增量编译。
make工具会检查文件的时间戳,只有当源文件比目标文件新时,才会重新执行相应的命令。这避免了重复编译未更改的代码,极大地提高了编译效率。
二、一个简单的 Makefile 示例
让我们从一个最简单的例子开始,它展示了 Makefile 的基本结构:
# 这是一个注释
# 定义一个变量,表示编译器
CC = gcc
# 最终目标:要生成的可执行文件名叫 "myapp"
all: myapp
# 规则1: myapp 依赖于 main.o 和 utils.o
# 如果 main.o 或 utils.o 比 myapp 新,就会执行下面的命令来链接生成 myapp
myapp: main.o utils.o
$(CC) -o myapp main.o utils.o
# 规则2: main.o 依赖于 main.c 和 utils.h
# 如果 main.c 或 utils.h 比 main.o 新,就会执行命令编译 main.c
main.o: main.c utils.h
$(CC) -c main.c
# 规则3: utils.o 依赖于 utils.c 和 utils.h
utils.o: utils.c utils.h
$(CC) -c utils.c
# 规则4: 定义一个伪目标,它不生成实际的文件名称为 "clean" 的文件
clean:
rm -f *.o myapp
执行方式:
-
make或make all:会构建all目标,即myapp。 -
make clean:会执行clean目标下的命令,删除所有.o文件和myapp。
三、Makefile 的核心语法详解
1. 规则 (Rule)
这是 Makefile 最基本的单元。每条规则的结构如下:
target [target2 ...]: [prerequisite1 prerequisite2 ...]
[command1]
[command2]
...
-
target(目标):通常是需要生成的文件名(如
main.o,myapp),也可以是一个动作的名称(如clean),这称为伪目标。 -
prerequisite(先决条件/依赖):生成
target所需要的文件或其它目标。如果任何先决条件比目标文件新,make就会决定重新构建目标。 -
command(命令):由 shell 执行的命令。非常重要:命令前必须是一个真正的制表符(Tab),而不是空格。这是历史遗留问题,也是新手最容易犯的错误。
2. 变量 (Variables)
变量用于简化 Makefile 的编写和维护,类似于宏定义。
-
定义变量:
VAR_NAME = value -
使用变量:
$(VAR_NAME)或${VAR_NAME}
常见内置变量:
-
CC:C 语言编译器,默认为cc(通常是gcc的链接) -
CFLAGS:给 C 编译器的 flags,如-g -Wall -O2 -
LDFLAGS:给链接器的 flags -
LD:链接器,默认为ld -
$@:当前规则中的目标文件名 (自动变量) -
$<:当前规则中的第一个依赖文件 (自动变量) -
$^:当前规则中的所有依赖文件列表 (自动变量)
示例:使用变量优化上面的 Makefile
CC = gcc
CFLAGS = -Wall -g
OBJS = main.o utils.o
TARGET = myapp
$(TARGET): $(OBJS)
$(CC) -o $@ $^ # 等价于: gcc -o myapp main.o utils.o
main.o: main.c utils.h
$(CC) $(CFLAGS) -c $< # 等价于: gcc -Wall -g -c main.c
utils.o: utils.c utils.h
$(CC) $(CFLAGS) -c $< # 等价于: gcc -Wall -g -c utils.c
clean:
rm -f $(OBJS) $(TARGET)
3. 伪目标 (Phony Targets)
伪目标不代表一个实际的文件名,它只是一个标签,用于执行一系列命令。为了避免和同名文件冲突,应使用 .PHONY 显式声明。
.PHONY: all clean install
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
install: $(TARGET)
cp $(TARGET) /usr/local/bin/
4. 通配符和模式规则 (Wildcards and Pattern Rules)
-
通配符:和 shell 一样,
*,?,[...]可用于文件名。-
SRCS = *.c# (获取所有.c文件,但不完美) -
SRCS = $(wildcard *.c)# (使用 wildcard 函数更可靠)
-
-
模式规则:一种高级规则,用于为多个文件定义相同的构建方式。
-
%.o: %.c:这是一个模式规则,表示“如何从任何.c文件生成对应的.o文件”。
-
示例:使用模式规则极大简化 Makefile
CC = gcc
CFLAGS = -Wall -g
SRCS = $(wildcard *.c) # 获取所有.c文件,例如: main.c utils.c
OBJS = $(SRCS:.c=.o) # 将.c替换为.o,得到: main.o utils.o
TARGET = myapp
$(TARGET): $(OBJS)
$(CC) -o $@ $^
# 这条神奇的规则可以编译任何 .c 文件到 .o 文件
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
四、一个更通用、更强大的 Makefile 模板
这个模板适用于大多数中小型 C/C++ 项目。
# Compiler and flags
CC = gcc
CXX = g++
CFLAGS = -Wall -Wextra -g -std=c11
CXXFLAGS = -Wall -Wextra -g -std=c++17
LDFLAGS =
LDLIBS = -lm # Link with math library, if needed
# Project structure
SRC_DIR = src
BUILD_DIR = build
TARGET = $(BUILD_DIR)/myapp
# Automatically find all source files
SRCS = $(wildcard $(SRC_DIR)/*.c) $(wildcard $(SRC_DIR)/*.cpp)
# Generate object file names in the build directory
OBJS = $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
OBJS := $(OBJS:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
# Default target
all: $(TARGET)
# Link the target
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
# Compile C source files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
# Compile C++ source files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
# Create build directory if it doesn't exist
$(BUILD_DIR):
mkdir -p $@
# Clean up
.PHONY: clean
clean:
rm -rf $(BUILD_DIR)
# Run the program
.PHONY: run
run: $(TARGET)
./$(TARGET)
总结
| 概念 | 描述 | 示例 |
|---|---|---|
| 规则 | 定义目标、依赖和命令 | target: dep; command |
| 变量 | 存储文本以供复用 | CC = gcc |
| 自动变量 | make 自动设置的变量 |
$@ (目标名), $< (第一个依赖) |
| 伪目标 | 不代表文件的目标 | .PHONY: clean |
| 函数 | 处理文本的工具 | $(wildcard *.c) |
| 模式规则 | 通用构建规则 | %.o: %.c |
理解 Makefile 的关键在于掌握依赖关系树。make 工具会从你指定的最终目标(如 all)开始,递归地向下解析依赖树,根据文件的新旧程度决定是否需要重新执行命令,最终自底向上地完成整个构建过程。
浙公网安备 33010602011771号