Newsgroup: it.comp.os.linux.development
Titolo: -D_FILE_OFFSET_BITS=64 dove va messa (makefile) ?

Ciao,
ho un progetto con make. La macro di cui sopra va messa in 
makefile.am
o in 
configure.ac
 affinchè venga prodotto il Makefile con tale macro
??
Grazie,
--
Colossus
Xarchiver, a GTK2 only archive manager -
http://xarchiver.sourceforge.net
Cpsed, a Linux OpenGL 3D scene editor - 
http://cpsed.sourceforge.net
Mizio, a QT proxy hunter scanner tool - 
http://mizio.sourceforge.net

 o in 
configure.ac
 affinchè venga prodotto il Makefile con tale macro
Dal Makefile.am di 
yex.sf.net
bin_PROGRAMS = yex
yex_CFLAGS = @CFLAGS@ @LIBUSB_CFLAGS@
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! Drink To Your Brothers Who Are Never To Fall, We Are Brothers Of Metal
  		Here In The Hall! !>- Manowar - Brothers Of Metal PT1

Ti ringrazio, mi hanno detto della macro AC_SYS_LARGEFILE da mettere in
configure.ac
 che "dovrebbe" fare tutto lei. Sono costretto ad usarla e
non aggiungere manualmente il -D in questione perchè aggiungo files
continuamente al progetto per cui quando lancio autoconf e automake
verrebbe cancellata.


 verrebbe cancellata.
??? Qui non ho capito.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! I Never Wanted To Be What They Told Me To Be
  		Fulfill My Fate Then I'll Be Free >!- Blind Guardian - Mordred's Song

 > verrebbe cancellata.
Usando make e company (autoheader,autoconf,automake) non posso
aggiungere dei flag manualmente al makefile, perchè verrebbero
cancellati da un successivo autoconf o automake ( che sono obbligato a
lanciare qualora aggiungessi nuovi files al progetto).


 lanciare qualora aggiungessi nuovi files al progetto).
puoi metterli dentro CFLAGS nel 
makefile.am
, per quanto imho la macro
dell'autoconf mi sembra migliore, perche' dovrebbe anche controllare al
configure che sia supportata.

 configure che sia supportata.
Si, questo è un workaround, grazie.


Ok, ho messo nel 
configure.ac
 questo:
CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES"


 CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES"
aspetta, io ti dicevo di mettere AC_SYS_LARGEFILE in 
configure.in
perche' cosi' dovrebbe aggiungere da solo _FILE_OFFSET_BITS=64

 2GB. La devi obbligatoriamente mettere nei CPPFLAGS. Ci ho sbattuto parecchio fidati !


>2GB. La devi obbligatoriamente mettere nei CPPFLAGS. Ci ho sbattuto parecchio fidati !
ma scusa eh, nei file non hai in testa una cosa tipo
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
?

Si, ma quando davo make l'output era così:
[gt@Paradise Xarchiver-0.4]$ make
make  all-recursive
make[1]: Entering directory `/home/gt/Projects/Xarchiver-0.4'
Making all in src
make[2]: Entering directory `/home/gt/Projects/Xarchiver-0.4/src'
if gcc -DHAVE_CONFIG_H -I. -I. -I..
-DPACKAGE_DATA_DIR=\""/usr/local/share"\" -D
PACKAGE_LOCALE_DIR=\""/usr/local/share/locale"\" -I/usr/include/gtk-2.0
-I/usr/l
ib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo
-I/usr/include/pa
ngo-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  -g -O2 -MT
interface.o -MD -MP -MF ".deps/interface.Tpo" -
c -o interface.o interface.c; \
then mv -f ".deps/interface.Tpo" ".deps/interface.Po"; else rm -f
".deps/interfa
ce.Tpo"; exit 1; fi
gcc  -g -O2   -o xarchiver  main.o support.o interface.o callbacks.o
arj.o zip.o rar.o rpm.o bzip2.o gzip.o tar.o iso.o 7zip.o -lgtk-x11-2.0
-lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0
-lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
make[2]: Leaving directory `/home/gt/Projects/Xarchiver-0.4/src'
Making all in po
Come puoi vedere mancano -D_FILE_OFFSET_BITS=64 e -D_LARGE_FILES
passate al compilatore per cui la stat "funzionava" a 32 bit. Se noti
nel sorgente delle libcdio e delle wxwidgets, nei files 
configure.ac
 ci
sono degli if che impostano CPPFLAGS con le macro di cui sopra. Se non
le metti nei CPPFLAGS non compila col supporto per i files grandi. Ti
riporto cosa c'è scritto nel manuale di autoconf alla voce
AC_SYS_LARGEFILE:
Macro: AC_SYS_LARGEFILE
    Arrange for large-file support. On some hosts, one must use special
compiler options to build programs that can access large files. Append
any such options to the output variable CC. Define _FILE_OFFSET_BITS
and _LARGE_FILES if necessary.
Ciao,



ma quelle macro non vanno passate al compilatore, servono solo al
preprocessore per smandrupparsi i file di include. Quindi se metti
l'include di config.h prima di ogni altro include funziona.

>Quindi se metti l'include di config.h prima di ogni altro include funziona.
Il manuale di autoconf che ti ho quotato non è d'accordo, comunque
prova ad usare la stat per ricavare le dimensioni di un file più
grande di 2 gigabyte solo con il config.h e ti convincerai.


 grande di 2 gigabyte solo con il config.h e ti convincerai.
due cose
1) ho le libc troppo nuove, funziona anche senza:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main () {
        struct stat s;
        stat("/tmp/file.grande", &s);
        printf ("size: %lu\n", s.st_size);
        return 0;
}
bott@pcimg12:/tmp$ du -m file.grande
3000    file.grande
bott@pcimg12:/tmp$ ./test
size: 
3145728000
2) prova questo:
metti la macro in 
configure.in
, in testa al file metti
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
e subito dopo ci metti
#include <features.h>
poi includi tutto il resto. Adesso ti spiego perche'
la macro autoconf ti porta ad avere in config.h una riga tipo
#define _FILE_OFFSET_BITS 64
che viene incluso dal programma. Il file /usr/include/features.h
contiene tra le varie cose
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
# define __USE_FILE_OFFSET64    1
#endif
quindi ti definisce la macro __USE_FILE_OFFSET64 che, per esempio in
unistd viene usata in righe tipo
# ifndef __off_t_defined
#  ifndef __USE_FILE_OFFSET64
typedef __off_t off_t;
#  else
typedef __off64_t off_t;
#  endif
#  define __off_t_defined
# endif
# if defined __USE_LARGEFILE64 && !defined __off64_t_defined
typedef __off64_t off64_t;
#  define __off64_t_defined
# endif
ma ancora piu' interessante e' fcntl.h, dove hai roba del tipo
#ifndef __USE_FILE_OFFSET64
extern int open (__const char *__file, int __oflag, ...) __nonnull ((1));
#else
# ifdef __REDIRECT
extern int __REDIRECT (open, (__const char *__file, int __oflag, ...),
open64)
     __nonnull ((1));
# else
#  define open open64
# endif
#endif
#ifdef __USE_LARGEFILE64
extern int open64 (__const char *__file, int __oflag, ...) __nonnull ((1));
#endif
e quindi hai la selezione delle funzioni normali o a 64 bit.

Ottavio Campana wrote:
dimenticavo:
passare -DVARIABILE=X a gcc equivale a mettere in testa del file un
#define VARIABILE X
non fa nient'altro.

Ottavio, il tuo codice al punto 1 funziona correttamente anche sulla
mia linux box senza nessuna macro. Se modifico l'if in questo modo
però:
if ( stat("/Stuff2/Fahrenheit.iso", &s) < 0) printf ("Error:
%s\n",strerror(errno));
            else printf ("size: %lu\n", s.st_size);
Mi da l'errore "Value too large for defined data type". A questo punto
sono attonito. Il controllo degli errori lo debbo implementare, ma se
uso files più grandi di 2GB senza le macro per il supporto ai files
grandi, ottengo l'errore che non otterrei se non implementassi il
controllo degli errori ! Perchè questo comportamento della stat ?


Colossus wrote:
ho fatto questa prova:
#define _FILE_OFFSET_BITS     64
#define _LARGE_FILES
#include <features.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main () {
        struct stat s;
        int i;
        i = stat("/tmp/file.grande", &s);
        printf ("size: %lu\n", s.st_size);
        printf ("i = %d\n");
        printf ("errno = %d\n", errno);
        perror ("errore: ");
        return 0;
}
che compilato con gcc test.c -o test ed eseguito da':
bott@pcimg12:/tmp$ ./test
size: 
3145728000
i = -1149239296
errno = 0
errore: : Success
bott@pcimg12:/tmp$
Se compilo
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main () {
        struct stat s;
        int i;
        i = stat("/tmp/file.grande", &s);
        printf ("size: %lu\n", s.st_size);
        printf ("i = %d\n");
        printf ("errno = %d\n", errno);
        perror ("errore: ");
        return 0;
}
col comando gcc -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES test.c -o test
ottengo
bott@pcimg12:/tmp$ ./test
size: 
3145728000
i = -1149239296
errno = 0
errore: : Success
bott@pcimg12:/tmp$
Sono la stessa cosa.
Ti ripeto: e' importante che l'include del config.h sia la prima cosa
(in questo caso e' stato simulato dai due define) e che come seconda ci
sia l'inclusione di features.h. In questo modo hai fin da subito la
definizione delle macro dal config.h e l'attivazione immediatamente
successiva della macro __USE_FILE_OFFSET64 da features.h. Poi includi
quello che vuoi, e tutto si trovera' quest'ultima macro e si comportera'
di conseguenza. Piuttosto e' brutto il valore della variabile i, che
stando alla manpage dovrebbe essere 0. Quindi non ti resta che
controllare su errno==0. Non mi chiedere perche', lo ignoro. Potresti
chiedere sulla lista della libc.

 chiedere sulla lista della libc.
Ehm, guarda meglio il tuo codice. Hai usato la printf senza una
variabile !


 variabile !
ok, la riga dalla printf della i ok, ma noon era quello che dovevi
vedere. Quello che devi capire e' che se includi fin dall'inizio
config.h fatto dagli autotools le due costanti definite poi modificano
il comportamento della libc e che e' lo stesso includere il config.h
generato con la macro che mettere il define nei flag del compilatore.
Era solo per spiegarti come funziona la libc e come fare l'include giusto.

Si, l'avevo capito ! Grazie comunque del codice e della esauriente
spiegazione, mi è stata utile.
