我有一个包含很多目标的Makefile,每个目标的配方非常相似。
TARGET_NAME:
gcc $(TARGET_NAME).c -o $(TARGET_NAME)
mv $(TARGET_NAME) ~/bin
我想避免所有这些重复。我想有类似下面的内容(这不是有效的语法;这只表达了我的意图)。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
namespace Resources
{
public class ResManager
{
public static void SoundCopy(String ResourceName, String Dest)
{
try
{
var rm = Resources.Sounds.ResourceManager;
var resStream = rm.GetStream(ResourceName);
if (!File.Exists(Dest))
{
File.Create(Dest).Close();
}
FileStream fs = new FileStream(Dest, FileMode.OpenOrCreate);
CopyStream(resStream, fs);
resStream.Close();
resStream = null;
fs.Close();
fs = null;
rm.ReleaseAllResources();
rm = null;
}
catch (Exception e)
{
// nothlng
}
} // S copy();
private static void CopyStream(Stream from, Stream to)
{
int bufSize = 1024, count;
byte[] buffer = new byte[bufSize];
count = from.Read(buffer, 0, bufSize);
while (count > 0)
{
// StackOverflow -- working set raises here
to.Write(buffer, 0, count);
count = from.Read(buffer, 0, bufSize);
}
// clean up
buffer = null;
} // c str()
} //class
} //namespace
有可能做这样的事吗?如果没有,我可以写的最好的Makefile是什么,可以减少食谱中的重复?
答案 0 :(得分:4)
您的makefile错误,因为您的目标(foo
,bar
等)不依赖于他们的源文件(foo
不依赖于foo.c
等等)因此,更改源代码不会导致目标重建。
此外,您的makefile表示您正在创建文件foo
,但您的配方实际上会创建一个文件~/bin/foo
,这不是一回事。
无论如何,这正是pattern rules的用途:
EXES = foo bar baz
all: $(addprefix $(HOME)/bin/,$(EXES))
$(HOME)/bin/%:: %.c
gcc $< -o $@
(感谢Beta指出我原来的想法)
答案 1 :(得分:2)
make
规则实际上可以匹配多个目标:
foo bar baz:
gcc $@.c -o $@
mv $@ ~/bin
但是,您应该在规则中明确依赖关系:
foo: foo.c
bar: bar.c
baz: baz.c
foo bar baz:
gcc $< -o $@
mv $@ ~/bin
前三行只指定了依赖项,而没有任何实际构建它们的操作。您可以在gcc的帮助下生成这些内容:gcc -MM foo.c
将为foo.c
打印规则。