Building the FreeImage lib for PIE and armv7

Hi all,

I had a go at rebuilding the FreeImage library to get rid of this non-PIE-warning - just to have less warnings when building and also to hopefully prevent warnings from Apple when submitting apps.

As I’m out of my depth with this kinda stuff, I thought I’d post the full details of what I did here, just in case I did anything stupid and everyone’s apps start crashing :wink:

Set-up:

Targets:

  • iPad 1 running iOS 5.1.1

  • iOS Simulator v7.0 iPad / iOS 7.0.3

Started off with the FreeImage-3.15.4 source download.

I then modified the Makefile.iphone a little:

  • Updated the iOS min version so that it finds the right SDK in my development folders: IPHONEOS_DEPLOYMENT_TARGET = 5.0

  • Updated the architecture from arm 6 to arm 7: ARCH_PHONE = armv7

  • To fix the non-PIE-warning I removed -mdynamic-no-pic from the EXTRA_CFLAGS_PHONE definition.

  • Also, to get it to build correctly I changed the gcc-$(GCC_VERSION) and g+±$(GCC_VERSION) references to just gcc and g++

  • Finally, towards the end of the file, updated another armv6 reference to armv7

Here is the updated Makefile.iphone:

  
# Configuration for iPhone OS, making static libs  
# this will generate both iPhone (arm) and iPhoneSimulator (i686) libs  
  
include Makefile.srcs  
  
CFLAGS =  -g -O2 -Wall -Wmissing-prototypes -std=c99 -ffast-math -fno-strict-aliasing  
CXXFLAGS =  -g -O2 -Wall -fno-strict-aliasing  
  
GCC_VERSION = 4.2  
IPHONEOS_DEPLOYMENT_TARGET = 5.0  
MACOSX_DEPLOYMENT_TARGET = 10.6  
  
PLATFORM_SIM = iPhoneSimulator  
PLATFORM_PHONE = iPhoneOS  
  
ARCH_SIM = i686  
ARCH_PHONE = armv7  
  
PLATFORM_SIM_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin  
PLATFORM_PHONE_DEVELOPER_BIN_DIR = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin  
  
SDKROOT_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/SDKs/$(PLATFORM_SIM)$(IPHONEOS_DEPLOYMENT_TARGET).sdk  
SDKROOT_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/SDKs/$(PLATFORM_PHONE)$(IPHONEOS_DEPLOYMENT_TARGET).sdk  
  
EXTRA_CFLAGS_SIM += -arch $(ARCH_SIM) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_SIM)  
EXTRA_LDFLAGS_SIM += -arch $(ARCH_SIM) -isysroot $(SDKROOT_SIM) -Wl,-dead_strip  
EXTRA_CFLAGS_SIM += -D__IPHONE_OS_VERSION_MIN_REQUIRED=20000 -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)  
EXTRA_LDFLAGS_SIM += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)  
  
# Xcode complains about the -mdynamic-no-pic with an Apple Mach-O Linker Warning, so removed  
#EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -mdynamic-no-pic -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_PHONE)  
EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -fvisibility=hidden $(INCLUDE) -isysroot $(SDKROOT_PHONE)  
EXTRA_LDFLAGS_PHONE += -arch $(ARCH_PHONE) -isysroot $(SDKROOT_PHONE) -Wl,-dead_strip  
EXTRA_CFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)  
EXTRA_LDFLAGS_PHONE += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET)  
  
AR_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/ar  
AR_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/ar  
  
CC_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/gcc  
CC_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/gcc  
  
CFLAGS_SIM = $(CFLAGS) $(EXTRA_CFLAGS_SIM)  
LDFLAGS_SIM = $(EXTRA_LDFLAGS_SIM)  
CXX_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/g++  
CXXFLAGS_SIM += $(EXTRA_CFLAGS_SIM) -fvisibility-inlines-hidden  
LIBTOOL_SIM = /Developer/Platforms/$(PLATFORM_SIM).platform/Developer/usr/bin/libtool  
  
CFLAGS_PHONE = $(CFLAGS) $(EXTRA_CFLAGS_PHONE)  
LDFLAGS_PHONE += $(EXTRA_LDFLAGS_PHONE)  
CXX_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/g++  
CXXFLAGS_PHONE += $(EXTRA_CFLAGS_PHONE) -fvisibility-inlines-hidden  
LIBTOOL_PHONE = /Developer/Platforms/$(PLATFORM_PHONE).platform/Developer/usr/bin/libtool  
  
TARGET = freeimage  
STATICLIB_SIM = lib$(TARGET)-iphonesimulator.a  
STATICLIB_PHONE = lib$(TARGET)-iphone.a  
HEADER = Source/FreeImage.h  
  
.SUFFIXES: .o-i686 .o-arm  
MODULES_ARM = $(SRCS:.c=.o-arm)  
MODULES_ARM := $(MODULES_ARM:.cpp=.o-arm)  
MODULES_i686 = $(SRCS:.c=.o-i686)  
MODULES_i686 := $(MODULES_i686:.cpp=.o-i686)  
  
default: all  
  
all: dist  
  
dist: FreeImage  
	cp *.a Dist  
	cp Source/FreeImage.h Dist  
  
FreeImage: $(STATICLIB_SIM) $(STATICLIB_PHONE)  
  
$(STATICLIB_SIM): $(MODULES_i686)  
	$(LIBTOOL_SIM) -arch_only i686 -o $@ $(MODULES_i686)  
  
.c.o-i686:  
	$(CC_SIM) $(CFLAGS_SIM) -c $< -o $@  
  
.cpp.o-i686:  
	$(CXX_SIM) $(CXXFLAGS_SIM) -c $< -o $@  
  
$(STATICLIB_PHONE): $(MODULES_ARM)  
	$(LIBTOOL_PHONE) -arch_only armv7 -o $@ $(MODULES_ARM)  
  
.c.o-arm:  
	$(CC_PHONE) $(CFLAGS_PHONE) -c $< -o $@  
  
.cpp.o-arm:  
	$(CXX_PHONE) $(CXXFLAGS_PHONE) -c $< -o $@  
  
clean:  
	rm -f core Dist/*.* u2dtmp* $(MODULES_i686) $(MODULES_ARM) $(STATICLIB_SIM) $(STATICLIB_PHONE)  
  

I then built the libs (for iOS and simulator) using: make -f Makefile.iphone

The resulting built libs, libfreeimage-iphone.a and libfreeimage-iphonesimulator.a, I renamed as freeimage.a and copied over to my OF0.8 /libs/FreeImage/lib/ios and /libs/FreeImage/lib/osx folders, respectively. Did a clean and rebuild and the warnings have disappeared and it seems to run on the iPad and simulator fine. In our code we use the OF loadImage method which, I think, uses FreeImage functions and the images appear to load fine, so looks ok…

I also ran the otool-check on the app executable and confirmed that the PIE flag is set.

Finally, here are the compiled libs and the makefile:
https://www.dropbox.com/sh/ie5w9id6y6okrqx/QMeko-e6wR

Note:

  • I don’t know how any of this will affect armv6 or pre iOS5 targets.

  • Use at your own risk!

An updated way to build FreeImage 3.16.0 and 3.17.0 for iOS is with openFramework’s Apothecary.

  1. Simply checkout the latest openFrameworks.
  2. Open a terminal and navigate to openFrameworks/scripts/apothecary/
  3. Run this code ./apothecary -t ios update FreeImage
  4. Once completed successfully the output will be stored in openFrameworks/libs/FreeImage/
  5. In the /lib/ios folder is the iOS fat lib for FreeImage

Or simply grab the files from Step 4 and 5 prebuilt.

For those wondering how this compiled, check the apothecary script:
https://github.com/openframeworks/openFrameworks/blob/master/scripts/apothecary/formulas/FreeImage/FreeImage.sh