作者:朱金灿
来源:clever101的专栏
我经常使用的编译linux程序的makefile不太正式,类似如下:
g++ a.cpp b.cpp \
-I"/opt/ThirdPartyLib/pugixml/include" \
-L"/opt/ThirdPartyLib/pugixml/lib" -lpugixml \
-std=c++11 -fPIE -o /opt/bin/MyApp
这是一个简单的编译应用程序的makefile。制作这个makefile的痛点在哪里呢?假如一个模块存在很多源码文件的话,需要把很多的源码文件都加进makefile文件,这样工作量是很大的。此时可以考虑使用python来遍历源码目录来自动构建一个makefile文件。代码比较简单,如下:
#!/usr/bin/python
# -*- coding=utf-8 -*-
# author : [email protected]
# date: 2023-02-07
# version: 0.2
#propose:提供一个文件夹,生成对应的编译sh文件
import os
# 从指定path下递归获取所有文件
def getAllFile(path, fileList):
dirList = [] # 存放文件夹路径的列表
for ff in os.listdir(path):
wholepath = os.path.join(path, ff)
# wholepath = path+'/'+ff
if os.path.isdir(wholepath):
dirList.append(wholepath) # 如果是文件添加到结果文件列表中
if os.path.isfile(wholepath):
fileList.append(wholepath) # 如果是文件夹,存到文件夹列表中
for dir in dirList:
getAllFile(dir, fileList) # 对于dirList列表中的文件夹,递归提取其中的文件,fileList一直在往下传,所有的文件路径都会被保存在这个列表中
# 从文件路径列表中筛选出指定后缀的文件
# 这里可以从源列表中删除 非后缀 项,也可以新建一个 后缀列表,遍历源列表向后缀列表中.append()后缀项
# 后者更容易一些,我这里选择了前者,还费劲解决了一波list循环remove的问题。。。
# list循环remove http://itdarcy.wang/index.php/20200109/381
def getSufFilePath(fileList, suffixs):
# print(len(fileList))
for ff in fileList[:]:
bMatch = False
for suffix in suffixs[:]:
if ff.endswith(suffix):
bMatch = True
break
if not bMatch:
fileList.remove(ff)
# 遍历文件夹,获取里面的所有cpp文件名和c文件名
# 创建一个sh文件,将所有的文件名都写入到sh文件中
def CreateBuildShell(folder):
fileList = []
#用于过滤的文件后缀
suffixs = ['.cpp','.c']
getAllFile(folder, fileList)
getSufFilePath(fileList, suffixs)
shellFile = folder + "\\make.sh"
count =0
line = "g++ "
with open(shellFile, 'w') as file:
for codeFile in fileList:
fileName = os.path.basename(codeFile) # 带后缀的文件名
if(0==count):
line += fileName
else:
line +=" "+fileName
count = count+1
if(3==count):
line+=" \\"
file.write(line + '\n')
line = ""
count=0
if __name__ == "__main__":
folder = "D:\\MyProject\\MyApp"
CreateBuildShell(folder)
当然使用python生成的这个makefile文件叫make.sh,它只是一个半成品。效果如下:
g++ a.cpp b.cpp \
你还得添加包含的头文件路径、链接库路径以及库名称,输出是一个应用程序还是so库,还有其它一些gcc编译选项等。