Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

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.

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ć.

r   e   k   l   a   m   a

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