【问题标题】:Xcode 10: unable to attach DB errorXcode 10:无法附加数据库错误
【发布时间】:2018-12-11 16:56:25
【问题描述】:

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

xcodebuild -target TargetName -configuration Release clean build

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

注意:使用新的构建系统

注意:规划构建

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

** 构建失败 **

** 构建失败 **

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

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

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

【问题讨论】:

    标签: ios xcodebuild xcode10


    【解决方案1】:

    好的,看来我设法解决了。我在Build Phases 中有/bin/sh 脚本,它试图构建胖静态库。在脚本中,我将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" \
    

    为我解决了这个问题。

    【讨论】:

    • 感谢您添加解决方案。我也开始关注这个了。
    • 你能补充更多细节吗,拜托。也许您可以添加脚本的副本,以便其他人可以看到您如何使用此变量以及为什么错误的路径会导致此问题。谢谢
    • @TMin 将其添加到我的答案中。希望对你有帮助。
    • 不幸的是,这并没有为我解决问题(我没有在我的项目中使用${OBJROOT}
    • 在我的情况下,我遇到了错误“错误:访问构建数据库 .../Build/Intermediates.noindex/XCBuildData/build.db:磁盘 I/O 错误”,我添加了“OBJROOT " 参数,它解决了我的问题。谢谢!
    【解决方案2】:

    Open XCode File->Project Settings

    Build System->Legacy Build System

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

    【讨论】:

    • 谁能向我解释一下它的不同之处?
    【解决方案3】:

    如果你像我一样使用构建脚本来构建子模块的库。 您还需要在您的 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
    

    【讨论】:

    • 我实际上在我的一些构建脚本中使用了它,只是忘了用这些说明更新我的答案。感谢您提到这个解决方案,它很好,我喜欢它。
    • 这似乎可以删除“数据库已锁定可能有两个并发构建在同一文件系统位置运行”,但是我遇到了“错误:错误:访问构建数据库”/ Users/MyFolder/XCBuildData/build.db": 磁盘 I/O 错误',有什么想法吗?
    【解决方案4】:

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

    # 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 并阻止它们

    【讨论】:

    • RECURSION 是什么意思?我们如何阻止它?谢谢。
    【解决方案5】:

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

    xcodebuild -scheme SchemeName -configuration Release clean build
    

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 很有趣。在你的情况下,我没有想到任何可能导致这种情况的事情。感谢分享解决方案!
      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

          【解决方案9】:

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

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

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

          在使用xcodebuild( ) 触发时,以前的构建工作正常

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

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

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

          【讨论】:

            猜你喜欢
            • 2022-08-10
            • 2022-08-10
            • 2023-04-08
            • 1970-01-01
            • 2016-09-04
            • 1970-01-01
            • 2016-03-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多