1import("//llvm/utils/gn/build/symlink_or_copy.gni")
2import("//llvm/utils/gn/build/write_cmake_config.gni")
3
4# create_clangd_xpc_framework() in cmake creates both the ClangdXPC.framework
5# bundle and the clangd.xpc bundle within it in a single action.
6# Since GN has some native support for macOS bundles, it's more natural
7# to have one create_bundle() each for both ClangdXPC.framework and clangd.xpc.
8# See `llvm/utils/gn/gn.py help create_bundle` and ../cmake/modules.
9
10######################################################################
11# clangd.xpc bundle
12
13write_cmake_config("XPCServiceInfo.plist") {
14  input = "../cmake/XPCServiceInfo.plist.in"
15  output = "$target_gen_dir/XPCServiceInfo.plist"
16  service_name = "clangd"
17  values = [
18    "CLANGD_XPC_SERVICE_NAME=$service_name",
19    "CLANGD_XPC_SERVICE_BUNDLE_NAME=org.llvm.$service_name",
20  ]
21}
22
23bundle_data("clangxpc_bundle_xpc_service_info_plist") {
24  public_deps = [ ":XPCServiceInfo.plist" ]
25  sources = [ "$target_gen_dir/XPCServiceInfo.plist" ]
26  outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
27}
28
29bundle_data("clangxpc_bundle_xpc_service_executable") {
30  public_deps = [ "//clang-tools-extra/clangd/tool:clangd" ]
31  sources = [ "$root_out_dir/bin/clangd" ]
32  outputs = [ "{{bundle_executable_dir}}/{{source_file_part}}" ]
33}
34
35create_bundle("clangd.xpc") {
36  # .app directory structure.
37  # Since this target only exists to be copied into ClangdXPC.framework,
38  # put it in $target_gen_dir, not $root_out_dir.
39  bundle_root_dir = "$target_gen_dir/$target_name"
40  bundle_contents_dir = "$bundle_root_dir/Contents"
41  bundle_executable_dir = "$bundle_contents_dir/MacOS"
42
43  deps = [
44    ":clangxpc_bundle_xpc_service_executable",
45    ":clangxpc_bundle_xpc_service_info_plist",
46  ]
47}
48
49######################################################################
50# ClangdXPC.framework
51
52write_cmake_config("Info.plist") {
53  input = "../cmake/Info.plist.in"
54  output = "$target_gen_dir/Info.plist"
55  values = [ "CLANGD_XPC_FRAMEWORK_NAME=ClangdXPC" ]
56}
57
58bundle_data("clangdxpc_bundle_info_plist") {
59  public_deps = [ ":Info.plist" ]
60  sources = [ "$target_gen_dir/Info.plist" ]
61  outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
62}
63
64shared_library("ClangdXPCLib") {
65  deps = [ "//clang-tools-extra/clangd/tool:clangd" ]
66  sources = [ "ClangdXPC.cpp" ]
67}
68
69bundle_data("clangdxpc_bundle_executable") {
70  public_deps = [ ":ClangdXPCLib" ]
71  sources = [ "$root_out_dir/lib/libClangdXPCLib.dylib" ]
72  outputs = [ "{{bundle_executable_dir}}/ClangdXPC" ]
73}
74
75bundle_data("clangdxpc_bundle_xpc") {
76  public_deps = [ ":clangd.xpc" ]
77  sources = [ "$target_gen_dir/clangd.xpc" ]
78  outputs = [ "{{bundle_contents_dir}}/XPCServices/{{source_file_part}}" ]
79}
80
81# .framework bundle symlinks:
82# - ./ClangdXPC -> Versions/Current/ClangdXPC
83# - ./Resources -> Versions/Current/Resources
84# - ./XPCServices -> Versions/Current/XPCServices
85# - ./Versions/Current -> Versions/A
86# Since bundles are a mac thing, we know that symlink_or_copy() will symlink
87# and not copy, and hence creating the symlink before the target exists is safe.
88symlinks = [
89  "ClangdXPC",
90  "Resources",
91  "XPCServices",
92]
93foreach(target, symlinks) {
94  symlink_or_copy("clangdxpc_symlink_$target") {
95    source = "Versions/Current/$target"
96    output = "$root_out_dir/lib/ClangdXPC.framework/$target"
97  }
98}
99symlink_or_copy("clangdxpc_symlink_Versions_Current") {
100  source = "A"
101  output = "$root_out_dir/lib/ClangdXPC.framework/Versions/Current"
102}
103
104create_bundle("ClangdXPC.framework") {
105  # .framework directory structure.
106  bundle_root_dir = "$root_out_dir/lib/$target_name"
107  bundle_contents_dir = "$bundle_root_dir/Versions/A"
108  bundle_executable_dir = "$bundle_contents_dir"
109  bundle_resources_dir = "$bundle_contents_dir/Resources"
110
111  deps = [
112    ":clangdxpc_bundle_executable",
113    ":clangdxpc_bundle_info_plist",
114    ":clangdxpc_bundle_xpc",
115    ":clangdxpc_symlink_Versions_Current",
116  ]
117  foreach(target, symlinks) {
118    deps += [ ":clangdxpc_symlink_$target" ]
119  }
120}
121