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
This commit is contained in:
Igor Canadi 2014-04-04 13:11:44 -07:00
parent 32b2c1ae75
commit 51023c3911
8 changed files with 58 additions and 30 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ build_config.mk
*.class *.class
*.jar *.jar
*.*jnilib* *.*jnilib*
*.d-e
ldb ldb
manifest_dump manifest_dump

View File

@ -67,6 +67,9 @@ libraries. You are on your own.
* Please note that some of the optimizations/features are disabled in OSX. * Please note that some of the optimizations/features are disabled in OSX.
We did not run any production workloads on it. We did not run any production workloads on it.
* **iOS**:
* Run: `TARGET_OS=IOS make static_lib`
## Compilation ## Compilation
`make clean; make` will compile librocksdb.a (RocksDB static library) and all `make clean; make` will compile librocksdb.a (RocksDB static library) and all
the unit tests. You can run all unit tests with `make check`. the unit tests. You can run all unit tests with `make check`.

View File

@ -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 # this file is generated by the previous line to set build flags and sources
include build_config.mk 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. # ASAN doesn't work well with jemalloc. If we're compiling with ASAN, we should use regular malloc.
ifdef COMPILE_WITH_ASAN ifdef COMPILE_WITH_ASAN
# ASAN compile flags # ASAN compile flags
@ -36,9 +44,9 @@ else
PLATFORM_CCFLAGS += $(JEMALLOC_INCLUDE) -DHAVE_JEMALLOC PLATFORM_CCFLAGS += $(JEMALLOC_INCLUDE) -DHAVE_JEMALLOC
endif endif
WARNING_FLAGS = -Wall -Werror -Wno-sign-compare WARNING_FLAGS = -Wall -Werror -Wno-sign-compare -Wno-unused-const-variable
CFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) CFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
CXXFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual CXXFLAGS += $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual
LDFLAGS += $(PLATFORM_LDFLAGS) LDFLAGS += $(PLATFORM_LDFLAGS)
@ -148,11 +156,15 @@ $(SHARED3):
endif # PLATFORM_SHARED_EXT endif # PLATFORM_SHARED_EXT
.PHONY: blackbox_crash_test check clean coverage crash_test ldb_tests \ .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 dbg
all: $(LIBRARY) $(PROGRAMS) all: $(LIBRARY) $(PROGRAMS)
static_lib: $(LIBRARY)
shared_lib: $(SHARED)
dbg: $(LIBRARY) $(PROGRAMS) dbg: $(LIBRARY) $(PROGRAMS)
# Will also generate shared libraries. # Will also generate shared libraries.
@ -218,8 +230,6 @@ tags:
format: format:
build_tools/format-diff.sh build_tools/format-diff.sh
shared_lib: $(SHARED)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Unit tests and tools # Unit tests and tools
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -435,20 +445,20 @@ ifeq ($(PLATFORM), IOS)
PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms
SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer
DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.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: .cc.o:
mkdir -p ios-x86/$(dir $@) 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 $@) 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 $@ lipo ios-x86/$@ ios-arm/$@ -create -output $@
.c.o: .c.o:
mkdir -p ios-x86/$(dir $@) 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 $@) 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 $@ lipo ios-x86/$@ ios-arm/$@ -create -output $@
else else

View File

@ -87,7 +87,7 @@ PLATFORM_SHARED_CFLAGS="-fPIC"
PLATFORM_SHARED_VERSIONED=false PLATFORM_SHARED_VERSIONED=false
# generic port files (working on all platform by #ifdef) go directly in /port # 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 # On GCC, we pick libc's memcmp over GCC's memcmp via -fno-builtin-memcmp
case "$TARGET_OS" in case "$TARGET_OS" in
@ -98,6 +98,13 @@ case "$TARGET_OS" in
PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name " PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name "
# PORT_FILES=port/darwin/darwin_specific.cc # 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) Linux)
PLATFORM=OS_LINUX PLATFORM=OS_LINUX
COMMON_FLAGS="$COMMON_FLAGS -DOS_LINUX" COMMON_FLAGS="$COMMON_FLAGS -DOS_LINUX"

View File

@ -64,7 +64,11 @@ struct PerfContext {
uint64_t write_memtable_time; uint64_t write_memtable_time;
}; };
#if defined(OS_MACOSX)
extern PerfContext perf_context;
#else
extern __thread PerfContext perf_context; extern __thread PerfContext perf_context;
#endif
} }

View File

@ -313,26 +313,12 @@ static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) {
table0_[c >> 24]; table0_[c >> 24];
} }
#ifdef __SSE4_2__
static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) { static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) {
#ifdef __SSE4_2__
*l = _mm_crc32_u64(*l, LE_LOAD64(*p)); *l = _mm_crc32_u64(*l, LE_LOAD64(*p));
*p += 8; *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<void (*CRC32)(uint64_t*, uint8_t const**)> template<void (*CRC32)(uint64_t*, uint8_t const**)>
uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) { 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); typedef uint32_t (*Function)(uint32_t, const char*, size_t);
static inline Function Choose_Extend() { static inline Function Choose_Extend() {
return isSSE42() ? ExtendImpl<Fast_CRC32> : ExtendImpl<Slow_CRC32>; #ifdef __SSE4_2__
return ExtendImpl<Fast_CRC32>;
#else
return ExtendImpl<Slow_CRC32>;
#endif
} }
Function ChosenExtend = Choose_Extend(); Function ChosenExtend = Choose_Extend();

View File

@ -10,7 +10,11 @@
namespace rocksdb { namespace rocksdb {
// by default, enable counts only // by default, enable counts only
#if defined(IOS_CROSS_COMPILE)
PerfLevel perf_level = kEnableCount;
#else
__thread PerfLevel perf_level = kEnableCount; __thread PerfLevel perf_level = kEnableCount;
#endif
void SetPerfLevel(PerfLevel level) { perf_level = level; } void SetPerfLevel(PerfLevel level) { perf_level = level; }
@ -69,6 +73,9 @@ std::string PerfContext::ToString() const {
return ss.str(); return ss.str();
} }
#if defined(IOS_CROSS_COMPILE)
PerfContext perf_context;
#else
__thread PerfContext perf_context; __thread PerfContext perf_context;
#endif
} }

View File

@ -9,7 +9,13 @@
namespace rocksdb { 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; extern __thread PerfLevel perf_level;
#endif
inline void StartPerfTimer(StopWatchNano* timer) { inline void StartPerfTimer(StopWatchNano* timer) {
if (perf_level >= PerfLevel::kEnableTime) { if (perf_level >= PerfLevel::kEnableTime) {