1# Things aren't as nice in here as we'd like, but that's because
2# we need to preserve how things build in the autoconf and windows
3# builds for watchman.
4
5compiler_flags = [
6    "-Wunused-variable",
7    "-DWATCHMAN_FACEBOOK_INTERNAL",
8]
9
10# Generates 'config.h' by probing for system capabilities
11def prober():
12    import os
13
14    # We're going to extract the configured compiler from the buck config
15    # and pass that down to the probe script.
16    config_flags = {
17      'cc': 'cc_real',
18      'cppflags': 'cppflags',
19      'ldflags': 'ldflags',
20    }
21
22    probe_cmd = [
23        'python',
24        '$SRCDIR/probe.py',
25        '--configure=$SRCDIR/configure.ac',
26        '--cwd=%s' % os.getcwd()]
27
28    for name, key in config_flags.iteritems():
29        val = read_config('cxx', key)
30        probe_cmd.append("--%s='%s'" % (name, val))
31
32    probe_cmd.append('> $OUT')
33
34    buck_genrule(
35        name='generate_config_h',
36        srcs=[
37            'probe.py',
38            'configure.ac',
39        ],
40        cmd=' '.join(probe_cmd),
41        out='config.h',
42    )
43
44def config_h():
45    # we use this same convention in the eden build to discover whether
46    # we are building in the internal fb repo or in the opensourced project(s).
47    if read_config('codebase', 'mode') == 'public':
48        prober()
49    else:
50        # Just copy the pre-configured linux attributes so that we have
51        # know precisely what the characteristics will be for this build.
52        buck_genrule(
53            name='generate_config_h',
54            srcs=['facebook/linux_config.h'],
55            cmd='cp $SRCDIR/facebook/linux_config.h $OUT',
56            out='config.h',
57        )
58
59config_h()
60
61# Wraps the generated config.h file in a library rule that we can
62# depend upon.
63buck_cxx_library(
64    name = "config_h",
65    header_namespace = "",
66    exported_headers = [
67        ":generate_config_h",
68    ],
69    visibility = ["PUBLIC"],
70)
71
72# Exports all watchman headers without the 'watchman/' prefix that
73# they would otherwise have in our build tree.
74buck_cxx_library(
75    name = "headers",
76    header_namespace = "",
77    exported_headers = glob(["**/*.h"]),
78    exported_deps = [
79        ":config_h",
80        "//common/base:build_info",
81        "//watchman/thirdparty/jansson:config_h",
82    ],
83    visibility = ["PUBLIC"],
84)
85
86cpp_library(
87    name = "eden_watcher",
88    srcs = [
89        "watcher/eden.cpp",
90    ],
91    compiler_flags = compiler_flags,
92    # We use constructors to declare commands rather than maintaining
93    # static tables of things.  Ensure that they don't get stripped
94    # out of the final binary!
95    link_whole = True,
96    supported_platforms_regex = "glibc",
97    deps = [
98        ":err",
99        ":headers",
100        "@/eden/fs/service:thrift-streaming-cpp2",
101    ],
102)
103
104# Linux specific watcher module
105cpp_library(
106    name = "sysdep_watcher",
107    srcs = ["watcher/inotify.cpp"],
108    compiler_flags = compiler_flags,
109    # We use constructors to declare commands rather than maintaining
110    # static tables of things.  Ensure that they don't get stripped
111    # out of the final binary!
112    link_whole = True,
113    supported_platforms_regex = "glibc",
114    deps = [
115        ":eden_watcher",
116        ":err",
117        ":headers",
118    ],
119)
120
121# mac specific watcher module
122cpp_library(
123    name = "sysdep_watcher",
124    srcs = [
125        "watcher/fsevents.cpp",
126        "watcher/kqueue.cpp",
127    ],
128    compiler_flags = compiler_flags,
129    # We use constructors to declare commands rather than maintaining
130    # static tables of things.  Ensure that they don't get stripped
131    # out of the final binary!
132    link_whole = True,
133    supported_platforms_regex = "macos",
134    deps = [":headers"],
135)
136
137# windows specific watcher module
138cpp_library(
139    name = "sysdep_watcher",
140    srcs = ["watcher/win32.cpp"],
141    compiler_flags = compiler_flags,
142    # We use constructors to declare commands rather than maintaining
143    # static tables of things.  Ensure that they don't get stripped
144    # out of the final binary!
145    link_whole = True,
146    supported_platforms_regex = "windows",
147    deps = [":headers"],
148)
149
150cpp_library(
151    name = "log",
152    srcs = [
153        "PubSub.cpp",
154        "log.cpp",
155    ],
156    compiler_flags = compiler_flags,
157    deps = [
158        ":headers",
159        "@/watchman/thirdparty/jansson:jansson",
160    ],
161)
162
163cpp_library(
164    name = "hash",
165    srcs = ["hash.cpp"],
166    compiler_flags = compiler_flags,
167    deps = [":headers"],
168)
169
170cpp_library(
171    name = "string",
172    srcs = ["string.cpp"],
173    compiler_flags = compiler_flags,
174    deps = [
175        ":hash",
176        ":headers",
177        "@/watchman/thirdparty/jansson:utf",
178    ],
179)
180
181cpp_library(
182    name = "err",
183    srcs = [
184        "root/poison.cpp",
185        "root/warnerr.cpp",
186    ],
187    compiler_flags = compiler_flags,
188    deps = [":headers"],
189)
190
191cpp_library(
192    name = "pcre",
193    srcs = ["query/pcre.cpp"],
194    compiler_flags = ["-DHAVE_PCRE_H"] + compiler_flags,
195    link_whole = True,
196    deps = [":headers"],
197    external_deps = ["pcre"],
198)
199
200cpp_library(
201    name = "testsupport",
202    srcs = [
203        "ChildProcess.cpp",
204        "FileDescriptor.cpp",
205        "FileInformation.cpp",
206        "Pipe.cpp",
207        "ThreadPool.cpp",
208        "bser.cpp",
209        "cfg.cpp",
210        "expflags.cpp",
211        "ignore.cpp",
212        "opendir.cpp",
213        "pending.cpp",
214        "time.cpp",
215    ],
216    compiler_flags = compiler_flags,
217    deps = [
218        ":headers",
219        ":log",
220        ":string",
221        "@/watchman/thirdparty/jansson:jansson",
222        "@/watchman/thirdparty/libart/src:art",
223    ],
224)
225
226# The bulk of the watchman implementation lives in this library
227cpp_library(
228    name = "watchmanlib",
229    srcs = glob(
230        [
231            "*.cpp",
232            "query/*.cpp",
233            "watcher/auto.cpp",
234            "root/*.cpp",
235            "cmds/*.cpp",
236            "scm/*.cpp",
237        ],
238        excludes = [
239            "main.cpp",
240            "stream_win.cpp",
241            "log.cpp",
242            "query/pcre.cpp",
243            "root/warnerr.cpp",
244            "root/poison.cpp",
245        ],
246    ),
247    compiler_flags = compiler_flags,
248    # We use constructors to declare commands rather than maintaining
249    # static tables of things.  Ensure that they don't get stripped
250    # out of the final binary!
251    link_whole = True,
252    deps = [
253        ":err",
254        ":headers",
255        ":log",
256        ":pcre",
257        ":string",
258        ":sysdep_watcher",
259        "@/watchman/thirdparty/jansson:jansson",
260        "@/watchman/thirdparty/libart/src:art",
261        "@/watchman/thirdparty/wildmatch:wildmatch",
262    ],
263)
264
265# and the watchman binary itself
266cpp_binary(
267    name = "watchman",
268    srcs = ["main.cpp"],
269    compiler_flags = compiler_flags,
270    deps = [
271        ":headers",
272        ":watchmanlib",
273    ],
274)
275
276# This is the custom test runner used by the open source build.
277python_library(
278    name = "runtests",
279    srcs = ["runtests.py"],
280    py_version = "<3",
281    deps = [
282        ":watchman",
283        "@/watchman/tests/integration:testlib",
284    ],
285)
286
287python_library(
288    name = "runtests-py3",
289    srcs = ["runtests.py"],
290    py_version = ">=3.5",
291    deps = [
292        ":watchman",
293        "@/watchman/tests/integration:testlib-py3",
294    ],
295)
296