2 dnl autostars m4 macro for detecting a Linux source tree (or
3 dnl equivalent) for compiling modules.
5 dnl David Schleef <ds@schleef.org>
6 dnl Frank Mori Hess <fmhess@users.sourceforge.net>
7 dnl thomas@apestaart.org
11 dnl this macro adds the options --with-linuxdir and --with-linux-config.
12 dnl this macro defines:
14 dnl The directory where the Linux source resides.
16 dnl The Linux config file
18 dnl $(ARCH) in kernel Makefiles
20 dnl $(AFLAGS) in kernel Makefiles
22 dnl Linker flags used by Linux
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
31 dnl CFLAGS used by Linux. Includes both $CFLAGS and $MODFLAGS from
32 dnl kernel Makefiles. Also includes warnings and optimization.
34 dnl Compiler used by Linux.
36 dnl Path to linker (possibly with options) used by Linux.
38 dnl Assembler used by Linux.
40 dnl Module extension (.o or .ko)
43 dnl End of search list.
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],
51 AC_ARG_WITH([linuxdir],
52 [AC_HELP_STRING([--with-linuxdir=DIR],
53 [specify path to Linux source directory])],
54 [LINUX_DIR="${withval}"],
57 if test "${LINUX_DIR}" != "default" ; then
58 AS_TRY_LINUX_DIR([${LINUX_DIR}], , AC_MSG_ERROR([Linux dir not found]) )
61 if test "${LINUX_DIR}" = "default" ; then
62 dir="/lib/modules/`uname -r`/build";
63 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
65 if test "${LINUX_DIR}" = "default" ; then
67 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
69 if test "${LINUX_DIR}" = "default" ; then
71 AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], )
74 if test "${LINUX_DIR}" = "default" ; then
75 AC_MSG_ERROR([Linux source directory not found])
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)
85 if test -f "$1/Makefile" ; then
93 AC_MSG_RESULT($result)
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],
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])
107 if test "${CONFIG_FILE}" != "default" ; then
108 AS_TRY_CONFIG_FILE([${CONFIG_FILE}], , AC_MSG_ERROR([Linux config not found]) )
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}], )
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`
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}], )
133 if test "${CONFIG_FILE}" = "default" ; then
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.])
140 AC_SUBST(CONFIG_FILE)
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)
147 if test -f "$1" ; then
155 AC_MSG_RESULT($result)
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],
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;
173 AC_MSG_RESULT(found); HAVE_REDHAT_KERNEL=true,
174 AC_MSG_RESULT(not found))
176 CFLAGS="$ac_save_CFLAGS"
178 dnl check for Red Hat define flags to use - see /sbin/mkkerneldoth
180 dnl initialize the booleans we want to detect
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`
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)
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)
205 dnl FIXME: need to check hugemem and enterprise config files, which
206 dnl aren't provided in Fedora Core 1 !
208 case "$KERNEL_TYPE" in
210 -enterprise) ENTERPRISE='1';;
211 -bigmem) BIGMEM='1';;
212 -hugemem) HUGEMEM='1';;
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"
224 dnl checks the version, and figures out all flags to use to make modules.
231 AC_MSG_CHECKING([Linux major/minor version])
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.])
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([
245 int code = LINUX_VERSION_CODE;
247 :, AC_MSG_ERROR([${LINUX_DIR}/include/linux/version.h does not contain LINUX_VERSION_CODE]))
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([
254 #define KERNEL_VERSION_MAJOR(code) ((code) >> 16)
256 return KERNEL_VERSION_MAJOR(LINUX_VERSION_CODE);
258 LINUX_VERSION_MAJOR=0,
259 LINUX_VERSION_MAJOR=$?)
260 AC_RUN_IFELSE(AC_LANG_PROGRAM([
262 #define KERNEL_VERSION_MINOR(code) (((code) >> 8) & 0xff)
264 return KERNEL_VERSION_MINOR(LINUX_VERSION_CODE);
266 LINUX_VERSION_MINOR=0,
267 LINUX_VERSION_MINOR=$?)
268 AC_MSG_RESULT($LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR)
270 CFLAGS="$ac_save_CFLAGS"
272 case $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR in
280 AC_MSG_ERROR([Unknown Linux major.minor $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR])
285 AC_DEFUN([AS_LINUX_2_6],
287 AC_MSG_CHECKING(for Linux CFLAGS)
289 tmpdir="`pwd`/tmp-noicrwa"
291 rm -rf ${tmpdir} || :
294 cat >${tmpdir}/Makefile <<EOF
297 \$(obj)/fake.c: 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
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
320 LINUX_MODULE_EXT=".ko"
322 LINUX_CFLAGS="$LINUX_CFLAGS $LINUX_CFLAGS_MODULE"
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)
334 AC_SUBST(LINUX_MODULE_EXT)
340 AC_DEFUN([AS_LINUX_2_4],
342 AC_MSG_CHECKING(for Linux 2.4 make flags)
343 dnl we try to figure out the CFLAGS by invoking the Makefile on
345 dnl we use the correct config file by substituting the MAKEFILES
346 dnl Makefile variable, which originally points to .config
348 if [[ ! -f "${LINUX_DIR}/.hdepend" ]];then
350 You need to run 'make dep' on the kernel source before continuing.])
353 TMPFILE=`mktemp /tmp/linux.XXXXXXXX` || exit 1
357 ( sed "s|\.config|${CONFIG_FILE}|g" Makefile && cat <<EOF ) | make -f - get_cflags > ${TMPFILE}
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)\"
376 LINUX_MODULE_EXT=".o"
378 LINUX_CFLAGS="$LINUX_CFLAGS $LINUX_MODFLAGS"
380 dnl if we have REDHAT_CFLAGS, put them in LINUX_CFLAGS
381 if test "x$REDHAT_CFLAGS" != "x";
383 LINUX_CFLAGS="$LINUX_CFLAGS $REDHAT_CFLAGS"
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)
395 AC_SUBST(LINUX_MODULE_EXT)
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)
405 AC_DEFUN([AS_CHECK_LINUX_CONFIG_OPTION],
407 AC_MSG_CHECKING([Linux config option $1])
409 if grep '^$1=y$' ${CONFIG_FILE} >/dev/null 2>/dev/null; then
412 else if grep '^$1=m$' ${CONFIG_FILE} >/dev/null 2>/dev/null; then
421 AC_MSG_RESULT([$result])
424 AC_DEFUN([AS_LINUX_CONFIG_OPTION],
426 AS_CHECK_LINUX_CONFIG_OPTION([$1],
431 AM_CONDITIONAL([$1],[test "${$1}" = yes])
434 AC_DEFUN([AS_LINUX_CONFIG_OPTION_MODULE],
436 AS_CHECK_LINUX_CONFIG_OPTION([$1],
441 AM_CONDITIONAL([$1],[test "${$1}" = yes -o "${$1}" = module])