今天开始nginx的学习,Mark一下。争取能在一个月入门个皮毛,对于nginx的打算,主要是学习其各种应用场景和配置,下好源码只是为了配合理解。
搭建调试环境
首先还是搭个调试环境,下好了nginx代码以后,查看目录。
localhost:nginx-master jjchen$ tree -L 1
.
├── Makefile
├── auto
├── conf
├── contrib
├── docs
├── misc
├── objs
└── src
直接编译
bash auto/configure
make
程序就编译好了,可执行程序生成在objs/nginx。
代码在src中,我们用ide将代码导入,我这里是xcode。此处直接导入代码,没有处理编译错误,不能直接debug运行了,我们直接用附加程序的方式来调试。注意先附加到进程,后启动程序。
进入objs目录,启动nginx程序,这里用了root权限,不然一些日志文件创建不了。
sudo ./nginx -c ../conf/ngin.conf
开始跟踪代码。--- 发现了大问题,debug的堆栈信息好像不准,而且IDE内函数不能跳转。。
看来不能偷懒了,还是回到开头,修改配置,修改代码让IDE能直接Debug起来;整个过程花了我两个多小时。记录一下避免后人踩坑。
有几个步骤。
1.加入头文件路径,这个在makefile文件可以找到。
-I src/core \
-I src/event \
-I src/event/modules \
-I src/os/unix \
-I objs \
-I src/http \
-I src/http/modules
2.1 直接删掉其他平台的代码,比如win,linux非macos部分。
2.2 删掉其他makefile文件中没有的.c、.cpp文件。这个还是写个程序来做吧,如下。
import java.io.*;
import java.nio.CharBuffer;
import java.util.*;
public class FilterCppsInMakefile {
private static String srcRoot = "/Users/jjchen/cpro/nginx-test/src";
private static String MakefilePath = "/Users/jjchen/cpro/nginx-master/objs/Makefile";
private static Map<String,String> cppFiles = new HashMap<>();
public static void GetCppFiles(String dirPath){
File dir = new File(dirPath);
if (!dir.isDirectory()){
throw new RuntimeException("can not read path: "+dirPath);
}
File []srcs = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()){
GetCppFiles(pathname.getPath());
return false;
}
return pathname.getName().endsWith(".c")||pathname.getName().endsWith(".cpp");
}
});
for (File src: srcs){
cppFiles.put(src.getName().replace(".c","").replace(".cpp",""),src.getAbsolutePath());
}
}
public static String read (String filePath)throws Exception{
Reader reader = new BufferedReader(new FileReader(filePath));
StringBuilder stringBuilder = new StringBuilder();
String part = "";
while((part =((BufferedReader) reader).readLine())!= null){
stringBuilder.append(part);
}
return stringBuilder.toString();
}
public static void deleteSrcFiles(List<String>fileList){
for(String fileName : fileList) {
for (int i=0; i<2;i++){
File file = new File(fileName);
if (!file.exists()) {
continue;
} else {
if (file.isFile())
file.delete();
}
//同时删除头文件
fileName = fileName.replace(".cpp",".h").replace(".c",".h");
}
}
}
public static void main(String[] args) {
GetCppFiles(srcRoot);
String content = "";
try {
content = read(MakefilePath);
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println(cppFiles.toString());
List<String> delList= new ArrayList<>();
Iterator<HashMap.Entry<String,String>> iterator = cppFiles.entrySet().iterator();
while (iterator.hasNext()){
HashMap.Entry<String,String> node = iterator.next();
if(!content.contains(node.getKey())){
delList.add(node.getValue());
}
}
System.out.println(cppFiles.size());
System.out.println(Arrays.toString(delList.toArray()));
deleteSrcFiles(delList);
}
}
导入正则的库,我本地的头文件 /usr/local/Cellar/pcre/8.41/include/,静态库libpre.a;
执行完make以后,将objs文件夹下的ngx_modules.c文件和两个头文件拷入代码。
做完这些就可以正常启动了。去掉空的文件夹只剩下如下的模块。