xref: /aosp_15_r20/external/vulkan-validation-layers/BUILD.gn (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1*b7893ccfSSadaf Ebrahimi# Copyright (C) 2018-2019 The ANGLE Project Authors.
2*b7893ccfSSadaf Ebrahimi# Copyright (C) 2019 LunarG, Inc.
3*b7893ccfSSadaf Ebrahimi#
4*b7893ccfSSadaf Ebrahimi# Licensed under the Apache License, Version 2.0 (the "License");
5*b7893ccfSSadaf Ebrahimi# you may not use this file except in compliance with the License.
6*b7893ccfSSadaf Ebrahimi# You may obtain a copy of the License at
7*b7893ccfSSadaf Ebrahimi#
8*b7893ccfSSadaf Ebrahimi#     https://www.apache.org/licenses/LICENSE-2.0
9*b7893ccfSSadaf Ebrahimi#
10*b7893ccfSSadaf Ebrahimi# Unless required by applicable law or agreed to in writing, software
11*b7893ccfSSadaf Ebrahimi# distributed under the License is distributed on an "AS IS" BASIS,
12*b7893ccfSSadaf Ebrahimi# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7893ccfSSadaf Ebrahimi# See the License for the specific language governing permissions and
14*b7893ccfSSadaf Ebrahimi# limitations under the License.
15*b7893ccfSSadaf Ebrahimi
16*b7893ccfSSadaf Ebrahimiimport("//build_overrides/vulkan_validation_layers.gni")
17*b7893ccfSSadaf Ebrahimi
18*b7893ccfSSadaf Ebrahimi# Fuchsia has non-upstream changes to the vulkan layers, so we don't want
19*b7893ccfSSadaf Ebrahimi# to build it from upstream sources.
20*b7893ccfSSadaf Ebrahimiassert(!is_fuchsia)
21*b7893ccfSSadaf Ebrahimi
22*b7893ccfSSadaf Ebrahimivulkan_undefine_configs = []
23*b7893ccfSSadaf Ebrahimiif (is_win) {
24*b7893ccfSSadaf Ebrahimi  vulkan_undefine_configs += [
25*b7893ccfSSadaf Ebrahimi    "//build/config/win:nominmax",
26*b7893ccfSSadaf Ebrahimi    "//build/config/win:unicode",
27*b7893ccfSSadaf Ebrahimi  ]
28*b7893ccfSSadaf Ebrahimi}
29*b7893ccfSSadaf Ebrahimi
30*b7893ccfSSadaf Ebrahimivulkan_gen_dir = "$target_gen_dir/$vulkan_gen_subdir"
31*b7893ccfSSadaf Ebrahimiraw_vulkan_gen_dir = rebase_path(vulkan_gen_dir, root_build_dir)
32*b7893ccfSSadaf Ebrahimi
33*b7893ccfSSadaf Ebrahimivulkan_data_dir = "$root_out_dir/$vulkan_data_subdir"
34*b7893ccfSSadaf Ebrahimiraw_vulkan_data_dir = rebase_path(vulkan_data_dir, root_build_dir)
35*b7893ccfSSadaf Ebrahimi
36*b7893ccfSSadaf Ebrahimiraw_root_out_dir = rebase_path(root_out_dir, root_build_dir)
37*b7893ccfSSadaf Ebrahimi
38*b7893ccfSSadaf Ebrahimi# This special action is needed to remove old VVL objects that are now renamed.
39*b7893ccfSSadaf Ebrahimiaction("vulkan_clean_old_validation_layer_objects") {
40*b7893ccfSSadaf Ebrahimi  script = "build-gn/remove_files.py"
41*b7893ccfSSadaf Ebrahimi
42*b7893ccfSSadaf Ebrahimi  # inputs is a (random) new file since the vvl roll, used to ensure the cleanup is done only once
43*b7893ccfSSadaf Ebrahimi  inputs = [
44*b7893ccfSSadaf Ebrahimi    "layers/gpu_validation.cpp",
45*b7893ccfSSadaf Ebrahimi  ]
46*b7893ccfSSadaf Ebrahimi  outputs = [
47*b7893ccfSSadaf Ebrahimi    "$vulkan_gen_dir/old_vvl_files_are_removed",
48*b7893ccfSSadaf Ebrahimi  ]
49*b7893ccfSSadaf Ebrahimi  args = [
50*b7893ccfSSadaf Ebrahimi    "$raw_vulkan_gen_dir/old_vvl_files_are_removed",
51*b7893ccfSSadaf Ebrahimi    "$raw_root_out_dir/libVkLayer*",
52*b7893ccfSSadaf Ebrahimi    "$raw_root_out_dir/VkLayer*",
53*b7893ccfSSadaf Ebrahimi    "$raw_vulkan_data_dir/VkLayer*.json",
54*b7893ccfSSadaf Ebrahimi  ]
55*b7893ccfSSadaf Ebrahimi}
56*b7893ccfSSadaf Ebrahimi
57*b7893ccfSSadaf Ebrahimiconfig("vulkan_internal_config") {
58*b7893ccfSSadaf Ebrahimi  defines = [
59*b7893ccfSSadaf Ebrahimi    "VULKAN_NON_CMAKE_BUILD",
60*b7893ccfSSadaf Ebrahimi    "API_NAME=\"Vulkan\"",
61*b7893ccfSSadaf Ebrahimi  ]
62*b7893ccfSSadaf Ebrahimi  if (is_clang || !is_win) {
63*b7893ccfSSadaf Ebrahimi    cflags = [ "-Wno-unused-function" ]
64*b7893ccfSSadaf Ebrahimi  }
65*b7893ccfSSadaf Ebrahimi  if (is_linux) {
66*b7893ccfSSadaf Ebrahimi    defines += [
67*b7893ccfSSadaf Ebrahimi      "SYSCONFDIR=\"/etc\"",
68*b7893ccfSSadaf Ebrahimi      "FALLBACK_CONFIG_DIRS=\"/etc/xdg\"",
69*b7893ccfSSadaf Ebrahimi      "FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
70*b7893ccfSSadaf Ebrahimi    ]
71*b7893ccfSSadaf Ebrahimi  }
72*b7893ccfSSadaf Ebrahimi}
73*b7893ccfSSadaf Ebrahimi
74*b7893ccfSSadaf Ebrahimi# The validation layers
75*b7893ccfSSadaf Ebrahimi# ---------------------
76*b7893ccfSSadaf Ebrahimi
77*b7893ccfSSadaf Ebrahimiconfig("vulkan_layer_config") {
78*b7893ccfSSadaf Ebrahimi  include_dirs = [
79*b7893ccfSSadaf Ebrahimi    "layers",
80*b7893ccfSSadaf Ebrahimi    "layers/generated",
81*b7893ccfSSadaf Ebrahimi  ]
82*b7893ccfSSadaf Ebrahimi}
83*b7893ccfSSadaf Ebrahimi
84*b7893ccfSSadaf Ebrahimicore_validation_sources = [
85*b7893ccfSSadaf Ebrahimi  # This file is manually included in the layer
86*b7893ccfSSadaf Ebrahimi  # "layers/generated/vk_safe_struct.cpp",
87*b7893ccfSSadaf Ebrahimi  "layers/buffer_validation.cpp",
88*b7893ccfSSadaf Ebrahimi  "layers/buffer_validation.h",
89*b7893ccfSSadaf Ebrahimi  "layers/core_validation.cpp",
90*b7893ccfSSadaf Ebrahimi  "layers/core_validation.h",
91*b7893ccfSSadaf Ebrahimi  "layers/convert_to_renderpass2.cpp",
92*b7893ccfSSadaf Ebrahimi  "layers/descriptor_sets.cpp",
93*b7893ccfSSadaf Ebrahimi  "layers/descriptor_sets.h",
94*b7893ccfSSadaf Ebrahimi  "layers/drawdispatch.cpp",
95*b7893ccfSSadaf Ebrahimi  "layers/gpu_validation.cpp",
96*b7893ccfSSadaf Ebrahimi  "layers/gpu_validation.h",
97*b7893ccfSSadaf Ebrahimi  "layers/shader_validation.cpp",
98*b7893ccfSSadaf Ebrahimi  "layers/shader_validation.h",
99*b7893ccfSSadaf Ebrahimi  "layers/xxhash.c",
100*b7893ccfSSadaf Ebrahimi  "layers/xxhash.h",
101*b7893ccfSSadaf Ebrahimi]
102*b7893ccfSSadaf Ebrahimi
103*b7893ccfSSadaf Ebrahimiobject_lifetimes_sources = [
104*b7893ccfSSadaf Ebrahimi  "layers/generated/object_tracker.cpp",
105*b7893ccfSSadaf Ebrahimi  "layers/generated/object_tracker.h",
106*b7893ccfSSadaf Ebrahimi  "layers/object_tracker_utils.cpp",
107*b7893ccfSSadaf Ebrahimi]
108*b7893ccfSSadaf Ebrahimi
109*b7893ccfSSadaf Ebrahimistateless_validation_sources = [
110*b7893ccfSSadaf Ebrahimi  "layers/generated/parameter_validation.cpp",
111*b7893ccfSSadaf Ebrahimi  "layers/generated/parameter_validation.h",
112*b7893ccfSSadaf Ebrahimi  "layers/parameter_validation_utils.cpp",
113*b7893ccfSSadaf Ebrahimi]
114*b7893ccfSSadaf Ebrahimi
115*b7893ccfSSadaf Ebrahimithread_safety_sources = [
116*b7893ccfSSadaf Ebrahimi  "layers/generated/thread_safety.cpp",
117*b7893ccfSSadaf Ebrahimi  "layers/generated/thread_safety.h",
118*b7893ccfSSadaf Ebrahimi]
119*b7893ccfSSadaf Ebrahimi
120*b7893ccfSSadaf Ebrahimiunique_objects_sources = []
121*b7893ccfSSadaf Ebrahimi
122*b7893ccfSSadaf Ebrahimichassis_sources = [
123*b7893ccfSSadaf Ebrahimi  "layers/core_validation.h",
124*b7893ccfSSadaf Ebrahimi  "layers/generated/vk_safe_struct.h",
125*b7893ccfSSadaf Ebrahimi  "layers/generated/thread_safety.h",
126*b7893ccfSSadaf Ebrahimi  "layers/generated/chassis.cpp",
127*b7893ccfSSadaf Ebrahimi  "layers/generated/chassis.h",
128*b7893ccfSSadaf Ebrahimi  "layers/generated/layer_chassis_dispatch.cpp",
129*b7893ccfSSadaf Ebrahimi  "layers/generated/layer_chassis_dispatch.h",
130*b7893ccfSSadaf Ebrahimi  "$vulkan_headers_dir/include/vulkan/vk_layer.h",
131*b7893ccfSSadaf Ebrahimi  "$vulkan_headers_dir/include/vulkan/vulkan.h",
132*b7893ccfSSadaf Ebrahimi]
133*b7893ccfSSadaf Ebrahimi
134*b7893ccfSSadaf Ebrahimilayers = [
135*b7893ccfSSadaf Ebrahimi  [
136*b7893ccfSSadaf Ebrahimi    "core_validation",
137*b7893ccfSSadaf Ebrahimi    core_validation_sources + chassis_sources + thread_safety_sources,
138*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
139*b7893ccfSSadaf Ebrahimi    [ "BUILD_CORE_VALIDATION" ],
140*b7893ccfSSadaf Ebrahimi  ],
141*b7893ccfSSadaf Ebrahimi  [
142*b7893ccfSSadaf Ebrahimi    "object_lifetimes",
143*b7893ccfSSadaf Ebrahimi    object_lifetimes_sources + chassis_sources + thread_safety_sources + core_validation_sources,
144*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
145*b7893ccfSSadaf Ebrahimi    [ "BUILD_OBJECT_TRACKER" ],
146*b7893ccfSSadaf Ebrahimi  ],
147*b7893ccfSSadaf Ebrahimi  [
148*b7893ccfSSadaf Ebrahimi    "stateless_validation",
149*b7893ccfSSadaf Ebrahimi    stateless_validation_sources + chassis_sources + core_validation_sources,
150*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
151*b7893ccfSSadaf Ebrahimi    [ "BUILD_PARAMETER_VALIDATION" ],
152*b7893ccfSSadaf Ebrahimi  ],
153*b7893ccfSSadaf Ebrahimi  [
154*b7893ccfSSadaf Ebrahimi    "thread_safety",
155*b7893ccfSSadaf Ebrahimi    thread_safety_sources + chassis_sources + core_validation_sources,
156*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
157*b7893ccfSSadaf Ebrahimi    [ "BUILD_THREAD_SAFETY" ],
158*b7893ccfSSadaf Ebrahimi  ],
159*b7893ccfSSadaf Ebrahimi  [
160*b7893ccfSSadaf Ebrahimi    "unique_objects",
161*b7893ccfSSadaf Ebrahimi    unique_objects_sources + chassis_sources + core_validation_sources,
162*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
163*b7893ccfSSadaf Ebrahimi    [ "LAYER_CHASSIS_CAN_WRAP_HANDLES" ],
164*b7893ccfSSadaf Ebrahimi  ],
165*b7893ccfSSadaf Ebrahimi  [
166*b7893ccfSSadaf Ebrahimi    "khronos_validation",
167*b7893ccfSSadaf Ebrahimi    core_validation_sources + object_lifetimes_sources +
168*b7893ccfSSadaf Ebrahimi        stateless_validation_sources + thread_safety_sources +
169*b7893ccfSSadaf Ebrahimi        unique_objects_sources + chassis_sources,
170*b7893ccfSSadaf Ebrahimi    [ ":vulkan_core_validation_glslang" ],
171*b7893ccfSSadaf Ebrahimi    [
172*b7893ccfSSadaf Ebrahimi      "BUILD_KHRONOS_VALIDATION",
173*b7893ccfSSadaf Ebrahimi      "BUILD_CORE_VALIDATION",
174*b7893ccfSSadaf Ebrahimi      "BUILD_OBJECT_TRACKER",
175*b7893ccfSSadaf Ebrahimi      "BUILD_THREAD_SAFETY",
176*b7893ccfSSadaf Ebrahimi      "BUILD_PARAMETER_VALIDATION",
177*b7893ccfSSadaf Ebrahimi      "LAYER_CHASSIS_CAN_WRAP_HANDLES",
178*b7893ccfSSadaf Ebrahimi    ],
179*b7893ccfSSadaf Ebrahimi  ],
180*b7893ccfSSadaf Ebrahimi]
181*b7893ccfSSadaf Ebrahimi
182*b7893ccfSSadaf Ebrahimiif (!is_android) {
183*b7893ccfSSadaf Ebrahimi  action("vulkan_gen_json_files") {
184*b7893ccfSSadaf Ebrahimi    script = "build-gn/generate_vulkan_layers_json.py"
185*b7893ccfSSadaf Ebrahimi    public_deps = [
186*b7893ccfSSadaf Ebrahimi      ":vulkan_clean_old_validation_layer_objects",
187*b7893ccfSSadaf Ebrahimi    ]
188*b7893ccfSSadaf Ebrahimi    json_names = [
189*b7893ccfSSadaf Ebrahimi      "VkLayer_core_validation.json",
190*b7893ccfSSadaf Ebrahimi      "VkLayer_object_lifetimes.json",
191*b7893ccfSSadaf Ebrahimi      "VkLayer_stateless_validation.json",
192*b7893ccfSSadaf Ebrahimi      "VkLayer_standard_validation.json",
193*b7893ccfSSadaf Ebrahimi      "VkLayer_thread_safety.json",
194*b7893ccfSSadaf Ebrahimi      "VkLayer_unique_objects.json",
195*b7893ccfSSadaf Ebrahimi      "VkLayer_khronos_validation.json",
196*b7893ccfSSadaf Ebrahimi    ]
197*b7893ccfSSadaf Ebrahimi    sources = [
198*b7893ccfSSadaf Ebrahimi      "$vulkan_headers_dir/include/vulkan/vulkan_core.h",
199*b7893ccfSSadaf Ebrahimi      "$vulkan_headers_dir/include/vulkan/vk_layer.h",
200*b7893ccfSSadaf Ebrahimi    ]
201*b7893ccfSSadaf Ebrahimi    outputs = []
202*b7893ccfSSadaf Ebrahimi    foreach(json_name, json_names) {
203*b7893ccfSSadaf Ebrahimi      sources += [ "layers/json/$json_name.in" ]
204*b7893ccfSSadaf Ebrahimi      outputs += [ "$vulkan_data_dir/$json_name" ]
205*b7893ccfSSadaf Ebrahimi    }
206*b7893ccfSSadaf Ebrahimi    args = [
207*b7893ccfSSadaf Ebrahimi             rebase_path("layers/json", root_build_dir),
208*b7893ccfSSadaf Ebrahimi             rebase_path(vulkan_data_dir, root_build_dir),
209*b7893ccfSSadaf Ebrahimi           ] + rebase_path(sources, root_build_dir)
210*b7893ccfSSadaf Ebrahimi
211*b7893ccfSSadaf Ebrahimi    # The layer JSON files are part of the necessary data deps.
212*b7893ccfSSadaf Ebrahimi    data = outputs
213*b7893ccfSSadaf Ebrahimi  }
214*b7893ccfSSadaf Ebrahimi}
215*b7893ccfSSadaf Ebrahimi
216*b7893ccfSSadaf Ebrahimisource_set("vulkan_layer_utils") {
217*b7893ccfSSadaf Ebrahimi  include_dirs = [
218*b7893ccfSSadaf Ebrahimi    "layers",
219*b7893ccfSSadaf Ebrahimi    "layers/generated",
220*b7893ccfSSadaf Ebrahimi  ]
221*b7893ccfSSadaf Ebrahimi  sources = [
222*b7893ccfSSadaf Ebrahimi    "layers/vk_format_utils.cpp",
223*b7893ccfSSadaf Ebrahimi    "layers/vk_format_utils.h",
224*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_config.cpp",
225*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_config.h",
226*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_extension_utils.cpp",
227*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_extension_utils.h",
228*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_utils.cpp",
229*b7893ccfSSadaf Ebrahimi    "layers/vk_layer_utils.h",
230*b7893ccfSSadaf Ebrahimi    "$vulkan_headers_dir/include/vulkan/vk_layer.h",
231*b7893ccfSSadaf Ebrahimi    "$vulkan_headers_dir/include/vulkan/vulkan.h",
232*b7893ccfSSadaf Ebrahimi    "$vulkan_headers_dir/include/vulkan/vk_sdk_platform.h",
233*b7893ccfSSadaf Ebrahimi  ]
234*b7893ccfSSadaf Ebrahimi  public_configs = [
235*b7893ccfSSadaf Ebrahimi    "$vulkan_headers_dir:vulkan_headers_config",
236*b7893ccfSSadaf Ebrahimi    ":vulkan_internal_config",
237*b7893ccfSSadaf Ebrahimi  ]
238*b7893ccfSSadaf Ebrahimi  configs -= [ "//build/config/compiler:chromium_code" ]
239*b7893ccfSSadaf Ebrahimi  configs += [ "//build/config/compiler:no_chromium_code" ]
240*b7893ccfSSadaf Ebrahimi  public_deps = []
241*b7893ccfSSadaf Ebrahimi  configs -= vulkan_undefine_configs
242*b7893ccfSSadaf Ebrahimi}
243*b7893ccfSSadaf Ebrahimi
244*b7893ccfSSadaf Ebrahimiconfig("vulkan_core_validation_config") {
245*b7893ccfSSadaf Ebrahimi  include_dirs = [ "$vvl_glslang_dir" ]
246*b7893ccfSSadaf Ebrahimi}
247*b7893ccfSSadaf Ebrahimi
248*b7893ccfSSadaf Ebrahimisource_set("vulkan_core_validation_glslang") {
249*b7893ccfSSadaf Ebrahimi  public_deps = [
250*b7893ccfSSadaf Ebrahimi    "${vvl_spirv_tools_dir}:spvtools",
251*b7893ccfSSadaf Ebrahimi    "${vvl_spirv_tools_dir}:spvtools_opt",
252*b7893ccfSSadaf Ebrahimi    "${vvl_spirv_tools_dir}:spvtools_val",
253*b7893ccfSSadaf Ebrahimi  ]
254*b7893ccfSSadaf Ebrahimi  public_configs = [
255*b7893ccfSSadaf Ebrahimi    "$vulkan_headers_dir:vulkan_headers_config",
256*b7893ccfSSadaf Ebrahimi    ":vulkan_core_validation_config",
257*b7893ccfSSadaf Ebrahimi  ]
258*b7893ccfSSadaf Ebrahimi}
259*b7893ccfSSadaf Ebrahimi
260*b7893ccfSSadaf Ebrahimiconfig("vulkan_stateless_validation_config") {
261*b7893ccfSSadaf Ebrahimi  if (is_clang) {
262*b7893ccfSSadaf Ebrahimi    cflags_cc = [ "-Wno-unused-const-variable" ]
263*b7893ccfSSadaf Ebrahimi  }
264*b7893ccfSSadaf Ebrahimi}
265*b7893ccfSSadaf Ebrahimi
266*b7893ccfSSadaf Ebrahimiforeach(layer_info, layers) {
267*b7893ccfSSadaf Ebrahimi  name = layer_info[0]
268*b7893ccfSSadaf Ebrahimi  shared_library("VkLayer_$name") {
269*b7893ccfSSadaf Ebrahimi    configs -= [ "//build/config/compiler:chromium_code" ]
270*b7893ccfSSadaf Ebrahimi    configs += [ "//build/config/compiler:no_chromium_code" ]
271*b7893ccfSSadaf Ebrahimi    configs -= vulkan_undefine_configs
272*b7893ccfSSadaf Ebrahimi    public_configs = [ ":vulkan_layer_config" ]
273*b7893ccfSSadaf Ebrahimi    deps = [
274*b7893ccfSSadaf Ebrahimi      ":vulkan_layer_utils",
275*b7893ccfSSadaf Ebrahimi    ]
276*b7893ccfSSadaf Ebrahimi    if (layer_info[2] != "") {
277*b7893ccfSSadaf Ebrahimi      deps += layer_info[2]
278*b7893ccfSSadaf Ebrahimi    }
279*b7893ccfSSadaf Ebrahimi    sources = layer_info[1]
280*b7893ccfSSadaf Ebrahimi    if (is_win) {
281*b7893ccfSSadaf Ebrahimi      sources += [ "layers/VkLayer_$name.def" ]
282*b7893ccfSSadaf Ebrahimi    }
283*b7893ccfSSadaf Ebrahimi    if (is_linux || is_android) {
284*b7893ccfSSadaf Ebrahimi      ldflags = [ "-Wl,-Bsymbolic,--exclude-libs,ALL" ]
285*b7893ccfSSadaf Ebrahimi    }
286*b7893ccfSSadaf Ebrahimi    if (is_android) {
287*b7893ccfSSadaf Ebrahimi      libs = [
288*b7893ccfSSadaf Ebrahimi        "log",
289*b7893ccfSSadaf Ebrahimi        "nativewindow",
290*b7893ccfSSadaf Ebrahimi      ]
291*b7893ccfSSadaf Ebrahimi      configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
292*b7893ccfSSadaf Ebrahimi    }
293*b7893ccfSSadaf Ebrahimi    defines = layer_info[3]
294*b7893ccfSSadaf Ebrahimi  }
295*b7893ccfSSadaf Ebrahimi}
296*b7893ccfSSadaf Ebrahimi
297*b7893ccfSSadaf Ebrahimigroup("vulkan_validation_layers") {
298*b7893ccfSSadaf Ebrahimi  data_deps = []
299*b7893ccfSSadaf Ebrahimi  foreach(layer_info, layers) {
300*b7893ccfSSadaf Ebrahimi    name = layer_info[0]
301*b7893ccfSSadaf Ebrahimi    data_deps += [ ":VkLayer_$name" ]
302*b7893ccfSSadaf Ebrahimi  }
303*b7893ccfSSadaf Ebrahimi}
304