remove unused hh_paths
[hiphop-php.git] / hphp / hack / CMakeLists.txt
blob831c46db9e49aad6dfaf05b7d934e4b3cf83722e
1 option(BUILD_HACK "True if we should build the Hack typechecker." ON)
3 include(CMakeParseArguments)
5 if (NOT BUILD_HACK)
6   message(STATUS "Skipping hack")
7   return()
8 endif()
10 message(STATUS "Building hack")
12 find_package(LZ4)
13 find_package(LibElf)
15 # native_libraries: values for `-l` flags
16 # lib_paths: values for `-L` flags (directories)
17 # extra_link_opts: opaque options passed to the linker
19 # We need extra_link_opts for:
20 # - static libraries
21 # - anything built from third-party: cmake gives us the link flags
22 unset(extra_include_paths)
23 unset(extra_native_libraries)
24 unset(extra_lib_paths)
25 unset(extra_link_opts)
26 unset(extra_cc_flags)
28 # Allows '#include "hphp/path/to/library/"' paths to start from hphp
29 # project directory  which is consistent with fbmake's include paths.
30 list(APPEND extra_include_paths ${HPHP_HOME})
31 list(APPEND extra_cc_flags -pthread)
33 # Xcode/Ninja generators undefined MAKE
34 if(NOT MAKE)
35   set(MAKE make)
36 endif()
38 if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
39   set(DUNE_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/_build")
40   set(OPAM_STAMP_FILE "_build/opam.stamp")
41   set(RUST_FFI_BUILD_ROOT "${DUNE_BUILD_DIR}/rust_ffi")
42   set(CARGO_HOME "${DUNE_BUILD_DIR}/cargo_home")
43 else()
44   set(DUNE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
45   set(RUST_FFI_BUILD_ROOT "${CMAKE_BINARY_DIR}")
46   set(CARGO_HOME "${CMAKE_CURRENT_BINARY_DIR}/cargo_home")
47   set(OPAM_STAMP_FILE "opam.stamp")
48 endif()
49 set(HACK_BUILD_ROOT "${DUNE_BUILD_DIR}/default")
51 get_target_property(OPAM_EXECUTABLE opam IMPORTED_LOCATION)
53 add_custom_command(
54   OUTPUT "${OPAM_STAMP_FILE}"
55   DEPENDS opam opam_setup.sh
56   COMMAND
57     ${CMAKE_CURRENT_SOURCE_DIR}/opam_setup.sh
58     "${OPAM_EXECUTABLE}"
59     "${DUNE_BUILD_DIR}"
60     && cmake -E touch "${OPAM_STAMP_FILE}"
62 add_custom_target(opam_setup DEPENDS "${OPAM_STAMP_FILE}" opam_setup.sh)
64 if (SKIP_OPAM)
65   set(OPAMROOT "~/.opam")
66 else ()
67   set(OPAMROOT "${DUNE_BUILD_DIR}/opam")
68 endif()
70 if(LZ4_FOUND)
71   list(APPEND extra_include_paths ${LZ4_INCLUDE_DIR})
72   get_filename_component(pth ${LZ4_LIBRARY} DIRECTORY)
73   list(APPEND extra_lib_paths ${pth})
74   list(APPEND extra_native_libraries "lz4")
75 else()
76   get_target_property(LZ4_INCLUDE_DIRS lz4 INTERFACE_INCLUDE_DIRECTORIES)
77   list(APPEND extra_include_paths ${LZ4_INCLUDE_DIRS})
78   # If LZ4_FOUND is false either we didn't find lz4 or we found it but it's the
79   # wrong version.  We can't just add the new path and a native_lib because we
80   # can't control the order (and -l won't accept the raw path to the lib).  By
81   # doing it this way we specify the path explicitly.
82   get_target_property(LZ4_LIBS lz4 INTERFACE_LINK_LIBRARIES)
83   list(APPEND extra_link_opts ${LZ4_LIBS})
84 endif()
86 get_target_property(ZSTD_INCLUDE_DIRS zstd INTERFACE_INCLUDE_DIRECTORIES)
87 list(APPEND extra_include_paths ${ZSTD_INCLUDE_DIRS})
88 get_target_property(ZSTD_LIBS zstd INTERFACE_LINK_LIBRARIES)
89 list(APPEND extra_link_opts ${ZSTD_LIBS})
91 list(APPEND extra_include_paths ${LIBSQLITE3_INCLUDE_DIR})
92 get_filename_component(pth ${LIBSQLITE3_LIBRARY} DIRECTORY)
93 list(APPEND extra_lib_paths ${pth})
94 list(APPEND extra_native_libraries "sqlite3")
96 get_target_property(RUSTC_EXE rustc LOCATION)
97 get_target_property(CARGO_EXE cargo LOCATION)
98 get_filename_component(RUSTC_BIN_DIR "${RUSTC_EXE}" DIRECTORY)
99 get_filename_component(CARGO_BIN_DIR "${CARGO_EXE}" DIRECTORY)
101 function(invoke_dune name target)
102   add_custom_target(
103       ${name}
104       COMMAND
105         . "${CMAKE_CURRENT_BINARY_DIR}/dev_env.sh" &&
106         opam exec --
107         $(MAKE) --makefile=Makefile.dune ${target}
108         BYTECODE="${EMIT_OCAML_BYTECODE}"
109       WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
110     )
112   add_dependencies(${name} rustc cargo zstd)
113   if (NOT SKIP_OPAM)
114     add_dependencies(${name} opam_setup)
115   endif()
116 endfunction()
118 invoke_dune(hack_dune_debug debug)
119 invoke_dune(hack_dune_test test)
120 invoke_dune(hack_dune all)
122 set(INVOKE_CARGO "${CMAKE_SOURCE_DIR}/hphp/hack/scripts/invoke_cargo.sh")
124 if(DEFINED ENV{HACKDEBUG})
125   set(PROFILE "debug")
126 else()
127   set(PROFILE "release")
128 endif()
130 set(RUST_OPCODES_DIR "${CMAKE_BINARY_DIR}/hphp/hack/src/hackc")
131 set(RUST_OPCODES "${RUST_OPCODES_DIR}/opcodes.rs")
133 set(HHBC_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc")
134 set(HHBC_AST_SRCS
135   "${HHBC_PREFIX}/hhbc/adata.rs"
136   "${HHBC_PREFIX}/hhbc/attribute.rs"
137   "${HHBC_PREFIX}/hhbc/body.rs"
138   "${HHBC_PREFIX}/hhbc/class.rs"
139   "${HHBC_PREFIX}/hhbc/coeffects.rs"
140   "${HHBC_PREFIX}/hhbc/constant.rs"
141   "${HHBC_PREFIX}/hhbc/function.rs"
142   "${HHBC_PREFIX}/hhbc/id.rs"
143   "${HHBC_PREFIX}/hhbc/instruct.rs"
144   "${HHBC_PREFIX}/hhbc/method.rs"
145   "${HHBC_PREFIX}/hhbc/module.rs"
146   "${HHBC_PREFIX}/hhbc/param.rs"
147   "${HHBC_PREFIX}/hhbc/pos.rs"
148   "${HHBC_PREFIX}/hhbc/property.rs"
149   "${HHBC_PREFIX}/hhbc/symbol_refs.rs"
150   "${HHBC_PREFIX}/hhbc/types.rs"
151   "${HHBC_PREFIX}/hhbc/type_const.rs"
152   "${HHBC_PREFIX}/hhbc/typedef.rs"
153   "${HHBC_PREFIX}/hhbc/typed_value.rs"
154   "${HHBC_PREFIX}/hhbc/unit.rs"
155   "${HHBC_PREFIX}/hhbc/unit_cbindgen.rs"  # Not in a crate.
156   "${RUST_OPCODES}"
159 set(NAMING_SPECIAL_NAMES_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/src/naming")
160 set(NAMING_SPECIAL_NAMES_SRCS
161    "${NAMING_SPECIAL_NAMES_PREFIX}/naming_special_names.rs"
162    "${NAMING_SPECIAL_NAMES_PREFIX}/naming_special_names_ffi_cbindgen.rs"
165 set(FFI_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/src/utils/ffi")
166 set(FFI_SRCS
167    "${FFI_PREFIX}/ffi.rs"
168    "${FFI_PREFIX}/ffi_ffi_cbindgen.rs"
171 add_custom_command(
172   OUTPUT ${RUST_OPCODES}
173   COMMAND
174     ${CMAKE_COMMAND} -E make_directory "${RUST_OPCODES_DIR}" &&
175     . "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
176     ${INVOKE_CARGO} dump-opcodes dump-opcodes --exe &&
177     ${INVOKE_CARGO} dump-opcodes dump-opcodes --bin dump_opcodes
178       -o "${RUST_OPCODES}"
179   COMMENT "Generating Rust opcode struct for cbindgen to use to generate hhbc-ast.h"
180   DEPENDS "${OPCODE_DATA}"
183 set(HHBC_AST_HEADER "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/hackc/hhbc-ast.h")
184 set(FFI_HEADER "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/utils/ffi.h")
185 set(NAMING_SPECIAL_NAMES_HEADER "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/naming/naming-special-names.h")
186 set(TYPE_CONSTRAINT_HEADER "${CMAKE_SOURCE_DIR}/hphp/runtime/vm/type-constraint-flags.h")
187 set(FCALL_HEADER "${CMAKE_SOURCE_DIR}/hphp/runtime/vm/fcall-args-flags.h")
188 set(HHBC_HEADER "${CMAKE_SOURCE_DIR}/hphp/runtime/vm/hhbc-shared.h")
189 set(ATTR_HEADER "${CMAKE_SOURCE_DIR}/hphp/runtime/base/attr.h")
190 set(FFI_EXTRA_HEADER "${CMAKE_SOURCE_DIR}/hphp/hack/src/utils/ffi/ffi_extra.h")
192 add_custom_command(
193   OUTPUT ${HHBC_AST_HEADER}
194   COMMAND
195    . "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
196     ${INVOKE_CARGO} ffi_cbindgen ffi_cbindgen --exe &&
197     ${INVOKE_CARGO} ffi_cbindgen ffi_cbindgen --bin ffi_cbindgen
198       --header "${FFI_HEADER}" --namespaces "HPHP,hackc"
199       --includes "${FFI_EXTRA_HEADER}"
200       ${FFI_SRCS} &&
201     ${INVOKE_CARGO} ffi_cbindgen ffi_cbindgen --bin ffi_cbindgen
202       --header "${NAMING_SPECIAL_NAMES_HEADER}" --namespaces "HPHP,hackc,hhbc"
203       ${NAMING_SPECIAL_NAMES_SRCS} &&
204     ${INVOKE_CARGO} ffi_cbindgen ffi_cbindgen --bin ffi_cbindgen
205       --header "${HHBC_AST_HEADER}" --namespaces "HPHP,hackc,hhbc"
206       --includes "${FFI_HEADER},${NAMING_SPECIAL_NAMES_HEADER},${TYPE_CONSTRAINT_HEADER},${ATTR_HEADER},${FCALL_HEADER},${HHBC_HEADER}"
207       ${HHBC_AST_SRCS}
208   DEPENDS rustc cargo "${RUST_OPCODES}"
209   COMMENT "Generating hhbc-ast.h"
212 add_custom_target(
213   "hhbc_ast_cbindgen"
214   DEPENDS ${HHBC_AST_HEADER}
217 add_library("hhbc_ast_header" INTERFACE)
218 add_dependencies("hhbc_ast_header" "hhbc_ast_cbindgen")
220 add_custom_target(hack_rust_ffi_bridge_targets)
222 # Compiling cxx entrypoints for hhvm
224 # Usage:
225 #     build_cxx_bridge(
226 #       name
227 #       DIR directory
228 #       [EXTRA_SRCS src [src ...]]
229 #       [LINK_LIBS lib [lib ...]]
230 #     )
232 # Where:
233 #   `name` is the target name of the cxx_bridge.
234 #   `directory` is the required directory of the cxx_bridge sources.
235 #   `src` are extra source files to include in the bridge.
236 #   `lib` are extra link libraries to include in the bridge.
238 function(build_cxx_bridge NAME)
239   cmake_parse_arguments(CXX_BRIDGE "" "DIR" "EXTRA_SRCS;LINK_LIBS" ${ARGN})
241   if ("${CXX_BRIDGE_DIR}" STREQUAL "")
242     message(FATAL_ERROR "Missing DIR parameter")
243   endif()
244   if (NOT "${CXX_BRIDGE_UNPARSED_ARGUMENTS}" STREQUAL "")
245     message(FATAL_ERROR "Unexpected parameters: ${CXX_BRIDGE_UNPARSED_ARGUMENTS}")
246   endif()
248   set(FFI_BRIDGE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${CXX_BRIDGE_DIR}")
249   set(FFI_BRIDGE_BIN "${RUST_FFI_BUILD_ROOT}/hphp/hack/${CXX_BRIDGE_DIR}")
251   set(RUST_PART_LIB "${FFI_BRIDGE_BIN}/${PROFILE}/${CMAKE_STATIC_LIBRARY_PREFIX}${NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
252   set(RUST_PART_CXX "${FFI_BRIDGE_BIN}/${NAME}.cpp")
253   set(RUST_PART_HEADER "${FFI_BRIDGE_BIN}/${NAME}.rs.h")
254   set(GENERATED "${FFI_BRIDGE_BIN}/cxxbridge/${NAME}/${NAME}")
255   set(GENERATED_CXXBRIDGE "${FFI_BRIDGE_BIN}/cxxbridge")
257   add_custom_command(
258       OUTPUT
259         ${RUST_PART_CXX}
260         ${RUST_PART_HEADER}
261         ${RUST_PART_LIB}
262         ${GENERATED_CXXBRIDGE}
263       COMMAND
264         ${CMAKE_COMMAND} -E make_directory "${FFI_BRIDGE_BIN}" &&
265         . "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
266         ${INVOKE_CARGO} "${NAME}" "${NAME}" --target-dir "${FFI_BRIDGE_BIN}" &&
267         ${CMAKE_COMMAND} -E copy "${GENERATED}.rs.cc" "${RUST_PART_CXX}" &&
268         ${CMAKE_COMMAND} -E copy "${GENERATED}.rs.h" "${RUST_PART_HEADER}"
269       WORKING_DIRECTORY ${FFI_BRIDGE_SRC}
270       DEPENDS rustc cargo "${OPCODE_DATA}"
271   )
272   add_custom_target(
273     "${NAME}_cxx"
274     DEPENDS ${RUST_PART_LIB}
275   )
276   add_library("${NAME}" STATIC ${RUST_PART_CXX} ${CXX_BRIDGE_EXTRA_SRCS} )
277   add_dependencies(hack_rust_ffi_bridge_targets "${NAME}")
278   add_library("${NAME}_rust_part" STATIC IMPORTED)
279   add_dependencies("${NAME}_rust_part" "${NAME}_cxx")
281   # Intentionally create link-time cyclic dependency between ${NAME}_rust_part
282   # and ${NAME} so that CMake will automatically construct the link line so
283   # that the linker will scan through involved static libraries multiple times.
284   set_target_properties(
285     "${NAME}_rust_part"
286     PROPERTIES
287     IMPORTED_LOCATION ${RUST_PART_LIB}
288     IMPORTED_LINK_DEPENDENT_LIBRARIES "${NAME}"
289   )
290   target_link_libraries(
291     "${NAME}"
292     PUBLIC
293       "${NAME}_rust_part"
294       ${CXX_BRIDGE_LINK_LIBS}
295   )
296   target_include_directories("${NAME}" INTERFACE "${RUST_FFI_BUILD_ROOT}")
297   target_include_directories("${NAME}" PRIVATE "${GENERATED_CXXBRIDGE}")
298 endfunction()
300 build_cxx_bridge(
301   parser_ffi
302   DIR "src/parser/ffi_bridge"
304 build_cxx_bridge(
305   compiler_ffi
306   DIR "src/hackc/ffi_bridge"
307   EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/ffi_bridge/external_decl_provider.cpp"
308   LINK_LIBS hdf
310 build_cxx_bridge(
311   hdf
312   DIR "src/utils/hdf"
313   EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/utils/hdf/hdf-wrap.cpp"
314   LINK_LIBS folly
316 build_cxx_bridge(
317   hhvm_types_ffi
318   DIR "src/hackc/hhvm_cxx/hhvm_types"
319   EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_types/as-base-ffi.cpp"
321 build_cxx_bridge(
322  hhvm_hhbc_defs_ffi
323  DIR "src/hackc/hhvm_cxx/hhvm_hhbc_defs"
324  EXTRA_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/hackc/hhvm_cxx/hhvm_hhbc_defs/as-hhbc-ffi.cpp"
327 if (NOT LZ4_FOUND)
328   add_dependencies(hack_dune lz4)
329   add_dependencies(hack_dune_debug lz4)
330   add_dependencies(hack_dune_test lz4)
331 endif()
333 # Intentionally not using `hack_dune_debug` as it generates output files of a
334 # different format (bytecode instead of raw executables, which is useful if
335 # you're working with Hack. Keep it around, but require it to be explicitly used
336 add_custom_target(hack ALL DEPENDS hack_dune "${OPCODE_DATA}")
337 add_custom_target(hack_test DEPENDS hack_dune_test "${OPCODE_DATA}")
339 configure_file(dev_env.sh.in dev_env.sh ESCAPE_QUOTES @ONLY)
340 configure_file(dev_env_common.sh.in dev_env_common.sh ESCAPE_QUOTES @ONLY)
341 configure_file(dev_env_rust_only.sh.in dev_env_rust_only.sh ESCAPE_QUOTES @ONLY)
343 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_client
344   DESTINATION bin
345   COMPONENT dev)
347 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_server
348   DESTINATION bin
349   COMPONENT dev)
351 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hackfmt
352   DESTINATION bin
353   COMPONENT dev)
355 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_parse
356   DESTINATION bin
357   COMPONENT dev)