From 0460a68ae7d2ef7f771c407dd5b9f9c86d2c8d49 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 May 2011 04:04:06 +0000 Subject: [PATCH] made generic module for generating project files from cmake, added netbeans project file generator. --- build_files/cmake/cmake_netbeans_project.py | 227 +++++++++++++++++++ build_files/cmake/cmake_qtcreator_project.py | 176 +------------- build_files/cmake/project_info.py | 218 ++++++++++++++++++ 3 files changed, 450 insertions(+), 171 deletions(-) create mode 100755 build_files/cmake/cmake_netbeans_project.py create mode 100644 build_files/cmake/project_info.py diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py new file mode 100755 index 00000000000..7709bac12e6 --- /dev/null +++ b/build_files/cmake/cmake_netbeans_project.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +# $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, M.G. Kishalmi +# +# ***** END GPL LICENSE BLOCK ***** + +# + +""" +Example linux usage + python .~/blenderSVN/blender/build_files/cmake/cmake_netbeans_project.py ~/blenderSVN/cmake + +Windows not supported so far +""" + +from project_info import * + +import os +from os.path import join, dirname, normpath, abspath, splitext, relpath, exists + + +def create_nb_project_main(): + files = list(source_list(SOURCE_DIR, filename_check=is_project_file)) + files_rel = [relpath(f, start=PROJECT_DIR) for f in files] + files_rel.sort() + + if SIMPLE_PROJECTFILE: + pass + else: + includes, defines = cmake_advanced_info() + # for some reason it doesnt give all internal includes + includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f))) + includes.sort() + + PROJECT_NAME = "Blender" + FILE_NAME = PROJECT_NAME.lower() + + # --------------- NB spesific + defines = [("%s=%s" % cdef) if cdef[1] else cdef[0] for cdef in defines] + defines += [cdef.replace("#define", "").strip() for cdef in cmake_compiler_defines()] + + def file_list_to_nested(files): + # convert paths to hierarchy + paths_nested = {} + + def ensure_path(filepath): + filepath_split = filepath.split(os.sep) + + pn = paths_nested + for subdir in filepath_split[:-1]: + pn = pn.setdefault(subdir, {}) + pn[filepath_split[-1]] = None + + for path in files: + ensure_path(path) + return paths_nested + + PROJECT_DIR_NB = join(PROJECT_DIR, "nbproject") + if not exists(PROJECT_DIR_NB): + os.mkdir(PROJECT_DIR_NB) + + SOURCE_DIR_REL = relpath(SOURCE_DIR, PROJECT_DIR) + + f = open(join(PROJECT_DIR_NB, "project.xml"), 'w') + + f.write('\n') + f.write('\n') + f.write(' org.netbeans.modules.cnd.makeproject\n') + f.write(' \n') + f.write(' \n') + f.write(' %s\n' % PROJECT_NAME) + f.write(' c,m\n') + f.write(' cpp,mm\n') + f.write(' h,hpp,inl\n') + f.write(' UTF-8\n') + f.write(' \n') + f.write(' \n') + f.write(' %s\n' % SOURCE_DIR) # base_root_rel + f.write(' \n') + f.write(' \n') + f.write(' \n') + f.write(' Default\n') + f.write(' 0\n') + f.write(' \n') + f.write(' \n') + f.write(' \n') + f.write(' \n') + f.write('\n') + + f = open(join(PROJECT_DIR_NB, "configurations.xml"), 'w') + + f.write('\n') + f.write('\n') + f.write(' \n') + f.write(' \n' % SOURCE_DIR) # base_root_rel + + # write files! + files_rel_local = [normpath(relpath(join(CMAKE_DIR, path), SOURCE_DIR)) for path in files_rel] + files_rel_hierarchy = file_list_to_nested(files_rel_local) + # print(files_rel_hierarchy) + + def write_df(hdir, ident): + dirs = [] + files = [] + for key, item in sorted(hdir.items()): + if item is None: + files.append(key) + else: + dirs.append((key, item)) + + for key, item in dirs: + f.write('%s \n' % (ident, key)) + write_df(item, ident + " ") + f.write('%s \n' % ident) + + for key in files: + f.write('%s%s\n' % (ident, key)) + + write_df(files_rel_hierarchy, ident=" ") + + f.write(' \n') + + f.write(' \n') + # f.write(' ../GNUmakefile\n') + f.write(' \n') + + f.write(' \n') + f.write(' ^(nbproject)$\n') + f.write(' \n') + f.write(' %s\n' % SOURCE_DIR) # base_root_rel + f.write(' \n') + + f.write(' Makefile\n') + + # paths again + f.write(' \n') + f.write(' \n') + + f.write(' \n') + f.write(' LOCAL_SOURCES\n') + f.write(' default\n') + f.write(' \n') + f.write(' \n') + + f.write(' \n') + f.write(' .\n') + f.write(' ${MAKE} -f Makefile\n') + f.write(' ${MAKE} -f Makefile clean\n') + f.write(' ./bin/blender\n') + + def write_toolinfo(): + f.write(' \n') + for inc in includes: + f.write(' %s\n' % inc) + f.write(' \n') + f.write(' \n') + for cdef in defines: + f.write(' %s\n' % cdef) + f.write(' \n') + + f.write(' \n') + write_toolinfo() + f.write(' \n') + + f.write(' \n') + write_toolinfo() + f.write(' \n') + + f.write(' \n') + f.write(' \n') + # finishe makefle info + + f.write(' \n') + + for path in files_rel_local: + f.write(' \n') + f.write(' \n') + + f.write(' \n') + f.write(' \n') + f.write(' \n') + f.write(' %s\n' % os.path.join(CMAKE_DIR, "bin/blender")) + f.write(' %s\n' % SOURCE_DIR) + f.write(' false\n') + f.write(' 0\n') + f.write(' 0\n') + f.write(' \n') + f.write(' \n') + f.write(' \n') + + f.write(' \n') + f.write(' \n') + + # todo + + f.write('\n') + + +def main(): + create_nb_project_main() + + +if __name__ == "__main__": + main() diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 59b8b2a3b02..2159f34ae76 100644 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -31,182 +31,16 @@ example linux usage python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake """ -import sys +from project_info import * + import os from os.path import join, dirname, normpath, abspath, splitext, relpath, exists -base = join(os.path.dirname(__file__), "..", "..") -base = normpath(base) -base = abspath(base) - -SIMPLE_PROJECTFILE = False - -# get cmake path -CMAKE_DIR = sys.argv[-1] - -if not os.path.exists(os.path.join(CMAKE_DIR, "CMakeCache.txt")): - CMAKE_DIR = os.getcwd() -if not os.path.exists(os.path.join(CMAKE_DIR, "CMakeCache.txt")): - print("CMakeCache.txt not found in %r or %r\n Pass CMake build dir as an argument, or run from that dir, aborting" % (CMAKE_DIR, os.getcwd())) - sys.exit(1) - - -# could be either. -# PROJECT_DIR = base -PROJECT_DIR = CMAKE_DIR - - -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: - filepath = join(dirpath, filename) - if filename_check is None or filename_check(filepath): - yield filepath - - -# extension checking -def is_cmake(filename): - ext = splitext(filename)[1] - return (ext == ".cmake") or (filename.endswith("CMakeLists.txt")) - - -def is_c_header(filename): - ext = splitext(filename)[1] - return (ext in (".h", ".hpp", ".hxx")) - - -def is_py(filename): - ext = splitext(filename)[1] - return (ext == ".py") - - -def is_glsl(filename): - ext = splitext(filename)[1] - return (ext == ".glsl") - - -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 is_svn_file(filename): - dn, fn = os.path.split(filename) - filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn) - return exists(filename_svn) - - -def is_project_file(filename): - return (is_c_any(filename) or is_cmake(filename) or is_glsl(filename)) # and is_svn_file(filename) - - -def cmake_advanced_info(): - """ Extracr includes and defines from cmake. - """ - - def create_eclipse_project(CMAKE_DIR): - print("CMAKE_DIR %r" % CMAKE_DIR) - if sys.platform == "win32": - cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR - else: - cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR - - os.system(cmd) - - includes = [] - defines = [] - - create_eclipse_project(CMAKE_DIR) - - from xml.dom.minidom import parse - tree = parse(os.path.join(CMAKE_DIR, ".cproject")) - ''' - f = open(".cproject_pretty", 'w') - f.write(tree.toprettyxml(indent=" ", newl="")) - ''' - ELEMENT_NODE = tree.ELEMENT_NODE - - cproject, = tree.getElementsByTagName("cproject") - for storage in cproject.childNodes: - if storage.nodeType != ELEMENT_NODE: - continue - - if storage.attributes["moduleId"].value == "org.eclipse.cdt.core.settings": - cconfig = storage.getElementsByTagName("cconfiguration")[0] - for substorage in cconfig.childNodes: - if substorage.nodeType != ELEMENT_NODE: - continue - - moduleId = substorage.attributes["moduleId"].value - - # org.eclipse.cdt.core.settings - # org.eclipse.cdt.core.language.mapping - # org.eclipse.cdt.core.externalSettings - # org.eclipse.cdt.core.pathentry - # org.eclipse.cdt.make.core.buildtargets - - if moduleId == "org.eclipse.cdt.core.pathentry": - for path in substorage.childNodes: - if path.nodeType != ELEMENT_NODE: - continue - kind = path.attributes["kind"].value - - if kind == "mac": - # - defines.append((path.attributes["name"].value, path.attributes["value"].value)) - elif kind == "inc": - # - includes.append(path.attributes["include"].value) - else: - pass - - return includes, defines - - -def cmake_cache_var(var): - cache_file = open(os.path.join(CMAKE_DIR, "CMakeCache.txt")) - lines = [l_strip for l in cache_file for l_strip in (l.strip(),) if l_strip if not l_strip.startswith("//") if not l_strip.startswith("#")] - cache_file.close() - - for l in lines: - if l.split(":")[0] == var: - return l.split("=", 1)[-1] - return None - - -def cmake_compiler_defines(): - compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too - - if compiler is None: - print("Couldn't find the compiler, os defines will be omitted...") - return - - import tempfile - temp_c = tempfile.mkstemp(suffix=".c")[1] - temp_def = tempfile.mkstemp(suffix=".def")[1] - - os.system("%s -dM -E %s > %s" % (compiler, temp_c, temp_def)) - - temp_def_file = open(temp_def) - lines = [l.strip() for l in temp_def_file if l.strip()] - temp_def_file.close() - - os.remove(temp_c) - os.remove(temp_def) - return lines +import sys def create_qtc_project_main(): - files = list(source_list(base, filename_check=is_project_file)) + files = list(source_list(SOURCE_DIR, filename_check=is_project_file)) files_rel = [relpath(f, start=PROJECT_DIR) for f in files] files_rel.sort() @@ -260,7 +94,7 @@ def create_qtc_project_main(): def create_qtc_project_python(): - files = list(source_list(base, filename_check=is_py)) + files = list(source_list(SOURCE_DIR, filename_check=is_py)) files_rel = [relpath(f, start=PROJECT_DIR) for f in files] files_rel.sort() diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py new file mode 100644 index 00000000000..77b9cff21f2 --- /dev/null +++ b/build_files/cmake/project_info.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python + +# $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, M.G. Kishalmi +# +# ***** END GPL LICENSE BLOCK ***** + +# + +""" +Example Win32 usage: + c:\Python32\python.exe c:\blender_dev\blender\build_files\cmake\cmake_qtcreator_project.py c:\blender_dev\cmake_build + +example linux usage + python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake +""" + +__all__ = ( + "SIMPLE_PROJECTFILE", + "SOURCE_DIR", + "CMAKE_DIR", + "PROJECT_DIR", + "source_list", + "is_project_file", + "is_c_header", + "is_py", + "cmake_advanced_info", + "cmake_compiler_defines", +) + +import sys +import os +from os.path import join, dirname, normpath, abspath, splitext, relpath, exists + +SOURCE_DIR = join(dirname(__file__), "..", "..") +SOURCE_DIR = normpath(SOURCE_DIR) +SOURCE_DIR = abspath(SOURCE_DIR) + +SIMPLE_PROJECTFILE = False + +# get cmake path +CMAKE_DIR = sys.argv[-1] + +if not exists(join(CMAKE_DIR, "CMakeCache.txt")): + CMAKE_DIR = os.getcwd() +if not exists(join(CMAKE_DIR, "CMakeCache.txt")): + print("CMakeCache.txt not found in %r or %r\n Pass CMake build dir as an argument, or run from that dir, aborting" % (CMAKE_DIR, os.getcwd())) + sys.exit(1) + + +# could be either. +# PROJECT_DIR = SOURCE_DIR +PROJECT_DIR = CMAKE_DIR + + +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: + filepath = join(dirpath, filename) + if filename_check is None or filename_check(filepath): + yield filepath + + +# extension checking +def is_cmake(filename): + ext = splitext(filename)[1] + return (ext == ".cmake") or (filename.endswith("CMakeLists.txt")) + + +def is_c_header(filename): + ext = splitext(filename)[1] + return (ext in (".h", ".hpp", ".hxx")) + + +def is_py(filename): + ext = splitext(filename)[1] + return (ext == ".py") + + +def is_glsl(filename): + ext = splitext(filename)[1] + return (ext == ".glsl") + + +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 is_svn_file(filename): + dn, fn = os.path.split(filename) + filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn) + return exists(filename_svn) + + +def is_project_file(filename): + return (is_c_any(filename) or is_cmake(filename) or is_glsl(filename)) # and is_svn_file(filename) + + +def cmake_advanced_info(): + """ Extracr includes and defines from cmake. + """ + + def create_eclipse_project(CMAKE_DIR): + print("CMAKE_DIR %r" % CMAKE_DIR) + if sys.platform == "win32": + cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR + else: + cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + + os.system(cmd) + + includes = [] + defines = [] + + create_eclipse_project(CMAKE_DIR) + + from xml.dom.minidom import parse + tree = parse(join(CMAKE_DIR, ".cproject")) + ''' + f = open(".cproject_pretty", 'w') + f.write(tree.toprettyxml(indent=" ", newl="")) + ''' + ELEMENT_NODE = tree.ELEMENT_NODE + + cproject, = tree.getElementsByTagName("cproject") + for storage in cproject.childNodes: + if storage.nodeType != ELEMENT_NODE: + continue + + if storage.attributes["moduleId"].value == "org.eclipse.cdt.core.settings": + cconfig = storage.getElementsByTagName("cconfiguration")[0] + for substorage in cconfig.childNodes: + if substorage.nodeType != ELEMENT_NODE: + continue + + moduleId = substorage.attributes["moduleId"].value + + # org.eclipse.cdt.core.settings + # org.eclipse.cdt.core.language.mapping + # org.eclipse.cdt.core.externalSettings + # org.eclipse.cdt.core.pathentry + # org.eclipse.cdt.make.core.buildtargets + + if moduleId == "org.eclipse.cdt.core.pathentry": + for path in substorage.childNodes: + if path.nodeType != ELEMENT_NODE: + continue + kind = path.attributes["kind"].value + + if kind == "mac": + # + defines.append((path.attributes["name"].value, path.attributes["value"].value)) + elif kind == "inc": + # + includes.append(path.attributes["include"].value) + else: + pass + + return includes, defines + + +def cmake_cache_var(var): + cache_file = open(join(CMAKE_DIR, "CMakeCache.txt")) + lines = [l_strip for l in cache_file for l_strip in (l.strip(),) if l_strip if not l_strip.startswith("//") if not l_strip.startswith("#")] + cache_file.close() + + for l in lines: + if l.split(":")[0] == var: + return l.split("=", 1)[-1] + return None + + +def cmake_compiler_defines(): + compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too + + if compiler is None: + print("Couldn't find the compiler, os defines will be omitted...") + return + + import tempfile + temp_c = tempfile.mkstemp(suffix=".c")[1] + temp_def = tempfile.mkstemp(suffix=".def")[1] + + os.system("%s -dM -E %s > %s" % (compiler, temp_c, temp_def)) + + temp_def_file = open(temp_def) + lines = [l.strip() for l in temp_def_file if l.strip()] + temp_def_file.close() + + os.remove(temp_c) + os.remove(temp_def) + return lines -- 2.28.0