Xcode10:无法附加数据库错误

Xcode 10: unable to attach DB error

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

xcodebuild -target TargetName -configuration Release clean build

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

note: Using new build system

note: Planning build

note: Constructing build description Build system information error: unable to attach DB: error: accessing build database "/Users/uerceg/random-path/build/XCBuildData/build.db": database is locked Possibly there are two concurrent builds running in the same filesystem location.

** BUILD FAILED **

** BUILD FAILED **

The following build commands failed: PhaseScriptExecution MultiPlatform\ Build /Users/uerceg/random-path/build/Library.build/Release-iphoneos/LibraryTarget.build/Script-9DE7C9021AE68FA5001556E5.sh (1 failure)

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

有人知道哪里出了问题吗?

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

OBJROOT="${OBJROOT}"

似乎是 Xcode10,新的构建系统在途中更改了一些路径,这一行是问题的根源。需要调整为:

OBJROOT="${OBJROOT}/DependentBuilds"

之后,xcodebuild 成功构建了这个目标,并且在 Xcode 10.

中引入的新构建系统没有出现问题

我自己没有得到这个解决方案,非常感谢 Matt Gallagher 和他的 post 在这里: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 "" \
    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 "" "" -output ""
}

# 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" \

帮我解决了这个问题。

Open XCode File->Project Settings

Build System->Legacy Build System

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

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

例如:

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

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

# 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

before Xcode 10 build system uses single thread, but in Xcode 10 usees new build system with multiple threads, so every time you run your build Xcode run button this script

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

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

别忘了用 (fi) 结束 IF 条件结束你的脚本

第 1 步是检测递归并停止它们

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

xcodebuild -scheme SchemeName -configuration Release clean build

感谢 2015 年的 this post 讨论了一个非常相似的问题,它给了我解决这个问题的提示。正如同一位作者所说,

I would hazard a guess, that xcodebuild without a scheme goes wrongly through the "modern build system", giving the mentioned error

我遇到了同样的问题并根据提示尝试了所有方法,但此错误仍然存​​在。有时候工程建好了,下次就没有和报错了。对我有帮助的解决方案是编辑方案并关闭 Parallelize Build。之后一切正常。

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

不确定是否相关,但我的项目使用 Realm(与 CocoaPods 一起安装)。这是启发 "fix" -> https://github.com/realm/realm-cocoa/issues/5812.

的 GitHub 问题

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

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

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

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

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

构建之前在使用 xcodebuild( )

触发时运行良好

None above/approved 的回答对我有用。

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

希望这个回答对以后的人有所帮助。

删除派生数据对我有用。 看看你是怎么做到的:https://programmingwithswift.com/delete-derived-data-xcode/

对我来说,我刚刚清理了我的项目。 重新启动 IDE 并重建项目,它运行得非常棒。