2

I followed the guide at Build fat static library (device + simulator) using Xcode and SDK 4+ to build the libmms ( https://github.com/kosher-penguin/xcode-libmms ), and got a fat static library, but it seems not work. I got errors when add the library to my project(xCode4.2+iOS5.0):

Undefined symbols for architecture armv7:
  "_iconv_close", referenced from:
      _mms_connect in libMMS.a(mms.o)
  "_Status_GetNewStatusByKey", referenced from:
      _report_progress in libMMS.a(mms.o)
  "_Status_SetNewStatusByKey", referenced from:
      _report_progress in libMMS.a(mms.o)
  "_iconv", referenced from:
      _string_utf16 in libMMS.a(mms.o)
  "_iconv_open", referenced from:
      _mms_connect in libMMS.a(mms.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Firstly,I clone the code from https://github.com/kosher-penguin/xcode-libmms.git Secondly, I open it with xCode4.2, and add the follow script to Run Script(Build Phases), and then run the project. Thirdly, I copy the file named libmms.a in the folder named Release-universal, and then add the library to a new project. Fourthly, in the new project,add the header file from xcode-libmms project, import mms.h and mms_config.h, and call the function mms_connect, and then build it, but get the errors.

DEBUG_THIS_SCRIPT="false"

if [ $DEBUG_THIS_SCRIPT = "true" ]
then
echo "########### TESTS #############"
echo "Use the following variables when debugging this script; note that they may change on recursions"
echo "BUILD_DIR = $BUILD_DIR"
echo "BUILD_ROOT = $BUILD_ROOT"
echo "CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR"
echo "BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR"
echo "CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR"
echo "TARGET_BUILD_DIR = $TARGET_BUILD_DIR"
fi

#####################[ part 1 ]##################
# First, work out the BASESDK version number (NB: Apple ought to report this, but they hide it)
#    (incidental: searching for substrings in sh is a nightmare! Sob)

SDK_VERSION=$(echo ${SDK_NAME} | grep -o '.\{3\}$')

# Next, work out if we're in SIM or DEVICE

if [ ${PLATFORM_NAME} = "iphonesimulator" ]
then
OTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION}
else
OTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION}
fi

echo "XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})"
echo "...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}"
#
#####################[ end of part 1 ]##################

#####################[ part 2 ]##################
#
# IF this is the original invocation, invoke WHATEVER other builds are required
#
# Xcode is already building ONE target...
#
# ...but this is a LIBRARY, so Apple is wrong to set it to build just one.
# ...we need to build ALL targets
# ...we MUST NOT re-build the target that is ALREADY being built: Xcode WILL CRASH YOUR COMPUTER if you try this (infinite recursion!)
#
#
# So: build ONLY the missing platforms/configurations.

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: I am NOT the root invocation, so I'm NOT going to recurse"
else
# CRITICAL:
# Prevent infinite recursion (Xcode sucks)
export ALREADYINVOKED="true"

echo "RECURSION: I am the root ... recursing all missing build targets NOW..."
echo "RECURSION: ...about to invoke: xcodebuild -configuration \"${CONFIGURATION}\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO"
xcodebuild -configuration "${CONFIGURATION}" -target "${TARGET_NAME}" -sdk "${OTHER_SDK_TO_BUILD}" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

ACTION="build"

#Merge all platform binaries as a fat binary for each configurations.

# Calculate where the (multiple) built files are coming from:
CURRENTCONFIG_DEVICE_DIR=${SYMROOT}/${CONFIGURATION}-iphoneos
CURRENTCONFIG_SIMULATOR_DIR=${SYMROOT}/${CONFIGURATION}-iphonesimulator

echo "Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}"
echo "Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}"

CREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal
echo "...I will output a universal build to: ${CREATING_UNIVERSAL_DIR}"

# ... remove the products of previous runs of this script
#      NB: this directory is ONLY created by this script - it should be safe to delete!

rm -rf "${CREATING_UNIVERSAL_DIR}"
mkdir "${CREATING_UNIVERSAL_DIR}"

#
echo "lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"
lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"

#########
#
# Added: StackOverflow suggestion to also copy "include" files
#    (untested, but should work OK)
#
if [ -d "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include" ]
then
mkdir -p "${CREATING_UNIVERSAL_DIR}/usr/local/include"
# * needs to be outside the double quotes?
cp "${CURRENTCONFIG_DEVICE_DIR}/usr/local/include/"* "${CREATING_UNIVERSAL_DIR}/usr/local/include"
fi
fi

Please give me some help, thank you.

update: After add libiconv library, the error as follow:

Undefined symbols for architecture armv7:
  "_Status_GetNewStatusByKey", referenced from:
      _report_progress in libMMS.a(mms.o)
  "_Status_SetNewStatusByKey", referenced from:
      _report_progress in libMMS.a(mms.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Community
  • 1
  • 1
wilson
  • 21
  • 1
  • 4

1 Answers1

2

One of the problems is that your library has a dependency on libiconv. When you use your library, you should not just add libMMS but libiconv as well, which comes with any XCode installation. See libiconv not linking to iOS project for how to add it to the project.

I don't know what dependency _Status_GetNewStatusByKey and _Status_SetNewStatusByKey. They might be similar.

Update:

The second problem is the function report_progress() in mms.c that uses the functions Status_GetNewStatusByKey and Status_SetNewStatusByKey, which don't seem to be defined anywhere (didn't you get warnings when you compiled the library?). Remove everything that declares, defines or uses report_progress(). It has been removed in the latest version of libmms anyway.

Community
  • 1
  • 1
Codo
  • 75,595
  • 17
  • 168
  • 206
  • thank you, as you said, after add libiconv, the error:Undefined symbols for architecture armv7: "_Status_GetNewStatusByKey", referenced from: _report_progress in libMMS.a(mms.o) "_Status_SetNewStatusByKey", referenced from: _report_progress in libMMS.a(mms.o) ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) – wilson Dec 19 '11 at 09:58
  • ,thank you very much, it can be build now, but I still go an error where run. The error is EXC_BAD_ACCESS on _malloc_initialize. – wilson Dec 19 '11 at 14:09
  • Codo, would you like to help me to build a fat library for the source code at https://launchpad.net/libmms, thank you. – wilson Dec 19 '11 at 16:06
  • I don't think I can help you with your latest error. It's rather different from the initial problem. You'd better start a new question that focuses on the latest error. And to help find the cause, you'll need to add a full stack trace and the affected code to your question. – Codo Dec 20 '11 at 18:19