makefile太难了,学不会,自己用Python写个简单的构建工具

来源:互联网 发布:windows informix 编辑:程序博客网 时间:2024/04/29 13:46

makefile 太复杂了,学的不精。自己用Python写一个构建工具,经过简单测试,可用



#!/usr/bin/env python  # -*- coding: utf-8 -*-    import sys  import argparse  import os  import commands  import re      # .c对应的.o文件  def obj_file_path(srcpath):      return srcpath[:-1] + 'o'      # 检测.[hc]是否比.o文件新  def is_newer_than(src, obj):      srcmtime = os.stat(src).st_mtime      if os.path.exists(obj):          objmtime = os.stat(obj).st_mtime      else:          objmtime = 0      return srcmtime > objmtime      # 检查是否需要重新编译.c文件  def need_compile_src(srcpath):      output = commands.getoutput('{} -MM {}'.format(cc, srcpath))      hlist = output.split(':')[1].strip().split(' ')      hfiles = [h for h in hlist if h.endswith('.h')]      objpath = obj_file_path(srcpath)    # 检查依赖的头文件是否更新了    for h in hfiles:          if is_newer_than(h, objpath):              return True    # 检查源文件是否更新了    if is_newer_than(srcpath, objpath):          return True        # 检查配置文件是否更新了    cfgpath = os.path.abspath('buildconfig')    execpath = os.path.abspath(execname)    if is_newer_than(cfgpath, execpath):        return True    return False          # target build  def build():      # compile      needlink = False      objfiles = []      for srcfile in srcfiles:          objfile = obj_file_path(srcfile)          objfiles.append(objfile)          if need_compile_src(srcfile):              needlink = True              cccmd = '{} {} -c {} -o {}'.format(cc, cflags, srcfile, objfile)              if not quiet:                  print(cccmd)              if os.system(cccmd):                  sys.exit(1)        # link      if needlink:          dependency = ''          for objfile in objfiles:              dependency += (' ' + objfile)          execpath = os.path.abspath(execname);          ldcmd = '{} {} {} -o {}'.format(cc, ldflags, dependency, execpath)          if not quiet:              print(ldcmd)          os.system(ldcmd)      def remove_file(filepath):      if os.path.exists(filepath):          if not quiet:              print('rm {}'.format(filepath))          os.remove(filepath)      # target clean  def clean():      # remove obj files      for srcfile in srcfiles:          objfile = obj_file_path(srcfile)                  remove_file(objfile)        # remove exec file      execpath = os.path.abspath(execname);      remove_file(execpath)      # generate the buildconfig file  def gen_buildconfig():      with open('buildconfig', 'w') as cfgfile:          cfgfile.writelines('''######## buildconfig ########  CC=cc                   # eg. cc/gcc/clang CFLAGS=-g LDFLAGS= EXECNAME=main  ''')      # parse command line opthons  def args_parser():      parser = argparse.ArgumentParser()      parser.add_argument('-c', '--config', action='store_true', help='create the buildconfig file')      parser.add_argument('-q', '--quiet', action='store_true', help='quiet')      parser.add_argument('target', nargs='?', choices=['build', 'clean'], default='build', help='build or clean.')      return parser      # parse buildconfig file  def parse_build_config():      variables = dict()      cfgpath = os.path.abspath('buildconfig');      if not os.path.exists(cfgpath):          print('先创建一个buildconfig文件')          parser.print_help()          sys.exit(2)        with open(cfgpath) as cfgfile:          pattern = re.compile(r'#.*$')              for line in cfgfile:              line = pattern.sub('', line)              line = line.strip()              pair = line.split('=')              if len(pair) == 2:                  variables[pair[0].strip()] = pair[1].strip()      return variables      # find all src files  def src_file_list(srcdir, ext):      srcfiles = []      for dirpath, dirnames, filenames in os.walk(srcdir):          for filename in filenames:              fileext = os.path.splitext(filename)[1]              if fileext == '.' + ext:                  srcpath = os.path.join(dirpath, filename)                  srcfiles.append(srcpath)      return srcfiles      # main entry  if __name__ == '__main__':      parser = args_parser()        # parse args      args = parser.parse_args()      quiet = args.quiet      config = args.config      if config:          gen_buildconfig()          sys.exit(0)        # parse variables      variables = parse_build_config();      cc = variables.setdefault('CC', 'cc')      cflags = variables.setdefault('CFLAGS', '-g')      ldflags = variables.setdefault('LDFLAGS', '')      execname = variables.setdefault('EXECNAME', 'main')        # src files      srcfiles = src_file_list(os.getcwd(), 'c')            # make target      if args.target == 'build':          build()      elif args.target == 'clean':          clean()        







使用演示




开启树莓派探索模式




                                             
0 0
原创粉丝点击