include headers in cmake source, added a script to check for consistency, reporting missing headers & C files.
this is important so IDE's using CMake integration always get blender headers. - QtCreator & MSVC for eg, probably others too.
This commit is contained in:
191
build_files/cmake/cmake_consistency_check.py
Normal file
191
build_files/cmake/cmake_consistency_check.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# $Id:
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Contributor(s): Campbell Barton
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
IGNORE = \
|
||||
"/test/",\
|
||||
"/decimate_glut_test/",\
|
||||
"/BSP_GhostTest/",\
|
||||
"/release/",\
|
||||
"/xembed/",\
|
||||
"/decimation/intern/future/",\
|
||||
"/TerraplayNetwork/",\
|
||||
"/ik_glut_test/"
|
||||
|
||||
import os
|
||||
from os.path import join, dirname, normpath
|
||||
|
||||
base = join(os.getcwd(), "..", "..")
|
||||
base = normpath(base)
|
||||
|
||||
global_h = set()
|
||||
global_c = set()
|
||||
|
||||
import os
|
||||
from os.path import splitext
|
||||
def source_list(path, filename_check=None):
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
|
||||
# skip '.svn'
|
||||
if dirpath.startswith("."):
|
||||
continue
|
||||
|
||||
for filename in filenames:
|
||||
if filename_check is None or filename_check(filename):
|
||||
yield os.path.join(dirpath, filename)
|
||||
|
||||
# extension checking
|
||||
def is_c_header(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in (".h", ".hpp", ".hxx"))
|
||||
|
||||
def is_cmake(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".cmake") or (filename == "CMakeLists.txt")
|
||||
|
||||
def is_c_header(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in (".h", ".hpp", ".hxx"))
|
||||
|
||||
def is_c(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
|
||||
|
||||
def is_c_any(filename):
|
||||
return is_c(filename) or is_c_header(filename)
|
||||
|
||||
def cmake_get_src(f):
|
||||
|
||||
sources_h = []
|
||||
sources_c = []
|
||||
|
||||
filen = open(f, "r")
|
||||
it = iter(filen)
|
||||
found = False
|
||||
i = 0
|
||||
# print(f)
|
||||
while it is not None:
|
||||
while it is not None:
|
||||
i += 1
|
||||
try:
|
||||
l = next(it)
|
||||
except StopIteration:
|
||||
it = None
|
||||
break
|
||||
l = l.strip()
|
||||
if not l.startswith("#"):
|
||||
if 'SET(SRC' in l or ('SET(' in l and l.endswith("SRC")):
|
||||
if len(l.split()) > 1:
|
||||
raise Exception("strict formatting not kept 'SET(SRC*' %s:%d" % (f, i))
|
||||
found = True
|
||||
break
|
||||
|
||||
if "LIST(APPEND SRC" in l:
|
||||
if l.endswith(")"):
|
||||
raise Exception("strict formatting not kept 'LIST(APPEND SRC...)' on 1 line %s:%d" % (f, i))
|
||||
found = True
|
||||
break
|
||||
|
||||
if found:
|
||||
cmake_base = dirname(f)
|
||||
|
||||
while it is not None:
|
||||
i += 1
|
||||
try:
|
||||
l = next(it)
|
||||
except StopIteration:
|
||||
it = None
|
||||
break
|
||||
|
||||
l = l.strip()
|
||||
|
||||
if not l.startswith("#"):
|
||||
|
||||
if ")" in l:
|
||||
if l.strip() != ")":
|
||||
raise Exception("strict formatting not kept '*)' %s:%d" % (f, i))
|
||||
break
|
||||
|
||||
if not l:
|
||||
pass
|
||||
elif l.startswith("$"):
|
||||
print("Cant use var '%s' %s:%d" % (l, f, i))
|
||||
elif len(l.split()) > 1:
|
||||
raise Exception("Multi-line define '%s' %s:%d" % (l, f, i))
|
||||
else:
|
||||
new_file = normpath(join(cmake_base, l))
|
||||
|
||||
if is_c_header(new_file):
|
||||
sources_h.append(new_file)
|
||||
elif is_c(new_file):
|
||||
sources_c.append(new_file)
|
||||
else:
|
||||
raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file))
|
||||
|
||||
# print(new_file)
|
||||
|
||||
global_h.update(set(sources_h))
|
||||
global_c.update(set(sources_c))
|
||||
'''
|
||||
if not sources_h and not sources_c:
|
||||
raise Exception("No sources %s" % f)
|
||||
|
||||
sources_h_fs = list(source_list(cmake_base, is_c_header))
|
||||
sources_c_fs = list(source_list(cmake_base, is_c))
|
||||
'''
|
||||
# find missing C files:
|
||||
'''
|
||||
for ff in sources_c_fs:
|
||||
if ff not in sources_c:
|
||||
print(" missing: " + ff)
|
||||
'''
|
||||
|
||||
filen.close()
|
||||
|
||||
|
||||
for cmake in source_list(base, is_cmake):
|
||||
cmake_get_src(cmake)
|
||||
|
||||
def is_ignore(f):
|
||||
for ig in IGNORE:
|
||||
if ig in f:
|
||||
return True
|
||||
return False
|
||||
|
||||
# First do stupid check, do these files exist?
|
||||
for f in (global_h | global_c):
|
||||
if f.endswith("dna.c"):
|
||||
continue
|
||||
|
||||
if not os.path.exists(f):
|
||||
raise Exception("CMake referenced file missing: " + f)
|
||||
|
||||
|
||||
# now check on files not accounted for.
|
||||
print("\nC/C++ Files CMake doesnt know about...")
|
||||
for cf in sorted(source_list(base, is_c)):
|
||||
if not is_ignore(cf):
|
||||
if cf not in global_c:
|
||||
print("missing_c: ", cf)
|
||||
print("\nC/C++ Headers CMake doesnt know about...")
|
||||
for hf in sorted(source_list(base, is_c_header)):
|
||||
if not is_ignore(hf):
|
||||
if hf not in global_h:
|
||||
print("missing_h: ", hf)
|
||||
Reference in New Issue
Block a user