From d35dfeba58ea107b25ea73f9aa1f873461bac169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan=20Talpalaru?= Date: Thu, 24 Mar 2022 10:39:21 +0100 Subject: [PATCH] Makefile: support Mingw + more cross-compilation Tested on an Ubuntu 20.04 host, targeting: - Linux ARM64, using aarch64-linux-gnu-g++ - macOS AMD64 and ARM64, using https://github.com/tpoechtrager/osxcross - Windows AMD64, using Mingw-w64 from https://github.com/mxe/mxe "build_tools/build_detect_platform" and "Makefile" have been partially cleaned, in the process. There is more stuff left to clean there. The Makefile now passes more command line arguments to the detection script via environment variables. --- HISTORY.md | 4 ++ INSTALL.md | 16 ++++++ Makefile | 83 +++++++++++++++++-------------- build_tools/build_detect_platform | 39 ++++++++------- 4 files changed, 88 insertions(+), 54 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 98d66f9f7..0149881b4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,10 @@ ### Bug Fixes * Fixed a race condition when 2PC is disabled and WAL tracking in the MANIFEST is enabled. The race condition is between two background flush threads trying to install flush results, causing a WAL deletion not tracked in the MANIFEST. A future DB open may fail. +### New Features +* Support Mingw when using the Makefile. +* Support more cross-compilation scenarios when using the Makefile. + ## 7.1.0 (03/23/2022) ### New Features * Allow WriteBatchWithIndex to index a WriteBatch that includes keys with user-defined timestamps. The index itself does not have timestamp. diff --git a/INSTALL.md b/INSTALL.md index 0afba94d3..64b8dc7db 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -27,6 +27,22 @@ CPU supports it. To print a warning if your CPU does not support SSE4.2, build w to build a portable binary, add `PORTABLE=1` before your make commands, like this: `PORTABLE=1 make static_lib`. +* When cross-compiling, you may want to disable dependency and CPU feature + autodetection. You do that by setting `CROSS_COMPILE=true`: + +```sh +# Target macOS on Apple M1, from a Linux host, using https://github.com/tpoechtrager/osxcross +make -j $(nproc) \ + CROSS_COMPILE=true \ + PORTABLE=1 \ + DISABLE_WARNING_AS_ERROR=1 \ + TARGET_OS=Darwin \ + TARGET_ARCHITECTURE=arm64 \ + CXX=oa64-clang++ \ + AR=arm64-apple-darwin20.4-ar \ + static_lib +``` + ## Dependencies * You can link RocksDB with following compression libraries: diff --git a/Makefile b/Makefile index a1d0a3303..befb279e2 100644 --- a/Makefile +++ b/Makefile @@ -118,16 +118,19 @@ OPT += -momit-leaf-frame-pointer endif endif -ifeq (,$(shell $(CXX) -fsyntax-only -maltivec -xc /dev/null 2>&1)) -CXXFLAGS += -DHAS_ALTIVEC -CFLAGS += -DHAS_ALTIVEC -HAS_ALTIVEC=1 -endif +# A cross-compiler can support PPC, even though that's not our target. +ifneq ($(CROSS_COMPILE), true) + ifeq (,$(shell $(CXX) -fsyntax-only -maltivec -xc /dev/null 2>&1)) + CXXFLAGS += -DHAS_ALTIVEC + CFLAGS += -DHAS_ALTIVEC + HAS_ALTIVEC=1 + endif -ifeq (,$(shell $(CXX) -fsyntax-only -mcpu=power8 -xc /dev/null 2>&1)) -CXXFLAGS += -DHAVE_POWER8 -CFLAGS += -DHAVE_POWER8 -HAVE_POWER8=1 + ifeq (,$(shell $(CXX) -fsyntax-only -mcpu=power8 -xc /dev/null 2>&1)) + CXXFLAGS += -DHAVE_POWER8 + CFLAGS += -DHAVE_POWER8 + HAVE_POWER8=1 + endif endif # if we're compiling for shared libraries, add the shared flags @@ -136,34 +139,31 @@ CXXFLAGS += $(PLATFORM_SHARED_CFLAGS) -DROCKSDB_DLL CFLAGS += $(PLATFORM_SHARED_CFLAGS) -DROCKSDB_DLL endif -# if we're compiling for release, compile without debug code (-DNDEBUG) -ifeq ($(DEBUG_LEVEL),0) -OPT += -DNDEBUG +ifeq ($(DEBUG_LEVEL),0) # release build + # if we're compiling for release, compile without debug code (-DNDEBUG) + OPT += -DNDEBUG + USE_RTTI := 0 +else # debug build + USE_RTTI := 1 -ifneq ($(USE_RTTI), 1) - CXXFLAGS += -fno-rtti -else - CXXFLAGS += -DROCKSDB_USE_RTTI -endif -else -ifneq ($(USE_RTTI), 0) - CXXFLAGS += -DROCKSDB_USE_RTTI -else - CXXFLAGS += -fno-rtti -endif + ifdef ASSERT_STATUS_CHECKED + # For ASC, turn off constructor elision, preventing the case where a constructor returned + # by a method may pass the ASC check if the status is checked in the inner method. Forcing + # the copy constructor to be invoked disables the optimization and will cause the calling method + # to check the status in order to prevent an error from being raised. + PLATFORM_CXXFLAGS += -fno-elide-constructors + ifeq ($(filter -DROCKSDB_ASSERT_STATUS_CHECKED,$(OPT)),) + OPT += -DROCKSDB_ASSERT_STATUS_CHECKED + endif + endif -ifdef ASSERT_STATUS_CHECKED -# For ASC, turn off constructor elision, preventing the case where a constructor returned -# by a method may pass the ASC check if the status is checked in the inner method. Forcing -# the copy constructor to be invoked disables the optimization and will cause the calling method -# to check the status in order to prevent an error from being raised. -PLATFORM_CXXFLAGS += -fno-elide-constructors -ifeq ($(filter -DROCKSDB_ASSERT_STATUS_CHECKED,$(OPT)),) - OPT += -DROCKSDB_ASSERT_STATUS_CHECKED -endif -endif + $(warning Warning: Compiling in debug mode. Don't use the resulting binary in production) +endif # DEBUG_LEVEL -$(warning Warning: Compiling in debug mode. Don't use the resulting binary in production) +ifeq ($(USE_RTTI), 0) + CXXFLAGS += -fno-rtti +else + CXXFLAGS += -DROCKSDB_USE_RTTI endif # `USE_LTO=1` enables link-time optimizations. Among other things, this enables @@ -217,12 +217,18 @@ AM_SHARE = $(AM_V_CCLD) $(CXX) $(PLATFORM_SHARED_LDFLAGS)$@ -L. $(patsubst lib%. # Export some common variables that might have been passed as Make variables # instead of environment variables. dummy := $(shell (export ROCKSDB_ROOT="$(CURDIR)"; \ - export CXXFLAGS="$(EXTRA_CXXFLAGS)"; \ - export LDFLAGS="$(EXTRA_LDFLAGS)"; \ + export CC="$(CC)"; \ + export CXX="$(CXX)"; \ + export AR="$(AR)"; \ + export CFLAGS="$(CFLAGS)"; \ + export CXXFLAGS="$(CXXFLAGS)"; \ export COMPILE_WITH_ASAN="$(COMPILE_WITH_ASAN)"; \ export COMPILE_WITH_TSAN="$(COMPILE_WITH_TSAN)"; \ export COMPILE_WITH_UBSAN="$(COMPILE_WITH_UBSAN)"; \ export PORTABLE="$(PORTABLE)"; \ + export CROSS_COMPILE="$(CROSS_COMPILE)"; \ + export TARGET_OS="$(TARGET_OS)"; \ + export TARGET_ARCHITECTURE="$(TARGET_ARCHITECTURE)"; \ export ROCKSDB_NO_FBCODE="$(ROCKSDB_NO_FBCODE)"; \ export USE_CLANG="$(USE_CLANG)"; \ export LIB_MODE="$(LIB_MODE)"; \ @@ -504,6 +510,11 @@ ifeq ($(NO_THREEWAY_CRC32C), 1) CXXFLAGS += -DNO_THREEWAY_CRC32C endif +# The original CFLAGS and CXXFLAGS have already been included in +# PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS, but we can't avoid the duplication +# here because more parameters have been appended in the mean time. +# TODO: move all the new flags to PLATFORM_* after "make_config.mk" is +# included, so we can := instead of += here. CFLAGS += $(C_WARNING_FLAGS) $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) CXXFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual -Wnon-virtual-dtor -Wno-missing-field-initializers diff --git a/build_tools/build_detect_platform b/build_tools/build_detect_platform index 4dc9dd31b..da4b50c69 100755 --- a/build_tools/build_detect_platform +++ b/build_tools/build_detect_platform @@ -45,16 +45,15 @@ if test -z "$OUTPUT"; then exit 1 fi +PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS ${CXXFLAGS}" + # we depend on C++17, but should be compatible with newer standards if [ "$ROCKSDB_CXX_STANDARD" ]; then - PLATFORM_CXXFLAGS="-std=$ROCKSDB_CXX_STANDARD" + PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS -std=$ROCKSDB_CXX_STANDARD" else - PLATFORM_CXXFLAGS="-std=c++17" + PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS -std=c++17" fi -# we currently depend on POSIX platform -COMMON_FLAGS="-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX" - # Default to fbcode gcc on internal fb machines if [ -z "$ROCKSDB_NO_FBCODE" -a -d /mnt/gvfs/third-party ]; then FBCODE_BUILD="true" @@ -136,10 +135,11 @@ if test -z "$WATCH"; then WATCH=watch fi -COMMON_FLAGS="$COMMON_FLAGS ${CFLAGS}" -CROSS_COMPILE= -PLATFORM_CCFLAGS= -PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS" +if [[ ! "$TARGET_OS" =~ MINGW ]]; then + COMMON_FLAGS="-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX" +fi + +PLATFORM_CCFLAGS="${CFLAGS}" PLATFORM_SHARED_EXT="so" PLATFORM_SHARED_LDFLAGS="-Wl,--no-as-needed -shared -Wl,-soname -Wl," PLATFORM_SHARED_CFLAGS="-fPIC" @@ -249,7 +249,7 @@ EOF Cygwin) PLATFORM=CYGWIN PLATFORM_SHARED_CFLAGS="" - PLATFORM_CXXFLAGS="-std=gnu++11" + #PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS -std=gnu++11" COMMON_FLAGS="$COMMON_FLAGS -DCYGWIN" if [ -z "$USE_CLANG" ]; then COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp" @@ -259,6 +259,10 @@ EOF PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread -lrt" # PORT_FILES=port/linux/linux_specific.cc ;; + MINGW*) + PLATFORM=MINGW + COMMON_FLAGS="$COMMON_FLAGS -DWIN32 -DOS_WIN -D_MBCS -DWIN64 -DNOMINMAX -D_WIN32_WINNT=_WIN32_WINNT_VISTA -D_POSIX_C_SOURCE=1" + ;; OS_ANDROID_CROSSCOMPILE) PLATFORM=OS_ANDROID COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp -D_REENTRANT -DOS_ANDROID -DROCKSDB_PLATFORM_POSIX" @@ -271,7 +275,6 @@ EOF exit 1 esac -PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS ${CXXFLAGS}" JAVA_LDFLAGS="$PLATFORM_LDFLAGS" JAVA_STATIC_LDFLAGS="$PLATFORM_LDFLAGS" JAVAC_ARGS="-source 8" @@ -416,7 +419,7 @@ EOF if ! test $ROCKSDB_DISABLE_TBB; then # Test whether tbb is available - $CXX $PLATFORM_CXXFLAGS $LDFLAGS -x c++ - -o test.o -ltbb 2>/dev/null </dev/null < int main() {} EOF @@ -667,13 +670,13 @@ else fi if [[ "${PLATFORM}" == "OS_MACOSX" ]]; then - # For portability compile for macOS 10.12 (2016) or newer - COMMON_FLAGS="$COMMON_FLAGS -mmacosx-version-min=10.12" - PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -mmacosx-version-min=10.12" + # For portability compile for macOS 10.14 (2018) or newer + COMMON_FLAGS="$COMMON_FLAGS -mmacosx-version-min=10.14" + PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -mmacosx-version-min=10.14" # -mmacosx-version-min must come first here. - PLATFORM_SHARED_LDFLAGS="-mmacosx-version-min=10.12 $PLATFORM_SHARED_LDFLAGS" - PLATFORM_CMAKE_FLAGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.12" - JAVA_STATIC_DEPS_COMMON_FLAGS="-mmacosx-version-min=10.12" + PLATFORM_SHARED_LDFLAGS="-mmacosx-version-min=10.14 $PLATFORM_SHARED_LDFLAGS" + PLATFORM_CMAKE_FLAGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.14" + JAVA_STATIC_DEPS_COMMON_FLAGS="-mmacosx-version-min=10.14" JAVA_STATIC_DEPS_LDFLAGS="$JAVA_STATIC_DEPS_COMMON_FLAGS" JAVA_STATIC_DEPS_CCFLAGS="$JAVA_STATIC_DEPS_COMMON_FLAGS" JAVA_STATIC_DEPS_CXXFLAGS="$JAVA_STATIC_DEPS_COMMON_FLAGS"