From 97a087a98595f6ac14191ac4831dbada16e609e0 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Fri, 29 Jun 2012 23:28:00 +0400
Subject: [PATCH] Try to use libobjc2 instead of compiler-supplied libobjc. Add
 a makefile to libobjc.

---
 CMakeLists.txt               |   1 +
 cfg/CMakeLists.txt           |   2 +-
 src/CMakeLists.txt           |   5 +-
 third_party/CMakeLists.txt   |  32 +++++++++
 third_party/libobjc/Makefile | 127 +++++++++++++++++++++++++++++++++++
 5 files changed, 164 insertions(+), 3 deletions(-)
 create mode 100644 third_party/libobjc/Makefile

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8a3d4722c..3500bff316 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -213,6 +213,7 @@ include_directories("${PROJECT_SOURCE_DIR}")
 include_directories("${PROJECT_SOURCE_DIR}/include")
 include_directories("${PROJECT_BINARY_DIR}/include")
 include_directories("${PROJECT_SOURCE_DIR}/connector/c/include")
+include_directories("${PROJECT_SOURCE_DIR}/third_party/libobjc")
 
 #
 # Specify prefixes
diff --git a/cfg/CMakeLists.txt b/cfg/CMakeLists.txt
index 023137b493..0319f8449f 100644
--- a/cfg/CMakeLists.txt
+++ b/cfg/CMakeLists.txt
@@ -70,4 +70,4 @@ add_custom_target(config
     DEPENDS ${CMAKE_SOURCE_DIR}/cfg/prscfg.h ${generated_headers})
 
 
-add_dependencies(cfg libluajit)
+add_dependencies(cfg libluajit libobjc)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 50a510e95c..3351823803 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -87,14 +87,15 @@ add_library(core STATIC ${common_sources})
 add_dependencies(core generate_headers)
 set_target_properties(core PROPERTIES COMPILE_FLAGS "${core_cflags}")
 
-set (common_libraries cfg core ev coro gopt misc objc)
+set (common_libraries cfg core ev coro gopt misc)
 
 set (THREAD_LIB pthread)
 if (ENABLE_STATIC)
     set (THREAD_LIB -Wl,--whole-archive pthread -Wl,--no-whole-archive)
 endif()
 
-set (common_libraries ${common_libraries} ${LUAJIT_LIB} ${THREAD_LIB})
+set (LIBOBJC_LIB "${PROJECT_BINARY_DIR}/third_party/libobjc/libobjc.a")
+set (common_libraries ${common_libraries} ${LUAJIT_LIB} ${LIBOBJC_LIB} ${THREAD_LIB})
 
 if (TARGET_OS_LINUX)
     set (common_libraries ${common_libraries} dl)
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 882ca44c20..f8297cfd00 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -69,6 +69,37 @@ macro (luajit_build)
     unset (luajit_buildoptions)
 endmacro()
 
+macro(libobjc_build)
+    if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+        set (extra_cflags "-g -O0 -fno-inline")
+    else ()
+        set (extra_cflags "-O3")
+    endif()
+    if (${TARGET_OS_LINUX})
+        set (extra_cflags "${extra_cflags} -D_GNU_SOURCE")
+    endif()
+    if (CMAKE_COMPILER_IS_CLANG)
+        set (extra_cflags "${extra_cflags} -Wno-deprecated-objc-isa-usage")
+    endif()
+    if (NOT (${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}))
+        add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/libobjc
+            COMMAND mkdir ${PROJECT_BINARY_DIR}/third_party/libobjc
+            COMMAND cp -r ${PROJECT_SOURCE_DIR}/third_party/libobjc/*
+                ${PROJECT_BINARY_DIR}/third_party/libobjc
+        )
+    endif()
+    add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/third_party/libobjc/libobjc.a
+        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/third_party/libobjc
+        COMMAND $(MAKE) clean
+        COMMAND $(MAKE) EXTRA_CFLAGS=""${extra_cflags}""
+        DEPENDS ${PROJECT_BINARY_DIR}/CMakeCache.txt
+    )
+    add_custom_target(libobjc
+        DEPENDS ${PROJECT_BINARY_DIR}/third_party/libobjc/libobjc.a
+    )
+    unset (extra_cflags)
+endmacro()
+
 #
 # building shipped luajit only if there is no
 # usable system one (see cmake/luajit.cmake) or by demand.
@@ -76,3 +107,4 @@ endmacro()
 if (ENABLE_BUNDLED_LUAJIT)
     luajit_build()
 endif()
+libobjc_build()
diff --git a/third_party/libobjc/Makefile b/third_party/libobjc/Makefile
new file mode 100644
index 0000000000..30eaebad64
--- /dev/null
+++ b/third_party/libobjc/Makefile
@@ -0,0 +1,127 @@
+.POSIX:
+
+.SUFFIXES: .cc .c .m .o .S
+
+MAJOR_VERSION = 4
+MINOR_VERSION = 6
+SUBMINOR_VERSION = 0
+VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION)
+
+LIBOBJCLIBNAME=objc
+LIBOBJC=libobjc
+LIBOBJCXX=libobjcxx
+
+SILENT=@
+
+CFLAGS += -std=gnu99 -fPIC -fexceptions
+CXXFLAGS += -fPIC -fexceptions
+CPPFLAGS += -DTYPE_DEPENDENT_DISPATCH -DGNUSTEP
+CPPFLAGS += -D__OBJC_RUNTIME_INTERNAL__=1 -D_XOPEN_SOURCE=500 -D__BSD_VISIBLE=1 -D_BSD_SOURCE=1
+
+ASMFLAGS += `if $(CC) -v 2>&1| grep -q 'clang' ; then echo -no-integrated-as ; fi`
+
+STRIP=`if [ "$(strip)" = "yes" ] ; then echo -s ; fi`
+
+# Suppress warnings about incorrect selectors
+CPPFLAGS += -DNO_SELECTOR_MISMATCH_WARNINGS
+# Some helpful flags for debugging.
+CPPFLAGS+= ${EXTRA_CFLAGS}
+
+PREFIX?= /usr/local
+LIB_DIR= ${PREFIX}/lib
+HEADER_DIR= ${PREFIX}/include
+
+OBJCXX_OBJECTS = \
+	objcxx_eh.o
+
+OBJECTS = \
+	NSBlocks.o\
+	Protocol2.o\
+	abi_version.o\
+	alias_table.o\
+	arc.o\
+	associate.o\
+	blocks_runtime.o\
+	block_to_imp.o\
+	block_trampolines.o\
+	objc_msgSend.o\
+	caps.o\
+	category_loader.o\
+	class_table.o\
+	dtable.o\
+	eh_personality.o\
+	encoding2.o\
+	gc_none.o\
+	hash_table.o\
+	hooks.o\
+	ivar.o\
+	legacy_malloc.o\
+	loader.o\
+	mutation.o\
+	properties.o\
+	protocol.o\
+	runtime.o\
+	sarray2.o\
+	selector_table.o\
+	sendmsg2.o\
+	statics_loader.o\
+	toydispatch.o
+
+all: $(LIBOBJC).a
+
+$(LIBOBJCXX).so.$(VERSION): $(LIBOBJC).so.$(VERSION) $(OBJCXX_OBJECTS)
+	$(SILENT)echo Linking shared Objective-C++ runtime library...
+	$(SILENT)$(CXX) -shared \
+            -Wl,-soname=$(LIBOBJCXX).so.$(MAJOR_VERSION) \
+            -o $@ $(OBJCXX_OBJECTS)
+
+$(LIBOBJC).so.$(VERSION): $(OBJECTS)
+	$(SILENT)echo Linking shared Objective-C runtime library...
+	$(SILENT)$(CC) -shared -rdynamic \
+            -Wl,-soname=$(LIBOBJC).so.$(MAJOR_VERSION) \
+            -o $@ $(OBJECTS)
+
+$(LIBOBJC).a: $(OBJECTS)
+	$(SILENT)echo Linking static Objective-C runtime library...
+	$(SILENT)ld -r -o $@ $(OBJECTS)
+
+.cc.o: Makefile
+	$(SILENT)echo Compiling `basename $<`...
+	$(SILENT)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
+
+.c.o: Makefile
+	$(SILENT)echo Compiling `basename $<`...
+	$(SILENT)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+.m.o: Makefile
+	$(SILENT)echo Compiling `basename $<`...
+	$(SILENT)$(CC) $(CPPFLAGS) $(CFLAGS) -fobjc-exceptions -c $< -o $@
+
+.S.o: Makefile
+	$(SILENT)echo Assembling `basename $<`...
+	$(SILENT)$(CC) $(CPPFLAGS) $(ASMFLAGS) -c $< -o $@
+
+install: all
+	$(SILENT)echo Installing libraries...
+	$(SILENT)install -d $(LIB_DIR)
+	$(SILENT)install -m 444 $(STRIP) $(LIBOBJC).so.$(VERSION) $(LIB_DIR)
+	$(SILENT)install -m 444 $(STRIP) $(LIBOBJCXX).so.$(VERSION) $(LIB_DIR)
+	$(SILENT)install -m 444 $(STRIP) $(LIBOBJC).a $(LIB_DIR)
+	$(SILENT)echo Creating symbolic links...
+	$(SILENT)ln -sf $(LIBOBJC).so.$(VERSION) $(LIB_DIR)/$(LIBOBJC).so
+	$(SILENT)ln -sf $(LIBOBJC).so.$(VERSION) $(LIB_DIR)/$(LIBOBJC).so.$(MAJOR_VERSION)
+	$(SILENT)ln -sf $(LIBOBJC).so.$(VERSION) $(LIB_DIR)/$(LIBOBJC).so.$(MAJOR_VERSION).$(MINOR_VERSION)
+	$(SILENT)ln -sf $(LIBOBJCXX).so.$(VERSION) $(LIB_DIR)/$(LIBOBJCXX).so
+	$(SILENT)ln -sf $(LIBOBJCXX).so.$(VERSION) $(LIB_DIR)/$(LIBOBJCXX).so.$(MAJOR_VERSION)
+	$(SILENT)ln -sf $(LIBOBJCXX).so.$(VERSION) $(LIB_DIR)/$(LIBOBJCXX).so.$(MAJOR_VERSION).$(MINOR_VERSION)
+	$(SILENT)echo Installing headers...
+	$(SILENT)install -d $(HEADER_DIR)/objc
+	$(SILENT)install -m 444 objc/*.h $(HEADER_DIR)/objc
+
+clean:
+	$(SILENT)echo Cleaning...
+	$(SILENT)rm -f $(OBJECTS)
+	$(SILENT)rm -f $(OBJCXX_OBJECTS)
+	$(SILENT)rm -f $(LIBOBJC).so.$(VERSION)
+	$(SILENT)rm -f $(LIBOBJCXX).so.$(VERSION)
+	$(SILENT)rm -f $(LIBOBJC).a
-- 
GitLab