Build info: Ensure hash length is same across all platforms and has no conflicts
[blender.git] / build_files / cmake / cmake_qtcreator_project.py
1 #!/usr/bin/env python3
2
3 # ***** BEGIN GPL LICENSE BLOCK *****
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #
19 # Contributor(s): Campbell Barton, M.G. Kishalmi
20 #
21 # ***** END GPL LICENSE BLOCK *****
22
23 # <pep8 compliant>
24
25 r"""
26 Example Linux usage:
27  python ~/blender-git/blender/build_files/cmake/cmake_qtcreator_project.py --build-dir ~/blender-git/cmake
28
29 Example Win32 usage:
30  c:\Python32\python.exe c:\blender_dev\blender\build_files\cmake\cmake_qtcreator_project.py --build-dir c:\blender_dev\cmake_build
31 """
32
33
34 import os
35
36
37 def quote_define(define):
38     if " " in define.strip():
39         return '"%s"' % define
40     else:
41         return define
42
43
44 def create_qtc_project_main(name):
45     from project_info import (
46         SIMPLE_PROJECTFILE,
47         SOURCE_DIR,
48         # CMAKE_DIR,
49         PROJECT_DIR,
50         source_list,
51         is_project_file,
52         is_c_header,
53         cmake_advanced_info,
54         cmake_compiler_defines,
55         project_name_get,
56     )
57
58     files = list(source_list(SOURCE_DIR, filename_check=is_project_file))
59     files_rel = [os.path.relpath(f, start=PROJECT_DIR) for f in files]
60     files_rel.sort()
61
62     # --- qtcreator specific, simple format
63     if SIMPLE_PROJECTFILE:
64         # --- qtcreator specific, simple format
65         PROJECT_NAME = name or "Blender"
66         FILE_NAME = PROJECT_NAME.lower()
67         with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
68             f.write("\n".join(files_rel))
69
70         with open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w') as f:
71             f.write("\n".join(sorted(list(set(os.path.dirname(f)
72                                               for f in files_rel if is_c_header(f))))))
73
74         qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
75         with open(qtc_prj, 'w') as f:
76             f.write("[General]\n")
77
78         qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
79         if not os.path.exists(qtc_cfg):
80             with open(qtc_cfg, 'w') as f:
81                 f.write("// ADD PREDEFINED MACROS HERE!\n")
82     else:
83         includes, defines = cmake_advanced_info()
84
85         if (includes, defines) == (None, None):
86             return
87
88         # for some reason it doesn't give all internal includes
89         includes = list(set(includes) | set(os.path.dirname(f)
90                                             for f in files_rel if is_c_header(f)))
91         includes.sort()
92
93         # be tricky, get the project name from CMake if we can!
94         PROJECT_NAME = name or project_name_get()
95
96         FILE_NAME = PROJECT_NAME.lower()
97         with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
98             f.write("\n".join(files_rel))
99
100         with open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w', encoding='utf-8') as f:
101             f.write("\n".join(sorted(includes)))
102
103         qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
104         with open(qtc_prj, 'w') as f:
105             f.write("[General]\n")
106
107         qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
108         with open(qtc_cfg, 'w') as f:
109             f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME)
110
111             qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME)
112             if os.path.exists(qtc_custom_cfg):
113                 with open(qtc_custom_cfg, 'r') as fc:
114                     f.write(fc.read())
115                     f.write("\n")
116
117             defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines]
118             if os.name != "nt":
119                 defines_final += cmake_compiler_defines()
120             f.write("\n".join(defines_final))
121
122     print("Blender project file written to: %r" % qtc_prj)
123     # --- end
124
125
126 def create_qtc_project_python(name):
127     from project_info import (
128         SOURCE_DIR,
129         # CMAKE_DIR,
130         PROJECT_DIR,
131         source_list,
132         is_py,
133         project_name_get,
134     )
135
136     files = list(source_list(SOURCE_DIR, filename_check=is_py))
137     files_rel = [os.path.relpath(f, start=PROJECT_DIR) for f in files]
138     files_rel.sort()
139
140     # --- qtcreator specific, simple format
141     # be tricky, get the project name from git if we can!
142     PROJECT_NAME = (name or project_name_get()) + "_Python"
143
144     FILE_NAME = PROJECT_NAME.lower()
145     with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
146         f.write("\n".join(files_rel))
147
148     qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
149     with open(qtc_prj, 'w') as f:
150         f.write("[General]\n")
151
152     qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
153     if not os.path.exists(qtc_cfg):
154         with open(qtc_cfg, 'w') as f:
155             f.write("// ADD PREDEFINED MACROS HERE!\n")
156
157     print("Python project file written to:  %r" % qtc_prj)
158
159
160 def argparse_create():
161     import argparse
162
163     parser = argparse.ArgumentParser(
164         description="This script generates Qt Creator project files for Blender",
165     )
166
167     parser.add_argument(
168         "-n", "--name",
169         dest="name",
170         metavar='NAME', type=str,
171         help="Override default project name (\"Blender\")",
172         required=False,
173     )
174
175     parser.add_argument(
176         "-b", "--build-dir",
177         dest="build_dir",
178         metavar='BUILD_DIR', type=str,
179         help="Specify the build path (or fallback to the $PWD)",
180         required=False,
181     )
182
183     return parser
184
185
186 def main():
187     parser = argparse_create()
188     args = parser.parse_args()
189     name = args.name
190
191     import project_info
192     if not project_info.init(args.build_dir):
193         return
194
195     create_qtc_project_main(name)
196     create_qtc_project_python(name)
197
198
199 if __name__ == "__main__":
200     main()