最近接手一个新的C++项目,写了一个自动化编译的脚本,包含单元测试的编译与执行。
脚本文件:Compile.py
# encoding:utf-8
import os
import datetime
import xml.etree.ElementTree as ET
class Target:
def __init__(self):
self.name = ""
self.build_dir = ""
self.result_dir = ""
self.target_type = ""
self.bit = ""
self.version = ""
def __str__(self):
return "name = %s, build_dir= %s, result_dir = %s, target_type = %s, bit = %s, version = %s"\
% (self.name, self.build_dir, self.result_dir, self.target_type, self.bit, self.version)
def get_xml_dict(source_file, target_list, unittest_list):
tree = ET.parse(source_file)
root = tree.getroot()
for child in root:
if child.tag == "targets" and child.get("compile") == "True":
for item in child:
target = Target()
target.name = item.get("name")
target.build_dir = item.get("build_dir")
target.result_dir = child.get("result_dir")
target.target_type = item.get("target_type")
target.bit = item.get("bit")
target.version = item.get("version")
target_list.append(target)
elif child.tag == "unit_tests" and child.get("compile") == "True":
for item in child:
target = Target()
target.name = item.get("name")
target.build_dir = item.get("build_dir")
target.result_dir = child.get("result_dir")
target.target_type = item.get("target_type")
target.bit = item.get("bit")
target.version = item.get("version")
unittest_list.append(target)
return root.get("build_type"), root.get("svn_path"), root.get("svn_version"), root.get("result_dir")
def compile_target(build_type, target, result_file):
print "Begin Compile Target: %s" % target.name
root_dir = os.getcwd()
os.chdir(target.build_dir)
write_version_file(target.version)
compile_file = "compile.bat"
write_compile_file(compile_file, target.name, target.bit, build_type)
ret = os.system(compile_file)
os.chdir(root_dir)
if ret != 0:
result = "Failed"
else:
result = "Success"
result_file.write("\nCompile %s %s.\n" % (target.name, result))
def pack(target, result_dir):
result_dir = result_dir + "\\" + target.result_dir
if not os.path.exists(result_dir):
os.mkdir(result_dir)
target_dir = result_dir + "\\" + target.name
if not os.path.exists(target_dir):
os.mkdir(target_dir)
build_info_dir = target_dir + "\\build_info"
if not os.path.exists(build_info_dir):
os.mkdir(build_info_dir)
if target.target_type == "dll":
os.system("copy %s\\%s.dll %s" % (target.build_dir, target.name, target_dir))
os.system("copy %s\\%s.lib %s" % (target.build_dir, target.name, target_dir))
elif target.target_type == "exe":
os.system("copy %s\\%s.exe %s" % (target.build_dir, target.name, target_dir))
os.system("copy %s\\%s.pdb %s" % (target.build_dir, target.name, build_info_dir))
os.system("copy %s\\%s_error.txt %s" % (target.build_dir, target.name, build_info_dir))
def exec_unittest(unittest_list, result_dir, result_file):
total_size = len(unittest_list)
if total_size == 0:
return 0
pass_count = 0
fail_count = 0
for unit_test in unittest_list:
target_dir = result_dir + "\\" + unit_test.result_dir + "\\" + unit_test.name
cmd = target_dir + "\\" + unit_test.name + ".exe"
ret = os.system(cmd)
if ret == 0:
result = "passed"
pass_count += 1
else:
result = "failed"
fail_count += 1
result_file.write("\nExec unittest %s %s" % (unit_test.name, result))
result_file.write("\n\nExec %d unittest, %d passed, %d failed.\n\n" % (total_size, pass_count, fail_count))
def svn_check_out(svn_path, svn_version, result_dir):
svn_path = svn_path.encode("gbk")
if svn_version == "":
cmd = "svn checkout %s ./" % svn_path
else:
cmd = "svn checkout %s ./ -r %s" % (svn_path, svn_version)
os.system("svn info %s > %s\\svn_info.txt" % (svn_path, result_dir))
os.system("echo %s >> %s\\svn_info.txt" % (cmd, result_dir))
os.system(cmd)
def get_dest_dir():
now = datetime.datetime.now()
dest_dir = "%04d%02d%02d_%02d%02d%02d" % (now.year, now.month, now.day, now.hour, now.minute, now.second)
return dest_dir
def write_version_file(version):
version_items = version.split('.')
print version_items
version_file = open("../src/version.h", "w")
version_file.write("#define MainVer %s\n" % version_items[0])
version_file.write("#define SubVer %s\n" % version_items[1])
version_file.write("#define PubVer %s\n" % version_items[2])
version_file.write("#define BuildVer %s\n" % version_items[3])
date_time = datetime.datetime.now()
version_file.write("#define UpdateDate %04d%02d%02d\n" % (date_time.year, date_time.month, date_time.day))
def write_compile_file(compile_file, name, bit, build_type):
env_cmd = 'call "%%VS_HOME%%/VC/vcvarsall.bat" %s\n' % bit
cmake_cmd = 'cmake -DCMAKE_BUILD_TYPE=%s .. -G"NMake Makefiles"\n' % build_type
nmake_cmd = 'nmake 2>>%s_error.txt\n' % name
command_file = open(compile_file, "w")
command_file.write(env_cmd)
command_file.write(cmake_cmd)
command_file.write(nmake_cmd)
command_file.close()
def main():
target_list = []
unittest_list = []
build_type, svn_path, svn_version, result_dir = get_xml_dict("compile.xml", target_list, unittest_list)
root_dir = os.getcwd()
dest_dir = get_dest_dir()
os.mkdir(dest_dir)
os.chdir(dest_dir)
if not os.path.exists(result_dir):
os.mkdir(result_dir)
os.system("copy ..\\compile.xml %s" % result_dir)
svn_check_out(svn_path, svn_version, result_dir)
result_file_name = result_dir + '\\' + 'result.txt'
result_file = open(result_file_name, mode="a")
for item in target_list:
compile_target(build_type, item, result_file)
pack(item, result_dir)
for item in unittest_list:
compile_target(build_type, item, result_file)
pack(item, result_dir)
exec_unittest(unittest_list, result_dir, result_file)
result_file.close()
os.system("type %s" % result_file_name)
os.chdir(root_dir)
if __name__ == '__main__':
main()
配置文件:Compile.xml