Skip to content
This repository has been archived by the owner on May 21, 2019. It is now read-only.

Commit

Permalink
Add support for "platform" configurations, which define a suite of co…
Browse files Browse the repository at this point in the history
…mpiler-rt

libraries to generate.
 - Each library may be built with different flags and for different
   architectures, and there is support for building Darwin style fat archives.

 - Uses an ambituous amount of make programming, but should be hidden to
   users and developers.

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@93720 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ddunbar committed Jan 18, 2010
1 parent ba990c4 commit 48464e0
Show file tree
Hide file tree
Showing 13 changed files with 358 additions and 20 deletions.
147 changes: 143 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SubDirs := lib

# Set default rule before anything else.
all::
all: help

include make/config.mk
include make/util.mk
Expand Down Expand Up @@ -32,14 +32,22 @@ help:
@echo " VERBOSE=1: Use to show all commands [default=0]"
@echo
@echo "Available targets:"
@echo " clean: clean all configurations"
@echo " test: run unit tests"
@echo " all: build all configurations"
@echo " <platform name>: build the libraries for 'platform'"
@echo " clean: clean all configurations"
@echo " test: run unit tests"
@echo
@echo " info-platforms: list available platforms"
@echo " help-devel: print additional help for developers"
@echo

help-devel: help
@echo "Development targets:"
@echo " <platform name>-<config name>:"
@echo " build the libraries for a single platform config"
@echo " <platform name>-<config name>-<arch name>:"
@echo " build the libraries for a single config and arch"
@echo " info-functions: list available compiler-rt functions"
@echo " help-hidden: print help for Makefile debugging"
@echo

help-hidden: help-devel
Expand All @@ -59,6 +67,15 @@ info-functions:
printf " %-20s - available in (%s)\n" $(fn)\
"$(foreach key,$(AvailableIn.$(fn)),$($(key).Dir))";)

info-platforms:
@echo "compiler-rt Available Platforms"
@echo
@echo "Platforms:"
@$(foreach key,$(PlatformKeys),\
printf " %s - from '%s'\n" $($(key).Name) $($(key).Path);\
printf " %s\n" "$($(key).Description)";\
printf " Configurations: %s\n\n" "$($(key).Configs)";)

# Provide default clean target which is extended by other templates.
.PHONY: clean
clean::
Expand Down Expand Up @@ -88,6 +105,128 @@ Dir := .
include make/subdir.mk
include make/lib_info.mk
include make/lib_util.mk
include make/lib_platforms.mk

###
# Define Platform Rules

define PerPlatform_template
$(call Set,Tmp.Key,$(1))
$(call Set,Tmp.Name,$($(Tmp.Key).Name))
$(call Set,Tmp.Configs,$($(Tmp.Key).Configs))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name))

# Top-Level Platform Target
$(Tmp.Name):: $(Tmp.Configs:%=$(Tmp.ObjPath)/%/libcompiler_rt.a)
.PHONY: $(Tmp.Name)

clean::
$(Verb) rm -rf $(Tmp.ObjPath)

# Per-Config Libraries
$(foreach config,$(Tmp.Configs),\
$(call PerPlatformConfig_template,$(config)))
endef

define PerPlatformConfig_template
$(call Set,Tmp.Config,$(1))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config))

# Compute the archs to build, depending on whether this is a universal build or
# not.
$(call Set,Tmp.ArchsToBuild,\
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),\
$($(Tmp.Key).UniversalArchs),\
$(call VarOrDefault,$(Tmp.Key).Arch.$(Tmp.Config),$($(Tmp.Key).Arch))))

# Copy or lipo to create the per-config library.
$(call Set,Tmp.Inputs,$(Tmp.ArchsToBuild:%=$(Tmp.ObjPath)/%/libcompiler_rt.a))
$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " FINAL-ARCHIVE: $(Tmp.Name)/$(Tmp.Config): $$@"
-$(Verb) $(RM) $$@
$(if $(call streq,1,$(words $(Tmp.ArchsToBuild))), \
$(Verb) $(CP) $(Tmp.Inputs) $$@, \
$(Verb) $(LIPO) -create -output $$@ $(Tmp.Inputs))
.PRECIOUS: $(Tmp.ObjPath)/.dir

# Per-Config Targets
$(Tmp.Name)-$(Tmp.Config):: $(Tmp.ObjPath)/libcompiler_rt.a
.PHONY: $(Tmp.Name)-$(Tmp.Config)

# Per-Config-Arch Libraries
$(foreach arch,$(Tmp.ArchsToBuild),\
$(call PerPlatformConfigArch_template,$(arch)))
endef

define PerPlatformConfigArch_template
$(call Set,Tmp.Arch,$(1))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch))
$(call Set,Tmp.Functions,$(strip \
$(call GetCNAVar,FUNCTIONS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.Optimized,$(strip \
$(call GetCNAVar,OPTIMIZED,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.AR,$(strip \
$(call GetCNAVar,AR,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.ARFLAGS,$(strip \
$(call GetCNAVar,ARFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.RANLIB,$(strip \
$(call GetCNAVar,RANLIB,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.RANLIBFLAGS,$(strip \
$(call GetCNAVar,RANLIBFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))

# Compute the object inputs for this library.
$(call Set,Tmp.Inputs,\
$(foreach fn,$(sort $(Tmp.Functions)),\
$(call Set,Tmp.FnDir,\
$(call SelectFunctionDir,$(Tmp.Config),$(Tmp.Arch),$(fn),$(Tmp.Optimized)))\
$(Tmp.ObjPath)/$(Tmp.FnDir)/$(fn).o))
$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " ARCHIVE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
-$(Verb) $(RM) $$@
$(Verb) $(Tmp.AR) $(Tmp.ARFLAGS) $$@ $(Tmp.Inputs)
$(Verb) $(Tmp.RANLIB) $(Tmp.RANLIBFLAGS) $$@
.PRECIOUS: $(Tmp.ObjPath)/.dir

# Per-Config-Arch Targets
$(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch):: $(Tmp.ObjPath)/libcompiler_rt.a
.PHONY: $(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch)

# Per-Config-Arch-SubDir Objects
$(foreach key,$(SubDirKeys),\
$(call PerPlatformConfigArchSubDir_template,$(key)))
endef

define PerPlatformConfigArchSubDir_template
$(call Set,Tmp.SubDirKey,$(1))
$(call Set,Tmp.SubDir,$($(Tmp.SubDirKey).Dir))
$(call Set,Tmp.SrcPath,$(ProjSrcRoot)/$(Tmp.SubDir))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch)/$(Tmp.SubDirKey))
$(call Set,Tmp.Dependencies,$($(Tmp.SubDirKey).Dependencies))
$(call Set,Tmp.CC,$(strip \
$(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.CFLAGS,$(strip \
$(call GetCNAVar,CFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.ArchFlag,$(strip \
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),-arch $(Tmp.Arch),)))

$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.s $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS) -c -o $$@ $$<
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.S $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS) -c -o $$@ $$<
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS) -c -o $$@ $$<
.PRECIOUS: $(Tmp.ObjPath)/.dir

endef

# Run templates.
$(foreach key,$(PlatformKeys),\
$(eval $(call PerPlatform_template,$(key))))

###

ifneq ($(DEBUGMAKE),)
$(info MAKE: Done processing Makefile)
Expand Down
12 changes: 1 addition & 11 deletions make/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,9 @@ ProjObjRoot := $(ProjSrcRoot)
###
# Tool configuration variables.

CC := gcc
# FIXME: LLVM uses autoconf/mkinstalldirs ?
MKDIR := mkdir -p
DATE := date
AR := ar
# FIXME: Remove these pipes once ranlib errors are fixed.
AR.Flags := cru 2> /dev/null
RANLIB := ranlib
# FIXME: Remove these pipes once ranlib errors are fixed.
RANLIB.Flags := 2> /dev/null
LIPO := lipo
CP := cp

Expand All @@ -38,9 +31,6 @@ else
endif

Echo := @echo
Archive := $(AR) $(AR.Flags)
Ranlib := $(RANLIB) $(RANLIB.Flags)
Lipo := $(LIPO)
ifndef Summary
Summary = $(Echo)
Summary = $(Echo)
endif
5 changes: 5 additions & 0 deletions make/lib_info.mk
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ $(foreach arch,$(AvailableArchs),\
$(foreach key,$(SubDirKeys),\
$(foreach fn,$(basename $($(key).ObjNames)),\
$(call Append,AvailableIn.$(fn),$(key))))

# The names of all the available options.
AvailableOptions := AR ARFLAGS \
CC CFLAGS FUNCTIONS OPTIMIZED \
RANLIB RANLIBFLAGS
82 changes: 82 additions & 0 deletions make/lib_platforms.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# compiler-rt Configuration Support
#
# This should be included following 'lib_util.mk'.

# The simple variables configurations can define.
PlainConfigVariables := Configs UniversalArchs Description
PerConfigVariables := Arch $(AvailableOptions)
RequiredConfigVariables := Configs Description

###
# Load Platforms

# Template: subdir_traverse_template subdir
define load_platform_template
$(call Set,PlatformName,$(basename $(notdir $(1))))
ifneq ($(DEBUGMAKE),)
$$(info MAKE: $(PlatformName): Loading platform)
endif

# Construct the variable key for this directory.
$(call Set,PlatformKey,Platform.$(PlatformName))
$(call Append,PlatformKeys,$(PlatformKey))
$(call Set,$(PlatformKey).Name,$(PlatformName))
$(call Set,$(PlatformKey).Path,$(1))

# Reset platform specific variables to sentinel value.
$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\
$$(call Set,$$(var),UNDEFINED))
$$(foreach var,$(PerConfigVariables),\
$$(foreach config,$$(Configs),\
$$(call Set,$$(var).$$(config),UNDEFINED)))
$$(foreach var,$(PerConfigVariables),\
$$(foreach arch,$(AvailableArchs),\
$$(call Set,$$(var).$$(arch),UNDEFINED)))

# Get the platform variables.
include make/options.mk
include $(1)

# Check for undefined required variables.
$$(foreach var,$(RequiredConfigVariables),\
$$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
$$(error $(Dir): variable '$$(var)' was not undefined)))

# Check that exactly one of UniversalArchs or Arch was defined.
$$(if $$(and $$(call strneq,UNDEFINED,$$(UniversalArchs)),\
$$(call strneq,UNDEFINED,$$(Arch))),\
$$(error '$(1)': cannot define both 'UniversalArchs' and 'Arch'))
$$(if $$(or $$(call strneq,UNDEFINED,$$(UniversalArchs)),\
$$(call strneq,UNDEFINED,$$(Arch))),,\
$$(error '$(1)': must define one of 'UniversalArchs' and 'Arch'))

# Collect all the platform variables for subsequent use.
$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\
$$(if $$(call strneq,UNDEFINED,$$($$(var))),\
$$(call CopyVariable,$$(var),$(PlatformKey).$$(var))))
$$(foreach var,$(PerConfigVariables),\
$$(foreach config,$$(Configs),\
$$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config))),\
$$(call CopyVariable,$$(var).$$(config),$(PlatformKey).$$(var).$$(config))))\
$$(foreach arch,$(AvailableArchs),\
$$(if $$(call strneq,UNDEFINED,$$($$(var).$$(arch))),\
$$(call CopyVariable,$$(var).$$(arch),$(PlatformKey).$$(var).$$(arch))))\
$$(foreach config,$$(Configs),\
$$(foreach arch,$(AvailableArchs),\
$$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config).$$(arch))),\
$$(call CopyVariable,$$(var).$$(config).$$(arch),\
$(PlatformKey).$$(var).$$(config).$$(arch))))))

ifneq ($(DEBUGMAKE),)
$$(info MAKE: $(PlatformName): Done loading platform)
endif
endef

# Evaluate this now so we do not have to worry about order of evaluation.
PlatformFiles := $(wildcard make/platform/*.mk)
ifneq ($(DEBUGMAKE),)
$(info MAKE: Loading platforms: $(PlatformFiles))
endif

$(foreach file,$(PlatformFiles),\
$(eval $(call load_platform_template,$(file))))
9 changes: 9 additions & 0 deletions make/lib_util.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
#
# This should be included following 'lib_info.mk'.

# Function: GetCNAVar variable-name platform-key config arch
#
# Get a per-config-and-arch variable value.
GetCNAVar = $(strip \
$(or $($(2).$(1).$(3).$(4)), \
$($(2).$(1).$(3)), \
$($(2).$(1).$(4)), \
$($(2).$(1))))

# Function: SelectFunctionDir config arch function-name optimized
#
# Choose the appropriate implementation directory to use for 'function-name' in
Expand Down
25 changes: 25 additions & 0 deletions make/options.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Options which may be overriden for platforms, etc.
#
# This list of such variables should be kept up to date with AvailableOptions in
# 'make/lib_info.mk'.

# The compiler to use.
CC := gcc

# The compiler flags to use.
CFLAGS := -Wall -Werror

# The list of functions to include in the library.
FUNCTIONS :=

# Whether optimized function implementations should be used.
OPTIMIZED := 1

# Miscellaneous tools.

AR := ar
# FIXME: Remove these pipes once ranlib errors are fixed.
ARFLAGS := cru 2> /dev/null
RANLIB := ranlib
# FIXME: Remove these pipes once ranlib errors are fixed.
RANLIBFLAGS := 2> /dev/null
53 changes: 53 additions & 0 deletions make/platform/darwin_fat.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Configurations to build
#
# This section must define:
# Description - A description of this target.
# Configs - The names of each configuration to build; this is used to build
# multiple libraries inside a single configuration file (for
# example, Debug and Release builds, or builds with and without
# software floating point).
#
# This section must define one of:
# UniveralArchs - A list of architectures to build for, when using universal build
# support (e.g., on Darwin). This should only be used to build fat
# libraries, simply building multiple libraries for different
# architectures should do so using distinct configs, with the
# appropriate choices for CC and CFLAGS.
#
# Arch - The target architecture; this must match the compiler-rt name for the
# architecture and is used to find the appropriate function
# implementations.
#
# When not universal builds, this section may define:
# Arch.<Config Name> - Set the target architecture on a per-config basis.

Description := Target for building universal libraries for Darwin.

Configs := Debug Release Profile
UniversalArchs := i386 ppc x86_64

# Platform Options
#
# This section may override any of the variables in make/options.mk, using:
# <Option Name> := ... option value ...
#
# See make/options.mk for the available options and their meanings. Options can
# be override on a per-config, per-arch, or per-config-and-arch basis using:
# <Option Name>.<Config Name> := ...
# <Option Name>.<Arch Name> := ...
# <Option Name>.<Config Name>.<Arch Name> := ...

CC := gcc

CFLAGS := -Wall -Werror
CFLAGS.Debug := $(CFLAGS) -g
CFLAGS.Release := $(CFLAGS) -O3 -fomit-frame-pointer
CFLAGS.Profile := $(CFLAGS) -pg -g

FUNCTIONS.i386 := $(CommonFunctions) $(ArchFunctions.i386)
FUNCTIONS.ppc := $(CommonFunctions) $(ArchFunctions.ppc)
FUNCTIONS.x86_64 := $(CommonFunctions) $(ArchFunctions.x86_64)
FUNCTIONS.armv6 := $(CommonFunctions) $(ArchFunctions.armv6)
FUNCTIONS.armv7 := $(CommonFunctions) $(ArchFunctions.armv7)

OPTIMIZED.Debug := 0
Loading

0 comments on commit 48464e0

Please sign in to comment.