From 0fdbaa685f6b4ed474e906d9d02f7907a2d03a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Wed, 5 Aug 2015 18:02:49 -0700 Subject: [PATCH] Build system for Hack on Windows Summary: This PR contains a build-system for Hack on windows. It relies on OCPWin (as described in `hphp/hack/README.win32`). This alternative build system may also be used on Linux and OS X (see `hphp/hack/README.ocp-build`). *Warnings*: on Windows, the resulting binaries are not working yet, all tests are known to fail. The main file describing the build process is `hphp/hack/src/build.ocp`. It defines a set of libraries and programs. The library architecture has been sketched with our young knownledge about Hack. If someone with more experience could have a look at it, it would be appreciated. Some additional descriptions specific to Hack (i.e. not required when build Flow) may be found in the following files: - `hphp/hack/build.ocp` - `hphp/hack/src/h2tp/build.ocp` While in the long term it might require some efforts to maintain two build systems, for now we take care not to modify (and not to conflict with) the current build system. Closes https://github.com/facebook/hhvm/pull/5775 Reviewed By: @jwatzman Differential Revision: D2268695 Pulled By: @gabelevi --- hphp/hack/.gitignore | 2 + hphp/hack/00_config.ocp | 3 + hphp/hack/README.ocpbuild | 45 +++ hphp/hack/README.win32 | 67 ++++ hphp/hack/build.ocp | 14 + hphp/hack/make.bat | 62 ++++ hphp/hack/src/Makefile | 33 +- hphp/hack/src/build.ocp | 458 ++++++++++++++++++++++++ hphp/hack/src/fsnotify_win/fsnotify.ml | 28 ++ hphp/hack/src/fsnotify_win/fsnotify.mli | 42 +++ hphp/hack/src/h2tp/build.ocp | 50 +++ hphp/hack/src/heap/hh_shared.c | 91 ++++- hphp/hack/src/hhi/hhi_elf.c | 12 + hphp/hack/src/scripts/gen_build_id.ml | 66 ++++ hphp/hack/src/utils/nproc.c | 12 +- hphp/hack/src/utils/realpath.c | 17 + 16 files changed, 995 insertions(+), 7 deletions(-) create mode 100644 hphp/hack/00_config.ocp create mode 100644 hphp/hack/README.ocpbuild create mode 100644 hphp/hack/README.win32 create mode 100644 hphp/hack/build.ocp create mode 100644 hphp/hack/make.bat create mode 100644 hphp/hack/src/build.ocp create mode 100644 hphp/hack/src/fsnotify_win/fsnotify.ml create mode 100644 hphp/hack/src/fsnotify_win/fsnotify.mli create mode 100644 hphp/hack/src/h2tp/build.ocp create mode 100644 hphp/hack/src/scripts/gen_build_id.ml diff --git a/hphp/hack/.gitignore b/hphp/hack/.gitignore index 38c489bb7fdb4..0977c349b9c53 100644 --- a/hphp/hack/.gitignore +++ b/hphp/hack/.gitignore @@ -12,3 +12,5 @@ src/parsing/parser.mli *.so *.annot *.opt +_obuild/ +.ocp/ \ No newline at end of file diff --git a/hphp/hack/00_config.ocp b/hphp/hack/00_config.ocp new file mode 100644 index 0000000000000..1409b346b542c --- /dev/null +++ b/hphp/hack/00_config.ocp @@ -0,0 +1,3 @@ + +have_lz4 = false +debug = false diff --git a/hphp/hack/README.ocpbuild b/hphp/hack/README.ocpbuild new file mode 100644 index 0000000000000..f1fa0611e0dd6 --- /dev/null +++ b/hphp/hack/README.ocpbuild @@ -0,0 +1,45 @@ +This document describes an alternative build-system for Hack. This is +currently the only build system available on Windows. Meanwhile, this +document focuses on using this alternative build system on Linux and +OS X; for Windows, see `README.win32`. + +### ocp-build, a build system for OCaml applications + +ocp-build is a build system for OCaml applications, based on simple +descriptions of packages. ocp-build combines the descriptions of +packages in different directories, and optimize the parallel incremental +compilation of files depending on the number of cores and the +automatically-infered dependencies between source files. + +For more details, you can take a look at + + http://www.typerex.org/ocp-build.html + +### Download and install `ocp-build` by using OPAM + +OPAM is a source-based package manager for OCaml. It supports multiple +simultaneous compiler installations, flexible package constraints, and +a Git-friendly development workflow. + +To install OPAM, please check http://opam.ocaml.org/doc/Install.html + +Once OPAM is installed correctly with an OCaml compiler, you can setup +your configuration and installl `ocp-build`: + + $ opam init + $ eval $(opam config env) + $ opam install ocp-build + +Note that you will always need to use `eval $(opam config env)` when restarting +a shell in a terminal, to get your PATH properly configured. + +### Compiling Hack with ocp-build + +For Windows, see `README.win32.` Otherwise in `hack/src`, run: + + $ make fast + +Optionally, you may run: + + $ make test-ocp + \ No newline at end of file diff --git a/hphp/hack/README.win32 b/hphp/hack/README.win32 new file mode 100644 index 0000000000000..30120ee462236 --- /dev/null +++ b/hphp/hack/README.win32 @@ -0,0 +1,67 @@ +We are currently porting Hack and Flow to Windows 64 bits. This +document describes the build system, if you want to test +the prototype. Be aware that this work will take some time +and most tests are currently known to fail. + +### Dependency: OCPWin + +OCPWin is a binary OCaml distribution for Windows. It is +self-contained and runs natively on Windows, which means you can +generate OCaml applications with it without installing Cygwin or +Windows SDK. + +To download and install OCPWin, go to http://www.typerex.org/ocpwin.html, +and choose the "full" version. OCPWin installer is known to have problems +with PATHs exceeding 1024 characters. Be careful to save your PATH before +the installation to be able to restore it in case of problem, until the +problem is fixed. + +### Configuration and Compilation + +In the Hack root directory, edit the file `00_config.ocp` +and adjust the two following variables: + + has_lz4 = false (* true if lz4 is installed on your machine *) + debug = false (* true if you want to activate the debug mode *) + +NOTE: lz4 is not required to build Hack. If you want to use it, and lz4 is not + installed in the default path, you have to set the + `ccopt` variable correctly in the `00_config.ocp` file. For instance: + + ccopt = [ "-I/PATH/TO/LZ4/DIRECTORY" ] + +Then, execute the `make.bat` script: + + ./make + +This will call `ocp-build` and copy the generated files into the bin/ +sub-directory. + +If you want to clean your project, you may use: + + ./make clean + +Optionally, to run the test-suite adjust the path to the `python.exe` +in `make.bat`, and run: + + ./make test + +### Installing + +Coming soon + +### FAQ + +Q: While installing OCPWin, I got this message error: + + This version of C:\xxxx is not compatible with the version of + Windows that you're running. Check your computer's system information + and then contact the software publisher. + + What should I do ? + +A: You probably installed the wrong version of OCPWin, check that you + got the 32 or 64 bits version according to your system. Note that Hack + and Flow currently only work on 64 bits systems. + + \ No newline at end of file diff --git a/hphp/hack/build.ocp b/hphp/hack/build.ocp new file mode 100644 index 0000000000000..b591476c53140 --- /dev/null +++ b/hphp/hack/build.ocp @@ -0,0 +1,14 @@ +(** + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +begin library "ROOTPROJECT" + files = [] +end + diff --git a/hphp/hack/make.bat b/hphp/hack/make.bat new file mode 100644 index 0000000000000..8c24a6c875482 --- /dev/null +++ b/hphp/hack/make.bat @@ -0,0 +1,62 @@ + +@echo off + +if "%1" == "" goto build +if "%1" == "build" goto build +if "%1" == "all" goto build +if "%1" == "test" goto test +if "%1" == "init" goto init +if "%1" == "clean" goto clean +REM Invalid argument +echo Invalid argument, please check README.win32 +goto end + +REM initialize ocp-build and create _obuild directory +:init +if not exist "_obuild/" ocp-build init +goto end + +REM 1/ check if ocp-build init has already be done +REM 2/ generate get_build_id.gen.c +REM 3/ start build hack with ocp-build +:build +if not exist "_obuild/" ocp-build init +ocaml.exe unix.cma ./src/scripts/gen_build_id.ml ./src/utils/get_build_id.gen.c +ocp-build +md bin 2>NUL +copy _obuild\hh_server\hh_server.asm.exe bin\hh_server.exe +copy _obuild\hh_client\hh_client.asm.exe bin\hh_client.exe +copy _obuild\hh_single_type_check\hh_single_type_check.asm.exe bin\hh_single_type_check.exe +copy _obuild\hh_format\hh_format.asm.exe bin\hh_format.exe +copy _obuild\h2tp\h2tp.asm.exe bin\h2tp.exe + +goto end + +REM clean _obuild directory and executables in bin/ +:clean +ocp-build clean +del bin\hh_server.exe 2>NUL +del bin\hh_client.exe 2>NUL +del bin\hh_single_type_check.exe 2>NUL +del bin\hh_format.exe 2>NUL +del bin\h2tp.exe 2>NUL +goto end + +REM execute the Hack testsuite +:test +@echo on + +set "python3=python.exe" +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/autocomplete +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/color +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/coverage +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/dumpsymbolinfo +"%python3%" test/verify.py --program bin/hh_format.exe test/format +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/suggest +"%python3%" test/verify.py --program bin/hh_single_type_check.exe test/typecheck +"%python3%" test/verify.py --program bin/hh_format.exe test/typecheck ^ + --disabled-extension .no_format ^ + --out-extension .format_out ^ + --expect-extension '' ^ + --flags --root . +:end diff --git a/hphp/hack/src/Makefile b/hphp/hack/src/Makefile index 19b5febe61bdc..1ceca1d76f7f3 100644 --- a/hphp/hack/src/Makefile +++ b/hphp/hack/src/Makefile @@ -103,6 +103,7 @@ LINKER_FLAGS=$(NATIVE_OBJECT_FILES) $(NATIVE_LIB_OPTS) $(EXTRA_LIB_OPTS) \ rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)) all: build-hhi-archive build-hack copy-hack-files +all-ocp: build-hhi-archive build-hack-with-ocp copy-hack-files-ocp clean: ocamlbuild -clean @@ -111,6 +112,10 @@ clean: build-hack: $(TARGETS) build-hhi-archive +build-hack-with-ocp: build-hhi-archive build-hack-stubs-with-ocp + [ -d ${ROOT}/../_obuild ] || ( cd ${ROOT}/.. && ocp-build init ) + ocp-build build + # All targets are built in one time, so no parallelization is necessary .NOTPARALLEL: $(TARGETS) # As there is no efficient way to calculate the dependencies of @@ -131,9 +136,15 @@ $(TARGETS): $(ALL_SRC_FILES) build-hack-native-deps: build-hack-stubs ocamlbuild -cflags "-g $(EXTRA_INCLUDE_OPTS) $(EXTRA_CC_OPTS)" $(NATIVE_OBJECT_FILES) +# If you modify this rule, do not forget to edit the file +# `$(ROOT)/scripts/gen_build_id.ml` used on Windows. build-hack-stubs: REV="const char* const BuildInfo_kRevision = \"$$(git rev-parse HEAD)\";"; \ - if [ "$$REV" != "$$(cat utils/get_build_id.gen.c)" ]; then echo "$$REV" > utils/get_build_id.gen.c; fi + if [ "$$REV" != "$$(cat scripts/get_build_id.gen.c)" ]; then echo "$$REV" > utils/get_build_id.gen.c; fi + +build-hack-stubs-with-ocp: + ocaml unix.cma $(ROOT)/scripts/gen_build_id.ml \ + $(ROOT)/utils/get_build_id.gen.c build-hhi-archive: mkdir -p ../bin @@ -152,7 +163,27 @@ endif cp _build/hh_format.native ../bin/hh_format cp _build/h2tp/h2tp.native ../bin/h2tp +copy-hack-files-ocp: build-hack-with-ocp + mkdir -p ../bin +ifeq ($(OS), Linux) + objcopy --add-section hhi=../bin/hhi.tar.gz ../_obuild/hh_server/hh_server.asm ../bin/hh_server +else + cp ../_obuild/hh_server/hh_server.asm ../bin/hh_server +endif + cp ../_obuild/hh_client/hh_client.asm ../bin/hh_client + cp ../_obuild/hh_single_type_check/hh_single_type_check.asm ../bin/hh_single_type_check + cp ../_obuild/hh_format/hh_format.asm ../bin/hh_format + cp ../_obuild/h2tp/h2tp.asm ../bin/h2tp + + +.PHONY: test test-ocp do-test test: build-hack copy-hack-files + ${MAKE} do-test + +test-ocp: build-hack-with-ocp copy-hack-files-ocp + ${MAKE} do-test + +do-test: python3 ../test/verify.py --program ../bin/hh_single_type_check ../test/autocomplete python3 ../test/verify.py --program ../bin/hh_single_type_check ../test/color python3 ../test/verify.py --program ../bin/hh_single_type_check ../test/coverage diff --git a/hphp/hack/src/build.ocp b/hphp/hack/src/build.ocp new file mode 100644 index 0000000000000..8842b9780c71b --- /dev/null +++ b/hphp/hack/src/build.ocp @@ -0,0 +1,458 @@ +(** + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +comp = [ "-thread" ] +link = [ "-thread" ] + +if debug then { + comp += [ "-g" ] + link += [ "-g" ] +} + +if os_type = "linux" then { + cclib = [ "-lelf" ] +} + +if have_lz4 then { + cclib += [ "-llz4" ] +} else { + ccopt += [ "-DNO_LZ4" ] +} + +requires = [ "unix" "str" "threads" ] + +begin library "hh-third-party" + + files = [ + "third-party/core/caml.ml" + "third-party/core/commutative_group.ml" + "third-party/core/container.ml" + "third-party/core/core_printf.ml" + "third-party/core/monad.ml" + "third-party/core/polymorphic_compare.ml" + "third-party/core/poly.ml" + "third-party/core/core_list.ml" + "third-party/core/option.ml" + "third-party/core/result.ml" + "third-party/avl/monoidAvl.ml" + ] +end + +begin library "hh-fsnotify-linux" + if not (system = "linux" && os_type = "Unix") then enabled = false + cclib = [ "-lelf" ] + files = [ + "third-party/inotify/inotify_stubs.c" + "third-party/inotify/inotify.ml" + "fsnotify_linux/fsnotify.ml" + ] + requires = [ "hh-utils-core" ] +end + +begin library "hh-fsnotify-darwin" + if not (system = "macosx" && os_type = "Unix") then enabled = false + cclib = [ + "-sectcreate" "-__text" "hhi" "%{ROOTPROJECT_FULL_SRC_DIR}%/bin/hhi.tar.gz" + "-framework" "CoreServices" + "-framework" "CoreFoundation" + ] + files = [ + "fsevents/fsevents_stubs.c" + "fsevents/fsevents.ml" + "fsnotify_darwin/fsnotify.ml" + ] + requires += [ "ROOTPROJECT" ] +end + +begin library "hh-fsnotify-win" + if not (os_type = "Win32") then enabled = false + requires += [ "ROOTPROJECT" ] + files = [ "fsnotify_win/fsnotify.ml" ] +end + +begin library "hh-fsnotify" + if os_type = "Win32" then { + requires = [ "hh-fsnotify-win" ] + } else if system = "linux" then { + requires = [ "hh-fsnotify-linux" ] + } else { + requires = [ "hh-fsnotify-darwin" ] + } +end + +begin library "hh-utils-core" + requires = [ "hh-third-party" ] + files = [ "utils/core.ml" ] +end + +begin library "hh-utils-common" + requires += [ "hh-third-party" "hh-utils-core" "hh-fsnotify" ] + files = [ + "heap/hh_shared.c" + + "utils/get_build_id.gen.c" + "utils/get_build_id.c" + "utils/nproc.c" + "utils/realpath.c" + "utils/hh_json.ml" + "utils/ident.ml" + "utils/utils.ml" + "utils/sys_utils.ml" + "utils/path.ml" + "utils/relative_path.ml" + "utils/pos.ml" + "utils/errors.ml" + "utils/lint.ml" + "utils/config_file.ml" + ] +end + +begin library "hh-utils" + requires += [ "hh-utils-common" ] + files = [ + "utils/tmp.ml" + "utils/lock.ml" + "utils/pidLog.ml" + "utils/fork.ml" + "utils/daemon.ml" + "utils/build_id.ml" + "utils/wwwroot.ml" + "utils/tty.ml" + "utils/printSignal.ml" + "utils/trie.ml" + "utils/find.ml" + "utils/hh_logger.ml" + "utils/exit_status.ml" + ] +end + +begin library "hh-deps" + requires += [ "hh-third-party" "hh-utils" ] + files = [ + "deps/fileInfo.ml" + "deps/typing_deps.ml" + ] +end + +begin library "hh-stubs" + requires += [ "hh-utils" ] + files = [ + "stubs/eventLogger.ml" + "stubs/hackEventLogger.ml" + "stubs/filesToIgnore.ml" + "stubs/linting_service.ml" + "stubs/prologMain.ml" + "stubs/buildMain.ml" + "stubs/prolog.ml" + ] +end + +begin library "hh-heap" + requires += [ "hh-third-party" "hh-utils" "hh-stubs" ] + + files = [ + "heap/prefix.ml" + "heap/value.ml" + "heap/sharedMem.ml" + "heap/globalStorage.ml" + ] +end + +begin library "hh-globals" + requires += [ "hh-third-party" "hh-utils" ] + + files = [ + "globals/autocomplete.ml" + "globals/ide.ml" + "globals/globalConfig.ml" + ] +end + +begin library "hh-procs" + requires += [ "hh-third-party" "hh-utils" "hh-heap" "hh-globals" ] + + files = [ + "procs/worker.ml" + "procs/multiWorker.ml" + "procs/bucket.ml" + ] +end + +begin library "hh-parsing" + requires += [ "hh-third-party" "hh-utils" "hh-deps" "hh-heap" + "hh-globals" "hh-procs" ] + files = [ + "parsing/namespace_env.ml" + "parsing/ast.ml" + "parsing/lexer_hack.mll" + "parsing/namespaces.ml" + "parsing/parser_heap.ml" + "parsing/parser_hack.ml" + "parsing/parsing_hooks.ml" + "parsing/ast_utils.ml" + "parsing/parsing_service.ml" + ] +end + +begin library "hh-typing-base" + requires += [ "hh-utils" "hh-parsing" ] + files = [ + "naming/naming_special_names.ml" + "typing/typing_reason.ml" + "typing/typing_defs.ml" + "typing/typing_heap.ml" + "naming/naming_hooks.ml" + "naming/naming_ast_helpers.ml" + "naming/typecheckerOptions.ml" + "naming/nast.ml" + "naming/naming.ml" + ] +end + +begin library "hh-dfind" + requires += [ "hh-third-party" "hh-fsnotify" "hh-utils" ] + files = [ + "dfind/dfindEnv.ml" + "dfind/dfindMaybe.ml" + "dfind/dfindAddFile.ml" + "dfind/dfindServer.ml" + "dfind/dfindLib.ml" + ] +end + +begin library "hh-naming" + requires += [ "hh-typing-base" ] + + files = [ + "naming/naming_heap.ml" + "naming/nast_eval.ml" + "naming/attributes.ml" + "naming/nastVisitor.ml" + ] +end + +begin library "hh-typing" + requires += [ "hh-naming" ] + files = [ + "typing/typing_env.ml" + "typing/typing_hooks.ml" + "typing/typing_print.ml" + "typing/nastCheck.ml" + "typing/nast_terminality.ml" + "typing/typeVisitor.ml" + "typing/typing_dependent_type.ml" + "typing/typing_expand.ml" + "typing/typing_generic.ml" + "typing/typing_utils.ml" + "typing/typing_subst.ml" + "typing/typing_phase.ml" + "typing/typing_instantiate.ml" + "typing/typing_taccess.ml" + "typing/typing_tdef.ml" + "typing/typing_unification_env.ml" + "typing/typing_unify.ml" + "typing/typing_subtype.ml" + "typing/typing_ops.ml" + "typing/typing_suggest.ml" + "typing/nastInitCheck.ml" + "typing/typingEqualityCheck.ml" + "typing/typing_alias.ml" + "typing/typing_async.ml" + "typing/typing_enum.ml" + "typing/typing_hint.ml" + "typing/typing_extends.ml" + "typing/typing_exts.ml" + "typing/typing_lenv.ml" + "typing/typing_shapes.ml" + "typing/typing_variance.ml" + "typing/typing_sequencing.ml" + "typing/typing.ml" + "typing/typing_dynamic_yield.ml" + "typing/typing_inherit.ml" + "typing/typing_decl.ml" + "typing/typing_decl_service.ml" + "typing/typing_check_service.ml" + "typing/typing_check_utils.ml" + "typing/typing_compare.ml" + "typing/coverage_level.ml" + "typing/typing_redecl_service.ml" + "typing/typing_suggest_service.ml" + ] +end + +begin library "hh-search" + requires += [ "hh-utils" "hh-heap" "hh-parsing" ] + files = [ + "search/searchUtils.ml" + "search/fuzzySearchService.ml" + "search/trieSearchService.ml" + "search/searchService.ml" + "search/hackSearchService.ml" + ] +end + +begin library "hh-stubs-ai" + requires += [ "hh-typing-base" ] + files = [ + "stubs/ai.ml" + ] +end + +begin library "hh-socket" + requires += [ "hh-utils" ] + files = [ + "socket/socket.ml" + ] +end + +begin library "hh-hhi" + requires += [ "hh-globals" "hh-utils" ] + files = [ + "hhi/hhi_elf.c" + "hhi/hhi.ml" + ] +end + +begin library "hh-server-base" + requires += [ "hh-third-party" "hh-utils" "hh-typing" "hh-search" + "hh-stubs" "hh-stubs-ai" "hh-socket" "hh-dfind" "hh-hhi" ] + files = [ + "server/serverConfig.ml" + "server/serverArgs.ml" + "server/serverEnv.ml" + "server/serverUtils.ml" + "server/argumentInfoService.ml" + "server/autocompleteService.ml" + "server/fileOutline.ml" + "server/serverIdeUtils.ml" + "server/findRefsService.ml" + "server/findUtils.ml" + "server/identifySymbolService.ml" + "server/inferAtPosService.ml" + "server/methodJumps.ml" + "server/serverArgumentInfo.ml" + "server/serverAutoComplete.ml" + "server/serverBuild.ml" + "server/serverCheckpoint.ml" + "server/serverColorFile.ml" + "server/serverCoverageMetric.ml" + "server/serverError.ml" + "server/serverFindRefs.ml" + "server/serverIdentifyFunction.ml" + "server/serverInferType.ml" + "server/serverLint.ml" + "server/serverRefactor.ml" + "server/serverSearch.ml" + "server/symbolUtils.ml" + "server/symbolFunCallService.ml" + "server/symbolTypeService.ml" + "server/symbolInfoService.ml" + "server/serverRpc.ml" + "server/serverTypeCheck.ml" + "server/serverCommand.ml" + "server/serverConvert.ml" + ] +end + +begin library "hh-server" + requires += [ + "hh-third-party" "hh-utils" "hh-typing" + "hh-search" "hh-stubs" "hh-stubs-ai" + "hh-socket" "hh-dfind" "hh-server-base" + ] + files = [ + "server/serverEnvBuild.ml" + "server/serverPeriodical.ml" + "server/serverInit.ml" + "server/serverMain.ml" + ] +end + +begin library "hh-client" + requires += [ + "hh-deps" "hh-heap" "hh-parsing" + "hh-globals" "hh-search" "hh-stubs" + "hh-socket" "hh-server-base" + ] + files = [ + "client/clientConnectSimple.ml" + "client/clientStop.ml" + "client/hackClientStop.ml" + "client/clientStart.ml" + "client/clientConnect.ml" + "client/clientLogCommand.ml" + "client/clientBuild.ml" + "client/clientEnv.ml" + "client/clientCommand.ml" + "client/clientArgs.ml" + "client/clientArgumentInfo.ml" + "client/clientAutocomplete.ml" + "client/clientCheckStatus.ml" + "client/colorFile.ml" + "client/clientColorFile.ml" + "client/clientCoverageMetric.ml" + "client/clientFindRefs.ml" + "client/clientLint.ml" + "client/clientMethodJumps.ml" + "client/clientOutline.ml" + "client/clientRefactor.ml" + "client/clientSearch.ml" + "client/clientSymbolInfo.ml" + "client/clientTypeAtPos.ml" + "client/clientCheck.ml" + "client/clientLogCommandUtils.ml" + "client/clientRestart.ml" + ] +end + +begin program "hh_client" + requires += [ "hh-client" ] + files = [ "hh_client.ml" ] +end + +begin program "hh_server" + requires += [ "hh-server" ] + files = [ "hh_server.ml" ] +end + +begin library "hh-emitter" + requires += [ "hh-naming" ] + + files = [ + "emitter/emitter_core.ml" + "emitter/emitter_consts.ml" + "emitter/emitter_expr.ml" + "emitter/emitter_lit.ml" + "emitter/emitter_stmt.ml" + "emitter/emitter.ml" + ] +end + +begin library "hh-format" + requires += [ "hh-typing-base" ] + files = [ + "stubs/formatEventLogger.ml" + "format/format_hack.ml" + "format/format_diff.ml" + "format/format_mode.ml" + ] +end + +begin program "hh_format" + requires += [ "hh-format" "hh-client" ] + files = [ "hh_format.ml" ] +end + +begin program "hh_single_type_check" + requires += [ "hh-client" "hh-emitter" ] + files = [ + "hh_single_type_check.ml" + ] +end diff --git a/hphp/hack/src/fsnotify_win/fsnotify.ml b/hphp/hack/src/fsnotify_win/fsnotify.ml new file mode 100644 index 0000000000000..41b0aab34467c --- /dev/null +++ b/hphp/hack/src/fsnotify_win/fsnotify.ml @@ -0,0 +1,28 @@ +(** + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +exception Error of string * int + +type event = { + path : string; (* The full path for the file/directory that changed *) + wpath : string; (* The watched path that triggered this event *) +} + +type fd_select = Unix.file_descr * (unit -> unit) + +type watch + +type env + +let init roots = assert false + +let add_watch env path = assert false + +let select env ?(read_fdl=[]) ?(write_fdl=[]) ~timeout callback = assert false diff --git a/hphp/hack/src/fsnotify_win/fsnotify.mli b/hphp/hack/src/fsnotify_win/fsnotify.mli new file mode 100644 index 0000000000000..f28dce9830048 --- /dev/null +++ b/hphp/hack/src/fsnotify_win/fsnotify.mli @@ -0,0 +1,42 @@ +(** + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +exception Error of string * int + +(* Contains all the fsevents context *) +type env + +(* A subscription to events for a directory *) +type watch + +type event = { + path : string; (* The full path for the file/directory that changed *) + wpath : string; (* The watched path that triggered this event *) +} + +val init : string list -> env + +(* Returns None if we're already watching that path and Some watch otherwise *) +val add_watch : env -> string -> watch option + +(* A file descriptor and what to do when it is selected *) +type fd_select = Unix.file_descr * (unit -> unit) +val select : + (* The fsevents context *) + env -> + (* Additional file descriptor to select for reading *) + ?read_fdl:(fd_select list) -> + (* Additional file descriptor to select for writing *) + ?write_fdl:(fd_select list) -> + (* Timeout...like Unix.select *) + timeout:float -> + (* The callback for file system events *) + (event list -> unit) -> + unit diff --git a/hphp/hack/src/h2tp/build.ocp b/hphp/hack/src/h2tp/build.ocp new file mode 100644 index 0000000000000..db2cbf7871dd7 --- /dev/null +++ b/hphp/hack/src/h2tp/build.ocp @@ -0,0 +1,50 @@ +(** + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +(* This file is separated from the other sources of Hack, because the + h2tp/ sub-directory is not copied to the Flow tree. Consequently, + we moved its description here so that ocp-build will not complain + about these missing files. +*) + +begin program "h2tp" + + requires += [ "hh-format" ] + + files = [ + "Prepend_require.ml" + "common/fun.ml" + "common/Str_ext.ml" + "common/ast_ext.ml" + "common/common_exns.ml" + "common/converter_options.ml" + "common/sys_ext.ml" + "common/parser_hack_ext.ml" + "mapper/map_ast.ml" + "mapper/Deleted_constructs.ml" + "mapper/constructor_arg_promotion.ml" + "mapper/detect_collections.ml" + "mapper/empty_collection_as_bool.ml" + "mapper/enum.ml" + "mapper/erase_types.ml" + "mapper/hack_variadic.ml" + "mapper/initializer_expressions.ml" + "mapper/lambda_expressions.ml" + "mapper/misc.ml" + "mapper/ref_collections.ml" + "mapper/unsupported_constructs.ml" + "mapper/value_collections.ml" + "mapper/yield_break.ml" + "unparser/unparsed.ml" + "unparser/unparser.ml" + "engine.ml" + "h2tp.ml" + ] +end diff --git a/hphp/hack/src/heap/hh_shared.c b/hphp/hack/src/heap/hh_shared.c index 429ab80c4483b..866f0ccfc9397 100644 --- a/hphp/hack/src/heap/hh_shared.c +++ b/hphp/hack/src/heap/hh_shared.c @@ -76,13 +76,16 @@ */ /*****************************************************************************/ + +#include +#include +#include + +#ifndef _WIN32 /* define CAML_NAME_SPACE to ensure all the caml imports are prefixed with * 'caml_' */ #define CAML_NAME_SPACE #include -#include -#include -#include #include #include #include @@ -95,13 +98,13 @@ #include #include #include -#include - #ifndef NO_LZ4 #include #include #endif +#include + /*****************************************************************************/ /* Config settings (essentially constants, so they don't need to live in shared * memory), initialized in hh_shared_init */ @@ -999,3 +1002,81 @@ void hh_remove(value key) { assert(hashtbl[slot].hash == get_hash(key)); hashtbl[slot].addr = NULL; } + +#else // _WIN32 +// CAGO: some of theses functions will be the same as in linux version + +void hh_add(value key, value data) {} +void hh_add_dep(value ocaml_dep) {} +void hh_call_after_init() {} +void hh_collect() {} +void hh_move(value key1, value key2) {} +void hh_remove(value key) {} +void hh_save(value out_filename) {} +void hh_shared_clear() {} +void hh_shared_init(value global_size_val, value heap_size_val) {} +void hh_load(value in_filename) {} +void hh_shared_store(value data) {} +void hh_worker_init() {} + +value hh_counter_next() { + CAMLparam0(); + caml_failwith("'hh_counter_next` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_dep_slots() { + CAMLparam0(); + caml_failwith("'hh_dep_slots` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_dep_used_slots() { + CAMLparam0(); + caml_failwith("'hh_dep_used_slots` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_get(value key) { + CAMLparam1(key); + caml_failwith("'hh_get` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_get_dep(value dep) { + CAMLparam1(dep); + caml_failwith("'hh_get_dep` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_hash_slots() { + CAMLparam0(); + caml_failwith("'hh_hash_slots` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_hash_used_slots() { + CAMLparam0(); + caml_failwith("'hh_hash_used_slots` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_heap_size() { + CAMLparam0(); + caml_failwith("'hh_heap_size` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_mem(value key) { + CAMLparam1(key); + caml_failwith("'hh_mem` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +value hh_shared_load() { + CAMLparam0(); + caml_failwith("'hh_shared_load` is not implemented in `hh_shared.c`."); + CAMLreturn(Val_unit); +} + +#endif diff --git a/hphp/hack/src/hhi/hhi_elf.c b/hphp/hack/src/hhi/hhi_elf.c index fc543ca6de6b2..991da84b504aa 100644 --- a/hphp/hack/src/hhi/hhi_elf.c +++ b/hphp/hack/src/hhi/hhi_elf.c @@ -8,8 +8,11 @@ * */ + #include #include + +#ifndef _WIN32 #include #include #include @@ -149,3 +152,12 @@ value get_embedded_hhi_data(value filename) { } #endif + +#else +#include +value get_embedded_hhi_data(value filename) { + CAMLparam1(filename); + caml_failwith("'get_embedded_hhi_data` is not implemented in `hhi_elf.c`."); + CAMLreturn(Val_unit); +} +#endif diff --git a/hphp/hack/src/scripts/gen_build_id.ml b/hphp/hack/src/scripts/gen_build_id.ml new file mode 100644 index 0000000000000..9bd42727c6bb0 --- /dev/null +++ b/hphp/hack/src/scripts/gen_build_id.ml @@ -0,0 +1,66 @@ +(** + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +let with_pipe f = + let fd_r, fd_w = Unix.pipe () in + try + let res = f fd_r fd_w in + Unix.close fd_r; + Unix.close fd_w; + res + with exn -> + Unix.close fd_r; + Unix.close fd_w; + raise exn + +let with_in_channel filename f = + let ic = open_in_bin filename in + try let res = f ic in close_in ic; res + with exn -> close_in ic; raise exn + +let with_out_channel filename f = + let oc = open_out_bin filename in + try let res = f oc in close_out oc; res + with exn -> close_out oc; raise exn + +(* Read the first line in stdout or stderr of an external command. *) +let read_process_output name args = + with_pipe @@ fun in_r in_w -> + with_pipe @@ fun out_r out_w -> + let pid = Unix.create_process name args in_r out_w out_w in + let out_inch = Unix.in_channel_of_descr out_r in + let line = input_line out_inch in + match Unix.waitpid [] pid with + | _, Unix.WEXITED 0 -> line + | _ -> exit 1 + +let string_of_file filename = + with_in_channel filename @@ fun ic -> + let s = String.create 32759 in + let b = Buffer.create 1000 in + let rec iter ic b s = + let nread = input ic s 0 32759 in + if nread > 0 then begin + Buffer.add_substring b s 0 nread; + iter ic b s + end in + iter ic b s; + Buffer.contents b + +let () = + let out_file = Sys.argv.(1) in + let rev = read_process_output "git" [|"git"; "rev-parse"; "HEAD"|] in + let content = + Printf.sprintf "const char* const BuildInfo_kRevision = %S;\n" rev in + let do_dump = + not (Sys.file_exists out_file) || string_of_file out_file <> content in + if do_dump then + with_out_channel out_file @@ fun oc -> + output_string oc content diff --git a/hphp/hack/src/utils/nproc.c b/hphp/hack/src/utils/nproc.c index 953d3761f335c..c03f3411ede31 100644 --- a/hphp/hack/src/utils/nproc.c +++ b/hphp/hack/src/utils/nproc.c @@ -7,13 +7,23 @@ * of patent rights can be found in the PATENTS file in the same directory. * */ + #include +#ifdef _WIN32 +#include +#else #include +#endif value nproc(void) { CAMLparam0(); CAMLlocal1(result); - +#ifdef _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + result = Val_long(sysinfo.dwNumberOfProcessors); +#else result = Val_long(sysconf(_SC_NPROCESSORS_ONLN)); +#endif CAMLreturn(result); } diff --git a/hphp/hack/src/utils/realpath.c b/hphp/hack/src/utils/realpath.c index 81fa475304cd6..cb5ab5840e63e 100644 --- a/hphp/hack/src/utils/realpath.c +++ b/hphp/hack/src/utils/realpath.c @@ -7,12 +7,16 @@ * of patent rights can be found in the PATENTS file in the same directory. * */ + + #include #include #include #include #include +#ifndef _WIN32 + #define Val_none Val_int(0) static value @@ -41,3 +45,16 @@ hh_realpath(value v) { CAMLreturn(Val_some(caml_copy_string(output))); } } + +#else + +#include + +CAMLprim value +hh_realpath(value v) { + CAMLparam1(v); + caml_failwith("TODO: 'hh_realpath` is not implemented in `realpath.c`."); + CAMLreturn(Val_unit); +} + +#endif