Подтвердить что ты не робот

Xcode 10: невозможно подключить ошибку БД

При обновлении до Xcode 10 целевая статическая библиотека iOS не создается. Способ, которым я пытаюсь его построить, следующий:

xcodebuild -target TargetName -configuration Release clean build

С Xcode 9 все работает гладко, но когда Xcode 10 используется для сборки, я получаю следующую ошибку (после чистой работы плавно):

Примечание: Использование новой системы сборки

примечание: сборка планирования

примечание: построение описания сборки. Ошибка системной информации: невозможно подключить DB: ошибка: доступ к базе данных сборки "/Users/uerceg/random-path/build/XCBuildData/build.db": база данных заблокирована. Возможно, в ней работают две параллельные сборки то же расположение файловой системы.

** BUILD FAILED **

** BUILD FAILED **

Не удалось выполнить следующие команды сборки: 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 в качестве ошибок, поэтому я не делал дубликатов записей, но, вероятно, эта ошибка не связана с этим фактом.

Кто-нибудь знает, что может быть неправильным?

4b9b3361

Ответ 1

Хорошо, похоже, мне удалось решить это. У меня был сценарий /bin/sh в Build Phases который пытался собрать толстую статическую библиотеку. В сценарии я OBJROOT путь OBJROOT следующим образом:

OBJROOT="${OBJROOT}"

Похоже, Xcode 10 и новая система сборки изменили некоторые пути на пути, и эта строка была источником проблемы. Это должно быть приспособлено к:

OBJROOT="${OBJROOT}/DependentBuilds"

После этого xcodebuild удается построить эту цель без проблем с новой системой сборки, представленной в Xcode 10.

Я сам не дошел до этого решения, большое спасибо Мэтту Галлахеру и его посту здесь: 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 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" \

решает проблему для меня.

Ответ 3

Если вы используете скрипт для сборки библиотек субмодулей, как я. Вам также нужно явно отключить новую систему сборки в вашем скрипте сборки, используя -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

Ответ 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

Не забывайте заканчивать вас Script With (fi) своим концом условия IF

Шаг 1 - обнаружение рекурсии и остановка их

Ответ 5

Если вы хотите сохранить систему сборки XCode 10 по умолчанию, но по-прежнему запускать сборку вне среды IDE (например, в машине CI), просто замените параметр -target для параметра -scheme в команде xcodebuild например:

xcodebuild -scheme SchemeName -configuration Release clean build

Благодаря этому посту от 2015 года, в котором говорится об очень похожей проблеме, он дал мне подсказку, как решить эту проблему. Как говорит тот же автор,

Я бы xcodebuild предположить, что xcodebuild без схемы проходит неправильно через "современную систему сборки", давая указанную ошибку

Ответ 6

У меня те же проблемы, и я попробую все из подсказок, но эта ошибка все еще продолжается. Иногда проект строится, в следующий раз нет и ошибки. И решение, которое мне помогает, это отредактировать схему и отключить Parallelize Build. После этого все работает нормально.