fixed setting of -DMODULE for 2.6
[comedi.git] / m4 / as-linux.m4
1 dnl as-linux.m4 0.0.1
2 dnl autostars m4 macro for detecting a Linux source tree (or
3 dnl equivalent) for compiling modules.
4 dnl
5 dnl David Schleef <ds@schleef.org>
6 dnl Frank Mori Hess <fmhess@users.sourceforge.net>
7 dnl thomas@apestaart.org
8 dnl
9 dnl AS_LINUX()
10 dnl
11 dnl this macro adds the options --with-linuxdir and --with-linux-config.
12 dnl this macro defines:
13 dnl LINUX_DIR
14 dnl   The directory where the Linux source resides.
15 dnl CONFIG_FILE
16 dnl   The Linux config file
17 dnl LINUX_ARCH
18 dnl   $(ARCH) in kernel Makefiles
19 dnl LINUX_AFLAGS
20 dnl   $(AFLAGS) in kernel Makefiles
21 dnl LINUX_LDFLAGS
22 dnl   Linker flags used by Linux
23 dnl LINUX_ARFLAGS
24 dnl   Archiver flags used by Linux
25 dnl LINUX_CROSS_COMPILE
26 dnl   Cross-compiler prefix, if any. (example: "powerpc-linux-")
27 dnl LINUX_KERNELRELEASE
28 dnl   Kernel release name (2.4.5-pre4-ac5-rmk), $(KERNELRELEASE) in
29 dnl   Linux Makefiles.
30 dnl LINUX_CFLAGS
31 dnl   CFLAGS used by Linux.  Includes both $CFLAGS and $MODFLAGS from
32 dnl   kernel Makefiles. Also includes warnings and optimization.
33 dnl LINUX_CC
34 dnl   Compiler used by Linux.
35 dnl LINUX_LD
36 dnl   Path to linker (possibly with options) used by Linux.
37 dnl LINUX_AS
38 dnl   Assembler used by Linux.
39 dnl LINUX_MODULE_EXT
40 dnl   Module extension (.o or .ko)
41 dnl
42 dnl 
43 dnl End of search list.
44
45
46
47 dnl check if we can find a source dir for the Linux kernel
48 dnl defines LINUX_DIR to the absolute location of a usable kernel source tree
49 AC_DEFUN([AS_LINUX_DIR],
50 [
51         AC_ARG_WITH([linuxdir],
52                 [AC_HELP_STRING([--with-linuxdir=DIR],
53                         [specify path to Linux source directory])],
54                 [LINUX_DIR="${withval}"],
55                 [LINUX_DIR=default])
56
57         if test "${LINUX_DIR}" != "default" ; then
58                 AS_TRY_LINUX_DIR([${LINUX_DIR}], , AC_MSG_ERROR([Linux dir not found]) )
59         fi
60
61         if test "${LINUX_DIR}" = "default" ; then
62                 dir="/lib/modules/`uname -r`/build";
63                 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
64         fi
65         if test "${LINUX_DIR}" = "default" ; then
66                 dir="../linux";
67                 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
68         fi
69         if test "${LINUX_DIR}" = "default" ; then
70                 dir="/usr/src/linux";
71                 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
72         fi
73
74         if test "${LINUX_DIR}" = "default" ; then
75                 AC_MSG_ERROR([Linux source directory not found])
76         fi
77
78         AC_SUBST(LINUX_DIR)
79 ])
80
81 dnl check if the given candidate path for a linux source tree is usable
82 AC_DEFUN([AS_TRY_LINUX_DIR],
83         [AC_MSG_CHECKING(for Linux in $1)
84
85         if test -f "$1/Makefile" ; then
86                 result=yes
87                 $2
88         else
89                 result="not found"
90                 $3
91         fi
92
93         AC_MSG_RESULT($result)
94 ])
95
96 dnl check if we can find a config file for the Linux kernel
97 dnl defines CONFIG_FILE to the absolute location of a usable kernel source tree
98 dnl uses LINUX_DIR to find either .config or decent configs in configs/
99 AC_DEFUN([AS_CONFIG_FILE],
100 [
101         AC_ARG_WITH([linux-config],
102                 [AC_HELP_STRING([--with-linux-config=FILE],
103                         [specify path to Linux configuration file])],
104                 [CONFIG_FILE="${withval}"],
105                 [CONFIG_FILE=default])
106
107         if test "${CONFIG_FILE}" != "default" ; then
108                 AS_TRY_CONFIG_FILE([${CONFIG_FILE}], , AC_MSG_ERROR([Linux config not found]) )
109         fi
110
111         dnl if default specified, first check for the regular .config file
112         dnl in LINUX_DIR created by manual configuration
113         if test "${CONFIG_FILE}" = "default" ; then
114                 file="$LINUX_DIR/.config";
115                 AS_TRY_CONFIG_FILE([${file}], [CONFIG_FILE=${file}], )
116         fi
117         dnl second, try to guess what config file to use for the current kernel
118         if test "${CONFIG_FILE}" = "default" ; then
119                 dnl Red Hat stores configuration files for their built kernels
120                 dnl named kernel-(version)-(arch)(extra).config
121                 dnl where arch is athlon, i386, i586, i686, x86_64
122                 dnl and (extra) is empty or -smp, -BOOT, -bigmem
123                 dnl haven't seen combinations of extra yet as of FC1
124                 version=`uname -r | cut -d- -f1`
125                 machine=`uname -m`
126                 extra=
127                 uname -r | grep smp && extra="-smp"
128                 uname -r | grep bigmem && extra="-bigmem"
129                 uname -r | grep BOOT && extra="-BOOT"
130                 file="$LINUX_DIR/configs/kernel-$version-$machine$extra.config"
131                 AS_TRY_CONFIG_FILE([${file}], [CONFIG_FILE=${file}], )
132         fi
133         if test "${CONFIG_FILE}" = "default" ; then
134                 AC_MSG_ERROR([
135 The kernel source tree at ${LINUX_DIR} is not configured,
136 and no configuration files in config/ matching your kernel were found.
137 Fix before continuing or specify a config file using --with-linux-config.])
138         fi
139
140         AC_SUBST(CONFIG_FILE)
141 ])
142
143 dnl check if the given candidate config file is usable
144 AC_DEFUN([AS_TRY_CONFIG_FILE],
145         [AC_MSG_CHECKING(for configuration in $1)
146
147         if test -f "$1" ; then
148                 result=yes
149                 $2
150         else
151                 result="not found"
152                 $3
153         fi
154
155         AC_MSG_RESULT($result)
156 ])
157
158 dnl check if RED_HAT_LINUX_KERNEL is defined
159 dnl RH/Fedora defines this in linux/rhconfig.h, included from linux/version.h
160 dnl if this is present, a few extra defines need to be present to make sure
161 dnl symbol versioning is correct
162 dnl uses LINUX_DIR to find rhconfig.h
163 AC_DEFUN([AS_CHECK_REDHAT],
164 [
165         AC_MSG_CHECKING(Red Hat/Fedora kernel)
166         HAVE_REDHAT_KERNEL=false
167         ac_save_CFLAGS="$CFLAGS"
168         CFLAGS="$CFLAGS -I${LINUX_DIR}/include/linux"
169         AC_COMPILE_IFELSE(AC_LANG_PROGRAM([
170 #include "rhconfig.h"
171 int code = RED_HAT_LINUX_KERNEL;
172         ]),
173         AC_MSG_RESULT(found); HAVE_REDHAT_KERNEL=true,
174         AC_MSG_RESULT(not found))
175         dnl restore CFLAGS
176         CFLAGS="$ac_save_CFLAGS"
177
178         dnl check for Red Hat define flags to use - see /sbin/mkkerneldoth
179
180         dnl initialize the booleans we want to detect
181         ENTERPRISE='0'
182         SMP='0'
183         UP='0'
184         BIGMEM='0'
185         HUGEMEM='0'
186
187         dnl get variables from the currently running kernel as default 
188         KERNEL_TYPE=`uname -r | sed 's_^.*\(smp\|enterprise\|bigmem\|hugemem\)$_-\1_;t;s_.*__;'`
189         KERNEL_RELEASE=`uname -r | sed 's|smp\|enterprise\|bigmem\|hugemem||g'`
190         KERNEL_ARCH=`uname -m`
191
192         dnl check the config file and override KERNEL_ARCH
193         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_M386, KERNEL_ARCH=i386)
194         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_M586, KERNEL_ARCH=i586)
195         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_M686, KERNEL_ARCH=i686)
196         dnl for some reason the i686 bigmem config file has PENTIUM
197         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_MPENTIUMIII, KERNEL_ARCH=i686)
198         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_MK7, KERNEL_ARCH=athlon)
199
200         dnl check the config file and override KERNEL_TYPE
201         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_SMP, KERNEL_TYPE=-smp)
202         dnl bigmem is also smp, so this check is done after smp to override
203         AS_CHECK_LINUX_CONFIG_OPTION(CONFIG_HIGHMEM64G, KERNEL_TYPE=-bigmem)
204
205         dnl FIXME: need to check hugemem and enterprise config files, which
206         dnl aren't provided in Fedora Core 1 !
207
208         case "$KERNEL_TYPE" in
209                 -smp) SMP='1';;
210                 -enterprise) ENTERPRISE='1';;
211                 -bigmem) BIGMEM='1';;
212                 -hugemem) HUGEMEM='1';;
213                 *) UP='1';;
214         esac
215         REDHAT_CFLAGS="-D__MODULE_KERNEL_$KERNEL_ARCH=1"
216         REDHAT_CFLAGS="$REDHAT_CFLAGS -D__BOOT_KERNEL_ENTERPRISE=$ENTERPRISE"
217         REDHAT_CFLAGS="$REDHAT_CFLAGS -D__BOOT_KERNEL_UP=$UP"
218         REDHAT_CFLAGS="$REDHAT_CFLAGS -D__BOOT_KERNEL_SMP=$SMP"
219         REDHAT_CFLAGS="$REDHAT_CFLAGS -D__BOOT_KERNEL_BIGMEM=$BIGMEM"
220         REDHAT_CFLAGS="$REDHAT_CFLAGS -D__BOOT_KERNEL_HUGEMEM=$HUGEMEM"
221 ])
222
223 dnl main entry point
224 dnl checks the version, and figures out all flags to use to make modules.
225 AC_DEFUN([AS_LINUX],
226 [
227         AS_LINUX_DIR()
228         AS_CONFIG_FILE()
229         AS_CHECK_REDHAT()
230
231         AC_MSG_CHECKING([Linux major/minor version])
232
233         if [[ ! -f "${LINUX_DIR}/include/linux/version.h" ]];then
234                 AC_MSG_ERROR([The header file include/linux/version.h does not exist.
235 For 2.6 kernels, it can be generated by running 'make prepare' in
236 the kernel source directory.])
237         fi
238         dnl the next set of tests is for figuring out version major/minor
239         dnl we make sure we have the right version.h by faking out CFLAGS
240         ac_save_CFLAGS="$CFLAGS"
241         CFLAGS="$CFLAGS -I${LINUX_DIR}/include/linux"
242         dnl make sure we find version.h and it contains LINUX_VERSION_CODE
243         AC_COMPILE_IFELSE(AC_LANG_PROGRAM([
244 #include "version.h"
245 int code = LINUX_VERSION_CODE;
246 ]),
247  :, AC_MSG_ERROR([${LINUX_DIR}/include/linux/version.h does not contain LINUX_VERSION_CODE]))
248
249
250         dnl figure out the linux kernel version major and minor
251         dnl using the LINUX_VERSION_CODE defined in include/linux/version.h
252         AC_RUN_IFELSE(AC_LANG_PROGRAM([
253 #include "version.h"
254 #define KERNEL_VERSION_MAJOR(code) ((code) >> 16)
255 ],[
256   return KERNEL_VERSION_MAJOR(LINUX_VERSION_CODE);
257 ]),
258                 LINUX_VERSION_MAJOR=0,
259                 LINUX_VERSION_MAJOR=$?)
260         AC_RUN_IFELSE(AC_LANG_PROGRAM([
261 #include "version.h"
262 #define KERNEL_VERSION_MINOR(code) (((code) >> 8) & 0xff)
263 ],[
264   return KERNEL_VERSION_MINOR(LINUX_VERSION_CODE);
265 ]),
266                 LINUX_VERSION_MINOR=0,
267                 LINUX_VERSION_MINOR=$?)
268         AC_MSG_RESULT($LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR)
269         dnl restore CFLAGS
270         CFLAGS="$ac_save_CFLAGS"
271
272         case $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR in
273                 2.6)
274                         AS_LINUX_2_6()
275                         ;;
276                 2.[[01234]])
277                         AS_LINUX_2_4()
278                         ;;
279                 *)
280                         AC_MSG_ERROR([Unknown Linux major.minor $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR])
281                         ;;
282         esac
283 ])
284
285 AC_DEFUN([AS_LINUX_2_6],
286 [
287         AC_MSG_CHECKING(for Linux CFLAGS)
288
289         tmpdir="`pwd`/tmp-noicrwa"
290
291         rm -rf ${tmpdir} || :
292         mkdir ${tmpdir}
293
294         cat >${tmpdir}/Makefile <<EOF
295 obj-m += fake.o
296
297 \$(obj)/fake.c: flags
298         touch \$(obj)/fake.c
299
300 .PHONY: flags
301 flags:
302         echo LINUX_ARCH=\"\$(ARCH)\" >>\$(obj)/flags
303         echo LINUX_AFLAGS=\"\$(AFLAGS)\" | sed 's_Iinclude_I"\$(LINUXDIR)/include"_g'>>\$(obj)/flags
304         echo LINUX_LDFLAGS=\"\" >>\$(obj)/flags
305         echo LINUX_ARFLAGS=\"\$(ARFLAGS)\" >>\$(obj)/flags
306         echo LINUX_CROSS_COMPILE=\"\$(CROSS_COMPILE)\" >>\$(obj)/flags
307         echo LINUX_KERNELRELEASE=\"\$(KERNELRELEASE)\" >>\$(obj)/flags
308         echo LINUX_CFLAGS=\"\$(CFLAGS)\" | sed 's_Iinclude_I"\$(LINUXDIR)/include"_g'>>\$(obj)/flags
309         echo LINUX_CFLAGS_MODULE=\"\$(CFLAGS_MODULE)\" >>\$(obj)/flags
310         echo LINUX_CC=\"\$(CC)\" >>\$(obj)/flags
311         echo LINUX_LD=\"\$(LD) \$(LDFLAGS)\" >>\$(obj)/flags
312         echo LINUX_AS=\"\$(AS)\" >>\$(obj)/flags
313 EOF
314
315         echo ${MAKE-make} -C ${LINUX_DIR} V=1 SUBDIRS=${tmpdir} LINUXDIR=${LINUX_DIR} MODVERDIR=${tmpdir} modules >&5 2>&5
316         ${MAKE-make} -C ${LINUX_DIR} V=1 SUBDIRS=${tmpdir} LINUXDIR=${LINUX_DIR} MODVERDIR=${tmpdir} modules >&5 2>&5
317         . ${tmpdir}/flags
318         rm -rf ${tmpdir}
319
320         LINUX_MODULE_EXT=".ko"
321
322         LINUX_CFLAGS="$LINUX_CFLAGS $LINUX_CFLAGS_MODULE"
323
324         AC_SUBST(LINUX_ARCH)
325         AC_SUBST(LINUX_AFLAGS)
326         AC_SUBST(LINUX_LDFLAGS)
327         AC_SUBST(LINUX_ARFLAGS)
328         AC_SUBST(LINUX_CROSS_COMPILE)
329         AC_SUBST(LINUX_KERNELRELEASE)
330         AC_SUBST(LINUX_CFLAGS)
331         AC_SUBST(LINUX_CC)
332         AC_SUBST(LINUX_LD)
333         AC_SUBST(LINUX_AS)
334         AC_SUBST(LINUX_MODULE_EXT)
335
336         AC_MSG_RESULT([ok])
337 ])
338
339
340 AC_DEFUN([AS_LINUX_2_4],
341 [
342         AC_MSG_CHECKING(for Linux 2.4 make flags)
343         dnl we try to figure out the CFLAGS by invoking the Makefile on
344         dnl a test dir
345         dnl we use the correct config file by substituting the MAKEFILES
346         dnl Makefile variable, which originally points to .config
347
348         if [[ ! -f "${LINUX_DIR}/.hdepend" ]];then
349                 AC_MSG_ERROR([
350 You need to run 'make dep' on the kernel source before continuing.])
351         fi
352
353         TMPFILE=`mktemp /tmp/linux.XXXXXXXX` || exit 1
354
355         POPDIR=`(pwd)`
356         cd ${LINUX_DIR}
357 ( sed "s|\.config|${CONFIG_FILE}|g" Makefile && cat <<EOF ) | make -f - get_cflags > ${TMPFILE}
358
359 get_cflags:
360         @echo LINUX_ARCH=\"\$(ARCH)\"
361         @echo LINUX_AFLAGS=\"\$(AFLAGS)\" | sed 's_Iinclude_I\"\$(LINUXDIR)/include\"_g'
362         @echo LINUX_LDFLAGS=\"\"
363         @echo LINUX_ARFLAGS=\"\$(ARFLAGS)\"
364         @echo LINUX_CROSS_COMPILE=\"\$(CROSS_COMPILE)\"
365         @echo LINUX_KERNELRELEASE=\"\$(KERNELRELEASE)\"
366         @echo LINUX_CFLAGS=\"\$(CFLAGS)\" | sed 's_Iinclude_I\"\$(LINUXDIR)/include\"_g'
367         @echo LINUX_MODFLAGS=\"\$(MODFLAGS)\"
368         @echo LINUX_CC=\"\$(CC)\"
369         @echo LINUX_LD=\"\$(LD) \$(LDFLAGS)\"
370         @echo LINUX_AS=\"\$(AS)\"
371 EOF
372         . ${TMPFILE}
373         rm -rf ${TMPFILE}
374         cd $POPDIR
375
376         LINUX_MODULE_EXT=".o"
377
378         LINUX_CFLAGS="$LINUX_CFLAGS $LINUX_MODFLAGS"
379
380         dnl if we have REDHAT_CFLAGS, put them in LINUX_CFLAGS
381         if test "x$REDHAT_CFLAGS" != "x";
382         then
383                 LINUX_CFLAGS="$LINUX_CFLAGS $REDHAT_CFLAGS"
384         fi
385         AC_SUBST(LINUX_ARCH)
386         AC_SUBST(LINUX_AFLAGS)
387         AC_SUBST(LINUX_LDFLAGS)
388         AC_SUBST(LINUX_ARFLAGS)
389         AC_SUBST(LINUX_CROSS_COMPILE)
390         AC_SUBST(LINUX_KERNELRELEASE)
391         AC_SUBST(LINUX_CFLAGS)
392         AC_SUBST(LINUX_CC)
393         AC_SUBST(LINUX_LD)
394         AC_SUBST(LINUX_AS)
395         AC_SUBST(LINUX_MODULE_EXT)
396
397         AC_MSG_RESULT([ok])
398
399         AC_MSG_CHECKING(for Linux 2.4 CFLAGS)
400         AC_MSG_RESULT($LINUX_CFLAGS)
401         AC_MSG_CHECKING(for Linux 2.4 LDFLAGS)
402         AC_MSG_RESULT($LINUX_LDFLAGS)
403 ])
404
405 AC_DEFUN([AS_CHECK_LINUX_CONFIG_OPTION],
406 [
407         AC_MSG_CHECKING([Linux config option $1])
408
409         if grep '^$1=y$' ${CONFIG_FILE} >/dev/null 2>/dev/null; then
410                 result=yes
411                 $2
412         else if grep '^$1=m$' ${CONFIG_FILE} >/dev/null 2>/dev/null; then
413                 result=module
414                 $3
415         else
416                 result=no
417                 $4
418         fi
419         fi
420
421         AC_MSG_RESULT([$result])
422 ])
423
424 AC_DEFUN([AS_LINUX_CONFIG_OPTION],
425 [
426         AS_CHECK_LINUX_CONFIG_OPTION([$1],
427                 [$1=yes],
428                 [$1=module],
429                 [$1=no])
430
431         AM_CONDITIONAL([$1],[test "${$1}" = yes])
432 ])
433
434 AC_DEFUN([AS_LINUX_CONFIG_OPTION_MODULE],
435 [
436         AS_CHECK_LINUX_CONFIG_OPTION([$1],
437                 [$1=yes],
438                 [$1=module],
439                 [$1=no])
440
441         AM_CONDITIONAL([$1],[test "${$1}" = yes -o "${$1}" = module])
442 ])
443