2017-01-23 3 views
0

Извините, если это не место, чтобы опубликовать это. Я не уверен, где это.Как передать аргументы для boilermake

Я новичок в make, и после много исследований я наткнулся на boilermake и успешно реализовал его в своем проекте.

По умолчанию я создаю версию моего проекта. Я хотел бы знать, как создать отладочную версию моего проекта, предоставив аргумент командной строки, такой как debug. Например.

make debug

, который изменяет некоторые параметры компилятора, установленные в CXXFLAGS в моем верхнем уровне Makefile.

Однако я не смог заставить это работать.

Вот мой makefile, который включен в make-файл верхнего уровня boilermake.

INCDIRS := \ 
    ../component1/include \ 
    ../component2/include \ 
    ../component3/include 

CXXFLAGS := O2 -pipe -std=c++11 -Wall -Wextra -Wold-style-cast -pedantic \ 
    -isystem boost 

SUBMAKEFILES := \ 
    ../component1/build/component1.mk \ 
    ../component2/build/component3.mk \ 
    ../component3/build/component4.mk 

TARGET := my-project 

TGT_LDFLAGS := -L. -L${TARGET_DIR} 

TGT_LDLIBS := -lcomponent1 -lcomponent2 -lcomponent3 \ 
    libboost_date_time-mt-sd.a \ 
    libboost_filesystem-mt-sd.a 
    libcrypto.a \ 
    libssl.a \ 
    -lz \ 
    -ldl \ 
    -lpthread 

TGT_PREREQS := \ 
    libcomponent1.a \ 
    libcomponent2.a \ 
    libcomponent3.a 

SOURCES := \ 
    main.cpp 

Описание файла makefile для boillermake.

# boilermake: A reusable, but flexible, boilerplate Makefile. 
# 
# Copyright 2008, 2009, 2010 Dan Moulding, Alan T. DeKok 
# 
# This program 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 3 of the License, or 
# (at your option) any later version. 
# 
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. 

# Caution: Don't edit this Makefile! Create your own main.mk and other 
#   submakefiles, which will be included by this Makefile. 
#   Only edit this if you need to modify boilermake's behavior (fix 
#   bugs, add features, etc). 

# Note: Parameterized "functions" in this makefile that are marked with 
#  "USE WITH EVAL" are only useful in conjuction with eval. This is 
#  because those functions result in a block of Makefile syntax that must 
#  be evaluated after expansion. Since they must be used with eval, most 
#  instances of "$" within them need to be escaped with a second "$" to 
#  accomodate the double expansion that occurs when eval is invoked. 

# ADD_CLEAN_RULE - Parameterized "function" that adds a new rule and phony 
# target for cleaning the specified target (removing its build-generated 
# files). 
# 
# USE WITH EVAL 
# 
define ADD_CLEAN_RULE 
    clean: clean_${1} 
    .PHONY: clean_${1} 
    clean_${1}: 
    $$(strip rm -f ${TARGET_DIR}/${1} $${${1}_OBJS:%.o=%.[do]}) 
    $${${1}_POSTCLEAN} 
endef 

# ADD_OBJECT_RULE - Parameterized "function" that adds a pattern rule for 
# building object files from source files with the filename extension 
# specified in the second argument. The first argument must be the name of the 
# base directory where the object files should reside (such that the portion 
# of the path after the base directory will match the path to corresponding 
# source files). The third argument must contain the rules used to compile the 
# source files into object code form. 
# 
# USE WITH EVAL 
# 
define ADD_OBJECT_RULE 
${1}/%.o: ${2} 
    ${3} 
endef 

# ADD_TARGET_RULE - Parameterized "function" that adds a new target to the 
# Makefile. The target may be an executable or a library. The two allowable 
# types of targets are distinguished based on the name: library targets must 
# end with the traditional ".a" extension. 
# 
# USE WITH EVAL 
# 
define ADD_TARGET_RULE 
    ifeq "$$(suffix ${1})" ".a" 
     # Add a target for creating a static library. 
     $${TARGET_DIR}/${1}: $${${1}_OBJS} 
     @mkdir -p $$(dir [email protected]) 
     $$(strip $${AR} $${ARFLAGS} [email protected] $${${1}_OBJS}) 
     $${${1}_POSTMAKE} 
    else 
     # Add a target for linking an executable. First, attempt to select the 
     # appropriate front-end to use for linking. This might not choose the 
     # right one (e.g. if linking with a C++ static library, but all other 
     # sources are C sources), so the user makefile is allowed to specify a 
     # linker to be used for each target. 
     ifeq "$$(strip $${${1}_LINKER})" "" 
      # No linker was explicitly specified to be used for this target. If 
      # there are any C++ sources for this target, use the C++ compiler. 
      # For all other targets, default to using the C compiler. 
      ifneq "$$(strip $$(filter $${CXX_SRC_EXTS},$${${1}_SOURCES}))" "" 
       ${1}_LINKER = $${CXX} 
      else 
       ${1}_LINKER = $${CC} 
      endif 
     endif 

     $${TARGET_DIR}/${1}: $${${1}_OBJS} $${${1}_PREREQS} 
     @mkdir -p $$(dir [email protected]) 
     $$(strip $${${1}_LINKER} -o [email protected] $${LDFLAGS} $${${1}_LDFLAGS} \ 
      $${${1}_OBJS} $${LDLIBS} $${${1}_LDLIBS}) 
     $${${1}_POSTMAKE} 
    endif 
endef 

# CANONICAL_PATH - Given one or more paths, converts the paths to the canonical 
# form. The canonical form is the path, relative to the project's top-level 
# directory (the directory from which "make" is run), and without 
# any "./" or "../" sequences. For paths that are not located below the 
# top-level directory, the canonical form is the absolute path (i.e. from 
# the root of the filesystem) also without "./" or "../" sequences. 
define CANONICAL_PATH 
$(patsubst ${CURDIR}/%,%,$(abspath ${1})) 
endef 

# COMPILE_C_CMDS - Commands for compiling C source code. 
define COMPILE_C_CMDS 
    @mkdir -p $(dir [email protected]) 
    $(strip ${CC} -o [email protected] -c -MP -MD ${CFLAGS} ${SRC_CFLAGS} ${INCDIRS} \ 
     ${SRC_INCDIRS} ${SRC_DEFS} ${DEFS} $<) 
endef 

# COMPILE_CXX_CMDS - Commands for compiling C++ source code. 
define COMPILE_CXX_CMDS 
    @mkdir -p $(dir [email protected]) 
    $(strip ${CXX} -o [email protected] -c -MP -MD ${CXXFLAGS} ${SRC_CXXFLAGS} ${INCDIRS} \ 
     ${SRC_INCDIRS} ${SRC_DEFS} ${DEFS} $<) 
endef 

# INCLUDE_SUBMAKEFILE - Parameterized "function" that includes a new 
# "submakefile" fragment into the overall Makefile. It also recursively 
# includes all submakefiles of the specified submakefile fragment. 
# 
# USE WITH EVAL 
# 
define INCLUDE_SUBMAKEFILE 
    # Initialize all variables that can be defined by a makefile fragment, then 
    # include the specified makefile fragment. 
    TARGET  := 
    TGT_CFLAGS := 
    TGT_CXXFLAGS := 
    TGT_DEFS  := 
    TGT_INCDIRS := 
    TGT_LDFLAGS := 
    TGT_LDLIBS := 
    TGT_LINKER := 
    TGT_POSTCLEAN := 
    TGT_POSTMAKE := 
    TGT_PREREQS := 

    SOURCES  := 
    SRC_CFLAGS := 
    SRC_CXXFLAGS := 
    SRC_DEFS  := 
    SRC_INCDIRS := 

    SUBMAKEFILES := 

    # A directory stack is maintained so that the correct paths are used as we 
    # recursively include all submakefiles. Get the makefile's directory and 
    # push it onto the stack. 
    DIR := $(call CANONICAL_PATH,$(dir ${1})) 
    DIR_STACK := $$(call PUSH,$${DIR_STACK},$${DIR}) 

    include ${1} 

    # Initialize internal local variables. 
    OBJS := 

    # Ensure that valid values are set for BUILD_DIR and TARGET_DIR. 
    ifeq "$$(strip $${BUILD_DIR})" "" 
     BUILD_DIR := build 
    endif 
    ifeq "$$(strip $${TARGET_DIR})" "" 
     TARGET_DIR := . 
    endif 

    # Determine which target this makefile's variables apply to. A stack is 
    # used to keep track of which target is the "current" target as we 
    # recursively include other submakefiles. 
    ifneq "$$(strip $${TARGET})" "" 
     # This makefile defined a new target. Target variables defined by this 
     # makefile apply to this new target. Initialize the target's variables. 
     TGT := $$(strip $${TARGET}) 
     ALL_TGTS += $${TGT} 
     $${TGT}_CFLAGS := $${TGT_CFLAGS} 
     $${TGT}_CXXFLAGS := $${TGT_CXXFLAGS} 
     $${TGT}_DEFS  := $${TGT_DEFS} 
     $${TGT}_DEPS  := 
     TGT_INCDIRS  := $$(call QUALIFY_PATH,$${DIR},$${TGT_INCDIRS}) 
     TGT_INCDIRS  := $$(call CANONICAL_PATH,$${TGT_INCDIRS}) 
     $${TGT}_INCDIRS := $${TGT_INCDIRS} 
     $${TGT}_LDFLAGS := $${TGT_LDFLAGS} 
     $${TGT}_LDLIBS := $${TGT_LDLIBS} 
     $${TGT}_LINKER := $${TGT_LINKER} 
     $${TGT}_OBJS  := 
     $${TGT}_POSTCLEAN := $${TGT_POSTCLEAN} 
     $${TGT}_POSTMAKE := $${TGT_POSTMAKE} 
     $${TGT}_PREREQS := $$(addprefix $${TARGET_DIR}/,$${TGT_PREREQS}) 
     $${TGT}_SOURCES := 
    else 
     # The values defined by this makefile apply to the the "current" target 
     # as determined by which target is at the top of the stack. 
     TGT := $$(strip $$(call PEEK,$${TGT_STACK})) 
     $${TGT}_CFLAGS += $${TGT_CFLAGS} 
     $${TGT}_CXXFLAGS += $${TGT_CXXFLAGS} 
     $${TGT}_DEFS  += $${TGT_DEFS} 
     TGT_INCDIRS  := $$(call QUALIFY_PATH,$${DIR},$${TGT_INCDIRS}) 
     TGT_INCDIRS  := $$(call CANONICAL_PATH,$${TGT_INCDIRS}) 
     $${TGT}_INCDIRS += $${TGT_INCDIRS} 
     $${TGT}_LDFLAGS += $${TGT_LDFLAGS} 
     $${TGT}_LDLIBS += $${TGT_LDLIBS} 
     $${TGT}_POSTCLEAN += $${TGT_POSTCLEAN} 
     $${TGT}_POSTMAKE += $${TGT_POSTMAKE} 
     $${TGT}_PREREQS += $${TGT_PREREQS} 
    endif 

    # Push the current target onto the target stack. 
    TGT_STACK := $$(call PUSH,$${TGT_STACK},$${TGT}) 

    ifneq "$$(strip $${SOURCES})" "" 
     # This makefile builds one or more objects from source. Validate the 
     # specified sources against the supported source file types. 
     BAD_SRCS := $$(strip $$(filter-out $${ALL_SRC_EXTS},$${SOURCES})) 
     ifneq "$${BAD_SRCS}" "" 
      $$(error Unsupported source file(s) found in ${1} [$${BAD_SRCS}]) 
     endif 

     # Qualify and canonicalize paths. 
     SOURCES  := $$(call QUALIFY_PATH,$${DIR},$${SOURCES}) 
     SOURCES  := $$(call CANONICAL_PATH,$${SOURCES}) 
     SRC_INCDIRS := $$(call QUALIFY_PATH,$${DIR},$${SRC_INCDIRS}) 
     SRC_INCDIRS := $$(call CANONICAL_PATH,$${SRC_INCDIRS}) 

     # Save the list of source files for this target. 
     $${TGT}_SOURCES += $${SOURCES} 

     # Convert the source file names to their corresponding object file 
     # names. 
     OBJS := $$(addprefix $${BUILD_DIR}/$$(call CANONICAL_PATH,$${TGT})/,\ 
        $$(addsuffix .o,$$(basename $${SOURCES}))) 

     # Add the objects to the current target's list of objects, and create 
     # target-specific variables for the objects based on any source 
     # variables that were defined. 
     $${TGT}_OBJS += $${OBJS} 
     $${TGT}_DEPS += $${OBJS:%.o=%.d} 
     $${OBJS}: SRC_CFLAGS := $${$${TGT}_CFLAGS} $${SRC_CFLAGS} 
     $${OBJS}: SRC_CXXFLAGS := $${$${TGT}_CXXFLAGS} $${SRC_CXXFLAGS} 
     $${OBJS}: SRC_DEFS  := $$(addprefix -D,$${$${TGT}_DEFS} $${SRC_DEFS}) 
     $${OBJS}: SRC_INCDIRS := $$(addprefix -I,\ 
            $${$${TGT}_INCDIRS} $${SRC_INCDIRS}) 
    endif 

    ifneq "$$(strip $${SUBMAKEFILES})" "" 
     # This makefile has submakefiles. Recursively include them. 
     $$(foreach MK,$${SUBMAKEFILES},\ 
      $$(eval $$(call INCLUDE_SUBMAKEFILE,\ 
         $$(call CANONICAL_PATH,\ 
         $$(call QUALIFY_PATH,$${DIR},$${MK}))))) 
    endif 

    # Reset the "current" target to it's previous value. 
    TGT_STACK := $$(call POP,$${TGT_STACK}) 
    TGT := $$(call PEEK,$${TGT_STACK}) 

    # Reset the "current" directory to it's previous value. 
    DIR_STACK := $$(call POP,$${DIR_STACK}) 
    DIR := $$(call PEEK,$${DIR_STACK}) 
endef 

# MIN - Parameterized "function" that results in the minimum lexical value of 
# the two values given. 
define MIN 
$(firstword $(sort ${1} ${2})) 
endef 

# PEEK - Parameterized "function" that results in the value at the top of the 
# specified colon-delimited stack. 
define PEEK 
$(lastword $(subst :, ,${1})) 
endef 

# POP - Parameterized "function" that pops the top value off of the specified 
# colon-delimited stack, and results in the new value of the stack. Note that 
# the popped value cannot be obtained using this function; use peek for that. 
define POP 
${1:%:$(lastword $(subst :, ,${1}))=%} 
endef 

# PUSH - Parameterized "function" that pushes a value onto the specified colon- 
# delimited stack, and results in the new value of the stack. 
define PUSH 
${2:%=${1}:%} 
endef 

# QUALIFY_PATH - Given a "root" directory and one or more paths, qualifies the 
# paths using the "root" directory (i.e. appends the root directory name to 
# the paths) except for paths that are absolute. 
define QUALIFY_PATH 
$(addprefix ${1}/,$(filter-out /%,${2})) $(filter /%,${2}) 
endef 

############################################################################### 
# 
# Start of Makefile Evaluation 
# 
############################################################################### 

# Older versions of GNU Make lack capabilities needed by boilermake. 
# With older versions, "make" may simply output "nothing to do", likely leading 
# to confusion. To avoid this, check the version of GNU make up-front and 
# inform the user if their version of make doesn't meet the minimum required. 
MIN_MAKE_VERSION := 3.81 
MIN_MAKE_VER_MSG := boilermake requires GNU Make ${MIN_MAKE_VERSION} or greater 
ifeq "${MAKE_VERSION}" "" 
    $(info GNU Make not detected) 
    $(error ${MIN_MAKE_VER_MSG}) 
endif 
ifneq "${MIN_MAKE_VERSION}" "$(call MIN,${MIN_MAKE_VERSION},${MAKE_VERSION})" 
    $(info This is GNU Make version ${MAKE_VERSION}) 
    $(error ${MIN_MAKE_VER_MSG}) 
endif 

# Define the source file extensions that we know how to handle. 
C_SRC_EXTS := %.c 
CXX_SRC_EXTS := %.C %.cc %.cp %.cpp %.CPP %.cxx %.c++ 
ALL_SRC_EXTS := ${C_SRC_EXTS} ${CXX_SRC_EXTS} 

# Initialize global variables. 
ALL_TGTS := 
DEFS := 
DIR_STACK := 
INCDIRS := 
TGT_STACK := 

# Include the main user-supplied submakefile. This also recursively includes 
# all other user-supplied submakefiles. 
$(eval $(call INCLUDE_SUBMAKEFILE,main.mk)) 

# Perform post-processing on global variables as needed. 
DEFS := $(addprefix -D,${DEFS}) 
INCDIRS := $(addprefix -I,$(call CANONICAL_PATH,${INCDIRS})) 

# Define the "all" target (which simply builds all user-defined targets) as the 
# default goal. 
.PHONY: all 
all: $(addprefix ${TARGET_DIR}/,${ALL_TGTS}) 

# Add a new target rule for each user-defined target. 
$(foreach TGT,${ALL_TGTS},\ 
    $(eval $(call ADD_TARGET_RULE,${TGT}))) 

# Add pattern rule(s) for creating compiled object code from C source. 
$(foreach TGT,${ALL_TGTS},\ 
    $(foreach EXT,${C_SRC_EXTS},\ 
    $(eval $(call ADD_OBJECT_RULE,${BUILD_DIR}/$(call CANONICAL_PATH,${TGT}),\ 
      ${EXT},$${COMPILE_C_CMDS})))) 

# Add pattern rule(s) for creating compiled object code from C++ source. 
$(foreach TGT,${ALL_TGTS},\ 
    $(foreach EXT,${CXX_SRC_EXTS},\ 
    $(eval $(call ADD_OBJECT_RULE,${BUILD_DIR}/$(call CANONICAL_PATH,${TGT}),\ 
      ${EXT},$${COMPILE_CXX_CMDS})))) 

# Add "clean" rules to remove all build-generated files. 
.PHONY: clean 
$(foreach TGT,${ALL_TGTS},\ 
    $(eval $(call ADD_CLEAN_RULE,${TGT}))) 

# Include generated rules that define additional (header) dependencies. 
$(foreach TGT,${ALL_TGTS},\ 
    $(eval -include ${${TGT}_DEPS})) 

ответ

0

Если вы сделаете команду как:

make debug=true

Тогда в одном из ваших Makefiles:

ifeq (debug,true) CXXFLAGS += -DDEBUG else CXXFLAGS += -DNDEBUG endif

Смежные вопросы