1# Copyright (C) 2021 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6#     http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14import("//build/ohos.gni")
15import("./hiperf.gni")
16
17declare_args() {
18  hiperf_feature_mingw_uapi_dir =
19      "../../kernel/linux/patches/linux-5.10/prebuilts/usr/include"
20}
21
22function_disable_define = []
23
24config("hiperf_inner_config") {
25  visibility = [ ":*" ]
26  ldflags = []
27  cflags = code_check_flag
28  defines = function_disable_define
29
30  if (hiperf_code_analyze && is_ohos) {
31    cflags += code_analyze_flag
32    cflags -= [ "-Werror" ]
33  }
34
35  if (build_variant == "user") {
36    cflags += [ "-DIS_RELEASE_VERSION" ]
37  }
38
39  if (is_mingw) {
40    # lld: error: unable to find library -latomic
41    # lld: error: unable to find library -ldl
42    # lld: error: unable to find library -lrt
43    ldflags += [
44      "-Wl,--whole-archive",
45      "-lpthread",
46      "-Wl,--no-whole-archive",
47    ]
48  } else if (is_linux) {
49    ldflags += [
50      "-Wl,--whole-archive",
51      "-lpthread",
52      "-latomic",
53      "-ldl",
54      "-lrt",
55      "-Wl,--no-whole-archive",
56    ]
57  }
58
59  include_dirs = [ "${hiperf_path}/include" ]
60
61  # debug link
62  # ldflags += [ "-v"]
63
64  if (hiperf_debug) {
65    defines += [
66      "HIPERF_DEBUG",
67      "HIPERF_DEBUG_PRINTF",  # if u want to see printf in the log ?
68    ]
69  }
70
71  if (hiperf_check_time) {
72    defines += [ "HIPERF_DEBUG_TIME" ]
73  }
74
75  cflags += [
76    "-std=c++17",
77    "-fvisibility=hidden",
78    "-fdata-sections",
79    "-ffunction-sections",
80    "-Os",
81  ]
82  cflags_cc = [
83    "-fvisibility-inlines-hidden",
84    "-Os",
85  ]
86  defines += [ "is_mingw=${is_mingw}" ]
87  defines += [ "is_linux=${is_linux}" ]
88  defines += [ "is_ohos=${is_ohos}" ]
89  defines += [ "is_emulator=${is_emulator}" ]
90  defines += [ "is_double_framework=${is_double_framework}" ]
91  if (hiperf_target_host) {
92    defines += [ "target_cpu_${host_cpu}" ]
93  } else {
94    defines += [ "target_cpu_${target_cpu}" ]
95  }
96
97  if (is_mingw) {
98    cflags += [ "-includeMingW64Fix.h" ]
99    defines += [ "WIN32_LEAN_AND_MEAN" ]
100    defines += [ "__LITTLE_ENDIAN_BITFIELD" ]
101
102    include_dirs += [
103      "${hiperf_path}/include/nonlinux/",
104      hiperf_feature_mingw_uapi_dir,
105    ]
106  }
107
108  if (hiperf_test_coverage && is_ohos) {
109    cflags += [
110      "-fprofile-arcs",
111      "-ftest-coverage",
112    ]
113    ldflags += [ "--coverage" ]
114  }
115}
116
117sources_platform_common = [
118  "./src/perf_file_format.cpp",
119  "./src/command.cpp",
120  "./src/subcommand.cpp",
121  "./src/option.cpp",
122  "./src/utilities.cpp",
123  "./src/symbols_file.cpp",
124  "./src/virtual_runtime.cpp",
125  "./src/virtual_thread.cpp",
126  "./src/perf_file_reader.cpp",
127  "./src/perf_event_record.cpp",
128  "./src/dwarf_encoding.cpp",
129  "./src/subcommand_help.cpp",
130  "./src/subcommand_dump.cpp",
131  "./src/subcommand_report.cpp",
132  "./src/report.cpp",
133  "./src/report_json_file.cpp",
134  "./src/register.cpp",
135  "./src/unique_stack_table.cpp",
136]
137
138if (is_ohos) {
139  sources_platform_common += [ "./src/callstack.cpp" ]
140}
141
142if (hiperf_debug) {
143  sources_platform_common += [
144    "./src/debug_logger.cpp",
145    "./src/option_debug.cpp",
146  ]
147}
148
149sources_platform_linux = [
150  "./src/perf_events.cpp",
151  "./src/tracked_command.cpp",
152  "./src/ring_buffer.cpp",
153  "./src/perf_file_writer.cpp",
154  "./src/subcommand_stat.cpp",
155  "./src/subcommand_record.cpp",
156  "./src/subcommand_list.cpp",
157  "./src/spe_decoder.cpp",
158]
159
160common_deps = [
161  ":support_elf",
162  ":support_protobuf",
163]
164
165common_configs = [
166  ":hiperf_inner_config",
167  "../../commonlibrary/c_utils/base:utils_config",
168  "//third_party/googletest:gtest_config",
169]
170
171if (hiperf_target_static) {
172  common_deps -= [ ":support_protobuf" ]
173}
174
175config("hiperf_syspara_config") {
176  defines = [ "CONFIG_HAS_SYSPARA" ]
177}
178
179config("libunwinder_config") {
180  defines = [ "HAVE_LIBUNWINDER=1" ]
181}
182
183if (hiperf_use_libunwinder) {
184  common_configs += [ ":libunwinder_config" ]
185}
186
187if (is_ohos && hiperf_use_syspara) {
188  common_configs += [ ":hiperf_syspara_config" ]
189}
190
191ohos_source_set("hiperf_platform_common") {
192  part_name = "hiperf"
193  subsystem_name = "developtools"
194  use_exceptions = true
195  public_deps = common_deps
196  public_configs = common_configs
197  defines = []
198
199  if (is_ohos) {
200    external_deps = [
201      "c_utils:utils",
202      "faultloggerd:libunwinder_static",
203      "hilog:libhilog",
204      "init:libbegetutil",
205      "ipc:ipc_core",
206      "samgr:samgr_proxy",
207    ]
208    if (bundle_framework_enable) {
209      external_deps += [
210        "bundle_framework:appexecfwk_base",
211        "bundle_framework:appexecfwk_core",
212      ]
213      defines += [ "BUNDLE_FRAMEWORK_ENABLE" ]
214    }
215    if (ability_base_enable) {
216      external_deps += [ "ability_base:extractortool" ]
217      defines += [ "ENABLE_HAP_EXTRACTOR" ]
218    }
219  } else {
220    external_deps = [ "faultloggerd:unwinder_host" ]
221    defines += [ "CONFIG_NO_HILOG" ]
222  }
223  external_deps += [
224    "bounds_checking_function:libsec_shared",
225    "zlib:libz",
226  ]
227  sources = sources_platform_common
228}
229
230config("platform_linux_config") {
231  defines = [ "SUPPORT_PERF_EVENT" ]
232}
233
234ohos_source_set("hiperf_platform_linux") {
235  part_name = "hiperf"
236  subsystem_name = "developtools"
237  use_exceptions = true
238  public_deps = common_deps
239  public_configs = common_configs
240
241  if (is_ohos) {
242    external_deps = [
243      "faultloggerd:libunwinder_static",
244      "hilog:libhilog",
245      "init:libbegetutil",
246    ]
247  } else {
248    external_deps = [ "faultloggerd:unwinder_host" ]
249  }
250  external_deps += [
251    "bounds_checking_function:libsec_shared",
252    "zlib:libz",
253  ]
254  public_configs += [ ":platform_linux_config" ]
255  configs = [ "interfaces/innerkits/native:hiperf_client_config" ]
256
257  sources = sources_platform_linux
258}
259
260config("libunwind_config") {
261  defines = [ "HAVE_LIBUNWIND=1" ]
262}
263
264config("elf_config") {
265}
266ohos_source_set("support_elf") {
267  part_name = "hiperf"
268  subsystem_name = "developtools"
269  public_configs = common_configs
270  public_configs += [ ":elf_config" ]
271}
272
273config("protobuf_config") {
274  defines = [ "HAVE_PROTOBUF=1" ]
275  include_dirs = [
276    "//third_party/protobuf/src",
277    "//third_party/protobuf/src/google",
278    "//third_party/protobuf/src/google/protobuf",
279  ]
280}
281
282ohos_source_set("support_protobuf") {
283  part_name = "hiperf"
284  subsystem_name = "developtools"
285  use_exceptions = true
286
287  #protobuf
288  public_configs = common_configs
289  public_configs += [ ":protobuf_config" ]
290  public_deps = [ ":proto_file_cpp" ]
291
292  if (is_ohos) {
293    external_deps = [ "faultloggerd:libunwinder_static" ]
294  } else {
295    external_deps = [ "faultloggerd:unwinder_host" ]
296  }
297  external_deps += [ "bounds_checking_function:libsec_shared" ]
298  sources = [ "./src/report_protobuf_file.cpp" ]
299}
300
301#protobuf {
302proto_file_defines = [
303  # add your proto file here
304  "report_sample",
305]
306
307proto_base_dir = "proto"
308proto_out_dir = "$target_gen_dir" + "/" + proto_base_dir
309
310proto_file_codegen = []
311proto_file_sources = []
312
313foreach(proto_file, proto_file_defines) {
314  proto_file_codegen += [
315    "$proto_out_dir" + "/" + "$proto_file.pb.h",
316    "$proto_out_dir" + "/" + "$proto_file.pb.cc",
317  ]
318  proto_file_sources += [ "$proto_base_dir" + "/" + "$proto_file.proto" ]
319}
320
321# this is so bad , but someone config the protoc's subsystem_name
322# the better way is build system need provider host tools path or prebuild tools path
323protoc_subsystem_out_path = "thirdparty/protobuf"
324
325if (default_toolchain == current_toolchain) {
326  #if target build
327  host_out_path = "/" + get_label_info(host_toolchain, "name")
328} else {
329  #if host build (for some linke mingw)
330  host_out_path = "/../" + get_label_info(host_toolchain, "name")
331}
332host_protoc_path =
333    root_out_dir + host_out_path + "/" + protoc_subsystem_out_path + "/protoc"
334
335action("hiperf_host_build_proto") {
336  deps = [
337    "//third_party/protobuf:protoc(//build/toolchain/linux:clang_${host_cpu})",
338  ]
339  args = []
340  outputs = proto_file_codegen
341  sources = []
342  script = "proto/build_proto.sh"
343
344  args += [ rebase_path(host_protoc_path) ]
345  args += [
346    "--proto_path",
347    rebase_path(proto_base_dir),
348  ]
349  args += [
350    "--cpp_out",
351    rebase_path(proto_out_dir),
352  ]
353
354  foreach(proto_file_source, proto_file_sources) {
355    #tell gn to check which files as source time
356    sources += [ rebase_path(proto_file_source) ]
357    args += [ rebase_path(proto_file_source) ]
358  }
359}
360
361config("proto_file_cpp_config") {
362  include_dirs = [ proto_out_dir ]
363}
364
365ohos_source_set("proto_file_cpp") {
366  part_name = "hiperf"
367  subsystem_name = "developtools"
368  cflags = []
369
370  deps = [ ":hiperf_host_build_proto" ]
371  public_deps = [ "//third_party/protobuf:protobuf_lite_static" ]
372
373  sources = proto_file_codegen
374  public_configs = [ ":proto_file_cpp_config" ]
375}
376
377#protobuf }
378
379ohos_executable("hiperf") {
380  install_enable = true
381  sources = [ "./src/main.cpp" ]
382  deps = [
383    ":hiperf_etc",
384    ":hiperf_platform_common",
385    ":hiperf_platform_linux",
386  ]
387
388  if (hiperf_target_static) {
389    static_link = true
390  }
391
392  if (is_linux || is_mingw) {
393    # ld.lld: error: attempted static link of dynamic object hiviewdfx/hilog_native/libhilog.so
394    static_link = true
395  }
396
397  external_deps = [
398    "bounds_checking_function:libsec_shared",
399    "faultloggerd:libunwinder_static",
400    "hilog:libhilog",
401  ]
402
403  subsystem_name = "developtools"
404  part_name = "hiperf"
405}
406
407ohos_executable("hiperf_host") {
408  sources = [ "./src/main.cpp" ]
409  deps = [ ":hiperf_platform_common" ]
410
411  external_deps = [
412    "bounds_checking_function:libsec_shared",
413    "faultloggerd:unwinder_host",
414  ]
415
416  subsystem_name = "developtools"
417  part_name = "hiperf"
418}
419
420ohos_prebuilt_etc("hiperf.para") {
421  source = "etc/hiperf.para"
422  install_images = [
423    "system",
424    "updater",
425  ]
426  module_install_dir = "etc/param"
427  part_name = "hiperf"
428  subsystem_name = "developtools"
429}
430
431ohos_prebuilt_etc("hiperf.para.dac") {
432  source = "etc/hiperf.para.dac"
433  install_images = [
434    "system",
435    "updater",
436  ]
437  module_install_dir = "etc/param"
438  part_name = "hiperf"
439  subsystem_name = "developtools"
440}
441
442ohos_prebuilt_etc("hiperf.cfg") {
443  source = "etc/hiperf.cfg"
444  relative_install_dir = "init"
445  subsystem_name = "developtools"
446  part_name = "hiperf"
447}
448
449group("hiperf_etc") {
450  deps = [
451    ":hiperf.cfg",
452    ":hiperf.para",
453    ":hiperf.para.dac",
454  ]
455}
456
457ohos_source_set("hiperf_platform_host") {
458  part_name = "hiperf"
459  subsystem_name = "developtools"
460  sources = [ "./src/hiperf_libreport.cpp" ]
461  public_deps = [ ":hiperf_platform_common" ]
462  external_deps = [
463    "bounds_checking_function:libsec_shared",
464    "faultloggerd:unwinder_host",
465  ]
466}
467
468ohos_shared_library("hiperf_host_lib") {
469  public_deps = [ ":hiperf_platform_host" ]
470  output_name = "hiperf_report"
471
472  ldflags = [ "-static-libstdc++" ]
473
474  subsystem_name = "developtools"
475  part_name = "hiperf"
476}
477
478ohos_executable("hiperf_host_lib_demo") {
479  sources = [ "./src/hiperf_libreport_demo.cpp" ]
480  deps = [ ":hiperf_host_lib" ]
481  include_dirs = [ "${hiperf_path}/include" ]
482
483  subsystem_name = "developtools"
484  part_name = "hiperf"
485}
486
487ohos_copy("hiperf_host_python") {
488  sources = [ "./script" ]
489  outputs = [ target_out_dir + "/host/" ]
490
491  module_source_dir = target_out_dir + "/$target_name"
492  module_install_name = ""
493  subsystem_name = "developtools"
494  part_name = "hiperf"
495}
496
497ohos_source_set("hiperf_code_analyze") {
498  part_name = "hiperf"
499  deps = [
500    ":hiperf_platform_common",
501    ":hiperf_platform_linux",
502  ]
503}
504
505group("hiperf_target") {
506  if (hiperf_target_host) {
507    deps = [ ":hiperf(${host_toolchain})" ]
508  } else {
509    deps = [ ":hiperf" ]
510  }
511}
512
513group("hiperf_test_target") {
514  testonly = true
515  deps = [ "test:hiperf_test" ]
516}
517
518group("hiperf_target_all") {
519  if (!is_emulator) {
520    if (is_double_framework) {
521      deps = [ ":hiperf_target" ]
522    } else {
523      deps = []
524      if (!use_libfuzzer) {
525        deps += [
526          ":hiperf_host(//build/toolchain/linux:clang_${host_cpu})",  # host_linux
527          ":hiperf_host_lib(//build/toolchain/linux:clang_${host_cpu})",  # host_linux
528          ":hiperf_host_lib_demo(//build/toolchain/linux:clang_${host_cpu})",  # host_linux
529          ":hiperf_host_python",
530        ]
531        if (!is_tsan) {
532          deps += [
533            ":hiperf_host(//build/toolchain/mingw:mingw_x86_64)",  # host mingw
534            ":hiperf_host_lib(//build/toolchain/mingw:mingw_x86_64)",  # host_mingw
535          ]
536        }
537      }
538      deps += [
539        ":hiperf_target",
540        "interfaces/innerkits/native:hiperf_client",  # c++ api
541      ]
542      if (is_ohos) {
543        deps += [ "interfaces/kits/js/napi:hiperf_client_napi" ]  # js api
544      }
545    }
546  }
547}
548
549group("hiperf_demo") {
550  if (hiperf_target_host) {
551    deps = [ "demo/cpp:hiperf_demo(${host_toolchain})" ]
552  } else {
553    deps = [ "demo/cpp:hiperf_demo" ]
554  }
555}
556
557group("hiperf_example_cmd") {
558  if (hiperf_target_host) {
559    deps = [ "demo/cpp:hiperf_example_cmd(${host_toolchain})" ]
560  } else {
561    deps = [ "demo/cpp:hiperf_example_cmd" ]
562  }
563}
564
565group("hiperf_all") {
566  testonly = true
567  if (hiperf_code_analyze) {
568    deps = [ ":hiperf_code_analyze" ]
569  } else {
570    deps = [
571      ":hiperf_example_cmd",
572      ":hiperf_target_all",
573    ]
574    if (!is_double_framework) {
575      deps += [
576        ":hiperf_demo",
577        ":hiperf_test_target",
578      ]
579    }
580  }
581}
582