1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# xcmoc.py 5# Run Qt moc on all classes that contain Q_OBJECT 6# 7# Created by Jaakko Keränen on 2017-05-07. 8# Copyright © 2017 Jaakko Keränen <jaakko.keranen@iki.fi> 9 10import sys, os, re, subprocess, hashlib 11 12IGNORED_HEADERS = ['glwindow.h'] 13 14def contains_qobject(fn): 15 for line in open(fn, 'rt').readlines(): 16 if 'Q_OBJECT' in line: 17 return True 18 return False 19 20def find_headers(dir_path): 21 headers = [] 22 for fn in os.listdir(dir_path): 23 if fn in IGNORED_HEADERS: continue 24 file_path = os.path.join(dir_path, fn) 25 if os.path.isdir(file_path): 26 headers += find_headers(file_path) 27 elif fn.endswith('.h'): 28 if contains_qobject(file_path): 29 headers.append(os.path.abspath(file_path)) 30 return headers 31 32# def find_source(name, dir_path = os.path.join(sys.argv[1], 'src')): 33# for fn in os.listdir(dir_path): 34# file_path = os.path.join(dir_path, fn) 35# if os.path.isdir(file_path): 36# found = find_source(name, file_path) 37# if found: return found 38# elif fn == name[:-2] + '.cpp': 39# return os.path.abspath(file_path) 40# return None 41 42def md5sum(text): 43 m = hashlib.md5() 44 m.update(text.encode()) 45 m.update(os.getenv('GCC_PREPROCESSOR_DEFINITIONS').encode()) 46 m.update(os.getenv('HEADER_SEARCH_PATHS').encode()) 47 return m.hexdigest() 48 49#print "Running moc in", sys.argv[1] 50OUT_DIR = os.getenv('PROJECT_TEMP_DIR') 51try: 52 os.makedirs(OUT_DIR) 53except: 54 pass 55 56headers = find_headers(sys.argv[1]) 57 58QT_DIR = os.getenv('QT_DIR') 59defines = ['-D%s' % d for d in os.getenv('GCC_PREPROCESSOR_DEFINITIONS').split()] 60includes = ['-I%s' % d for d in re.split(r"(?<=\w)\s", os.getenv('HEADER_SEARCH_PATHS'))] 61args = ['%s/bin/moc' % QT_DIR] + defines + includes 62 63compilation = ['/* This file is autogenerated by xcmoc.py */'] 64 65for header in headers: 66 header_name = os.path.basename(header) 67 dir_path = os.path.dirname(header) 68 moc_name = '%s_moc_%s.cpp' % (md5sum(dir_path), header_name[:-2]) 69 moc_path = os.path.join(OUT_DIR, moc_name) 70 71 compilation.append('#include "%s"' % moc_name) 72 73 # Check timestamps. 74 if not os.path.exists(moc_path) or \ 75 os.path.getmtime(header) > os.path.getmtime(moc_path): 76 print 'Running moc:', header_name 77 subprocess.check_output(args + [header, '-o', moc_path], stderr=subprocess.STDOUT) 78 79comp_path = os.path.join(OUT_DIR, '%s_moc_compilation.cpp' % os.getenv('TARGETNAME')) 80 81open(comp_path, 'wt').write("\n".join(compilation) + "\n") 82 83