THAY ĐỔI:
Dễ dàng sao chép / dán phiên bản mới nhất (nhưng hướng dẫn cài đặt có thể thay đổi - xem bên dưới!)
Thư viện của Karl mất nhiều công sức hơn để thiết lập, nhưng giải pháp dài hạn đẹp hơn nhiều (nó chuyển đổi thư viện của bạn thành Khung).
Sử dụng cái này, sau đó tinh chỉnh nó để thêm hỗ trợ cho các bản dựng Lưu trữ - nhận xét của cf @ Frederik bên dưới về những thay đổi anh ấy đang sử dụng để làm cho công việc này hoạt động tốt với chế độ Lưu trữ.
THAY ĐỔI GẦN ĐÂY: 1. Đã thêm hỗ trợ cho iOS 10.x (trong khi vẫn duy trì hỗ trợ cho các nền tảng cũ hơn)
Thông tin về cách sử dụng tập lệnh này với dự án được nhúng trong dự án khác (mặc dù tôi rất khuyến khích KHÔNG làm điều đó, bao giờ - Apple có một vài lỗi trình chiếu trong Xcode nếu bạn nhúng các dự án vào nhau, từ Xcode 3.x đến Xcode 4.6.x)
Tập lệnh thưởng để cho phép bạn tự động bao gồm Gói (tức là bao gồm tệp PNG, tệp PLIST, v.v. từ thư viện của bạn!) - xem bên dưới (cuộn xuống dưới)
hiện hỗ trợ iPhone5 (sử dụng cách khắc phục của Apple đối với các lỗi trong lipo). LƯU Ý: hướng dẫn cài đặt đã thay đổi (tôi có thể đơn giản hóa việc này bằng cách thay đổi tập lệnh trong tương lai, nhưng không muốn mạo hiểm ngay bây giờ)
Phần "tiêu đề sao chép" hiện tôn trọng cài đặt bản dựng cho vị trí của các tiêu đề công khai (lịch sự của Frederik Wallner)
Đã thêm cài đặt rõ ràng của SYMROOT (có thể cũng cần cài đặt OBJROOT?), Nhờ Doug Dickinson
SCRIPT (đây là những gì bạn phải sao chép / dán)
Để biết hướng dẫn sử dụng / cài đặt, xem bên dưới
##########################################
#
# c.f. /programming/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4
#
# Version 2.82
#
# Latest Change:
# - MORE tweaks to get the iOS 10+ and 9- working
# - Support iOS 10+
# - Corrected typo for iOS 1-10+ (thanks @stuikomma)
#
# 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 '\d\{1,2\}\.\d\{1,2\}$')
# 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
HƯỚNG DẪN CÀI ĐẶT
- Tạo một dự án lib tĩnh
- Chọn mục tiêu
- Trong tab "Xây dựng cài đặt", đặt "Chỉ xây dựng kiến trúc hoạt động" thành "KHÔNG" (cho tất cả các mục)
- Trong tab "Xây dựng giai đoạn", chọn "Thêm ... Giai đoạn xây dựng mới ... Giai đoạn xây dựng tập lệnh chạy mới"
- Sao chép / dán tập lệnh (ở trên) vào hộp
... Sử dụng TIỀN THƯỞNG THƯỞNG:
- TÙY CHỌN: nếu bạn có các tiêu đề trong thư viện của mình, hãy thêm chúng vào giai đoạn "Sao chép tiêu đề"
- TÙY CHỌN: ... và kéo / thả chúng từ phần "Dự án" sang phần "Công khai"
- TÙY CHỌN: ... và chúng sẽ TỰ ĐỘNG được xuất mỗi khi bạn xây dựng ứng dụng, vào một thư mục con của thư mục "gỡ lỗi phổ quát" (chúng sẽ ở dạng usr / local / include)
- TÙY CHỌN: LƯU Ý: nếu bạn cũng cố gắng kéo / thả dự án của mình vào một dự án Xcode khác, điều này sẽ làm lộ ra lỗi trong Xcode 4, nơi nó không thể tạo tệp .IPA nếu bạn có Tiêu đề công khai trong dự án kéo / thả của bạn. Giải pháp thay thế: không 'nhúng các dự án xcode (quá nhiều lỗi trong mã của Apple!)
Nếu bạn không thể tìm thấy tệp đầu ra, đây là một cách giải quyết:
Thêm mã sau vào phần cuối của tập lệnh (lịch sự của Frederik Wallner): mở "$ {CREATING_UNIVERSAL_DIR}"
Apple xóa tất cả đầu ra sau 200 dòng. Chọn mục tiêu của bạn và trong Giai đoạn chạy tập lệnh, bạn PHẢI bỏ chọn: "Hiển thị các biến môi trường trong nhật ký xây dựng"
nếu bạn đang sử dụng thư mục "xây dựng đầu ra" tùy chỉnh cho XCode4, thì XCode sẽ đặt tất cả các tệp "không mong muốn" của bạn ở sai vị trí.
- Xây dựng dự án
- Nhấp vào biểu tượng cuối cùng bên phải, ở khu vực trên cùng bên trái của Xcode4.
- Chọn mục hàng đầu (đây là "bản dựng gần đây nhất" của bạn. Apple nên tự động chọn nó, nhưng họ không nghĩ về điều đó)
- trong cửa sổ chính, cuộn xuống dưới cùng. Dòng cuối cùng nên đọc: lipo: cho cấu hình hiện tại (Gỡ lỗi) tạo tệp đầu ra: /Users/blah/L Library / Nhà phát triển / XX / DecuredData / AppName -ashwnbutvodmoleijzlncudsekyf /Build / Products / Dugug
... đó là vị trí của Universal Build của bạn.
Cách bao gồm các tệp "không phải mã nguồn" trong dự án của bạn (PNG, PLIST, XML, v.v.)
- Làm mọi thứ ở trên, kiểm tra xem nó có hoạt động không
- Tạo giai đoạn Run Script mới xuất hiện SAU MỘT LẦN ĐẦU TIÊN (sao chép / dán mã bên dưới)
- Tạo một Target mới trong Xcode, thuộc loại "bó"
- Trong DỰ ÁN CHÍNH của bạn, trong "Xây dựng giai đoạn", hãy thêm gói mới dưới dạng thứ gì đó "phụ thuộc" (phần trên cùng, nhấn nút dấu cộng, cuộn xuống dưới, tìm tệp ".bundle" trong Sản phẩm của bạn)
- Trong MỤC TIÊU BUNDLE MỚI của bạn, trong "Xây dựng giai đoạn", thêm phần "Sao chép tài nguyên gói" và kéo / thả tất cả các tệp PNG, v.v.
Tập lệnh để tự động sao chép (các) gói được xây dựng vào cùng thư mục với thư viện tĩnh FAT của bạn:
echo "RunScript2:"
echo "Autocopying any bundles into the 'universal' output folder created by RunScript1"
CREATING_UNIVERSAL_DIR=${SYMROOT}/${CONFIGURATION}-universal
cp -r "${BUILT_PRODUCTS_DIR}/"*.bundle "${CREATING_UNIVERSAL_DIR}"