Automake + 条件コンパイル
条件コンパイルを試したメモ。
ある条件のときに、特定のソースコードをコンパイルから除外 or 包含する。
libevent の configure を参考にしました。
通信システム(select, poll, epoll, …etc)の有無をチェックしてコンパイル対象を選択するとこが今回の目的にピッタリ。
書いたコード一覧
hello.c
#include <stdio.h> #include <hello.h> #include "config.h" #ifdef HAVE_DOG extern const struct helloop dogop; #endif #ifdef HAVE_CAT extern const struct helloop catop; #endif const struct helloop *ops[] = { #ifdef HAVE_DOG &dogop, #endif #ifdef HAVE_CAT &catop, #endif NULL }; int main() { int i; for( i = 0; ops[i] != NULL; ++i ){ ops[i]->func( i ); } return 0; }
hello.h
#ifndef HELLO_H_ #define HELLO_H_ struct helloop { void (*func)(int); }; #endif
dog.c
#include <stdio.h> #include "hello.h" static void func_dog( int num ); const struct helloop dogop = { func_dog }; static void func_dog( int num ) { printf( "Hello dog. num:%d\n", num ); }
cat.c
#include <stdio.h> #include "hello.h" void func_cat( int num ); const struct helloop catop = { func_cat }; void func_cat( int num ) { printf( "Hello cat. num:%d\n", num ); }
configure.ac
AC_PREREQ(2.59) AC_INIT(automake-cond, 0.1, none) AC_CONFIG_SRCDIR([hello.h]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE AC_PROG_CC # テストコード。 # yes なら dog.c をコンパイル対象に。 have_dog="yes" if test "$have_dog" = "yes" then AC_SUBST([COMPILE_OBJS], 'dog.$(OBJEXT)') AC_DEFINE(HAVE_DOG, 1, [Define dog.]) fi # yes なら cat.c をコンパイル対象に。 have_cat="no" if test "$have_cat" = "yes" then AC_SUBST([COMPILE_OBJS], 'cat.$(OBJEXT)') AC_DEFINE(HAVE_CAT, 1, [Define cat.]) fi AC_C_CONST AC_CONFIG_FILES([Makefile]) AC_OUTPUT
Makefile.am
bin_PROGRAMS = hello hello_SOURCES = hello.c hello.h EXTRA_hello_SOURCES = dog.c cat.c hello_LDADD = @COMPILE_OBJS@ hello_DEPENDENCIES = @COMPILE_OBJS@
実行
configure.ac の中で have_dog=yes, have_cat=no と設定しているから最終的に dog.c がコンパイル&リンクされ func_dog() が呼ばれる。
$ ./configure $ make $ ./hello Hello dog. num:0