Don't re-run opam_setup every time hack is built when using cmake
[hiphop-php.git] / hphp / hack / CMakeLists.txt
blob8605ce62c3e006592cd9e087ff06485be3d8a865
1 CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7 FATAL_ERROR)
3 SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../CMake" ${CMAKE_MODULE_PATH})
5 option(BUILD_HACK "True if we should build the Hack typechecker." ON)
7 if (NOT BUILD_HACK)
8   message(STATUS "Skipping hack")
9   return()
10 endif()
12 message(STATUS "Building hack")
14 if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}")
15   set(HACK_ONLY_BUILD TRUE)
16 endif()
18 if (NOT WITH_DUNE)
19 if (HACK_ONLY_BUILD)
20   # Woah - this is special. They're running cmake in the hack directory
21   # itself so we don't have our usual set up.
22   get_filename_component(HPHP_HOME "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
23   set(TP_DIR "${HPHP_HOME}/third-party")
24   set(TP_BUILD_DIR ${TP_DIR})
26   if(NOT EXISTS "${TP_DIR}/CMakeLists.txt")
27     message(FATAL_ERROR
28       "${TP_DIR}/CMakeLists.txt missing. Try updating your submodule with:\n"
29       "    rm -r ${TP_DIR}\n"
30       "    git submodule update --init --recursive\n"
31       )
32   endif()
33 endif()
35 find_package(LZ4)
36 find_package(LibElf)
38 if (HACK_ONLY_BUILD AND NOT LZ4_FOUND)
39   add_subdirectory("${TP_DIR}/lz4" "${TP_DIR}/lz4" EXCLUDE_FROM_ALL)
40 endif()
42 if (HACK_ONLY_BUILD)
43   add_subdirectory("${TP_DIR}/ocaml" "${TP_DIR}/ocaml" EXCLUDE_FROM_ALL)
44 endif()
46 if (HACK_ONLY_BUILD AND NOT PC_SQLITE3_FOUND)
47   add_subdirectory(
48     "${TP_DIR}/libsqlite3"
49     "${TP_DIR}/libsqlite3"
50     EXCLUDE_FROM_ALL)
51 endif()
53 # This is totally the wrong way to do this, but I am tired of fighting with
54 # build systems and don't really care to make this work the right way.
55 # lz4 and sqlite3 are all we need right now anyways.
56 unset(extra_include_paths)
57 unset(extra_lib_paths)
58 unset(extra_cc_flags)
60 # Allows '#include "hphp/path/to/library/"' paths to start from hphp
61 # project directory  which is consistent with fbmake's include paths.
63 IF(HPHP_HOME)
64   list(APPEND extra_include_paths ${HPHP_HOME})
65 ELSE()
66   list(APPEND extra_include_paths ${CMAKE_CURRENT_SOURCE_DIR}/../..)
67 ENDIF()
69 list(APPEND extra_cc_flags -pthread)
71 if(LZ4_FOUND)
72   list(APPEND extra_include_paths ${LZ4_INCLUDE_DIR})
73   get_filename_component(pth ${LZ4_LIBRARY} PATH)
74   list(APPEND extra_lib_paths ${pth})
75   list(APPEND extra_native_libraries "lz4")
76 else()
77   list(APPEND extra_include_paths "${TP_DIR}/lz4/src/lib")
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   list(APPEND extra_link_opts "$<TARGET_LINKER_FILE:lz4>")
83 endif()
85 if(PC_SQLITE3_FOUND)
86   list(APPEND extra_include_paths ${LIBSQLITE3_INCLUDE_DIR})
87   get_filename_component(pth ${LIBSQLITE3_LIBRARY} PATH)
88   list(APPEND extra_lib_paths ${pth})
89 else()
90   list(APPEND extra_include_paths "${TP_DIR}/libsqlite3")
91   list(APPEND extra_lib_paths "${TP_BUILD_DIR}/libsqlite3")
92 endif()
93 list(APPEND extra_native_libraries "sqlite3")
95 else()
96 message(STATUS "Dune build detected")
98 list(APPEND extra_include_paths ${LZ4_INCLUDE_DIR})
99 list(APPEND extra_lib_paths ${LZ4_LIBRARY})
100 list(APPEND extra_native_libraries "lz4")
102 list(APPEND extra_include_paths ${LIBSQLITE3_INCLUDE_DIR})
103 list(APPEND extra_lib_paths ${LIBSQLITE3_LIBRARY})
104 list(APPEND extra_native_libraries "sqlite3")
105 endif(NOT WITH_DUNE)
107 # Xcode/Ninja generators undefined MAKE
108 if(NOT MAKE)
109   set(MAKE make)
110 endif()
112 add_custom_command(
113   OUTPUT opam.stamp
114   DEPENDS ocaml opam_setup.sh
115   COMMAND
116     ${CMAKE_CURRENT_SOURCE_DIR}/opam_setup.sh
117     "${OCAML_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}"
118     && cmake -E touch opam.stamp
120 add_custom_target(opam_setup DEPENDS opam.stamp opam_setup.sh)
122 if (SKIP_OPAM)
123   set(OPAMROOT "~/.opam")
124 else ()
125   set(OPAMROOT "${CMAKE_CURRENT_SOURCE_DIR}/_build/.opam")
126 endif()
128 # ARGV2 (optional unnamed argument) is expected to only be set to ALL
129 # if one wants the target to be run with the default rule of Makefile
130 function(invoke_ocamlbuild name target)
131   add_custom_target(
132     ${name}
133     ${ARGV2}
134     COMMAND
135         export OPAMROOT=${OPAMROOT} &&
136         export OCAMLFIND_COMMANDS="-ocamlc=${OCAMLC_EXECUTABLE} -ocamlopt=${OCAMLOPT_EXECUTABLE}" &&
137         PATH="${TP_BUILD_DIR}/ocaml/build/bin:$(PATH)"
138         opam config exec --
139         $(MAKE) --makefile=Makefile.ocamlbuild ${target}
140         EXTRA_INCLUDE_PATHS="${extra_include_paths}"
141         EXTRA_LIB_PATHS="${extra_lib_paths}"
142         EXTRA_LINK_OPTS="${extra_link_opts}"
143         EXTRA_CC_FLAGS="${extra_cc_flags}"
144         EXTRA_NATIVE_LIBRARIES="${extra_native_libraries}"
145         BYTECODE="${EMIT_OCAML_BYTECODE}"
146         OCAML="${OCAML_EXECUTABLE}"
147         OCAMLC="${OCAMLC_EXECUTABLE}"
148         OCAMLBUILD="${OCAMLBUILD_EXECUTABLE}"
149     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
150   )
151   add_dependencies(${name} ocaml opam_setup)
152 endfunction()
154 invoke_ocamlbuild(hack all ALL)
155 invoke_ocamlbuild(hack_test test)
157 function(invoke_dune name target)
158   add_custom_target(
159       ${name}
160       ${ARGV2}
161       COMMAND
162         export OPAMROOT=${OPAMROOT} &&
163         export OCAMLFIND_COMMANDS="-ocamlc=${OCAMLC_EXECUTABLE} -ocamlopt=${OCAMLOPT_EXECUTABLE}" &&
164         PATH="${TP_BUILD_DIR}/ocaml/build/bin:$(PATH)"
165         opam config exec --
166         $(MAKE) --makefile=Makefile.dune ${target}
167         EXTRA_INCLUDE_PATHS="${extra_include_paths}"
168         EXTRA_LIB_PATHS="${extra_lib_paths}"
169         EXTRA_NATIVE_LIBRARIES="${extra_native_libraries}"
170         BYTECODE="${EMIT_OCAML_BYTECODE}"
171         OCAML="${OCAML_EXECUTABLE}"
172         OCAMLC="${OCAMLC_EXECUTABLE}"
173         OCAMLBUILD="${OCAMLBUILD_EXECUTABLE}"
174       WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
175     )
177   add_dependencies(${name} ocaml)
178   if (NOT SKIP_OPAM)
179     add_dependencies(${name} opam_setup)
180   endif()
181 endfunction()
183 invoke_dune(hack_dune_debug debug)
184 invoke_dune(hack_dune_test test)
185 # TODO: when ocamlbuild is removed, add ALL to hack_dune
186 invoke_dune(hack_dune all)
188 if(NOT LZ4_FOUND)
189   # if the system does not have lz4, make sure that the one in public_tl
190   # gets built
191   add_dependencies(hack lz4)
192   add_dependencies(hack_dune lz4)
193   add_dependencies(hack_test lz4)
194 endif()
196 if(NOT PC_SQLITE3_FOUND)
197   # if the system does not have sqlite3, make sure that the one in public_tl
198   # gets built
199   add_dependencies(hack sqlite3)
200   add_dependencies(hack_dune sqlite3)
201   add_dependencies(hack_test sqlite3)
202 endif()
204 if (NOT WITH_DUNE)
205 configure_file(
206   "src/options/buildOptions.ml.in"
207   "${CMAKE_CURRENT_SOURCE_DIR}/src/options/buildOptions.ml"
208   ESCAPE_QUOTES
210 else()
211 configure_file(
212   "src/options/buildOptions.ml.in"
213   "${CMAKE_CURRENT_SOURCE_DIR}/src/options/default_buildOptions.ml"
214   ESCAPE_QUOTES
216 endif(NOT WITH_DUNE)
218 configure_file(
219   "src/fsnotify/dune.in"
220   "${CMAKE_CURRENT_SOURCE_DIR}/src/fsnotify/dune"
223 install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/bin/hh_client
224   DESTINATION bin
225   COMPONENT dev)
227 install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/bin/hh_server
228   DESTINATION bin
229   COMPONENT dev)
231 install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/bin/hackfmt
232   DESTINATION bin
233   COMPONENT dev)
235 install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/bin/hh_parse
236   DESTINATION bin
237   COMPONENT dev)
239 install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/bin/hh_single_compile
240   DESTINATION bin
241   COMPONENT dev)