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

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()

使用演示

20151017141306747

20151017141350786

20151017141401887

20151017141441988

20151017141727521

开启树莓派探索模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值