我最近决定尝试在iOS设备上运行我的一些图形代码,但我使用FreeImage来加载纹理。因此,我需要为iOS 5.0构建它。
当我尝试使用FreeImage库时,我当前收到了链接错误。链接错误都与标准C++库相关。例如..。
Undefined symbols for architecture i386:
"std::basic_string<char, std::char_traits<char>, std::allocator<char>>::~basic_string()", referenced from:
_FreeImage_GetMetadata in libfreeimage-iphonesimulator.a(BitmapAccess.o-i386)
_FreeImage_SetMetadata in libfreeimage-iphonesimulator.a(BitmapAccess.o-i386)
_FreeImage_CloneMetadata in libfreeimage-iphonesimulator.a(BitmapAccess.o-i386)
_FreeImage_Clone in libfreeimage-iphonesimulator.a(BitmapAccess.o-i386)
std::pair<std::string const, FITAG*>::~pair() in libfreeimage-iphonesimulator.a(BitmapAccess.o-i386)
Load(FreeImageIO*, void*, int, int, void*) in libfreeimage-iphonesimulator.a(PluginEXR.o-i386)
C_OStream::write(char const*, int) in libfreeimage-iphonesimulator.a(PluginEXR.o-i386)
...不幸的是,为iOS构建FreeImage所提供的makefile有点过时了,所以我不得不更新它。此外,在我的XCode项目中,我切换了编译器以支持C++11特性并使用libc++ (如这里所述的Can I use C++11 with Xcode?)。
因此,我尝试在FreeImage的makefile中镜像这些更改,但仍然收到这些错误。
我的makefile看起来像这样(我发现这篇文章有一定的帮助http://sourceforge.net/p/freeimage/discussion/36110/thread/51445acc)
# 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 -std=c++0x -stdlib=libc++
GCC_VERSION = 4.2
IPHONEOS_DEPLOYMENT_TARGET = 5.0
MACOSX_DEPLOYMENT_TARGET = 10.6
PLATFORM_SIM = iPhoneSimulator
PLATFORM_PHONE = iPhoneOS
ARCH_SIM = i386
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)
EXTRA_CFLAGS_PHONE += -arch $(ARCH_PHONE) -pipe -mdynamic-no-pic -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)/llvm-gcc-$(GCC_VERSION)
CC_PHONE = $(PLATFORM_PHONE_DEVELOPER_BIN_DIR)/llvm-gcc-$(GCC_VERSION)
CFLAGS_SIM = $(CFLAGS) $(EXTRA_CFLAGS_SIM)
LDFLAGS_SIM = $(EXTRA_LDFLAGS_SIM)
CXX_SIM = $(PLATFORM_SIM_DEVELOPER_BIN_DIR)/clang++
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)/clang++
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-i386 .o-arm
MODULES_ARM = $(SRCS:.c=.o-arm)
MODULES_ARM := $(MODULES_ARM:.cpp=.o-arm)
MODULES_i386 = $(SRCS:.c=.o-i386)
MODULES_i386 := $(MODULES_i386:.cpp=.o-i386)
default: all
all: dist
dist: FreeImage
cp *.a Dist
cp Source/FreeImage.h Dist
FreeImage: $(STATICLIB_SIM) $(STATICLIB_PHONE)
$(STATICLIB_SIM): $(MODULES_i386)
$(LIBTOOL_SIM) -arch_only $(ARCH_SIM) -o $@ $(MODULES_i386)
.c.o-i386:
$(CC_SIM) $(CFLAGS_SIM) -c $< -o $@
.cpp.o-i386:
$(CXX_SIM) $(CXXFLAGS_SIM) -c $< -o $@
$(STATICLIB_PHONE): $(MODULES_ARM)
$(LIBTOOL_PHONE) -arch_only $(ARCH_PHONE) -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_i386) $(MODULES_ARM) $(STATICLIB_SIM) $(STATICLIB_PHONE)也许有人能指出我哪里错了
编辑:我修复了一个问题,它没有重建i386目标文件,希望这是解决方案,但它仍然有相同的链接错误。
编辑:我将makefile调整为使用clang++
我还将libc++添加到链接的框架中

下面是我关于C++的XCode项目的设置

我的XCode项目中也有.cpp文件。然而,错误仍然存在。
Edit3:
请求查询的结果:
nm libfreeimage-iphonesimulator.a | c++filt | grep '~basic_string()' | sort -u
nm: no name list
nm: no name list
U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()完整的链接器错误输出可以在这里找到:http://pastebin.com/wjbWgE4S
发布于 2013-01-05 01:34:51
Objective C项目使用的是clang编译器(您可能还在使用gcc),它是(从技术上讲) C编译器,而不是C++编译器。它足够聪明,可以使用文件扩展名来确定是将代码编译为C、Objective C还是C++。
当您链接一个Objective C项目时,它使用clang链接,而不是在C++运行时中链接。您需要在运行时进行链接。
如果您正在使用libc++库构建您的库,则需要将libc++添加到链接到Build Phases -> Link Binary With Libraries中项目的库列表中。如果使用libstdc++库进行构建,则需要将libstdc++添加到链接的库列表中。
如果项目中只有一个C++文件,Xcode就足够智能地使用clang++进行链接,在这种情况下,您不需要在C++运行时中显式地进行链接。
tl;dr -看起来你在编译模拟器的C++代码时没有使用与你构建主应用程序相同的标志。这行代码:
CXXFLAGS_SIM += $(EXTRA_CFLAGS_SIM) -fvisibility-inlines-hidden实际上缺少基本$(CXXFLAGS)项,应为:
CXXFLAGS_SIM += $(CXXFLAGS) $(EXTRA_CFLAGS_SIM) -fvisibility-inlines-hiddenCXXFLAGS_PHONE行也是如此
结果,您混合了libc++和libstdc++编译后的代码,这会导致链接错误。这应该是一个提示,CXXFLAGS行没有被使用,因为它在编译行的开头有c++,如果在任何代码中使用它,就会触发编译错误。
还有其他问题,例如,要使用libc++,您的iPhone部署目标必须是iOS 5或更高版本(因此模拟器编译需要__IPHONE_OS_VERSION_MIN_REQUIRED=50000 ),并且由于签名扩展问题,您将需要修复一些文件。
Source/LibRawLite/./internal/dcraw_common.cpp:3926:19: error: constant expression evaluates to 128 which cannot be narrowed to type 'signed char' [-Wc++11-narrowing]如果要检查C++代码是使用-stdlib=libc++还是-stdlib=libstdc++编译的,可以对任何结果编译的代码执行nm,通过c++filt传递它。如果看到名称空间为std::__1::,则代码是用-stdlib=libc++编译的,否则就是用-stdlib=libstdc++编译的
https://stackoverflow.com/questions/14160444
复制相似问题