# Generic Makefile to support compilation for multiple languages.
# See also Makefile.prolog
#
-# Copyright (C) 2001-2003 ACT-Europe
+# Copyright (C) 2001-2004 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING. If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
# This Makefile provides a very generic framework of the following
# functionalities:
# CXX name of the C++ compiler (optional, default to gcc)
# AR_CMD command to create an archive (optional, default to "ar rc")
# AR_EXT file extension of an archive (optional, default to ".a")
-# RANLIB command to generate an index (optional, default to "ranlib")
+# RANLIB command to generate an index (optional, default to "ranlib")
# GNATMAKE name of the GNAT builder (optional, default to "gnatmake")
# ADAFLAGS additional Ada compilation switches, e.g "-gnatf" (optional)
# CFLAGS default C compilation switches, e.g "-O2 -g" (optional)
# PROJECT_FILE name of the project file, without the .gpr extension
# DEPS_PROJECTS list of project dependencies (optional)
+# SILENT (optional) when defined, make -s will not output anything
+# when all commands are successful.
+
# Set the source search path for C and C++ if needed
ifndef MAIN
MAIN=ada
endif
-ifndef CC
- CC=gcc
-endif
-
ifndef ADA_SPEC
ADA_SPEC=.ads
endif
endif
ifndef GNATMAKE
- GNATMAKE=gnatmake
+ GNATMAKE:=gnatmake
endif
ifndef ARCHIVE
EXEC_DIR=$(OBJ_DIR)
endif
+# Define display to echo only when SILENT is not defined
+
+ifdef SILENT
+define display
+ @gprcmd ignore
+endef
+
+else
+define display
+ @echo
+endef
+endif
+
+# Make sure gnatmake is called silently when SILENT is set
+ifdef SILENT
+ GNATMAKE:=$(GNATMAKE) -q
+endif
+
+# If C/C++ compiler is gcc, make sure gcc is called with the switch indicating
+# the language, in case the extension is not standard.
+
+ifeq ($(strip $(filter-out %gcc,$(CC))),)
+ C_Compiler=$(CC) -x c
+else
+ C_Compiler=$(CC)
+endif
+
+ifeq ($(strip $(filter-out %gcc %g++,$(CXX))),)
+ CXX_Compiler=$(CXX) -x c++
+else
+ CXX_Compiler=$(CXX)
+endif
+
# Set the object search path
vpath %$(OBJ_EXT) $(OBJ_DIR)
# character be part of a pathname on UNIX and this character can't be used in
# a pathname on Windows.
-clean_deps = $(subst :,|,$(DEPS_PROJECTS:%=clean_%))
-compile_deps = $(subst :,|,$(DEPS_PROJECTS:%=compile_%))
-object_deps = $(subst :,|,$(DEPS_PROJECTS:%=object_%))
-ada_deps = $(subst :,|,$(DEPS_PROJECTS:%=ada_%))
-c_deps = $(subst :,|,$(DEPS_PROJECTS:%=c_%))
-c++_deps = $(subst :,|,$(DEPS_PROJECTS:%=c++_%))
+clean_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=clean_%))
+compile_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=compile_%))
+object_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=object_%))
+ada_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=ada_%))
+c_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=c_%))
+c++_deps = $(subst :,__GPRCOLON__,$(DEPS_PROJECTS:%=c++_%))
# Default target is to build (compile/bind/link)
all: build
c++: $(c++deps) internal-c++
$(clean_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:clean_%=%))) -f Makefile.$(notdir $@) internal-clean
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:clean_%=%))) -f Makefile.$(notdir $@) internal-clean
$(compile_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:compile_%=%))) -f Makefile.$(notdir $@) internal-compile
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:compile_%=%))) -f Makefile.$(notdir $@) internal-compile
$(object_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:object_%=%))) -f Makefile.$(notdir $@) internal-archive-objects ARCHIVE=$(ARCHIVE)
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:object_%=%))) -f Makefile.$(notdir $@) internal-archive-objects ARCHIVE=$(ARCHIVE)
$(ada_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:ada_%=%))) -f Makefile.$(notdir $@) internal-ada
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:ada_%=%))) -f Makefile.$(notdir $@) internal-ada
$(c_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:c_%=%))) -f Makefile.$(notdir $@) internal-c
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:c_%=%))) -f Makefile.$(notdir $@) internal-c
$(c++_deps): force
- @$(MAKE) -C $(dir $(subst |,:,$(@:c++_%=%))) -f Makefile.$(notdir $@) internal-c++
+ @$(MAKE) -C $(dir $(subst __GPRCOLON__,:,$(@:c++_%=%))) -f Makefile.$(notdir $@) internal-c++
ifneq ($(EXEC),)
EXEC_RULE=-o $(EXEC)
ifeq ($(filter ada,$(LANGUAGES)),ada)
# C++ and Ada mixed
- LINKER = $(OBJ_DIR)/c++linker
LARGS = --LINK=$(LINKER)
ifeq ($(strip $(filter-out %gcc %g++,$(CXX))),)
- # Case of GNU C++ and GNAT
-
-$(LINKER): Makefile.$(PROJECT_BASE)
- @echo \#!/bin/sh > $(LINKER)
- @echo unset BINUTILS_ROOT >> $(LINKER)
- @echo unset GCC_ROOT >> $(LINKER)
- @echo $(CXX) $$\* >> $(LINKER)
- @chmod +x $(LINKER)
+ # Case of GNAT and a GNU C++ compiler
+$(LINKER):
else
+ # Case of GNAT and a non GNU C++ compiler
+ LINKER = $(OBJ_DIR)/c++linker
+
$(LINKER): Makefile.$(PROJECT_BASE)
@echo \#!/bin/sh > $(LINKER)
@echo $(CXX) $$\* $(shell gcc -print-libgcc-file-name) >> $(LINKER)
endif
C_INCLUDES := $(foreach name,$(SRC_DIRS),-I$(name))
-ALL_CFLAGS = $(CFLAGS) $(C_INCLUDES) $(DEP_CFLAGS)
-ALL_CXXFLAGS = $(CXXFLAGS) $(C_INCLUDES) $(DEP_CFLAGS)
+ALL_CFLAGS = $(CFLAGS) $(DEP_CFLAGS)
+ALL_CXXFLAGS = $(CXXFLAGS) $(DEP_CFLAGS)
LDFLAGS := $(LIBS) $(LDFLAGS)
# Compute list of objects based on languages
internal-compile: lib$(PROJECT_BASE)$(AR_EXT)
lib$(PROJECT_BASE)$(AR_EXT): $(OBJECTS)
- @echo creating archive file for $(PROJECT_BASE)
+ @$(display) creating archive file for $(PROJECT_BASE)
cd $(OBJ_DIR); $(AR_CMD) $@ $(strip $(OBJECTS))
-$(RANLIB) $(OBJ_DIR)/$@
else
link: $(EXEC_DIR)/$(EXEC) archive-objects
-$(EXEC_DIR)/$(EXEC): $(OBJ_FILES)
- @echo $(LINKER) -o $(EXEC_DIR)/$(EXEC) $(OBJ_DIR)/$(MAIN_OBJECT) $(LDFLAGS)
- $(LINKER) -o $(EXEC_DIR)/$(EXEC) $(OBJ_DIR)/$(MAIN_OBJECT) $(LDFLAGS)
+$(EXEC_DIR)/$(EXEC): $(OBJECTS)
+ @$(display) $(LINKER) -o $(EXEC_DIR)/$(EXEC) $(OBJ_DIR)/$(MAIN_OBJECT) $(LDFLAGS) $(FLDFLAGS)
+ @$(LINKER) -o $(EXEC_DIR)/$(EXEC) $(OBJ_DIR)/$(MAIN_OBJECT) $(LDFLAGS) $(FLDFLAGS)
endif
endif
ifeq ($(MAIN),ada)
# Ada main
link: $(LINKER) archive-objects force
- $(GNATMAKE) -b -l -P$(PROJECT_FILE) $(ADA_SOURCES) \
+ @$(display) $(GNATMAKE) -b -l -P$(PROJECT_FILE) $(ADA_SOURCES)
+ @$(GNATMAKE) -b -l -P$(PROJECT_FILE) $(ADA_SOURCES) \
-largs $(LARGS) $(LDFLAGS)
internal-build: $(LINKER) archive-objects force
- @echo $(GNATMAKE) -P$(PROJECT_FILE) $(ADA_SOURCES) $(EXEC_RULE) $(ADAFLAGS)
+ @$(display) $(GNATMAKE) -P$(PROJECT_FILE) $(ADA_SOURCES) $(EXEC_RULE) $(ADAFLAGS)
@$(GNATMAKE) -P$(PROJECT_FILE) $(EXEC_RULE) $(ADA_SOURCES) $(ADAFLAGS) \
-largs $(LARGS) $(LDFLAGS)
else
# C/C++ main
-# The trick here is to force gnatmake to bind/link, even if there is no
-# Ada main program. To achieve this effect, we use the -z switch, which is
-# close enough to our needs, and the usual -n gnatbind switch and --LINK=
-# gnatlink switch.
link: $(LINKER) archive-objects force
- $(GNATMAKE) $(EXEC_RULE) -z -P$(PROJECT_FILE) $(ADA_SOURCES) \
- -bargs -n -largs $(LARGS) $(LDFLAGS)
+ @$(display) $(GNATMAKE) $(EXEC_RULE) -B -P$(PROJECT_FILE) $(ADA_SOURCES)
+ @$(GNATMAKE) $(EXEC_RULE) -B -P$(PROJECT_FILE) $(ADA_SOURCES) \
+ -largs $(OBJ_DIR)/$(MAIN_OBJECT) $(LARGS) $(LDFLAGS) $(FLDFLAGS)
internal-build: $(LINKER) archive-objects force
- @echo $(GNATMAKE) -z -P$(PROJECT_FILE) $(ADA_SOURCES) $(EXEC_RULE) $(ADAFLAGS)
- @$(GNATMAKE) $(EXEC_RULE) -z \
- -P$(PROJECT_FILE) $(ADA_SOURCES) $(ADAFLAGS) \
- -bargs -n \
- -largs $(LARGS) $(LDFLAGS)
+ @$(display) $(GNATMAKE) $(EXEC_RULE) -B -P$(PROJECT_FILE) $(ADA_SOURCES) $(ADAFLAGS)
+ @$(GNATMAKE) $(EXEC_RULE) \
+ -B -P$(PROJECT_FILE) $(ADA_SOURCES) $(ADAFLAGS) \
+ -largs $(OBJ_DIR)/$(MAIN_OBJECT) $(LARGS) $(LDFLAGS) $(FLDFLAGS)
endif
else
# Automatic handling of dependencies
ifeq ($(strip $(filter-out %gcc %g++,$(CC) $(CXX))),)
-# Compiler is GCC, take avantage of the preprocessor option -MD
+# Compiler is GCC, take avantage of the preprocessor option -MD and
+# the CPATH environment variable
+
+empty:=
+space:=$(empty) $(empty)
+path_sep:=$(shell gprcmd path_sep)
+SRC_DIRS_PATH:= $(subst $(space),$(path_sep),$(SRC_DIRS))
+export CPATH:=$(SRC_DIRS_PATH)$(path_sep)$(CPATH)
+
DEP_CFLAGS = -Wp,-MD,$(OBJ_DIR)/$(*F).d
define post-compile
else
# Compiler unknown, use a more general approach based on the output of $(CC) -M
+ALL_CFLAGS := $(ALL_CFLAGS) $(C_INCLUDES)
+ALL_CXXFLAGS := $(ALL_CXXFLAGS) $(C_INCLUDES)
+
DEP_FLAGS = -M
DEP_CFLAGS =
# Compile C files individually
%$(OBJ_EXT) : %$(C_EXT)
- @echo $(CC) -c $(CFLAGS) $< -o $(OBJ_DIR)/$@
+ @$(display) $(C_Compiler) -c $(CFLAGS) $< -o $(OBJ_DIR)/$@
ifndef FAKE_COMPILE
- @$(CC) -c $(ALL_CFLAGS) $< -o $(OBJ_DIR)/$@
+ @$(C_Compiler) -c $(ALL_CFLAGS) $< -o $(OBJ_DIR)/$@
@$(post-compile)
endif
# Compile C++ files individually
%$(OBJ_EXT) : %$(CXX_EXT)
- @echo $(CXX) -c $(CXXFLAGS) $< -o $(OBJ_DIR)/$@
+ @$(display) $(CXX_Compiler) -c $(CXXFLAGS) $< -o $(OBJ_DIR)/$@
ifndef FAKE_COMPILE
- @$(CXX) -c $(ALL_CXXFLAGS) $< -o $(OBJ_DIR)/$@
+ @$(CXX_Compiler) -c $(ALL_CXXFLAGS) $< -o $(OBJ_DIR)/$@
@$(post-compile)
endif
.PHONY: force internal-clean internal-archive internal-build internal-compile internal-ada internal-c internal-c++ build compile clean ada c c++
internal-clean:
- @echo $(RM) $(OBJ_DIR)/*$(OBJ_EXT)
+ @$(display) $(RM) $(OBJ_DIR)/*$(OBJ_EXT)
@$(RM) $(OBJ_DIR)/*$(OBJ_EXT)
- @echo $(RM) $(OBJ_DIR)/*.ali
+ @$(display) $(RM) $(OBJ_DIR)/*.ali
@$(RM) $(OBJ_DIR)/*.ali
- @echo $(RM) $(OBJ_DIR)/b~*
+ @$(display) $(RM) $(OBJ_DIR)/b~*
@$(RM) $(OBJ_DIR)/b~*
- @echo $(RM) $(OBJ_DIR)/b_*
+ @$(display) $(RM) $(OBJ_DIR)/b_*
@$(RM) $(OBJ_DIR)/b_*
- @echo $(RM) $(OBJ_DIR)/*$(AR_EXT)
+ @$(display) $(RM) $(OBJ_DIR)/*$(AR_EXT)
@$(RM) $(OBJ_DIR)/*$(AR_EXT)
- @echo $(RM) $(OBJ_DIR)/*.d
+ @$(display) $(RM) $(OBJ_DIR)/*.d
@$(RM) $(OBJ_DIR)/*.d
ifneq ($(EXEC),)
- @echo $(RM) $(EXEC_DIR)/$(EXEC)
+ @$(display) $(RM) $(EXEC_DIR)/$(EXEC)
@$(RM) $(EXEC_DIR)/$(EXEC)
endif