FILENAME 3/4 - delete the old get_fun_path etc.
[hiphop-php.git] / hphp / hack / CMakeLists.txt
blobaea2a951c2c8d9c165a2d575b82745b8d767b34e
1 option(BUILD_HACK "True if we should build the Hack typechecker." ON)
3 if (NOT BUILD_HACK)
4   message(STATUS "Skipping hack")
5   return()
6 endif()
8 message(STATUS "Building hack")
10 find_package(LZ4)
11 find_package(LibElf)
13 # native_libraries: values for `-l` flags
14 # lib_paths: values for `-L` flags (directories)
15 # extra_link_opts: opaque options passed to the linker
17 # We need extra_link_opts for:
18 # - static libraries
19 # - anything built from third-party: cmake gives us the link flags
20 unset(extra_include_paths)
21 unset(extra_native_libraries)
22 unset(extra_lib_paths)
23 unset(extra_link_opts)
24 unset(extra_cc_flags)
26 # Allows '#include "hphp/path/to/library/"' paths to start from hphp
27 # project directory  which is consistent with fbmake's include paths.
28 list(APPEND extra_include_paths ${HPHP_HOME})
29 list(APPEND extra_cc_flags -pthread)
31 # Xcode/Ninja generators undefined MAKE
32 if(NOT MAKE)
33   set(MAKE make)
34 endif()
36 if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
37   set(DUNE_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/_build")
38   set(OPAM_STAMP_FILE "_build/opam.stamp")
39   set(RUST_FFI_BUILD_ROOT "${DUNE_BUILD_DIR}/rust_ffi")
40   set(CARGO_HOME "${DUNE_BUILD_DIR}/cargo_home")
41 else()
42   set(DUNE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
43   set(RUST_FFI_BUILD_ROOT "${CMAKE_BINARY_DIR}")
44   set(CARGO_HOME "${CMAKE_CURRENT_BINARY_DIR}/cargo_home")
45   set(OPAM_STAMP_FILE "opam.stamp")
46 endif()
47 set(HACK_BUILD_ROOT "${DUNE_BUILD_DIR}/default")
49 get_target_property(OPAM_EXECUTABLE opam IMPORTED_LOCATION)
51 add_custom_command(
52   OUTPUT "${OPAM_STAMP_FILE}"
53   DEPENDS opam opam_setup.sh
54   COMMAND
55     ${CMAKE_CURRENT_SOURCE_DIR}/opam_setup.sh
56     "${OPAM_EXECUTABLE}"
57     "${DUNE_BUILD_DIR}"
58     && cmake -E touch "${OPAM_STAMP_FILE}"
60 add_custom_target(opam_setup DEPENDS "${OPAM_STAMP_FILE}" opam_setup.sh)
62 if (SKIP_OPAM)
63   set(OPAMROOT "~/.opam")
64 else ()
65   set(OPAMROOT "${DUNE_BUILD_DIR}/opam")
66 endif()
68 if(LZ4_FOUND)
69   list(APPEND extra_include_paths ${LZ4_INCLUDE_DIR})
70   get_filename_component(pth ${LZ4_LIBRARY} DIRECTORY)
71   list(APPEND extra_lib_paths ${pth})
72   list(APPEND extra_native_libraries "lz4")
73 else()
74   get_target_property(LZ4_INCLUDE_DIRS lz4 INTERFACE_INCLUDE_DIRECTORIES)
75   list(APPEND extra_include_paths ${LZ4_INCLUDE_DIRS})
76   # If LZ4_FOUND is false either we didn't find lz4 or we found it but it's the
77   # wrong version.  We can't just add the new path and a native_lib because we
78   # can't control the order (and -l won't accept the raw path to the lib).  By
79   # doing it this way we specify the path explicitly.
80   get_target_property(LZ4_LIBS lz4 INTERFACE_LINK_LIBRARIES)
81   list(APPEND extra_link_opts ${LZ4_LIBS})
82 endif()
84 get_target_property(ZSTD_INCLUDE_DIRS zstd INTERFACE_INCLUDE_DIRECTORIES)
85 list(APPEND extra_include_paths ${ZSTD_INCLUDE_DIRS})
86 get_target_property(ZSTD_LIBS zstd INTERFACE_LINK_LIBRARIES)
87 list(APPEND extra_link_opts ${ZSTD_LIBS})
89 if(PC_SQLITE3_FOUND)
90   list(APPEND extra_include_paths ${LIBSQLITE3_INCLUDE_DIR})
91   get_filename_component(pth ${LIBSQLITE3_LIBRARY} DIRECTORY)
92   list(APPEND extra_lib_paths ${pth})
93   list(APPEND extra_native_libraries "sqlite3")
94 else()
95   list(APPEND extra_include_paths "${TP_DIR}/libsqlite3")
96   get_target_property(SQLITE_DIR sqlite3 BINARY_DIR)
97   list(APPEND extra_link_opts "${SQLITE_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}sqlite3${CMAKE_STATIC_LIBRARY_SUFFIX}")
98 endif()
100 get_target_property(RUSTC_EXE rustc LOCATION)
101 get_target_property(CARGO_EXE cargo LOCATION)
102 get_filename_component(RUSTC_BIN_DIR "${RUSTC_EXE}" DIRECTORY)
103 get_filename_component(CARGO_BIN_DIR "${CARGO_EXE}" DIRECTORY)
105 function(invoke_dune name target)
106   add_custom_target(
107       ${name}
108       COMMAND
109         . "${CMAKE_CURRENT_BINARY_DIR}/dev_env.sh" &&
110         opam config exec --
111         $(MAKE) --makefile=Makefile.dune ${target}
112         BYTECODE="${EMIT_OCAML_BYTECODE}"
113       WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
114     )
116   add_dependencies(${name} rustc cargo zstd)
117   if (NOT SKIP_OPAM)
118     add_dependencies(${name} opam_setup)
119   endif()
120 endfunction()
122 invoke_dune(hack_dune_debug debug)
123 invoke_dune(hack_dune_test test)
124 invoke_dune(hack_dune all)
126 set(CARGO_BUILD "${CMAKE_SOURCE_DIR}/hphp/hack/scripts/build_rust_to_ocaml.sh")
128 if(DEFINED ENV{HACKDEBUG})
129   set(PROFILE "debug")
130 else()
131   set(PROFILE "release")
132 endif()
134 set(HHBC_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/src/hhbc/hhbc_by_ref")
135 set(HHBC_AST_SRCS
136   "hhas_adata.rs"
137   "hhas_attribute.rs"
138   "hhas_body.rs"
139   "hhas_class.rs"
140   "hhas_coeffects.rs"
141   "hhas_constant.rs"
142   "hhas_function.rs"
143   "hhas_method.rs"
144   "hhas_param.rs"
145   "hhas_pos.rs"
146   "hhas_program.rs"
147   "hhas_property.rs"
148   "hhas_record_def.rs"
149   "hhas_symbol_refs.rs"
150   "hhas_type.rs"
151   "hhas_type_const.rs"
152   "hhas_typedef.rs"
153   "hhbc_ast.rs"
154   "hhbc_id.rs"
155   "instruction_sequence.rs"
156   "label.rs"
157   "local.rs"
158   "symbol_refs_state.rs"
159   "typed_value.rs"
162 foreach(src ${HHBC_AST_SRCS})
163   string(APPEND HHBC_AST_SRC_ARG "${HHBC_PREFIX}/${src},")
164 endforeach()
166 set(HHBC_AST_HEADER "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/hhbc/hhbc_by_ref/hhbc-ast.h")
167 set(FFI_HEADER "${RUST_FFI_BUILD_ROOT}/hphp/hack/src/utils/ffi.h")
168 add_custom_command(
169   OUTPUT ${HHBC_AST_HEADER}
170   COMMAND
171    . "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
172     ${CARGO_BUILD} ffi_cbindgen ffi_cbindgen --exe
173       --header "${FFI_HEADER}" --srcs "${CMAKE_CURRENT_SOURCE_DIR}/src/utils/ffi/ffi.rs"
174       --namespaces "HPHP,hackc" &&
175     ${CARGO_BUILD} ffi_cbindgen ffi_cbindgen --exe
176       --header "${HHBC_AST_HEADER}" --srcs "${HHBC_AST_SRC_ARG}" --namespaces "HPHP,hackc,hhbc"
177       --includes "${FFI_HEADER}"
178   DEPENDS rustc cargo
179   COMMENT "Generating hhbc-ast.h"
182 add_custom_target(
183   "hhbc_ast_cbindgen"
184   DEPENDS ${HHBC_AST_HEADER}
187 add_library("hhbc_ast_header" INTERFACE)
188 add_dependencies("hhbc_ast_header" "hhbc_ast_cbindgen")
190 add_custom_target(hack_rust_ffi_bridge_targets)
192 # Compiling cxx entrypoints for hhvm
193 function(build_cxx_bridge NAME FFI_BRIDGE_DIR)
194   set(FFI_BRIDGE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${FFI_BRIDGE_DIR}")
195   set(FFI_BRIDGE_BIN "${RUST_FFI_BUILD_ROOT}/hphp/hack/${FFI_BRIDGE_DIR}")
197   set(RUST_PART_LIB "${FFI_BRIDGE_BIN}/${PROFILE}/${CMAKE_STATIC_LIBRARY_PREFIX}${NAME}_ffi_bridge${CMAKE_STATIC_LIBRARY_SUFFIX}")
198   set(RUST_PART_CXX "${FFI_BRIDGE_BIN}/${NAME}_ffi_bridge.cpp")
199   set(RUST_PART_HEADER "${FFI_BRIDGE_BIN}/${NAME}_ffi_bridge.rs")
200   set(GENERATED "${FFI_BRIDGE_BIN}/cxxbridge/${NAME}_ffi_bridge/${NAME}_ffi_bridge")
202   add_custom_command(
203       OUTPUT ${RUST_PART_CXX}
204       COMMAND
205         ${CMAKE_COMMAND} -E make_directory "${FFI_BRIDGE_BIN}" &&
206         . "${CMAKE_CURRENT_BINARY_DIR}/dev_env_rust_only.sh" &&
207         ${CARGO_BUILD} "${NAME}_ffi_bridge" "${NAME}_ffi_bridge" --cxx "${FFI_BRIDGE_BIN}" &&
208         ${CMAKE_COMMAND} -E copy "${GENERATED}.rs.cc" "${RUST_PART_CXX}" &&
209         ${CMAKE_COMMAND} -E copy "${GENERATED}.rs.h" "${RUST_PART_HEADER}"
210       WORKING_DIRECTORY ${FFI_BRIDGE_SRC}
211       DEPENDS rustc cargo
212   )
213   add_custom_target(
214     "${NAME}_cxx"
215     DEPENDS ${RUST_PART_CXX}
216   )
218   add_library("${NAME}_ffi_bridge" STATIC ${RUST_PART_CXX})
219   add_dependencies("${NAME}_ffi_bridge" rustc cargo "${NAME}_cxx")
220   add_dependencies(hack_rust_ffi_bridge_targets "${NAME}_ffi_bridge")
221   target_link_libraries("${NAME}_ffi_bridge" PUBLIC ${RUST_PART_LIB})
222   # `-iquote` is like `-I` (or target_include_directories()`), except:
223   # - it takes precedence over `-I`
224   # - it only applies to `#include "foo"`, not `#include <foo>`
225   target_compile_options("${NAME}_ffi_bridge" INTERFACE "-iquote" "${RUST_FFI_BUILD_ROOT}")
226 endfunction()
228 build_cxx_bridge(rust_facts "src/facts/ffi_bridge")
229 build_cxx_bridge(rust_parser "src/parser/ffi_bridge")
230 build_cxx_bridge(rust_compile "src/hhbc/ffi_bridge")
231 build_cxx_bridge(rust_decl "src/decl/ffi_bridge")
233 if (NOT LZ4_FOUND)
234   add_dependencies(hack_dune lz4)
235   add_dependencies(hack_dune_debug lz4)
236   add_dependencies(hack_dune_test lz4)
237 endif()
239 if (NOT PC_SQLITE3_FOUND)
240   add_dependencies(hack_dune sqlite3)
241   add_dependencies(hack_dune_debug sqlite3)
242   add_dependencies(hack_dune_test sqlite3)
243 endif()
245 # Intentionally not using `hack_dune_debug` as it generates output files of a
246 # different format (bytecode instead of raw executables, which is useful if
247 # you're working with Hack, but means that e.g. hhvm can't find
248 # `hh_single_compile` in the source tree. Keep it around, but require it to be
249 # explicitly used
250 add_custom_target(hack ALL DEPENDS hack_dune)
251 add_custom_target(hack_test DEPENDS hack_dune_test)
253 configure_file(dev_env.sh.in dev_env.sh ESCAPE_QUOTES @ONLY)
254 configure_file(dev_env_common.sh.in dev_env_common.sh ESCAPE_QUOTES @ONLY)
255 configure_file(dev_env_rust_only.sh.in dev_env_rust_only.sh ESCAPE_QUOTES @ONLY)
257 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_client
258   DESTINATION bin
259   COMPONENT dev)
261 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_server
262   DESTINATION bin
263   COMPONENT dev)
265 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hackfmt
266   DESTINATION bin
267   COMPONENT dev)
269 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/bin/hh_parse
270   DESTINATION bin
271   COMPONENT dev)