Xcode - symbol(s) not found for architecture x86_64 (iOS Lib)
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
)
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
8) Navigate 1 directory up ("cmd + ↑"), and you will see "Release-universal"
directory.
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.
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.
Related videos on Youtube
Abdalrahman Shatou
Software Engineer with interest in Mobile, Web, and Backend development and testing.
Updated on July 09, 2022Comments
-
Abdalrahman Shatou almost 2 years
I am building a static library. The build setting has the Architectures set to:
$(ARCHS_STANDARD)
which is shown asStandard 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 insideDebug-iphonesimulator
, I uselipo -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:
- 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.
- I am using Xcode 5.1.1.
-
James about 10 yearsAre 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 about 10 yearsHonestly, 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 about 10 yearsMake sure "i386 x86_64" is listed along with "arm7 arm7s arm64" under "VAILD_ARCHS" build settings for your target.
-
Abdalrahman Shatou almost 10 yearsThis 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 almost 10 years+1 for hinting that YES is selected for debug which was my case.
-
l0gg3r almost 10 yearsI 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 almost 8 yearsIs 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 over 7 years@aleksandar-vacic i tried the way u r shown. But it is not working for me.