All of the dependencies that hhvm needs which don't have distribution/homebrew packages.
Facebook dependencies (e.g. folly, thrift, proxygen) should all be updated simultaneously, to identical versions.
Some tips:
- work in the oldest supported Linux distribution; this gets you the oldest C++ compiler and the oldest CMake, so you'll hopefully get most of the possible errors in your interactive environment, rather than hours later on CI
- it's also worth setting up an interactive build environment on your mac; if CI fails, try uninstalling the package from homebrew then figure out how to make the build pass without it
- it's easiest to do this with a separate build directory (e.g.
build/
orobj-x86_64-linux-gnu
), as this lets you easily delete all the relevant build state/artifacts without deleting your changes to the source and cmake. - several of these projects need patching; these can have several patch files in
patches/
, and they are applied in the order listed inseries
. quilt can be used to manage these as a form of source control, and is usually worth configuring.- The build will use quilt to apply patches if you
export HHVM_TP_QUILT=$(which quilt)
; you may need to delete$BUILD_DIR/third-party/
after setting that to get a clean build. - If patches fail to apply or more are needed:
cd
to the extracted source directory, e.g.$BUILD_DIR/third-party/folly/bundled_folly-prefix/src/bundled_folly
export QUILT_PATCHES=$SOURCE_DIR/third-party/$PROJECT/patches
quilt push -a
- If it fails because the patch has already been applied, use
quilt delete PATCH_NAME_HERE.patch
; if it is still needed but needs updates, usequilt push -f
to produce a.rej
(rejected changes) file, manually apply the changes, then runquilt refresh
when you are done - if you need to add additional files to the patch, use
quilt add FILE
before editing the file, thenquilt refresh
when you are done - if you need to add an additional patch, use
quilt new MY_PATCH.patch
,quilt add FILE
,quilt refresh
- if you want to update all the patches with current line numbers etc, run
quilt pop -a --refresh
- The build will use quilt to apply patches if you
Some Facebook-employee-specific tips:
- you can allocate a VM with a recent prebuilt environment via
i opensource/ondemand/facebook/hhvm
; when prompted, select the most recent successfully built for the oldest Ubuntu listed. - if the Mac CI is unable to find a dependency but it's found locally, uninstall it with
brew uninstall --force --ignore-dependencies FOO
; you can then install the same package used in the CI withyum install
; find the package withyum search foo
- you probably want the most recentnix2rpm
package, though you can check exactly which is used inhphp/facebook/autobuild/cmake/mac/cmake.sh
Overall process:
- Get a working build environment (ideally one on old Ubuntu, one on MacOS)
- Most FB projects should be fetching release tarballs with tags like
vYYYY.MM.DD.00
; full download URLs are listed in third-party/foo/CMakeLists.txt. Update these tags to the version you're targeting. - Download all of the URLs you just modified. For some projects, this will give you
vYYYY.MM.DD.00.tar.gz
, rename toPROJECT-vYYYY.MM.DD.00.tar.gz
- Update the hashes in
third-party/foo/CMakeLists.txt
to matchopenssl dgst -sha256 *.tar.gz
- Requires FB employee: update our CI caches - this can be done on your laptop, it does not need a devserver.
for file in *; do manifold put $file hhvm_opensource_dependency_cache/flat/$file; done
- Try to build; fix any patches/build issues
- Create pull request and (requires FB employee) diff
- If you were working in Ubuntu, pull onto MacOS and do a local test build. If you were working in MacOS, pull into Ubuntu and do a test build
- Land once everything's good :) Don't do this on a Friday.
- Check nightly build results the next day. Fix any portability issues that weren't caught by CI.
Steps 2-4 can be done by update-first-party.sh
Step 5 can be done by upload-first-party-to-manifold.sh
Most things here have 3 targets:
foo
foo_deps
bundled_foo
If bundled_foo
is used, foo
depends on bundled_foo
; for some projects (like folly), this is always the case, but for others (like boost), the system version of the library will be used instead if possible, and the foo
target will be configured to point to it.
foo_deps
is a fake target, that defines all of the direct dependencies; foo
will always depend on foo_deps
. This target is required because if myapp
depends on foo
and foo
depends on bar
, link order matters: the linker must know that foo
depends on bar
. myapp
-> [foo
, bar
] is not sufficient.
Finally, we also frequently have a FOO_DEPS
variable in addition to the foo_deps
target; this is because:
foo_deps
is anINTERFACE
library in cmake; this means that the target is fake (.PHONY
in gmake terms) - there is no .a/.so/.dylib output. it just tracks dependency informationbundled_foo
is also a special target (defined byExternalProject_Add
); if given an INTERFACE dependency, it makes it part of its' own interface dependencies, but doesn't actually build-depend on it.INTERFACE
targets are only allowedINTERFACE
libraries; in particular,PUBLIC
are not permitted by CMake, which is what would be correct here- so, we make
bundled_foo
depend directly on${FOO_DEPS}
, rather than the interfacefoo_deps
, even though they're otherwise equivalent.
Various licenses are used in this project; see the notices in relevant files and subdirectories for details.