cz.2| Jak to jest być deweloperem aplikacji wieloplatformowej - Deweloper vs Windows

Witam.

Zgodnie ze spisem treści kontynuuję serię, tym razem opowiem Wam o przygodzie budowania pliku binarnego EXE przy użyciu VirtualBox.

reklama

2. Ogólny proces paczkowania przez wirtualną maszynę

Na początku muszę pochwalić deweloperów projektu VirtualBox za świetną obsługę całego ich oprogramowania z poziomu shella - inaczej nie dałbym rady tego wystarczająco uprościć.

Dodatki VirtualBox dla systemu gościa również dużo wniosły do komfortu pracy pozwalając na dynamiczne skalowanie okna maszyny, ustawienie go na pełny ekran, czy na bardzo wygodne i wydajne udostępnianie plików po sambie.

1) Budowanie jednym kliknięciem - jak to działa?

Jak wcześniej chwaliłem deweloperów projektu VirtualBox to teraz pokażę za co dokładnie.

Listing build-windows.sh (Linux)

#!/bin/sh
subget_git="/home/webnull/Praca/python/subget" # katalog projektu
vm_name="Subget on windows" # nazwa maszyny

rm "$subget_git/setup.exe" # kasuje plik

# startuje maszynę
/usr/lib/virtualbox/VirtualBox --startvm "$vm_name" &

while [ True ]
do
	sleep 1 # odczekamy sekundę kolejną oczekując na zakończenie budowania

        # sprawdza czy budowanie zostało zakończone - czy istnieje wynik w postaci setup.exe w lokalnym katalogu
	if [ -f "$subget_git/setup.exe" ]
	then
		sleep 5 # trzeba mieć pewność czy zapis się nie urwie przy natychmiastowym odłączeniu, lepiej chwilę odczekać bo różnie z systemami plików bywa
		/usr/lib/virtualbox/VBoxManage controlvm "$vm_name" acpipowerbutton # wyłącza delikatnie system w maszynie naciskając na przycisk zasilania
		break
	fi
done

2) Budowanie paczki przy starcie systemu

W autostarcie systemu Windows XP siedzi skrót do pliku zapisanego w formacie batch.

Jego zawartość jest następująca:

f:\subget\windows\nsi-paths-build.py
ping 123.45.67.89 -n 1 -w 2000 > nul :: odpowiednik polecenia sleep
echo off
cd "c:\subget"
del "c:\Program Files\Subget\*" /Q
del "c:\subget\setup.exe" /Q
del "C:\Subget\build\exe.win32-2.7\*" /Q
copy f:\subget\usr c:\subget\usr
copy f:\alang-py\usr c:\subget\usr
copy f:\subget\subget.py c:\subget\subget.py
copy f:\alang-py\usr\share\alang\python\alang.py c:\subget\alang.py
copy f:\alang-py\usr\share\alang\python\alang.py c:\subget\usr\share\alang\python\alang.py
copy f:\alang-py\usr\share\alang\python\alang.py "C:\Subget\build\exe.win32-2.7\alang.py
del c:\subget\install.sh
del c:\subget\README
del "c:\subget\commit-copy"
del "c:\subget\install-dependencies.sh"
cd c:\subget
c:\subget\cx_freeze_build_windows.py build
"C:\Program Files\NSIS\makensis.exe" "f:\subget\windows\installer.nsi"
copy "c:\subget\setup.exe" "f:\subget\setup.exe"
f:\subget\setup.exe
pause

1> Generowanie listy plików do zapakowania dla instalatora NSIS
f:\subget\windows\nsi-paths-build.py, proces zostanie opisany w następnych częsciach serii

2> Budowanie pliku binarnego EXE z postaci kodu Pythona
c:\subget\cx_freeze_build_windows.py build

3> Tworzenie pliku setup.exe przez skrypt NSIS
"C:\Program Files\NSIS\makensis.exe" "f:\subget\windows\installer.nsi"
Ten podpunkt zostanie opisany w dalszej części serii według spisu treści.

4> Pora na testy - instalacja i uruchomienie programu
f:\subget\setup.exe

Najbardziej bawi mnie w Batchu brak polecenia sleep które by zatrzymało parser na X milisekund.

Zaraz ktoś powie, przecież jest ten cudowny PowerShell. No ale Panie i Panowie zapominamy o podstawowej rzeczy - Batch jest podstawową powłoką w systemie Windows. Podstawowa powłoka SH w systemach Uniksowych jest stukrotnie bardziej zaawansowana, któraś strona z nas wciąż żyje w erze kamienia łupanego.

Na stackoverflow.com pewien użytkownik podsunął pomysł aby wywołać polecenie ping podając nieistniejący adres maszyny i w timeoucie ustawić tyle czasu na ile chcemy zatrzymać parser - ręce opadają przy tak śmiesznym rozwiązaniu.

Windows (Batch):


ping 123.45.67.89 -n 1 -w 2000 > nul

Linux (Wszystkie powłoki):


sleep 2

3) Tworzenie plików binarnych

W zasadzie mogę na początku odpowiedzieć na pytanie - dlaczego budować plik binarny skoro można uruchomić aplikację bezpośrednio z pliku z rozszerzeniem .py?

1. Wymagałoby to instalacji Pythona w systemie jego bibliotek
2. W Windows nie można używać plików skryptowych w "Otwórz za pomocą" - można otrzymać komunikat "Nie jest prawidłową aplikacją systemu win32"

A teraz przejdę do rzeczy.
Program cx_freeze umożliwia pakowanie plików Pythona do pliku EXE oraz umieszczanie wszystkich wymaganych do działania bibliotek w jednym katalogu z aplikacją - bardzo przydatne, ale trochę niepraktyczne.

Jednak na samym starcie pojawia się wiele problemów - słaba dokumentacja cx_freeze powoduje, że człowiek przeszukuje całą sieć aby znaleźć opis podstawowych funkcji programu.

Po wielu godzinach przeszukiwania sieci znalazłem rozwiązania na swoje problemy i tak oto stworzyłem skrypt do budowy plików binarnych projektu.

from cx_Freeze import setup, Executable

import alang, os, sys

exe = Executable(
    script="subget.py",
    base="Win32GUI",
    icon = 'f:\\Subget\\windows\\icon.ico'
    )

includefiles = ['alang.py', 'usr']
includes = ['usr']
excludes = []
packages = ['usr.share.alang.python', '_socket', 'socket', 'httplib', 'subprocess', 'os', 'time', 'urllib', 'hashlib', 're', 'zipfile', 'xml', 'StringIO', 'struct', 'usr.share.subget.plugins.napiprojekt', 'usr.share.subget.plugins.napisy24', 'usr.share.subget.plugins.allsubs', 'usr.share.subget.plugins.napisy_info']
 
setup(
    name = "Subget",
    version = "0.6",
    description = "A simple Subtitle downloading application for Linux, Unix and Windows",
    appendScriptToExe = False,
    appendScriptToLibrary = False,
    options = {'build_exe': {'excludes':excludes,'packages':packages,'include_files':includefiles}}, 
    executables = [exe]
    )

Jednym z większych problemów cx_freeze jest potrzeba dodania wszystkich modułów dynamicznie ładowanych do projektu - owszem mogą one zostać automatycznie załadowane z plików projektu jednak co jeżeli projekt posiada wtyczki?

Jeżeli projekt posiada obsługę wtyczek to instalacja dodatkowej wtyczki może się okazać problemem, a mianowicie gdy zajdzie potrzeba użycia biblioteki niewymienionej wcześniej w projekcie to wtyczka nie ma prawa działać.

Powyższy skrypt po uruchomieniu poleceniem c:\subget\cx_freeze_build_windows.py build stworzy katalog build/exe.win32-2.7 w katalogu bieżącym. W zawartości znajdziemy plik wykonywalny .exe oraz masę bibliotek potrzebnych do jego uruchomienia.

Całość należy już tylko zapakować w instalator - a jak to zrobiłem to opiszę w następnej części.
 

Komentarze