-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build and link libfolly with RocksDB #10103
Conversation
17170da
to
1acc8fa
Compare
What version of gcc does folly require? I use Ubuntu 20.04 and 22.04 -- both are LTS (long term supported) but 22.04 has yet to be fully released. With 20.04 the default gcc is 9.4 and with 22.04 it is 11.2. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can we get some build size numbers? That might influence non-fbcode users.
@# NOTE: this hack is required for clang in some cases | ||
perl -pi -e 's/int rv = syscall/int rv = (int)syscall/' third-party/folly/folly/detail/Futex.cpp | ||
@# NOTE: this hack is required for gcc in some cases | ||
perl -pi -e 's/(__has_include.<experimental.memory_resource>.)/__cpp_rtti && $$1/' third-party/folly/folly/memory/MemoryResource.h | ||
|
||
build_folly: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: Mark changed my perspective in later comments.
Original feedback:
In my experience, quality builds are divided into (up to) two distinct phases:
- download any dependencies (without running the compiler)
- run the compiler and maybe tests (without hitting the network)
And there should be a "clean" step that gets you back to the state after 1 so that you can rebuild with a different compiler or compilation settings. Ideally, each of those two phases requires only one command invocation.
What that means here (I think):
- We should download, etc. any/all the folly dependencies as part of the checkout_folly step.
- If configured to use folly, we should automatically build libfolly.a if it doesn't exist as part of normal "make check" or "make all". We don't need to do dependency tracking in folly, because we are not intending to develop on it from rocksdb repo.
- If third-party/folly exists, then clean folly build outputs as part of our "make clean", so that libfolly.a is rebuilt automatically if changing compilers, etc.
Makefile
Outdated
echo "Please run checkout_folly first"; \ | ||
false; \ | ||
fi | ||
cd third-party/folly && CXXFLAGS=" -mavx2 -DHAVE_CXX11_ATOMIC " $(PYTHON) build/fbcode_builder/getdeps.py build --no-tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, hard-coded dependency on x86 (avx2). Perhaps you can do something like
&& MAYBE_AVX2=`echo $(CXXFLAGS) | grep -o -- -mavx2 || true` && CXXFLAGS=" $$MAYBE_AVX2 -DHAVE_CXX11_ATOMIC " ...
@mdcallag Folly coroutine support requires gcc 10 or newer. But if you're not using coroutines, gcc 7+ would work. |
add_compile_definitions(USE_FOLLY FOLLY_NO_CONFIG HAVE_CXX11_ATOMIC) | ||
list(APPEND THIRDPARTY_LIBS Folly::folly) | ||
set(FOLLY_LIBS Folly::folly) | ||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--copy-dt-needed-entries") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use find_package instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It did not work when the folly cmake dir was specified in the CMAKE_PREFIX_PATH. I can add calls to find_package, with a fallback to this approach if find_package fails. That'll at least allow an existing folly installation to be specified.
build_tools/build_detect_platform
Outdated
# Get the path for the folly installation dir | ||
if [ -z "$FOLLY_DIR" ]; then | ||
FOLLY_DIR="./third-party/folly" | ||
fi | ||
FOLLY_PATH=`cd $FOLLY_DIR && $PYTHON build/fbcode_builder/getdeps.py show-inst-dir folly` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not detect folly like any other add-on (such as ZSTD)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Folly doesn't have proper versions with compatibility promises (see Folly RPM for CentOS 7 and CentOS 6 folly#929 (comment))
- Folly uses a lot of conditional compilation and implementation-in-header, which likely affects linkability even between ABI-compatible compilers (because ODR, etc.)
- Folly tends to track newer C++ standards to take advantage of features
As a result of these things, pre-packaged folly binary+headers is not really a thing, and not expected to be in the foreseeable future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not pre-packaging. This is "if I already have folly installed and am using it in one tool, why can I not use that same code I built?
CacheLib uses folly. If there is a secondary cache that uses CacheLib, then RocksDB will end up with two versions of folly linked into it. Why can't all of the tools use the same version of folly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, you've convinced me that we should think about this as an optional external dependency, potentially with a shortcut script to checkout & build a known-compatible version.
By the way our internal solution to this problem is "use buck."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Maybe, if FOLLY_DIR is not specified, we don't try to detect and just assume the user has set the CXXFLAGS and EXEC_LDFLAGS environment variables appropriately.
Makefile
Outdated
# For some reason, glog and fmt libraries are under either lib or lib64 | ||
GLOG_LIB_PATH = $(shell (ls -d $(GLOG_PATH)/lib*)) | ||
FMT_LIB_PATH = $(shell (ls -d $(FMT_PATH)/lib*)) | ||
|
||
# AIX: pre-defined system headers are surrounded by an extern "C" block | ||
ifeq ($(PLATFORM), OS_AIX) | ||
PLATFORM_CCFLAGS += -I$(FOLLY_DIR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these two lines should be removed, like below
Makefile
Outdated
@@ -451,18 +456,37 @@ ifeq ($(USE_FOLLY),1) | |||
ifeq (,$(FOLLY_DIR)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have FOLLY_PATH, FOLLY_DIR is confusing. Perhaps call it FOLLY_SRC. It would be nice if FOLLY_SRC were optional (if libfolly.a and headers already available in FOLLY_PATH).
steps: | ||
- pre-steps | ||
- run: sudo apt-get update -y && sudo apt-get install gcc-10 g++-10 libgflags-dev | ||
- setup-folly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under the paradigm of folly being an external library, it would be nice if one shared CircleCI step downloaded & compiled folly, though we would probably need to add CC and CXX to the environment
for this build to make that work (which would reduce copy-paste anyway).
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines -Wno-maybe-uninitialized") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-redundant-move") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-memory-model") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these suppressed warnings for stuff in our code, or related to system / third party headers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are for warnings in the third-party code.
if(USE_FOLLY) | ||
include_directories(${PROJECT_SOURCE_DIR}/third-party/folly) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I don't know cmake well enough to advise here.)
@@ -549,10 +573,6 @@ LIB_OBJECTS += $(patsubst %.c, $(OBJ_DIR)/%.o, $(LIB_SOURCES_C)) | |||
LIB_OBJECTS += $(patsubst %.S, $(OBJ_DIR)/%.o, $(LIB_SOURCES_ASM)) | |||
endif | |||
|
|||
ifeq ($(USE_FOLLY),1) | |||
LIB_OBJECTS += $(patsubst %.cpp, $(OBJ_DIR)/%.o, $(FOLLY_SOURCES)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should remove FOLLY_SOURCES from src.mk
12d29f6
to
12179ba
Compare
@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM
@@ -139,9 +139,13 @@ endif | |||
GIT_COMMAND ?= git | |||
ifeq ($(USE_COROUTINES), 1) | |||
USE_FOLLY = 1 | |||
OPT += -DUSE_COROUTINES | |||
OPT += -DUSE_COROUTINES -DHAVE_CXX11_ATOMIC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't HAVE_CXX11_ATOMIC unused / obsolete?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its used in glog/logging.h. I guess glog still supports very old compilers.
@@ -449,9 +458,43 @@ endif | |||
# This provides a Makefile simulation of a Meta-internal folly integration. | |||
# It is not validated for general use. | |||
ifeq ($(USE_FOLLY),1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see some kind of comment explaining USE_FOLLY vs. USE_FOLLY_LITE and FOLLY_DIR vs. FOLLY_PATH.
- pre-steps | ||
- run: sudo apt-get update -y && sudo apt-get install gcc-10 g++-10 libgflags-dev | ||
- setup-folly | ||
- build-folly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess in other cases the system compiler is ABI compatible with the compiler used with RocksDB, but not in this case? (I would still expect ODR violations between compilers given how much conditional compilation is in folly headers.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, we need g++ 10 for coroutine support.
.circleci/config.yml
Outdated
- run: sudo apt-get update -y && sudo apt-get install gcc-10 g++-10 libgflags-dev | ||
- setup-folly | ||
- build-folly | ||
- run: (mkdir build && cd build && CC=gcc-10 CXX=g++-10 cmake -DUSE_COROUTINES=1 -DWITH_GFLAGS=1 -DROCKSDB_BUILD_SHARED=0 .. && CC=gcc-10 CXX=g++-10 make V=1 -j20 && ctest -j20) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need to set CC
and CXX
again if in environment.
a0acafe
to
ca369fc
Compare
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
6 similar comments
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
Summary: Make folly an external dependency by trying to detect it in build_detect_platform
44037b2
to
f45c2a3
Compare
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@anand1976 has updated the pull request. You must reimport the pull request before landing. |
@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
The current integration with folly requires cherry-picking folly source files to include in RocksDB for external CI builds. Its not scaleable as we depend on more features in folly, such as coroutines. This PR adds a dependency from RocksDB to the folly library when
USE_FOLLY
orUSE_COROUTINES
are set. We build folly using the build scripts inthird-party/folly
, relying on it to download and build its dependencies. A newMakefile
target,build_folly
, is provided to make building folly easier.A new option,
USE_FOLLY_LITE
is added to retain the old model of compiling selected folly sources with RocksDB. This might be useful for short-term development.