47

更新到 Xcode 10 时,iOS 静态库目标无法构建。我尝试构建它的方式如下:

xcodebuild -target TargetName -configuration Release clean build

使用 Xcode 9 一切运行顺利,但是当 Xcode 10 用于构建时,我收到以下错误(在 clean 运行顺利之后):

注意:使用新的构建系统

注:规划建设

注意:构建构建描述构建系统信息错误:无法附加数据库:错误:访问构建数据库“/Users/uerceg/random-path/build/XCBuildData/build.db”:数据库被锁定可能有两个并发构建在运行相同的文件系统位置。

** 构建失败 **

** 构建失败 **

以下构建命令失败:PhaseScriptExecution MultiPlatform\ Build /Users/uerceg/random-path/build/Library.build/Release-iphoneos/LibraryTarget.build/Script-9DE7C9021AE68FA5001556E5.sh(1 次失败)

这可能无关,但我注意到新的 Xcode 10 构建系统将重复Copy Bundle Resource的 Info.plist 文件标记为错误,所以我确实确保没有重复的条目,但可能这个错误与这个事实无关。

有谁知道可能出了什么问题?

4

9 回答 9

80

好的,看来我设法解决了。我正在尝试构建胖静态库的/bin/sh脚本。Build Phases在脚本中,我的OBJROOT路径设置如下:

OBJROOT="${OBJROOT}"

似乎 Xcode 10 和新的构建系统在途中改变了一些路径,这条线是问题的根源。它需要调整为:

OBJROOT="${OBJROOT}/DependentBuilds"

之后,xcodebuild设法在 Xcode 10 中引入的新构建系统没有问题地构建这个目标。

我自己没有找到这个解决方案,非常感谢 Matt Gallagher 和他在这里的帖子:https ://github.com/mattgallagher/CwlSignal/issues/24#issuecomment-396931001


根据@TMin 在评论中的要求,我的脚本如下所示:

set -e

# If we're already inside this script then die
if [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then
exit 0
fi
export RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1

RW_FRAMEWORK_NAME=${PROJECT_NAME}
RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a"
RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/static/${RW_FRAMEWORK_NAME}Sdk.framework"

function build_static_library {
    echo "1"
    echo "${BUILD_DIR}"
    # Will rebuild the static library as specified
    #     build_static_library sdk
    xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \
    -target "${TARGET_NAME}" \
    -configuration "${CONFIGURATION}" \
    -sdk "${1}" \
    ONLY_ACTIVE_ARCH=NO \
    BUILD_DIR="${BUILD_DIR}" \
    OBJROOT="${OBJROOT}" \
    BUILD_ROOT="${BUILD_ROOT}" \
    SYMROOT="${SYMROOT}" $ACTION
}

function make_fat_library {
    # Will smash 2 static libs together
    #     make_fat_library in1 in2 out
    xcrun lipo -create "${1}" "${2}" -output "${3}"
}

# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name
if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then
RW_SDK_PLATFORM=${BASH_REMATCH[1]}
else
echo "Could not find platform name from SDK_NAME: $SDK_NAME"
exit 1
fi

# 2 - Extract the version from the SDK
if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then
RW_SDK_VERSION=${BASH_REMATCH[1]}
else
echo "Could not find sdk version from SDK_NAME: $SDK_NAME"
exit 1
fi

# 3 - Determine the other platform
if [ "$RW_SDK_PLATFORM" == "iphoneos" ]; then
RW_OTHER_PLATFORM=iphonesimulator
else
RW_OTHER_PLATFORM=iphoneos
fi

# 4 - Find the build directory
if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$RW_SDK_PLATFORM$ ]]; then
RW_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}"
else
echo "Could not find other platform build directory."
exit 1
fi

# Build the other platform.
build_static_library "${RW_OTHER_PLATFORM}${RW_SDK_VERSION}"

# If we're currently building for iphonesimulator, then need to rebuild
#   to ensure that we get both i386 and x86_64
if [ "$RW_SDK_PLATFORM" == "iphonesimulator" ]; then
build_static_library "${SDK_NAME}"
fi

# Join the 2 static libs into 1 and push into the .framework
make_fat_library "${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}Sdk"

# Ensure that the framework is present in both platform's build directories
cp -a "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}Sdk" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/static/${RW_FRAMEWORK_NAME}Sdk.framework/Versions/A/${RW_FRAMEWORK_NAME}Sdk"

# Copy the framework to the project directory
ditto "${RW_FRAMEWORK_LOCATION}" "${SRCROOT}/Frameworks/static/${RW_FRAMEWORK_NAME}Sdk.framework"

问题出build_static_library在这一行的方法中:

OBJROOT="${OBJROOT}" \

将该行更改为:

OBJROOT="${OBJROOT}/DependantBuilds" \

为我解决了这个问题。

于 2018-07-04T07:03:05.480 回答
51

打开 XCode 文件->项目设置

构建系统->旧版构建系统

配置XCode 10.0 版本项目设置可以解决问题。

于 2018-09-18T12:41:20.350 回答
20

如果您像我一样使用构建脚本来构建子模块的库。您还需要通过-UseModernBuildSystem=NO在 xcodebuild 命令中使用来明确禁用构建脚本中的新构建系统。

例如:

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}" -UseModernBuildSystem=NO
于 2018-09-25T07:55:28.730 回答
0

使用这个脚本,它将在新的构建系统中正常工作

# Step 1 search RECURSION and if detected stop "*/

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# Step 2. Build Device and Simulator versions

xcodebuild -target logger ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

xcodebuild -target logger-configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 -arch x86_64 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 3. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}universal.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"

# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"

fi

在 Xcode 10 构建系统之前使用单线程,但在 Xcode 10 中使用具有多线程的新构建系统,因此每次运行构建 Xcode 运行按钮时,此脚本

 xcodebuild -target logger ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}".

将再调用一次构建等等,这将创建 RECURSION

不要忘记用 (fi) 结束 IF 条件结束你的脚本

第 1 步是检测 RECURSION 并停止它们

于 2018-10-17T07:32:00.817 回答
0

如果您想保留 XCode 10 默认构建系统,但仍然在 IDE 之外运行您的构建(例如在 CI 机器中),只需将您-target的参数替换为命令中的-scheme参数,xcodebuild例如:

xcodebuild -scheme SchemeName -configuration Release clean build

多亏了2015 年的这篇文章,它谈到了一个非常相似的问题,它给了我解决这个问题的提示。正如同一位作者所说,

我会冒险猜测,xcodebuild没有方案会错误地通过“现代构建系统”,给出提到的错误

于 2019-01-03T11:28:44.517 回答
0

我有同样的问题,并从提示中尝试一切,但这个错误仍然存​​在。有时候项目建好了,下次没有又报错。对我有帮助的解决方案是编辑方案并关闭 Parallelize Build。之后一切正常。

于 2019-01-24T12:13:35.857 回答
0

在我的构建脚本中添加一个Clean 派生数据步骤(在 Xcode 构建之前)似乎可以解决我的问题。

不确定它是否相关,但我的项目使用 Realm(与 CocoaPods 一起安装)。这是激发“修复”-> https://github.com/realm/realm-cocoa/issues/5812的 GitHub 问题。

于 2019-03-19T10:08:19.323 回答
0

我在运行时遇到了这个问题swift run <your_proj>

可以通过删除build.db文件及其同级文件和目录来实现快速修复。这可能看起来微不足道,但它对我有用。

于 2021-01-25T08:15:42.347 回答
0

我重新发布这个是因为版主认为删除我之前的答案是合适的。

由于 xcframeworks 的要求,当我通过构建升级到新构建系统时遇到了同样的问题。

错误:“.....Build/Intermediates.noindex/XCBuildData/build.db”:数据库已锁定 可能有两个并发构建在同一文件系统位置运行。”

该构建以前在触发时工作正常xcodebuild( )

以上/批准的答案都不适合我。

对我有用的是在我的 Fastlane 脚本中切换xcodebuild( )到。build_app( )

希望这个答案对将来的人有所帮助。

于 2021-05-05T08:10:32.080 回答