2016-07-29 19 views
0

我需要一些宏來對目標進行評估,但是我不能讓OBJECT_FILE被$^aparently評估。這是我的makefile:在makefile中eval上的列表

#___________________________________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 [email protected] $^ 

${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90 
    ${MKDIR} -p ${OBJECT_DIR} 
    ${COMPILER} ${FLAGS} -c -o [email protected] $< 

結果我得到的是:

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 [email protected] $^ 

${OBJECT_DIR}/%.o: ${SRC_DIR}/%.f90 
    ${MKDIR} -p ${OBJECT_DIR} 
    ${COMPILER} ${FLAGS} -c -o [email protected] $< 
+0

'$ {OBJECT_FILES}'將在文件解析過程中展開,而相應的'$(eval)'將在執行「測試」目標時進行評估,這會在稍後發生。你真的需要'$(eval)'這個沒有任何動態內容的東西嗎?只需按照通常的方式定義變量,它就可以工作。 – Dummy00001

+0

這只是makefile的一部分,測試是我編譯規則之一,是唯一使用'Test _%。f90'文件的,調試和發佈使用不同的必備條件列表。我想要一個通用而簡潔的方式,這樣我就可以將最後兩個目標用於任何對象的編譯列表。我不應該評估每個對象,如:$ {OBJECT_DIR} /%。o:$ {SRC_DIR} /%。f90'。這不是一個合適的方法,讓我們從指定要編譯的所有文件中評估需要什麼?如果有辦法讓不同的對象列表得到這個規則,我將不勝感激。 – RomuloPBenedetti

+0

'一個通用和簡潔的方式' - GNU make只是錯誤的工具。雖然,是的,您可以使用「輔助擴展」功能來實現這一點。我建議檢查一下BSD make,它有簡單的方法來做你想做的事情,因爲它基於傳統的預處理器,與GNU make相比,它更適合這樣的事情。 – Dummy00001

回答

0

好吧,我進一步調查了這個問題,正如問題中所指出的那樣,我可以使用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: $${[email protected]_FILES} 
     ${MKDIR} ${PROGRAM_DIR} 
     ${COMPILER} ${FLAGS} ${PROGRAM} $([email protected]_FILES:%o=${OBJ_DIR}/%o) 

%.o: ${SRC_DIR}/%.f90 
    ${MKDIR} ${OBJ_DIR} 
    ${COMPILER} -c ${FLAGS} ${OBJ_DIR}/[email protected] $< 

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} [email protected] $< 

由於如果在目標中使用${OBJ_DIR}則不展開。如果有人能解釋在這種情況下發生的事情,我會很感激。

我想感謝我在評論中收到的建議。