没有双关语,但是您正在使它变得比所需的要难。对于源和标头都在同一目录中的情况,使用通配符让make处理其余部分非常简单。例如,在Makefile
中使用三个简单的变量声明,可以告诉您源文件,包含文件以及如何为不是应用程序名称的每个源文件生成目标文件。
对于初学者,请指定您的应用程序名称:
# application name
APPNAME := justify
如果需要,请设置您的编译器变量,例如
# compiler
CC := gcc
CCLD := $(CC)
现在让您知道您的应用程序名称保存在APPNAME
中,您可以像访问Makefile
中的其他变量一样将其保存为$(APPNAME)
。
现在只需使用wildcard
收集所有源并包括变量,然后让make
关联目标文件输出:
# source/include/object variables
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:%.c=%.o)
设置您的编译器/链接器/库标志:
# compiler and linker flags
CFLAGS := -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast
LDFLAGS :=
# libraries
LIBS :=
现在为make
创建默认目标(注意:每个规则前面必须有一个 tab字符 '\t'
):
all: $(OBJECTS)
$(CCLD) -o $(APPNAME) $(OBJECTS) $(CFLAGS) $(LDFLAGS) $(LIBS)
将所有源编译为对象的规则:
$(OBJECTS): %.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
(有关使用的自动变量的说明,请参见What do the makefile symbols $@ and $< mean?)
最后是clean:
的目标
clean:
rm -rf $(APPNAME) *.o
完整的文件示例为:
# application name
APPNAME := justify
# compiler
CC := gcc
CCLD := $(CC)
# compiler and linker flags
CFLAGS := -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast
LDFLAGS :=
# libraries
LIBS :=
# source/include/object variables
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:%.c=%.o)
# target for all
all: $(OBJECTS)
$(CCLD) -o $(APPNAME) $(OBJECTS) $(CFLAGS) $(LDFLAGS) $(LIBS)
# strip only if -DDEBUG not set
ifneq ($(debug),-DDEBUG)
strip -s $(APPNAME)
endif
$(OBJECTS): %.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -rf $(APPNAME) *.o
(注意:strip
可执行文件的规则也已添加到all:
目标中)
示例构建
使用您的Makefile
源,并将文件包含在公共目录中,例如
$ ll
total 24
-rw-r--r-- 1 david david 668 Nov 6 12:38 Makefile
-rw-r--r-- 1 david david 161 Nov 6 12:31 justify.c
-rw-r--r-- 1 david david 106 Nov 6 12:32 line.c
-rw-r--r-- 1 david david 37 Nov 6 12:31 line.h
-rw-r--r-- 1 david david 104 Nov 6 12:32 word.c
-rw-r--r-- 1 david david 36 Nov 6 12:32 word.h
只需键入make
即可构建您的应用程序:
$ make
gcc -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast -c -o word.o word.c
gcc -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast -c -o line.o line.c
gcc -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast -c -o justify.o justify.c
gcc -o justify word.o line.o justify.o -Wall -Wextra -pedantic -finline-functions -std=c11 -Wshadow -Ofast
strip -s justify
没有错误,您可以检查所有文件是否按预期创建:
$ ll
total 44
-rw-r--r-- 1 david david 668 Nov 6 12:38 Makefile
-rwxr-xr-x 1 david david 6312 Nov 6 13:01 justify
-rw-r--r-- 1 david david 161 Nov 6 12:31 justify.c
-rw-r--r-- 1 david david 1760 Nov 6 13:01 justify.o
-rw-r--r-- 1 david david 106 Nov 6 12:32 line.c
-rw-r--r-- 1 david david 37 Nov 6 12:31 line.h
-rw-r--r-- 1 david david 1496 Nov 6 13:01 line.o
-rw-r--r-- 1 david david 104 Nov 6 12:32 word.c
-rw-r--r-- 1 david david 36 Nov 6 12:32 word.h
-rw-r--r-- 1 david david 1496 Nov 6 13:01 word.o
测试您的可执行文件:
$ ./justifiy
I'm in the main.
read_word
write_line
最后,用make clean
清理构建目录,例如
$ make clean
并确认已删除所有构建文件。
这是编写最少的make文件的最简单方法。您可以单独列出每个对象,并且必须包含支持它们的对象,但是为什么呢?自动变量将为您解决这一问题。您可以使用Makefile做更多的事情,但是对于入门而言,这将使您的生活更轻松。
,
您可以大大简化您拥有的64
。 Make提供了许多有用的变量。
--#SET TERMINATOR @
CREATE OR REPLACE FUNCTION COUNT_DATABASE_ROWS()
RETURNS TABLE (P_TABSCHEMA VARCHAR(128),P_TABNAME VARCHAR(128),P_ROWS BIGINT)
BEGIN
DECLARE L_STMT VARCHAR(256);
DECLARE L_ROWS BIGINT;
FOR V1 AS
SELECT TABSCHEMA,TABNAME
FROM SYSCAT.TABLES
WHERE TYPE IN ('T','S')
FETCH FIRST 10 ROWS ONLY
DO
SET L_STMT = 'SET ? = (SELECT COUNT(*) FROM "'||V1.TABSCHEMA||'"."'||V1.TABNAME||'")';
PREPARE S FROM L_STMT;
EXECUTE S INTO L_ROWS;
PIPE(V1.TABSCHEMA,V1.TABNAME,L_ROWS);
END FOR;
RETURN;
END@
SELECT * FROM TABLE(COUNT_DATABASE_ROWS())@
inlined compound
添加--#SET TERMINATOR @
CREATE OR REPLACE PROCEDURE COUNT_DATABASE_ROWS_DPF(OUT P_DOC XML)
READS SQL DATA
BEGIN
DECLARE L_STMT VARCHAR(256);
DECLARE L_ROWS BIGINT;
DECLARE L_NODE XML;
SET P_DOC = XMLELEMENT(NAME "DOC");
FOR V1 AS
SELECT TABSCHEMA,'S')
FETCH FIRST 10 ROWS ONLY
DO
SET L_STMT = 'SET ? = (SELECT COUNT(*) FROM "'||V1.TABSCHEMA||'"."'||V1.TABNAME||'")';
PREPARE S FROM L_STMT;
EXECUTE S INTO L_ROWS;
SET L_NODE = XMLELEMENT
(
NAME "NODE",XMLELEMENT(NAME "TABSCHEMA",V1.TABSCHEMA),XMLELEMENT(NAME "TABNAME",V1.TABNAME),XMLELEMENT(NAME "ROWS",L_ROWS)
);
SET P_DOC = XMLQUERY
(
'transform copy $mydoc := $doc modify do insert $node as last into $mydoc return $mydoc'
passing P_DOC as "doc",L_NODE as "node"
);
END FOR;
END@
CREATE OR REPLACE FUNCTION COUNT_DATABASE_ROWS_DPF()
RETURNS TABLE (P_TABSCHEMA VARCHAR(128),P_ROWS BIGINT)
BEGIN ATOMIC
DECLARE L_DOC XML;
CALL COUNT_DATABASE_ROWS_DPF(L_DOC);
RETURN
SELECT *
FROM XMLTABLE ('$D/NODE' PASSING L_DOC AS "D" COLUMNS
TYPESCHEMA VARCHAR(128) PATH 'TABSCHEMA',TABNAME VARCHAR(128) PATH 'TABNAME',LENGTH BIGINT PATH 'ROWS'
);
END@
-- Usage. Either CALL or SELECT:
CALL COUNT_DATABASE_ROWS_DPF(?)@
SELECT * FROM TABLE(COUNT_DATABASE_ROWS_DPF())@
也是个好主意
Makefile
$@ - target name
$< - first prequisite
$^ - all prequsites
,
make文件中存在错误。生成目标justify:
的命令缺少输出文件名。应该是这样的。
gcc -o justify justify.o line.o word.o
在您当前的命令行中,gcc将尝试通过链接line.o和word.o来输出justify.o,并且找不到_main
,这在line.o和word.o中没有定义
make命令已经知道如何将.c
文件转换为.o
,因此您无需在make文件中告诉它再次进行make。请记住,以下make文件足以满足您的测试用例。
# Makefile
justify: justify.o line.o word.o
gcc -o justify justify.o line.o word.o
您可以使用make的内置自动变量进一步简化此操作。 $@
和$^
。 $@
变量包含规则目标的名称。 $^
包含规则的所有前提条件的名称。因此,使用这两个变量,您的make文件将会是。
justify: justify.o line.o word.o
gcc -o $@ $^
本文链接:https://www.f2er.com/3149782.html