makefile 中的 eval 列表
Lists on eval inside a makefile
我需要一些宏在目标上进行评估,但我无法让 OBJECT_FILE
由 $^ 显然地进行评估。这是我的生成文件:
#___________________________________build tools_________________________________
MKDIR := mkdir
RM := rm
CP := cp
CD := cd
COMPILER := gfortran
GENERAL_FLAGS := -fno-automatic -static -I/usr/include -fimplicit-none
TESTING_DEBUG_FLAGS := -Og -g -fbounds-check -fbacktrace -pedantic -Wextra \
-Wall ${GENERAL_FLAGS}
RELEASE_FLAGS := ${GENERAL_FLAGS} -Ofast
#______________________________macros de diretórios_____________________________
SRC_DIR := src
BUILD_DIR := build
RELEASE_DIR := release
DEBUG_DIR := debug
TEST_DIR := test
DIST_DIR := dist
PROGRAM := ${DIST_DIR}/SimulArroz
#______________________________regras de compilação_____________________________
tests: | TEST_PATHS ${PROGRAM}
TEST_PATHS:
$(eval FLAGS = ${TESTING_DEBUG_FLAGS})
$(eval OBJECT_DIR = ${BUILD_DIR}/${TEST_DIR})
$(eval OBJECT_FILES = ${OBJECT_DIR}/Data.o ${OBJECT_DIR}/Model.o \
${OBJECT_DIR}/Control.o ${OBJECT_DIR}/Farmings.o \
${OBJECT_DIR}/Test_data.o ${OBJECT_DIR}/Test_main.o \
${OBJECT_DIR}/Test_subroutines.o)
${MKDIR} -p ${DIST_DIR}
${MKDIR} -p ${OBJECT_DIR}
clean :
${RM} -fr ${BUILD_DIR}
${RM} -fr ${DIST_DIR}
${RM} -f seed.mod
run :
${CD} ${DIST_DIR} ; ./${PROGRAM}
${PROGRAM}: ${OBJECT_FILES}
${COMPILER} ${FLAGS} -o $@ $^
${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} -p ${OBJECT_DIR}
${COMPILER} ${FLAGS} -c -o $@ $<
我得到的结果是:
gfortran -Og -g -fbounds-check -fbacktrace -pedantic -Wextra -Wall -fno-automatic -static -I/usr/include -fimplicit-none -o dist/SimulArroz
gfortran: fatal error: no input files; unwilling to write output files
compilation terminated.
makefile:90: recipe for target 'dist/SimulArroz' failed
make: *** [dist/SimulArroz] Error 1
更新:
我按照评论中的指示尝试了 secondary expansion
,但最终在我的情况下它给出了相同的结果,这是我尝试过的更改:
tests: FLAGS := ${TESTING_DEBUG_FLAGS}
tests: OBJECT_DIR := ${BUILD_DIR}/${TEST_DIR}
tests: OBJECT_FILES := ${TEST_OBJ_DIR}/Data.o ${TEST_OBJ_DIR}/Model.o \
${TEST_OBJ_DIR}/Control.o ${TEST_OBJ_DIR}/Farmings.o \
${TEST_OBJ_DIR}/Test_data.o ${TEST_OBJ_DIR}/Test_main.o \
${TEST_OBJ_DIR}/Test_subroutines.o
.SECONDEXPANSION:
tests: $$(PROGRAM)
${PROGRAM}: ${OBJECT_FILES}
${MKDIR} -p ${DIST_DIR}
${COMPILER} ${FLAGS} -o $@ $^
${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} -p ${OBJECT_DIR}
${COMPILER} ${FLAGS} -c -o $@ $<
好的,我进一步调查了它,正如问题评论中指出的那样,可以使用 second expansion
解决我的问题,我也使用 text function
解决了它。由于没有人给出答案,我把它放在这里:
#___________________________________build tools_________________________________
MKDIR := mkdir -p
RM := rm
CP := cp
CD := cd
COMPILER := gfortran
# flags do compilador
GENERAL_FLAGS := -fno-automatic -static -I/usr/include -fimplicit-none
TESTING_DEBUG_FLAGS := -Og -g -fbounds-check -fbacktrace -pedantic -Wextra \
-Wall ${GENERAL_FLAGS}
RELEASE_FLAGS := ${GENERAL_FLAGS} -Ofast
#______________________________macros de diretórios_____________________________
SRC_DIR := src
BUILD_DIR := build
RELEASE_DIR := release
DEBUG_DIR := debug
TEST_DIR := test
DIST_DIR := dist
test_FILES := Data.o Model.o Control.o Farmings.o Test_Data.o Test_Main.o \
Test_Subroutines.o
#______________________________regras de compilação_____________________________
.PHONY: test clean run
test: FLAGS := ${TESTING_DEBUG_FLAGS} -o
test: OBJ_DIR := ${BUILD_DIR}/${TEST_DIR}
test: PROGRAM_DIR := ${DIST_DIR}/${TEST_DIR}
test: PROGRAM := ${PROGRAM_DIR}/SimulArroz
.SECONDEXPANSION:
test: $${$$@_FILES}
${MKDIR} ${PROGRAM_DIR}
${COMPILER} ${FLAGS} ${PROGRAM} $($@_FILES:%o=${OBJ_DIR}/%o)
%.o: ${SRC_DIR}/%.f90
${MKDIR} ${OBJ_DIR}
${COMPILER} -c ${FLAGS} ${OBJ_DIR}/$@ $<
clean :
${RM} -fr ${BUILD_DIR}
${RM} -fr ${DIST_DIR}
${RM} -f seed.mod
run :
${CD} ${DIST_DIR} ; ./${PROGRAM}
但是...我仍然不明白为什么我不能只获得这样的目标:
${OBJ_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} ${OBJ_DIR}
${COMPILER} -c ${FLAGS} $@ $<
因为 ${OBJ_DIR}
如果在目标中使用则不会扩展。如果有人能解释一下在这种情况下发生了什么,我将不胜感激。
我也要感谢我在评论中收到的建议。
我需要一些宏在目标上进行评估,但我无法让 OBJECT_FILE
由 $^ 显然地进行评估。这是我的生成文件:
#___________________________________build tools_________________________________
MKDIR := mkdir
RM := rm
CP := cp
CD := cd
COMPILER := gfortran
GENERAL_FLAGS := -fno-automatic -static -I/usr/include -fimplicit-none
TESTING_DEBUG_FLAGS := -Og -g -fbounds-check -fbacktrace -pedantic -Wextra \
-Wall ${GENERAL_FLAGS}
RELEASE_FLAGS := ${GENERAL_FLAGS} -Ofast
#______________________________macros de diretórios_____________________________
SRC_DIR := src
BUILD_DIR := build
RELEASE_DIR := release
DEBUG_DIR := debug
TEST_DIR := test
DIST_DIR := dist
PROGRAM := ${DIST_DIR}/SimulArroz
#______________________________regras de compilação_____________________________
tests: | TEST_PATHS ${PROGRAM}
TEST_PATHS:
$(eval FLAGS = ${TESTING_DEBUG_FLAGS})
$(eval OBJECT_DIR = ${BUILD_DIR}/${TEST_DIR})
$(eval OBJECT_FILES = ${OBJECT_DIR}/Data.o ${OBJECT_DIR}/Model.o \
${OBJECT_DIR}/Control.o ${OBJECT_DIR}/Farmings.o \
${OBJECT_DIR}/Test_data.o ${OBJECT_DIR}/Test_main.o \
${OBJECT_DIR}/Test_subroutines.o)
${MKDIR} -p ${DIST_DIR}
${MKDIR} -p ${OBJECT_DIR}
clean :
${RM} -fr ${BUILD_DIR}
${RM} -fr ${DIST_DIR}
${RM} -f seed.mod
run :
${CD} ${DIST_DIR} ; ./${PROGRAM}
${PROGRAM}: ${OBJECT_FILES}
${COMPILER} ${FLAGS} -o $@ $^
${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} -p ${OBJECT_DIR}
${COMPILER} ${FLAGS} -c -o $@ $<
我得到的结果是:
gfortran -Og -g -fbounds-check -fbacktrace -pedantic -Wextra -Wall -fno-automatic -static -I/usr/include -fimplicit-none -o dist/SimulArroz
gfortran: fatal error: no input files; unwilling to write output files
compilation terminated.
makefile:90: recipe for target 'dist/SimulArroz' failed
make: *** [dist/SimulArroz] Error 1
更新:
我按照评论中的指示尝试了 secondary expansion
,但最终在我的情况下它给出了相同的结果,这是我尝试过的更改:
tests: FLAGS := ${TESTING_DEBUG_FLAGS}
tests: OBJECT_DIR := ${BUILD_DIR}/${TEST_DIR}
tests: OBJECT_FILES := ${TEST_OBJ_DIR}/Data.o ${TEST_OBJ_DIR}/Model.o \
${TEST_OBJ_DIR}/Control.o ${TEST_OBJ_DIR}/Farmings.o \
${TEST_OBJ_DIR}/Test_data.o ${TEST_OBJ_DIR}/Test_main.o \
${TEST_OBJ_DIR}/Test_subroutines.o
.SECONDEXPANSION:
tests: $$(PROGRAM)
${PROGRAM}: ${OBJECT_FILES}
${MKDIR} -p ${DIST_DIR}
${COMPILER} ${FLAGS} -o $@ $^
${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} -p ${OBJECT_DIR}
${COMPILER} ${FLAGS} -c -o $@ $<
好的,我进一步调查了它,正如问题评论中指出的那样,可以使用 second expansion
解决我的问题,我也使用 text function
解决了它。由于没有人给出答案,我把它放在这里:
#___________________________________build tools_________________________________
MKDIR := mkdir -p
RM := rm
CP := cp
CD := cd
COMPILER := gfortran
# flags do compilador
GENERAL_FLAGS := -fno-automatic -static -I/usr/include -fimplicit-none
TESTING_DEBUG_FLAGS := -Og -g -fbounds-check -fbacktrace -pedantic -Wextra \
-Wall ${GENERAL_FLAGS}
RELEASE_FLAGS := ${GENERAL_FLAGS} -Ofast
#______________________________macros de diretórios_____________________________
SRC_DIR := src
BUILD_DIR := build
RELEASE_DIR := release
DEBUG_DIR := debug
TEST_DIR := test
DIST_DIR := dist
test_FILES := Data.o Model.o Control.o Farmings.o Test_Data.o Test_Main.o \
Test_Subroutines.o
#______________________________regras de compilação_____________________________
.PHONY: test clean run
test: FLAGS := ${TESTING_DEBUG_FLAGS} -o
test: OBJ_DIR := ${BUILD_DIR}/${TEST_DIR}
test: PROGRAM_DIR := ${DIST_DIR}/${TEST_DIR}
test: PROGRAM := ${PROGRAM_DIR}/SimulArroz
.SECONDEXPANSION:
test: $${$$@_FILES}
${MKDIR} ${PROGRAM_DIR}
${COMPILER} ${FLAGS} ${PROGRAM} $($@_FILES:%o=${OBJ_DIR}/%o)
%.o: ${SRC_DIR}/%.f90
${MKDIR} ${OBJ_DIR}
${COMPILER} -c ${FLAGS} ${OBJ_DIR}/$@ $<
clean :
${RM} -fr ${BUILD_DIR}
${RM} -fr ${DIST_DIR}
${RM} -f seed.mod
run :
${CD} ${DIST_DIR} ; ./${PROGRAM}
但是...我仍然不明白为什么我不能只获得这样的目标:
${OBJ_DIR}/%.o: ${SRC_DIR}/%.f90
${MKDIR} ${OBJ_DIR}
${COMPILER} -c ${FLAGS} $@ $<
因为 ${OBJ_DIR}
如果在目标中使用则不会扩展。如果有人能解释一下在这种情况下发生了什么,我将不胜感激。
我也要感谢我在评论中收到的建议。