kconfig/kconfig.mk
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Wed Oct 15 21:29:56 2008 +0000 (2008-10-15)
changeset 940 f0f9ba3f98f2
parent 926 fe3e5a3331b6
child 942 86f3e28fa3cc
permissions -rw-r--r--
Cheesy kconfig stuff:
- silent/quiet/verbose build:
- ct-ng by default only prints quit messages, such as "CC xxx",
- if using V=0, nothing is printed,
- if using V=1, the full command lines are printed,
- other values are indeterminate,
- should help in debugging the kconfig stuff;
- complete kconfig/{,m}conf generation:
- fully dynamic dependencies on source files,
- compilation of .c into .o, then linking (instead of direct linking),
- VPATH usage when not --local;
Typo + a coment moved.

/trunk/kconfig/kconfig.mk | 140 87 53 0 +++++++++++++++++++++++++++++++++--------------------
/trunk/tools/tools.mk | 12 6 6 0 ++--
/trunk/steps.mk | 6 3 3 0 +-
/trunk/samples/samples.mk | 30 15 15 0 +++++-----
/trunk/ct-ng.in | 40 28 12 0 +++++++++++----
5 files changed, 139 insertions(+), 89 deletions(-)
yann@1
     1
# ===========================================================================
yann@197
     2
# crosstool-NG configuration targets
yann@1
     3
# These targets are used from top-level makefile
yann@1
     4
yann@148
     5
# Derive the project version from, well, the project version:
yann@148
     6
export PROJECTVERSION=$(CT_VERSION)
yann@148
     7
yann@926
     8
#-----------------------------------------------------------
yann@926
     9
# Some static /configuration/
yann@926
    10
yann@1
    11
KCONFIG_TOP = config/config.in
yann@926
    12
obj = kconfig
yann@925
    13
PHONY += clean help oldconfig menuconfig defoldconfig
yann@1
    14
yann@19
    15
# Darwin (MacOS-X) does not have proper libintl support
yann@19
    16
ifeq ($(shell uname -s),Darwin)
yann@19
    17
KBUILD_NO_NLS:=1
yann@19
    18
endif
yann@19
    19
yann@18
    20
ifneq ($(KBUILD_NO_NLS),)
yann@18
    21
CFLAGS += -DKBUILD_NO_NLS
yann@18
    22
endif
yann@18
    23
yann@926
    24
#-----------------------------------------------------------
yann@926
    25
# List all config files, source and generated
yann@97
    26
yann@926
    27
# Build the list of all source config files
yann@926
    28
STATIC_CONFIG_FILES = $(patsubst $(CT_LIB_DIR)/%,%,$(shell find $(CT_LIB_DIR)/config -type f -name '*.in' 2>/dev/null))
yann@926
    29
# ... and how to access them:
yann@926
    30
$(STATIC_CONFIG_FILES): config
yann@88
    31
yann@926
    32
# Build a list of per-component-type source config files
yann@926
    33
ARCH_CONFIG_FILES   = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/arch/*.in))
yann@926
    34
KERNEL_CONFIG_FILES = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/kernel/*.in))
yann@926
    35
CC_CONFIG_FILES     = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/cc/*.in))
yann@926
    36
LIBC_CONFIG_FILES   = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/libc/*.in))
yann@926
    37
DEBUG_CONFIG_FILES  = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/debug/*.in))
yann@926
    38
TOOL_CONFIG_FILES   = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/config/tools/*.in))
yann@182
    39
yann@926
    40
# Build the list of generated config files
yann@926
    41
GEN_CONFIG_FILES = config.gen/arch.in     \
yann@926
    42
                   config.gen/kernel.in   \
yann@926
    43
                   config.gen/cc.in       \
yann@926
    44
                   config.gen/libc.in     \
yann@926
    45
                   config.gen/tools.in    \
yann@926
    46
                   config.gen/debug.in
yann@926
    47
# ... and how to access them:
yann@926
    48
# Generated files depends on kconfig.mk (this file) because it has the
yann@926
    49
# functions needed to build the genrated files, and thus they might
yann@926
    50
# need re-generation if kconfig.mk changes
yann@926
    51
$(GEN_CONFIG_FILES): config.gen                         \
yann@861
    52
                     $(CT_LIB_DIR)/kconfig/kconfig.mk
yann@182
    53
yann@926
    54
# KCONFIG_TOP should already be in STATIC_CONFIG_FILES, anyway...
yann@926
    55
CONFIG_FILES = $(sort $(KCONFIG_TOP) $(STATIC_CONFIG_FILES) $(GEN_CONFIG_FILES))
yann@182
    56
yann@926
    57
# Where to access to the source config files from
yann@926
    58
config:
yann@940
    59
	@$(ECHO) "  LN    config"
yann@940
    60
	$(SILENT)ln -s $(CT_LIB_DIR)/config config
yann@926
    61
yann@926
    62
# Where to store the generated config files into
yann@926
    63
config.gen:
yann@940
    64
	@$(ECHO) "  MKDIR config.gen"
yann@940
    65
	$(SILENT)mkdir -p config.gen
yann@926
    66
yann@926
    67
#-----------------------------------------------------------
yann@926
    68
# Build list of per-component-type items to easily build generated files
yann@926
    69
yann@926
    70
ARCHS   = $(patsubst config/arch/%.in,%,$(ARCH_CONFIG_FILES))
yann@926
    71
KERNELS = $(patsubst config/kernel/%.in,%,$(KERNEL_CONFIG_FILES))
yann@926
    72
CCS     = $(patsubst config/cc/%.in,%,$(CC_CONFIG_FILES))
yann@926
    73
LIBCS   = $(patsubst config/libc/%.in,%,$(LIBC_CONFIG_FILES))
yann@926
    74
DEBUGS  = $(patsubst config/debug/%.in,%,$(DEBUG_CONFIG_FILES))
yann@926
    75
TOOLS   = $(patsubst config/tools/%.in,%,$(TOOL_CONFIG_FILES))
yann@926
    76
yann@926
    77
#-----------------------------------------------------------
yann@926
    78
# Helper functions to ease building generated config files
yann@926
    79
yann@926
    80
# The function 'build_gen_choice_in' builds a choice-menu of a list of
yann@926
    81
# components in the given list, also adding source-ing of associazted
yann@926
    82
# config files:
yann@912
    83
# $1 : destination file
yann@912
    84
# $2 : name for the entries family (eg. Architecture, kernel...)
yann@912
    85
# $3 : prefix for the choice entries (eg. ARCH, KERNEL...)
yann@912
    86
# $4 : base directory containing config files
yann@912
    87
# $5 : list of config entries (eg. for architectures: "alpha arm ia64"...,
yann@912
    88
#      and for kernels: "bare-metal linux"...)
yann@912
    89
# Example to build the kernels generated config file:
yann@920
    90
# $(call build_gen_choice_in,config.gen/kernel.in,Target OS,KERNEL,config/kernel,$(KERNELS))
yann@912
    91
define build_gen_choice_in
yann@940
    92
	@$(ECHO) '  IN    $(1)'
yann@940
    93
	$(SILENT)(echo "# $(2) menu";                                       \
yann@920
    94
	  echo "# Generated file, do not edit!!!";                          \
yann@920
    95
	  echo "";                                                          \
yann@920
    96
	  echo "choice";                                                    \
yann@920
    97
	  echo "    bool";                                                  \
yann@920
    98
	  echo "    prompt \"$(2)\"";                                       \
yann@920
    99
	  echo "";                                                          \
yann@920
   100
	  for entry in $(5); do                                             \
yann@920
   101
	    file="$(4)/$${entry}.in";                                       \
yann@920
   102
	    _entry=$$(echo "$${entry}" |sed -r -s -e 's/[-.+]/_/g;');       \
yann@920
   103
	    echo "config $(3)_$${_entry}";                                  \
yann@920
   104
	    echo "    bool";                                                \
yann@920
   105
	    printf "    prompt \"$${entry}";                                \
yann@920
   106
	    if grep -E '^# +EXPERIMENTAL$$' $${file} >/dev/null 2>&1; then  \
yann@920
   107
	      echo " (EXPERIMENTAL)\"";                                     \
yann@920
   108
	      echo "    depends on EXPERIMENTAL";                           \
yann@920
   109
	    else                                                            \
yann@920
   110
	      echo "\"";                                                    \
yann@920
   111
	    fi;                                                             \
yann@920
   112
	  done;                                                             \
yann@920
   113
	  echo "";                                                          \
yann@920
   114
	  echo "endchoice";                                                 \
yann@920
   115
	  for entry in $(5); do                                             \
yann@920
   116
	    file="$(4)/$${entry}.in";                                       \
yann@920
   117
	    _entry=$$(echo "$${entry}" |sed -r -s -e 's/[-.+]/_/g;');       \
yann@920
   118
	    echo "";                                                        \
yann@920
   119
	    echo "if $(3)_$${_entry}";                                      \
yann@920
   120
	    echo "config $(3)";                                             \
yann@920
   121
	    echo "    default \"$${entry}\" if $(3)_$${_entry}";            \
yann@920
   122
	    echo "source $${file}";                                         \
yann@920
   123
	    echo "endif";                                                   \
yann@920
   124
	  done;                                                             \
yann@912
   125
	 ) >$(1)
yann@912
   126
endef
yann@628
   127
yann@926
   128
# The function 'build_gen_menu_in' builds a menuconfig for each component in
yann@926
   129
# the given list, source-ing the associated files conditionnaly:
yann@916
   130
# $1 : destination file
yann@916
   131
# $2 : name of entries family (eg. Tools, Debug...)
yann@916
   132
# $3 : prefix for the menu entries (eg. TOOL, DEBUG)
yann@916
   133
# $4 : base directory containing config files
yann@916
   134
# $5 : list of config entries (eg. for tools: "libelf sstrip"..., and for
yann@916
   135
#      debug: "dmalloc duma gdb"...)
yann@916
   136
# Example to build the tools generated config file:
yann@916
   137
# $(call build_gen_menu_in,config.gen/tools.in,Tools,TOOL,config/tools,$(TOOLS))
yann@916
   138
define build_gen_menu_in
yann@940
   139
	@$(ECHO) '  IN    $(1)'
yann@940
   140
	$(SILENT)(echo "# $(2) facilities menu";                            \
yann@916
   141
	  echo "# Generated file, do not edit!!!";                          \
yann@916
   142
	  echo "";                                                          \
yann@916
   143
	  for entry in $(5); do                                             \
yann@916
   144
	    file="$(4)/$${entry}.in";                                       \
yann@916
   145
	    _entry=$$(echo "$${entry}" |sed -r -s -e 's/[-.+]/_/g;');       \
yann@916
   146
	    echo "menuconfig $(3)_$${_entry}";                              \
yann@916
   147
	    echo "    bool";                                                \
yann@916
   148
	    printf "    prompt \"$${entry}";                                \
yann@916
   149
	    if grep -E '^# +EXPERIMENTAL$$' $${file} >/dev/null 2>&1; then  \
yann@916
   150
	      echo " (EXPERIMENTAL)\"";                                     \
yann@916
   151
	      echo "    depends on EXPERIMENTAL";                           \
yann@916
   152
	    else                                                            \
yann@916
   153
	      echo "\"";                                                    \
yann@916
   154
	    fi;                                                             \
yann@916
   155
	    echo "if $(3)_$${_entry}";                                      \
yann@916
   156
	    echo "source $${file}";                                         \
yann@916
   157
	    echo "endif";                                                   \
yann@916
   158
	    echo "";                                                        \
yann@916
   159
	  done;                                                             \
yann@916
   160
	 ) >$(1)
yann@916
   161
endef
yann@916
   162
yann@926
   163
#-----------------------------------------------------------
yann@926
   164
# The rules for the generated config files
yann@916
   165
yann@926
   166
config.gen/arch.in: $(ARCH_CONFIG_FILES)
yann@926
   167
	$(call build_gen_choice_in,$@,Target Architecture,ARCH,config/arch,$(ARCHS))
yann@861
   168
yann@926
   169
config.gen/kernel.in: $(KERNEL_CONFIG_FILES)
yann@926
   170
	$(call build_gen_choice_in,$@,Target OS,KERNEL,config/kernel,$(KERNELS))
yann@182
   171
yann@926
   172
config.gen/cc.in: $(CC_CONFIG_FILES)
yann@926
   173
	$(call build_gen_choice_in,$@,C compiler,CC,config/cc,$(CCS))
yann@926
   174
yann@926
   175
config.gen/libc.in: $(LIBC_CONFIG_FILES)
yann@926
   176
	$(call build_gen_choice_in,$@,C library,LIBC,config/libc,$(LIBCS))
yann@926
   177
yann@926
   178
config.gen/tools.in: $(TOOL_CONFIG_FILES)
yann@926
   179
	$(call build_gen_menu_in,$@,Tools,TOOL,config/tools,$(TOOLS))
yann@926
   180
yann@926
   181
config.gen/debug.in: $(DEBUG_CONFIG_FILES)
yann@926
   182
	$(call build_gen_menu_in,$@,Debug,DEBUG,config/debug,$(DEBUGS))
yann@926
   183
yann@926
   184
#-----------------------------------------------------------
yann@926
   185
# The configurators rules
yann@182
   186
yann@940
   187
menuconfig: $(obj)/mconf $(CONFIG_FILES)
yann@940
   188
	$(SILENT)$< $(KCONFIG_TOP)
yann@1
   189
yann@940
   190
oldconfig: .config $(obj)/conf $(CONFIG_FILES)
yann@940
   191
	$(SILENT)$< -s $(KCONFIG_TOP)
yann@1
   192
yann@940
   193
defoldconfig: .config $(obj)/conf $(CONFIG_FILES)
yann@940
   194
	$(SILENT)yes "" |$< -s $(KCONFIG_TOP)
yann@159
   195
yann@926
   196
#-----------------------------------------------------------
yann@1
   197
# Help text used by make help
yann@926
   198
yann@176
   199
help-config::
yann@333
   200
	@echo  '  menuconfig         - Update current config using a menu based program'
yann@333
   201
	@echo  '  oldconfig          - Update current config using a provided .config as base'
yann@940
   202
	@echo  '  defoldconfig       - As oldconfig, above, but using defaults for new options'
yann@1
   203
yann@926
   204
#-----------------------------------------------------------
yann@940
   205
# Hmmm! Cheesy build!
yann@940
   206
# Or: where I can unveil my make-fu... :-]
yann@1
   207
yann@940
   208
# Oh! Files not here are there, in fact! :-)
yann@940
   209
vpath %.c $(CT_LIB_DIR)
yann@940
   210
vpath %.h $(CT_LIB_DIR)
yann@1
   211
yann@940
   212
# What is the compiler?
yann@940
   213
HOST_CC ?= gcc -funsigned-char
yann@182
   214
yann@940
   215
# Compiler and linker flags to use ncurses
yann@940
   216
CFLAGS += $(shell $(CT_LIB_DIR)/kconfig/lxdialog/check-lxdialog.sh -ccflags)
yann@940
   217
LDFLAGS += $(shell $(CT_LIB_DIR)/kconfig/lxdialog/check-lxdialog.sh -ldflags $(HOST_CC))
yann@182
   218
yann@940
   219
# Common source files, and lxdialog source files
yann@940
   220
SRC = kconfig/zconf.tab.c
yann@940
   221
LXSRC = $(patsubst $(CT_LIB_DIR)/%,%,$(wildcard $(CT_LIB_DIR)/kconfig/lxdialog/*.c))
yann@816
   222
yann@940
   223
# What's needed to build 'conf'
yann@940
   224
conf_SRC  = $(SRC) kconfig/conf.c
yann@940
   225
conf_OBJ  = $(patsubst %.c,%.o,$(conf_SRC))
yann@816
   226
yann@940
   227
# What's needed to build 'mconf'
yann@940
   228
mconf_SRC = $(SRC) $(LXSRC) kconfig/mconf.c
yann@940
   229
mconf_OBJ = $(patsubst %.c,%.o,$(mconf_SRC))
yann@1
   230
yann@940
   231
# Cheesy auto-dependencies
yann@940
   232
DEPS = $(patsubst %.c,%.d,$(sort $(conf_SRC) $(mconf_SRC)))
yann@940
   233
yann@940
   234
# This is not very nice, as they will get rebuild even if (dist)cleaning... :-(
yann@940
   235
# Should look into the Linux kernel Kbuild to see how they do that...
yann@940
   236
# To really make me look into this, keep the annoying "DEP xxx" messages.
yann@940
   237
# Also see the comment for the "%.o: %c" rule below
yann@940
   238
%.d: %.c $(CT_LIB_DIR)/kconfig/kconfig.mk
yann@940
   239
	$(SILENT)if [ ! -d $(obj)/lxdialog ]; then  \
yann@940
   240
	   $(ECHO) "  MKDIR $(obj)";           \
yann@940
   241
	   mkdir -p $(obj)/lxdialog;        \
yann@940
   242
	 fi
yann@940
   243
	@$(ECHO) "  DEP   $@"
yann@940
   244
	$(SILENT)$(HOST_CC) $(CFLAGS) -MM $< |sed -r -e 's|([^:]+.o)( *:+)|$(<:.c=.o) $@\2|;' >$@
yann@940
   245
-include $(DEPS)
yann@940
   246
yann@940
   247
# Each .o must depend on the corresponding .c (obvious, isn't it?),
yann@940
   248
# but *can not* depend on kconfig/, because kconfig can be touched
yann@940
   249
# during the build (who's touching it, btw?) so each .o would be
yann@940
   250
# re-built when they sould not be.
yann@940
   251
# So manually check for presence of $(obj) (ie. kconfig), and only mkdir
yann@940
   252
# if needed. After all, that's not so bad...
yann@940
   253
# mkdir $(obj)/lxdialog, because we need it, and incidentally, that
yann@940
   254
# also creates $(obj).
yann@940
   255
# Also rebuild the object files is the makefile is changed
yann@940
   256
%.o: %.c $(CT_LIB_DIR)/kconfig/kconfig.mk
yann@940
   257
	$(SILENT)if [ ! -d $(obj)/lxdialog ]; then  \
yann@940
   258
	   $(ECHO) "  MKDIR $(obj)";           \
yann@940
   259
	   mkdir -p $(obj)/lxdialog;        \
yann@940
   260
	 fi
yann@940
   261
	@$(ECHO) "  CC    $@"
yann@940
   262
	$(SILENT)$(HOST_CC) $(CFLAGS) -o $@ -c $<
yann@940
   263
yann@940
   264
$(obj)/mconf: $(mconf_OBJ)
yann@940
   265
	@$(ECHO) '  LD    $@'
yann@940
   266
	$(SILENT)$(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
yann@940
   267
yann@940
   268
$(obj)/conf: $(conf_OBJ)
yann@940
   269
	@$(ECHO) '  LD    $@'
yann@940
   270
	$(SILENT)$(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
yann@1
   271
yann@926
   272
#-----------------------------------------------------------
yann@926
   273
# Cleaning up the mess...
yann@926
   274
yann@1
   275
clean::
yann@940
   276
	@$(ECHO) "  CLEAN kconfig"
yann@940
   277
	$(SILENT)rm -f kconfig/{,m}conf $(conf_OBJ) $(mconf_OBJ) $(DEPS)
yann@940
   278
	$(SILENT)rmdir --ignore-fail-on-non-empty kconfig{/lxdialog,} 2>/dev/null || true
yann@940
   279
	@$(ECHO) "  CLEAN config"
yann@940
   280
	$(SILENT)rm -f config 2>/dev/null || true
yann@940
   281
	@$(ECHO) "  CLEAN config.gen"
yann@940
   282
	$(SILENT)rm -rf config.gen