LINUX.ORG.RU

Qt + Mac OS


2

2

Как собрать Qt проект для Mac OS со статической линковкой библиотек?

В крайнем случае, как создать установщик, что бы установить эти билиотеки?

Ответ на: комментарий от CrossFire

Второе — Qt приложения всегда читают/пишут ~/Library/Preferences/com.nokia.qt.plist. Отключить нельзя так как это было созданно специально для общих настроек Qt приложений. Но Apple не пропустит приложение которое пишет чужие настройки.

мдя... зачем они это сделали?

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

Я так понимаю, ман писался два года назад, и патчи брались из багтрекера, на сегодня эти моменты должны быть исправлены.

CrossFire ★★★★★ ()
Ответ на: комментарий от CrossFire

В общем рассказываю, как я решил проблему, мало ли кому пригодится. Задача: запустить приложение созданное на Qt на Mac OS при отсутствии на этом компьютере любых библиотек Qt. При всем при этом документация для приложения выполнена в Qt Assistant.

1) Для этого первое что необходимо сделать, это просто собрать проект Qt Creater (без каких то дополнительных действий).

2) Скопировать Qt Assistant куданибуть, что бы не поломать его у себя на компе.

3) Магия. В Qt для Mac есть специальная удилита macdeployqt. В качестве параметра она принимает приложение (asdfasdf.app).

Переходим в папку, куда скопировали Assistant и запускаем: macdeployqt assistant.app

После этого проверяем, ассистент не рабоатет) Печально. Откроем приложение (просмотр содержимого папки) Assistant.app и в папку Assistant.app/Contents/Frameworks копируем библиотеку /Developer/Applications/Qt/plugins/sqldrivers/libqsqlite.dylib (почему её? ну приперло мне. А на самом деле надо пользоваться otool (сами разберетесь, если надо будет)). Проверяем работоспособность. Работает.

4) Запускаем macdeployqt мой_проект.app

5) Открываем приложение мой_проект.app и в папке Contents создаем папку bin, в которую копируем наш Assistant.app.

Собственно все. Размер приложения у меня вырос с 1.5 Мбт до 70 Мбт, но при проверке работоспособности на стороннем компьютере с Mac OS, но без Qt и каких либо библиотек или компиляторов, все запостилось, заработало и зашипело.

Вот.

imirrori ()
Ответ на: комментарий от imirrori

Размер приложения у меня вырос с 1.5 Мбт до 70 Мбт

EPIC WIN, ящитаю

geek ★★★ ()
Ответ на: комментарий от geek

50 из них это Assistant. Ну я перепробовал все способы. Ближе всех был к победе CMake. На моем компе он запускал собранное приложение, а на другом нет. Так что это единственное, что у меня заработало. Кто знает решение лучше, скажите мне - я тока за. Ибо еще долго мне с Qt на Mac работать.

imirrori ()

Линукс тут при чём?

От iПарада отбился?

anonymous ()
GCLABELS="NightlyBuild, Type-Archive, OpSys-OSX, Version-Alpha, Qt-4.8.x"
GCSUMMARY="Vacuum-IM | Qt 4.8.4 | r${bamboo.custom.svn.lastchange.revision.number} | Mac OS X 10.6, 10.7, 10.8 | 64 bit only"
VERSION="${bamboo.vacuum.version}.${bamboo.custom.svn.lastchange.revision.number}"
VACUUM_BINARY_DIR="/Users/krab/Bamboo_MacOSX_Agent/data/binary/VACUUM-TRUNK-MACOSXDMG"

### Namespace
ORIG_NAME="vacuum"
PRODUCT_NAME="Vacuum-IM"
DMG_NAME="${PRODUCT_NAME}_${VERSION}-alpha_osx_x64_qt4.8.4"

### Environment
SVN_ROOT=${bamboo.build.working.directory}
PATH_TO_QMAKE="qmake"

# Build options
BUILDOPTS=" -recursive -spec macx-g++ CONFIG+=release CONFIG-=debug CONFIG+=x86_64"

# Directories
TMP_DIR="Applications"
DYLD_PREFIX="@executable_path/../Frameworks"
CONTENTS_DIR="$TMP_DIR/$ORIG_NAME.app/Contents"
FW_DIR="$CONTENTS_DIR/Frameworks"
SYS_PLUGINS_DIR=`$PATH_TO_QMAKE -query QT_INSTALL_PLUGINS`
SYS_TRANSLATIONS_DIR=`$PATH_TO_QMAKE -query QT_INSTALL_TRANSLATIONS`
SYS_FW_DIR=`$PATH_TO_QMAKE -query QT_INSTALL_LIBS`
SCRIPT_DIR="$SVN_ROOT/src/packages/macosx"

### Functions
function process_binary {
        local binary=$1
        local tab="$2"
        echo "$tab Processing" `basename $binary`
        if [ -f "$binary" ]; then
                #for str1 in `otool -LX "$binary" | grep $SYS_FW_DIR | cut -d " " -f 1`; do
                for str1 in `otool -LX "$binary" | grep Qt | cut -d " " -f 1`; do
                        local str=`basename "$str1"`
                        if [ `basename $binary` != $str ]; then
                                local l="$str.framework/Versions/4/$str"
                                echo "$tab\t Resolving dependency: $str"
                                #install_name_tool -change "$SYS_FW_DIR/$l" "$DYLD_PREFIX/$l" "$binary"
                                install_name_tool -change "$l" "$DYLD_PREFIX/$l" "$binary"
                                process_lib "$l" "$tab\t"
                        fi
                done;
                echo "$tab Processed" `basename $binary`
        else
                echo "$tab File not found: $binary"
        fi
}

function process_lib {
        local lib=$1
        local tab=$2
        if [ ! -f "$FW_DIR/$lib" ]; then                        
                if [ -f "$SYS_FW_DIR/$lib" ]; then
                        echo "$tab" `basename $lib` "still not in the bundle, fixing..."
                        echo "$tab\t Copying " `basename "$lib"` " to bundle... "
                        cp -Rf $SYS_FW_DIR/`basename $lib`.framework $FW_DIR
                        echo "copied!"
                        install_name_tool -id "$DYLD_PREFIX/$lib" "$FW_DIR/$lib"
                        strip -x "$FW_DIR/$lib"
                        process_binary "$FW_DIR/$lib" "$tab\t"
                        echo "$tab fixed" `basename $lib!`
                else
                        echo "$tab ERROR: Library $lib not found"
                fi
        fi
}

### Building part

cd $SCRIPT_DIR
rm -Rf $TMP_DIR
if [ -d $TMP_DIR ]
then
    rm $TMP_DIR
fi
mkdir $TMP_DIR

echo "Building..."
cd $SVN_ROOT
$PATH_TO_QMAKE $BUILDOPTS $ORIG_NAME.pro && make -j4 && make INSTALL_ROOT=$SCRIPT_DIR install
echo "Build done!"

cd $SCRIPT_DIR
echo "Copying Qt plugins to bundle..."
cp -R "$SYS_PLUGINS_DIR/imageformats" "$CONTENTS_DIR/PlugIns"
echo "done!"

echo "Copying Qt locales to bundle..."
AVIABLE_LANGUAGES=`ls $CONTENTS_DIR/Resources/translations/`
for lang in $AVIABLE_LANGUAGES ; do
        cp "$SYS_TRANSLATIONS_DIR/qt_$lang.qm" "$CONTENTS_DIR/Resources/translations/$lang/qt_$lang.qm"
done
echo "done!"

echo "Copying Qt libraries to bundle..."
strip "$CONTENTS_DIR/MacOS/vacuum"
process_binary "$CONTENTS_DIR/MacOS/vacuum" ""
for pl in `find "$CONTENTS_DIR" | egrep "\.dylib"` ; do
        strip -x "$pl"
        process_binary "$pl" ""
done

echo "Creating qt.conf..."
echo "[Paths]\nPlugins = PlugIns" > "$CONTENTS_DIR/Resources/qt.conf"
echo "done!"

echo "Cleaning up bundle..."
find "$CONTENTS_DIR/Frameworks" | egrep "debug|Headers" | xargs rm -rf
find "$CONTENTS_DIR/Frameworks" | egrep ".prl" | xargs rm
find "$CONTENTS_DIR" -type d -name .svn | xargs rm -rf
echo "done!"

echo "Setting program version to Info.plist and copy InfoPlist.strings..."
sed -i.bak "s/1.0.0.0/$VERSION/" $CONTENTS_DIR/Info.plist ; rm $CONTENTS_DIR/Info.plist.bak
mkdir $CONTENTS_DIR/Resources/en.lproj
cp $SCRIPT_DIR/InfoPlist.strings $CONTENTS_DIR/Resources/en.lproj/InfoPlist.strings
echo "done!"

### Copy vacuum.app for plugins

echo "Store copy of vacuum.app for plugins compilation..."
rm -rf ${VACUUM_BINARY_DIR}
mkdir -p ${VACUUM_BINARY_DIR}
cp -aR $TMP_DIR/$ORIG_NAME.app ${VACUUM_BINARY_DIR}
echo "${VERSION}" > ${VACUUM_BINARY_DIR}/info
echo "done!"

### DMG part

cd $SCRIPT_DIR
TMP_DMG_NAME="temporary.dmg"
if [ -f $TMP_DMG_NAME ]
then
    rm $TMP_DMG_NAME
fi

echo "Creating temporary dmg disk image..."
hdiutil create -ov -srcfolder $TMP_DIR -format UDRW -volname "$PRODUCT_NAME" "$TMP_DMG_NAME"

echo "Mounting temporary image..."
for i in /Volumes/${PRODUCT_NAME}*
do
	if [[ -d $i ]]
	then
		hdiutil unmount "$i"
	fi
done
device=$(hdiutil attach -readwrite -noverify -noautoopen "$TMP_DMG_NAME" | egrep '^/dev/' | sed 1q | awk '{print $1}')
echo "done! (device ${device})"

echo "Sleeping for 5 seconds..."
sleep 5

echo "Setting style for temporary dmg image..."
echo "* Copying background image... "
BG_FOLDER="/Volumes/$PRODUCT_NAME/.background"
mkdir "$BG_FOLDER"
cp "$SCRIPT_DIR/background.png" "${BG_FOLDER}/"
echo "* Copying volume icon... "
ICON_FOLDER="/Volumes/$PRODUCT_NAME"
cp "$SVN_ROOT/vacuum.icns" "$ICON_FOLDER/.VolumeIcon.icns"
echo "* Setting volume icon... "
SetFile -c icnC "$ICON_FOLDER/.VolumeIcon.icns"
SetFile -a C "$ICON_FOLDER"
echo "* Adding symlink to /Applications... "
ln -s /Applications "/Volumes/$PRODUCT_NAME/Applications"
echo "done!"

APPS_X=380
APPS_Y=185
BUNDLE_X=110
BUNDLE_Y=185
WINDOW_WIDTH=500
WINDOW_HEIGHT=300
WINDOW_LEFT=300
WINDOW_TOP=100
WINDOW_RIGHT=$(($WINDOW_LEFT + $WINDOW_WIDTH))
WINDOW_BOTTOM=$(($WINDOW_TOP + $WINDOW_HEIGHT))

echo "Executing applescript for further customization..."
APPLESCRIPT="
tell application \"Finder\"
	tell disk \"$PRODUCT_NAME\"
		open
		-- Setting view options
		set current view of container window to icon view
		set toolbar visible of container window to false
		set statusbar visible of container window to false
		set the bounds of container window to {${WINDOW_LEFT}, ${WINDOW_TOP}, ${WINDOW_RIGHT}, ${WINDOW_BOTTOM}}
		set theViewOptions to the icon view options of container window
		set arrangement of theViewOptions to not arranged
		set icon size of theViewOptions to 96
		-- Settings background
		${NO_BG}set background picture of theViewOptions to file \".background:background.png\"
		-- Rearranging
		set the position of item \"Applications\" to {$APPS_X, $APPS_Y}
		set the position of item \"$PRODUCT_NAME\" to {$BUNDLE_X, $BUNDLE_Y}
		-- Updating and sleeping for 5 secs
		update without registering applications
		-- Reopening
		close
		open
		delay 6
		-- Reopening, for .DS_STORE
		close
		open
		delay 6
		-- Eject
		eject
	end tell
end tell
"
echo "$APPLESCRIPT" | osascript
echo "done!"

echo "Fixing permissins and syncing..."
chmod -Rf go-w /Volumes/"$PRODUCT_NAME" &> /dev/null || true
sync
echo "done!"

echo "Converting..."
if [ -f $DMG_NAME ]
then
	rm $DMG_NAME
fi
hdiutil convert "$TMP_DMG_NAME" -format UDBZ -o "$SCRIPT_DIR/$DMG_NAME"
echo "done!"

echo "Removing temporary folder..."
rm $TMP_DMG_NAME
rm -rf $TMP_DIR
echo "done!"


Это скрипт сборки вакуума в dmg. Идея понятна. Смотри в мои Functions там копирование Qt библиотек и выпрямление путей instal_name_tool.

P.S. вы форумом ошиблись у нас про линукс.

bhfq ★★★★★ ()
Последнее исправление: bhfq (всего исправлений: 2)
Ответ на: комментарий от imirrori

Если Assistant занимает 50 метров, логично не использовать его, правда?) Ну и еще есть вариант, посмотреть как делают люди, выпускающие кроссплатформенные вещи на OS X, например вот.

CrossFire ★★★★★ ()
Ответ на: комментарий от bhfq

Ну это *nix платфома, так что не ошибся. Да и на Mac нет форума достойного.

Можно вас попросить, полностью объяснить скрипт. Что на входе, что на выходе, как работает, что делает, как запускать, возможные ошибки, что основное?

А то просто код это как то совсем не айс.

imirrori ()
Ответ на: комментарий от imirrori

Ну это *nix платфома, так что не ошибся.

Это не делает ей чести быть обсуждаемой здесь.

Что на входе

svn checkout http://vacuum-im.googlecode.com/svn/trunk/ vacuum-im-read-only

что на выходе

http://code.google.com/p/vacuum-im/downloads/list?can=2&q=opsys=OSX

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

Этот код не универсальный. Вам нужна часть Functions, она копирует бинарники Qt в app каталог, затем у всех бинарей вашей программы проверяет зависимости и меняет путь к Qt.

bhfq ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.