Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Chiarimenti sulla compilazione di binari per windows su linux
Forum - C/C++ - Chiarimenti sulla compilazione di binari per windows su linux

Avatar
GN (Member)
Guru


Messaggi: 772
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 18:51
Martedì, 08/09/2015
Ciao a tutti, apro questo topic perchè vorrei chiarirmi alcuni dubbi.
Vorrei scrivere un programmino abbastanza semplice che sia leggero, cross-platform (Windows e Linux) e non richieda che sul PC dell'utente siano installati framework come Java o .NET, quindi sto cercando di utilizzare ed approfondire le mie molto basilari conoscenze del C. Ok, forse con "leggero, cross-platform e senza necessità di framework" chiedo troppo, comunque per ora ci provo, se non riuscirò a farlo pazienza.
Arrivando al dunque, per fare quello che ho descritto ho installato sulla mia VM con Ubuntu il compilatore MingW-w64 per poter compilare in un colpo solo sia la versione Windows che quella Linux come descritto in questo tutorial http://www.blogcompiler.com/2010/07/11/compile-for-windows ..., solo nella versione i686 in modo da poter poi distribuire un solo binario a 32 bit per Windows, visto che se ho capito bene sull'OS Microsoft, anche quando CPU e OS sono a 64 bit i binari a 32 bit girano senza problemi grazie a WOW64 (come ho già detto, l'applicazione sarà molto semplice e non dovrà effettuare operazioni molto CPU-intensive quindi penso che anche se non è ottimizzata non sia un problema).
Poi ho provato a testare l'ambiente di compilazione scrivendo un banalissimo hello world (include stdio.h e nel main fa un printf e ritorna 0) e questo makefile:
Codice sorgente - presumibilmente Plain Text

  1. all: app-win32.exe app-linux
  2.  
  3. dir:
  4.         mkdir build
  5.  
  6. app-win32.exe: dir
  7.         i686-w64-mingw32-gcc main.c -o build/$@
  8.  
  9. app-linux: dir
  10.         gcc main.c -o build/$@


Lanciando make nella cartella dove si trovano il makefile e main.c funziona tutto come previsto: viene creata la cartella build, e dentro di essa i due binari app-linux e app-win32.exe. Lanciando ./build/app-linux compare Hello world nella console, ed app-win32.exe funziona sia sul mio PC reale con Windows 8.1 a 64 bit che su una VM con Windows XP a 32 bit.
Siccome però sono abbastanza alle prime armi e so che se una cosa funziona non significa necessariamente che la si stia facendo nel modo giusto, vi vorrei chiedere se secondo voi sto sbagliando qualcosa, in particolare perchè ho notato una cosa un po' strana:
il binario linux (app-linux) pesa solo 8.4KB, mentre quello windows (app-win32.exe) pesa "ben" 108,6KB! Non che sia un problema, direi che finchè rimaniamo sotto 1 MB il requisito di "leggero" è ampiamente soddisfatto, però mi sembra strano che la versione Windows pesi più di 10 volte di quella per Linux.

Grazie mille a tutti e scusatemi se sto chiedendo cose banali, vorrei solo essere sicuro di non partire con il piede sbagliato :).

P.S. se ho capito bene, inoltre, con il makefile che ho scritto il binario linux funziona solo sull'architettura della CPU su cui è stato compilato quindi, siccome lavoro su hardware e OS a 64 bit e su linux l'"emulazione" della CPU 32 bit negli OS 64 bit non funziona out-of-the box come su Win, farei meglio a compilare e poi distribuire sia un "app-linux32" (aggiungendo -m32 ai CFLAGS come ho letto qui http://stackoverflow.com/questions/1272357/how-to-compile- ... che un "app-linux64" (quello che adesso  è "app-linux"), giusto?

Ultima modifica effettuata da GN il 08/09/2015 alle 18:54
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 12:04
Mercoledì, 09/09/2015
Interessante la differenza, riesci a mettere qui il dump dei due eseguibili?

PM Quote
Avatar
GN (Member)
Guru


Messaggi: 772
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 18:41
Giovedì, 10/09/2015
Ciao e grazie per aver risposto, ecco qui eseguibili (nella cartella build), makefile e sorgente: https://drive.google.com/file/d/0BwPAgYhCws1yLXZuRWpmSi1fTH ...

Se ho capito male cosa si intendeva per "dump" scusami per l'ignoranza.

PM Quote
Avatar
ZioCrocifisso (Member)
Pro


Messaggi: 135
Iscritto: 06/03/2013

Segnala al moderatore
Postato alle 23:35
Venerdì, 11/09/2015
A me non piace questo approccio, in genere uno non si aspetta che facendo "make" senza argomenti tenti di compilare su più piattaforme, dando pure un errore per quella sbagliata, se non c'è il cross compiler. Piuttosto puoi usare gli if.
Per quanto riguarda l'eseguibile, potrebbe essere che con MinGW la libreria standard venga linkata staticamente (glibc pesa).
Riguardo all'ultima domanda, quasi tutte le applicazioni su Linux vengono distribuite principalmente tramite il codice sorgente (che poi i pacchetti delle distribuzioni siano in genere binari è un altro discorso), quindi potresti fare lo stesso. Inoltre, puoi benissimo eseguire applicazioni x86 su Linux x86_64, bisogna solo installare le versioni a 32-bit delle librerie richieste. Se distribuisci i pacchetti binari nei formati dei vari gestori di pacchetti (deb, rpm, pkg, ecc.), puoi semplicemente specificarle come dipendenze.
Ad ogni modo il fatto che i SO possano emulare le applicazioni a 32-bit non è assolutamente un buon motivo per scegliere il 32-bit, dovresti distribuire i binari per entrambe le architetture, se proprio devi.

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 1:14
Sabato, 12/09/2015
Considera anche quello che ha detto ZioCrocifisso, comunque prova per curiosità a vedere cosa succede con questo Makefile
Codice sorgente - presumibilmente Plain Text

  1. all: app-win32.exe app-linux
  2.  
  3. dir:
  4.         mkdir -p build
  5.  
  6. FLAGS = -Os -fdata-sections -ffunction-sections -Wl,--gc-sections
  7.  
  8. app-win32.exe: dir
  9.         i686-w64-mingw32-gcc main.c $(FLAGS) -o build/$@
  10.  
  11. app-linux: dir
  12.         gcc main.c $(FLAGS) -o build/$@


PM Quote
Avatar
GN (Member)
Guru


Messaggi: 772
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 16:39
Sabato, 12/09/2015
Innanzitutto grazie mille a entrambi.

@ZioCrocifisso: sì, sono d'accordo sul fatto che il makefile così com'è sia molto elementare, vedrò di approfondire il funzionamento di make e di aggiustare il makefile usando target differenti per le diverse piattaforme, oppure gli if. Per il discorso delle architetture ok, penso che vedrò di compilare sia una versione x86 che una x64 per entrambe le piattaforme.

@Lumo: interessanti i flag che hai aggiunto, se ho capito bene dovrebbero fare delle ottimizzazioni, ho provato ma le dimensioni degli eseguibili variano di pochissimo (app-linux passa da 8.4KB a 8.1KB, mentre app-win32.exe da 108.6 a 108.7KB). Le manterrò comunque, probabilmente hanno un effetto quantificabile su programmi "reali" e non su un banale hello world.

Ultima modifica effettuata da GN il 12/09/2015 alle 16:40
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1620
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 18:29
Sabato, 12/09/2015
Se attivi l'ottimizzazione non puoi fare il debug. O almeno io non ci sono mai riuscito.....

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 19:29
Sabato, 12/09/2015
Testo quotato

Postato originariamente da TheDarkJuster:

Se attivi l'ottimizzazione non puoi fare il debug. O almeno io non ci sono mai riuscito.....  


A parte che in genere non si rilascia l'eseguibile con i simboli di debug dentro, se su gcc usi -Og insieme a -g dovrebbe andare bene.

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1620
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 20:15
Sabato, 12/09/2015
Ah, grazie! Buono a sapersi!

PM Quote