• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14"""
15
16"""
17gn gen --ide=json
181. modifty at ./build/core/build_scripts/make_main.sh
19
20${BUILD_TOOLS_DIR}/gn gen ${TARGET_OUT_DIR} --> ${BUILD_TOOLS_DIR}/gn gen --ide=json ${TARGET_OUT_DIR}
21
222. build object --> generate project.json at out/ohos-arm-release/project.json
23
243. python3 gn_project_to_cmake.py root_path_of_project(eg. home/xxxx/code/openharmony)
25
26to generate CMakeLists.txt at home/xxxx/code/openharmony
27"""
28
29import datetime
30import json
31import os
32import re
33import sys
34from pathlib import Path, PureWindowsPath
35from typing import List
36
37def to_abs_path(path: str) -> str:
38    if path.startswith("//"):
39        path = path[2:]
40    return path
41
42
43class GnTarget(object):
44    def __init__(self, full_name: str, content: object):
45        self.full_name = full_name
46        self.content = content
47        self.resolved = False
48
49    @property
50    def dep_names(self) -> set:
51        return set(self.content.get('deps', []))
52
53    @property
54    def inputs_field(self) -> set:
55        return set(self.content.get('inputs', set()))
56
57    @property
58    def sources_field(self) -> set:
59        return set(self.content.get('sources', set()))
60
61    @property
62    def include_dirs_field(self) -> set:
63        return set(self.content.get('include_dirs', set()))
64
65    def __filter_src_dirs(self, files) -> set:
66        return set(f.split("/src/")[0] + "/src" for f in files)
67
68    @property
69    def cpp_src_files(self) -> set:
70        return set(to_abs_path(jf) for jf in self.sources_field
71                   if
72                   jf.endswith(".cpp") or jf.endswith(".h") or jf.endswith(".c++") or jf.endswith(".cc"))
73
74    @property
75    def cpp_hdr_dirs(self) -> set:
76        return set(to_abs_path(x) for x in self.include_dirs_field if x != "//" and not x.startswith("//out"))
77
78
79class ProjectJson(object):
80    def __init__(self, path: str):
81        self.path = path
82        with open(path, 'r') as project_file:
83            self.jobj = json.load(project_file)
84
85        self.gn_targets_cache = dict()
86        project_targets = self.jobj['targets']
87        for k, v in project_targets.items():
88            if (k.find("rosen") < 0):
89                continue
90            print(k)
91            self.gn_targets_cache[k] = GnTarget(full_name=k, content=v)
92
93    @property
94    def targets(self):
95        return self.gn_targets_cache.values()
96
97    @property
98    def target_names(self):
99        return set([x.full_name for x in self.targets])
100
101    def find_targets_startswith(self, prefix: str) -> List[GnTarget]:
102        return [x for x in self.targets if x.full_name.startswith(prefix)]
103
104    def get_target(self, name: str) -> GnTarget:
105        return next(x for x in self.targets if x.full_name == name)
106
107
108class CMakeCreator(object):
109    def __init__(self, project_json: ProjectJson, project_root_dir: str):
110        self.project_json = project_json
111        self.project_root_dir = project_root_dir
112        self.project_name = os.path.basename(self.project_root_dir)
113
114    @property
115    def project_cpp_srcs(self):
116        ret = set()
117        for x in self.project_json.targets:
118            for f in x.cpp_src_files:
119                f = os.path.join(self.project_root_dir, f)
120                if os.path.isfile(f):
121                    ret.add(f)
122                    print(f)
123
124        return sorted(ret)
125
126    @property
127    def project_cpp_hdrs(self):
128        ret = set()
129        for x in self.project_json.targets:
130            ret.update([_ for _ in x.cpp_hdr_dirs if os.path.isdir(self.project_root_dir + "/" + _)])
131        return sorted(ret)
132
133    @property
134    def jar_deps(self):
135        ret = set()
136        for x in self.project_json.targets:
137            ret.update([_ for _ in x.jar_files if os.path.isfile(self.project_root_dir + "/" + _)])
138        return sorted(ret)
139
140    def write_cmakelist(self):
141        hdr_list_str = "\n                                   ".join(self.project_cpp_hdrs)
142        src_list_str = "\n                                   ".join(self.project_cpp_srcs)
143
144        project_name = self.project_name + "clion"
145
146        with open(os.path.join(self.project_root_dir, 'CMakeLists.txt'), "w") as f:
147            f.write("""cmake_minimum_required(VERSION 3.15)\n""")
148            f.write("project(" + project_name + ")\n""")
149            f.write("set(CMAKE_CXX_STANDARD 17)\n")
150            f.write("include_directories(" + hdr_list_str + ")\n")
151            f.write("add_executable(" + project_name + " " + src_list_str + ")\n")
152
153        with open(os.path.join(self.project_root_dir, 'CMakeLists.txt'), "w") as f:
154            f.write('# Generated by gn_project_to_cmake.py.\n')
155            f.write("""cmake_minimum_required(VERSION 3.15)
156project({}clion)
157set(CMAKE_CXX_STANDARD 17)
158include_directories({})
159add_executable({}clion  {})
160        """.format(self.project_name, hdr_list_str, self.project_name, src_list_str))
161
162    def write(self):
163        self.write_cmakelist()
164
165
166if __name__ == "__main__":
167    #
168    # read args
169    #
170    if len(sys.argv) < 2:
171        print("""Usage: {} <project_root_dir>,
172eg. {} /home/xxxxxx/codes/openharmony""".format(sys.argv[0], sys.argv[0]))
173        sys.exit(1)
174
175    project_root_dir = sys.argv[1]
176    if not os.path.isdir(project_root_dir):
177        print(project_root_dir + " not exist!")
178        sys.exit(1)
179
180    #
181    # parse project.json
182    #
183    project_json = ProjectJson(path=os.path.join(*[project_root_dir, "out", "ohos-arm-release", "project.json"]))
184    print(project_json)
185
186    #
187    # write CMakeLists.txt
188    #
189    CMakeCreator(project_json=project_json, project_root_dir=project_root_dir).write()
190
191