From 51023c39110e56ee7ff514c88f9cce4538dbc53f Mon Sep 17 00:00:00 2001 From: Igor Canadi Date: Fri, 4 Apr 2014 13:11:44 -0700 Subject: [PATCH] Make RocksDB compile for iOS Summary: I had to make number of changes to the code and Makefile: * Add `make lib`, that will create static library without debug info. We need this to avoid growing binary too much. Currently it's 14MB. * Remove cpuinfo() function and use __SSE4_2__ macro. We actually used the macro as part of Fast_CRC32() function. As a result, I also accidentally fixed this issue: https://www.facebook.com/groups/rocksdb.dev/permalink/549700778461774/?stream_ref=2 * Remove __thread locals in OS_MACOSX Test Plan: `make lib PLATFORM=IOS` Reviewers: ljin, haobo, dhruba, sdong Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D17475 --- .gitignore | 1 + INSTALL.md | 3 +++ Makefile | 32 ++++++++++++++++++++----------- build_tools/build_detect_platform | 9 ++++++++- include/rocksdb/perf_context.h | 4 ++++ util/crc32c.cc | 24 +++++++---------------- util/perf_context.cc | 9 ++++++++- util/perf_context_imp.h | 6 ++++++ 8 files changed, 58 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 5e62839420..a3a70ee311 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ build_config.mk *.class *.jar *.*jnilib* +*.d-e ldb manifest_dump diff --git a/INSTALL.md b/INSTALL.md index 86934db69c..2a91be6974 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -67,6 +67,9 @@ libraries. You are on your own. * Please note that some of the optimizations/features are disabled in OSX. We did not run any production workloads on it. +* **iOS**: + * Run: `TARGET_OS=IOS make static_lib` + ## Compilation `make clean; make` will compile librocksdb.a (RocksDB static library) and all the unit tests. You can run all unit tests with `make check`. diff --git a/Makefile b/Makefile index e1e982f152..a578c12c8e 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,14 @@ $(shell (export ROCKSDB_ROOT=$(CURDIR); $(CURDIR)/build_tools/build_detect_platf # this file is generated by the previous line to set build flags and sources include build_config.mk +ifneq ($(PLATFORM), IOS) +CFLAGS += -g +CXXFLAGS += -g +else +# no debug info for IOS, that will make our library big +OPT += -DNDEBUG +endif + # ASAN doesn't work well with jemalloc. If we're compiling with ASAN, we should use regular malloc. ifdef COMPILE_WITH_ASAN # ASAN compile flags @@ -36,9 +44,9 @@ else PLATFORM_CCFLAGS += $(JEMALLOC_INCLUDE) -DHAVE_JEMALLOC endif -WARNING_FLAGS = -Wall -Werror -Wno-sign-compare -CFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) -CXXFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual +WARNING_FLAGS = -Wall -Werror -Wno-sign-compare -Wno-unused-const-variable +CFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) +CXXFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual LDFLAGS += $(PLATFORM_LDFLAGS) @@ -148,11 +156,15 @@ $(SHARED3): endif # PLATFORM_SHARED_EXT .PHONY: blackbox_crash_test check clean coverage crash_test ldb_tests \ - release tags valgrind_check whitebox_crash_test format shared_lib all \ + release tags valgrind_check whitebox_crash_test format static_lib shared_lib all \ dbg all: $(LIBRARY) $(PROGRAMS) +static_lib: $(LIBRARY) + +shared_lib: $(SHARED) + dbg: $(LIBRARY) $(PROGRAMS) # Will also generate shared libraries. @@ -218,8 +230,6 @@ tags: format: build_tools/format-diff.sh -shared_lib: $(SHARED) - # --------------------------------------------------------------------------- # Unit tests and tools # --------------------------------------------------------------------------- @@ -435,20 +445,20 @@ ifeq ($(PLATFORM), IOS) PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer -IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/versionCFBundleShortVersionString) +IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString) .cc.o: mkdir -p ios-x86/$(dir $@) - $(SIMULATORROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ $(COVERAGEFLAGS) + $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) - $(DEVICEROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ $(COVERAGEFLAGS) + xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -arch armv7s -arch arm64 -c $< -o ios-arm/$@ lipo ios-x86/$@ ios-arm/$@ -create -output $@ .c.o: mkdir -p ios-x86/$(dir $@) - $(SIMULATORROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ + $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) - $(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ + xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -arch armv7s -arch arm64 -c $< -o ios-arm/$@ lipo ios-x86/$@ ios-arm/$@ -create -output $@ else diff --git a/build_tools/build_detect_platform b/build_tools/build_detect_platform index 5a15aca333..94aafd62ef 100755 --- a/build_tools/build_detect_platform +++ b/build_tools/build_detect_platform @@ -87,7 +87,7 @@ PLATFORM_SHARED_CFLAGS="-fPIC" PLATFORM_SHARED_VERSIONED=false # generic port files (working on all platform by #ifdef) go directly in /port -GENERIC_PORT_FILES=`find $ROCKSDB_ROOT/port -name '*.cc' | tr "\n" " "` +GENERIC_PORT_FILES=`cd $ROCKSDB_ROOT; find port -name '*.cc' | tr "\n" " "` # On GCC, we pick libc's memcmp over GCC's memcmp via -fno-builtin-memcmp case "$TARGET_OS" in @@ -98,6 +98,13 @@ case "$TARGET_OS" in PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name " # PORT_FILES=port/darwin/darwin_specific.cc ;; + IOS) + PLATFORM=IOS + COMMON_FLAGS="$COMMON_FLAGS -DOS_MACOSX -DIOS_CROSS_COMPILE" + PLATFORM_SHARED_EXT=dylib + PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name " + CROSS_COMPILE=true + ;; Linux) PLATFORM=OS_LINUX COMMON_FLAGS="$COMMON_FLAGS -DOS_LINUX" diff --git a/include/rocksdb/perf_context.h b/include/rocksdb/perf_context.h index 61adad6b73..45399ac2d5 100644 --- a/include/rocksdb/perf_context.h +++ b/include/rocksdb/perf_context.h @@ -64,7 +64,11 @@ struct PerfContext { uint64_t write_memtable_time; }; +#if defined(OS_MACOSX) +extern PerfContext perf_context; +#else extern __thread PerfContext perf_context; +#endif } diff --git a/util/crc32c.cc b/util/crc32c.cc index 50178ae71d..9500c44c1b 100644 --- a/util/crc32c.cc +++ b/util/crc32c.cc @@ -313,26 +313,12 @@ static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) { table0_[c >> 24]; } +#ifdef __SSE4_2__ static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) { - #ifdef __SSE4_2__ *l = _mm_crc32_u64(*l, LE_LOAD64(*p)); *p += 8; - #else - Slow_CRC32(l, p); - #endif -} - -// Detect if SS42 or not. -static bool isSSE42() { - #ifdef __GNUC__ - uint32_t c_; - uint32_t d_; - __asm__("cpuid" : "=c"(c_), "=d"(d_) : "a"(1) : "ebx"); - return c_ & (1U << 20); // copied from CpuId.h in Folly. - #else - return false; - #endif } +#endif template uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) { @@ -380,7 +366,11 @@ uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) { typedef uint32_t (*Function)(uint32_t, const char*, size_t); static inline Function Choose_Extend() { - return isSSE42() ? ExtendImpl : ExtendImpl; +#ifdef __SSE4_2__ + return ExtendImpl; +#else + return ExtendImpl; +#endif } Function ChosenExtend = Choose_Extend(); diff --git a/util/perf_context.cc b/util/perf_context.cc index fc8efba645..855e7c45ab 100644 --- a/util/perf_context.cc +++ b/util/perf_context.cc @@ -10,7 +10,11 @@ namespace rocksdb { // by default, enable counts only +#if defined(IOS_CROSS_COMPILE) +PerfLevel perf_level = kEnableCount; +#else __thread PerfLevel perf_level = kEnableCount; +#endif void SetPerfLevel(PerfLevel level) { perf_level = level; } @@ -69,6 +73,9 @@ std::string PerfContext::ToString() const { return ss.str(); } +#if defined(IOS_CROSS_COMPILE) +PerfContext perf_context; +#else __thread PerfContext perf_context; - +#endif } diff --git a/util/perf_context_imp.h b/util/perf_context_imp.h index 7b06e4c1dc..ac044ca098 100644 --- a/util/perf_context_imp.h +++ b/util/perf_context_imp.h @@ -9,7 +9,13 @@ namespace rocksdb { +// TODO(icanadi): when calling perf_context is macro-ed (TODO ljin), make it +// noop in case IOS_CROSS_COMPILE +#if defined(IOS_CROSS_COMPILE) +extern enum PerfLevel perf_level; +#else extern __thread PerfLevel perf_level; +#endif inline void StartPerfTimer(StopWatchNano* timer) { if (perf_level >= PerfLevel::kEnableTime) {