Xcode - symbol(s) not found for architecture x86_64 (iOS Lib)

73,527

Solution 1

I had the same trouble with building static library.
Finally I have found the basic solution. (You need to build universal library for x86_64/armv7/armv7s/arm64)

enter image description here

1) Click on the project file
2) Click on the target
3) Open "Build Phases"
4) Open "Run Script"
5) Add "/bin/sh" and the script below

##########################################
#
# c.f. http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
#
# Version 2.7
#
# Latest Change:
# - Supports iPhone 5 / iPod Touch 5 (uses Apple's workaround to lipo bug)
#
# Purpose:
#   Automatically create a Universal static library for iPhone + iPad + iPhone Simulator from within XCode
#
# Author: Adam Martin - http://twitter.com/redglassesapps
# Based on: original script from Eonil (main changes: Eonil's script WILL NOT WORK in Xcode GUI - it WILL CRASH YOUR COMPUTER)
#

set -e
set -o pipefail

#################[ Tests: helps workaround any future bugs in Xcode ]########
#
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}\" -project \"${PROJECT_NAME}.xcodeproj\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO" BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" SYMROOT=\"${SYMROOT}\"

xcodebuild -configuration "${CONFIGURATION}" -project "${PROJECT_NAME}.xcodeproj" -target "${TARGET_NAME}" -sdk "${OTHER_SDK_TO_BUILD}" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}"

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}"
xcrun -sdk iphoneos 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)
#
echo "Fetching headers from ${PUBLIC_HEADERS_FOLDER_PATH}"
echo "  (if you embed your library project in another project, you will need to add"
echo "   a "User Search Headers" build setting of: (NB INCLUDE THE DOUBLE QUOTES BELOW!)"
echo '        "$(TARGET_BUILD_DIR)/usr/local/include/"'
if [ -d "${CURRENTCONFIG_DEVICE_DIR}${PUBLIC_HEADERS_FOLDER_PATH}" ]
then
mkdir -p "${CREATING_UNIVERSAL_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"
# * needs to be outside the double quotes?
cp -r "${CURRENTCONFIG_DEVICE_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"* "${CREATING_UNIVERSAL_DIR}${PUBLIC_HEADERS_FOLDER_PATH}"
fi
fi

6) Hit "cmd + B" (Build Project)

7) Open Product in Finder

enter image description here

8) Navigate 1 directory up ("cmd + ↑"), and you will see "Release-universal" directory. enter image description here

There will be your "fat/universal" library, You are ready to go!

Solution 2

I encountered this with a framework lib I'm using in one of my apps, when I tried to test it in iPhone Retina 64bit simulator.

I simply added x86_64 as an architecture to build for and set it to always build for all architectures. Worked a charm.

enter image description here

Solution 3

The lipo tool can not only create fat mach-o binaries, but it can inspect them: xcrun lipo -info /path/to/libThing.a

This will output what architectures are in the file. Before you join binaries using lipo, run this to make sure the architectures you expect are present. It's also a good idea to run this on the product of a fat binary join.

In your case you need:

iPhoneSDK Configuration: armv7, armv7s, arm64

iPhoneSimulator Configuration: i386, x86_64

It seems that the iPhoneSimulator build product is not producing an x86_64 binary based on your question. Check your build configuration - in particular, "Build Active Architectures Only" (ONLY_ACTIVE_ARCH ) should be set to NO. The default is for this to be NO for Release, but YES for debug. If it is YES, only one architecture will be in the build product.

Share:
73,527

Related videos on Youtube

Abdalrahman Shatou
Author by

Abdalrahman Shatou

Software Engineer with interest in Mobile, Web, and Backend development and testing.

Updated on July 09, 2022

Comments

  • Abdalrahman Shatou
    Abdalrahman Shatou almost 2 years

    I am building a static library. The build setting has the Architectures set to: $(ARCHS_STANDARD) which is shown as Standard Architectures (armv7, armv7s, arm64) I build the lib choosing iOS Device AND then using the simulator (for example iPhone Retina).

    Now that I have two builds (one inside Debug-iphoneos and the other inside Debug-iphonesimulator, I use lipo -create to create the aggregated lib:

    lipo -create path/to/first/lib /path/to/second/lib -o MyLib.a
    

    If I used this library in another project to simulate on any iOS device with 64-bit architecture, it gives symbol(s) not found for architecture x86_64. What really makes me so angry that the lib project itself is inside a workspace with another project that use the lib. I can simulate on 64-bit iOS simulator! (on all simulators and devices for that matter). What am I doing wrong?

    Notes:

    1. This is not duplicate Q. Before accusing me of that (since this is my second day trying to fix this stupid issue), I did search on Stack and Google. All answers don't help.
    2. I am using Xcode 5.1.1.
    • James
      James about 10 years
      Are you using lipo that comes with the OS or Xcode? To use Xcode's, run "xcrun -sdk iphoneos lipo [arguments as before]". Maybe that will help.
    • cjserio
      cjserio about 10 years
      Honestly, I'm pretty confused by your question but two things to check...first you should see if "Build Active Architectures" is set to Yes or No. If it's set to Yes, then it's only building for that one device. If you pick NO, it'll build all 3. Second, i would type "file MyLib.a" from the Terminal and it'll tell you what architectures are actually in your fat static lib.
    • gagarwal
      gagarwal about 10 years
      Make sure "i386 x86_64" is listed along with "arm7 arm7s arm64" under "VAILD_ARCHS" build settings for your target.
  • Abdalrahman Shatou
    Abdalrahman Shatou almost 10 years
    This is the best answer. Just out of curiosity, how can you build a "Release" build using cmd-B. For what I know, cmd-b builds a "Debug" version. I have to use Product > Archive to build a "Release" version.
  • Abdalrahman Shatou
    Abdalrahman Shatou almost 10 years
    +1 for hinting that YES is selected for debug which was my case.
  • l0gg3r
    l0gg3r almost 10 years
    I change the build configuration, here are the steps [1]: i.stack.imgur.com/RqWkL.png [2]: i.stack.imgur.com/xZayM.png [3]: i.stack.imgur.com/xk5on.png
  • nr5
    nr5 almost 8 years
    Is there a way till date without using this script? I mean if we build again simulator and device without using the script, two folders are created. The lib files in these gives "symbols not found" error. So what are these two lib files for?
  • Ramakrishna
    Ramakrishna over 7 years
    @aleksandar-vacic i tried the way u r shown. But it is not working for me.