Skip to content
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

Closed
wants to merge 17 commits into from

Conversation

anand1976
Copy link
Contributor

@anand1976 anand1976 commented Jun 2, 2022

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 or USE_COROUTINES are set. We build folly using the build scripts in third-party/folly, relying on it to download and build its dependencies. A new Makefile 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.

@anand1976 anand1976 force-pushed the build_with_folly branch 2 times, most recently from 17170da to 1acc8fa Compare June 30, 2022 21:13
@anand1976 anand1976 changed the title cmake build with folly coroutines Add dependency on libfolly.a Jun 30, 2022
@anand1976 anand1976 marked this pull request as ready for review June 30, 2022 23:56
@mdcallag
Copy link
Contributor

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.

Copy link
Contributor

@pdillinger pdillinger left a 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:
Copy link
Contributor

@pdillinger pdillinger Jul 19, 2022

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:

  1. download any dependencies (without running the compiler)
  2. 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
Copy link
Contributor

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 " ...

@anand1976
Copy link
Contributor Author

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.

@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()
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Comment on lines 830 to 848
# 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`

Copy link
Contributor

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)?

Copy link
Contributor

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.

Copy link
Contributor

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?

Copy link
Contributor

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."

Copy link
Contributor Author

@anand1976 anand1976 Jul 28, 2022

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)
Copy link
Contributor

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))
Copy link
Contributor

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
Copy link
Contributor

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")
Copy link
Contributor

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?

Copy link
Contributor Author

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)
Copy link
Contributor

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))
Copy link
Contributor

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

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@anand1976 anand1976 changed the title Add dependency on libfolly.a Build and link libfolly with RocksDB Aug 4, 2022
Copy link
Contributor

@pdillinger pdillinger left a 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
Copy link
Contributor

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?

Copy link
Contributor Author

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)
Copy link
Contributor

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
Copy link
Contributor

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.)

Copy link
Contributor Author

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.

- 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)
Copy link
Contributor

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.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

6 similar comments
@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants