我的项目(解释语言)有一个由多个文件组成的标准库,每个文件都将构建到.so动态库中,解释器将根据用户请求加载(使用import指令)。 每个源文件都位于表示其“名称空间”的子目录中,例如:
libraries tree http://img707.imageshack.us/img707/7299/screenshot1tv.png
构建过程必须创建一个“构建”目录,然后在编译每个文件时必须在“构建”目录中创建其名称空间目录,例如,在编译时
std/io/network/tcp.cc
他用
运行mkdir命令mkdir -p build/std/io/network
Makefile片段是:
STDSRC=stdlib/std/hashing/md5.cc \
stdlib/std/hashing/crc32.cc \
stdlib/std/hashing/sha1.cc \
stdlib/std/hashing/sha2.cc \
stdlib/std/io/network/http.cc \
stdlib/std/io/network/tcp.cc \
stdlib/std/io/network/smtp.cc \
stdlib/std/io/file.cc \
stdlib/std/io/console.cc \
stdlib/std/io/xml.cc \
stdlib/std/type/reflection.cc \
stdlib/std/type/string.cc \
stdlib/std/type/matrix.cc \
stdlib/std/type/array.cc \
stdlib/std/type/map.cc \
stdlib/std/type/type.cc \
stdlib/std/type/binary.cc \
stdlib/std/encoding.cc \
stdlib/std/os/dll.cc \
stdlib/std/os/time.cc \
stdlib/std/os/threads.cc \
stdlib/std/os/process.cc \
stdlib/std/pcre.cc \
stdlib/std/math.cc
STDOBJ=$(STDSRC:.cc=.so)
all: stdlib
stdlib: $(STDOBJ)
.cc.so:
mkdir -p `dirname $< | sed -e 's/stdlib/stdlib\/build/'`
$(CXX) $< -o `dirname $< | sed -e 's/stdlib/stdlib\/build/'`/`basename $< .cc`.so $(CFLAGS) $(LDFLAGS)
我有两个问题:
1 - 问题是make命令,我真的不知道为什么,不检查文件是否被修改并在所有文件上启动构建过程,无论如何,所以如果我只需要构建一个文件,我必须构建它们或使用命令:
make path/to/single/file.so
有什么方法可以解决这个问题吗?
2 - 任何方式以“更清洁”的方式执行此操作而无需使用源分发所有构建目录?
谢谢
答案 0 :(得分:12)
对于1)问题是你的规则的目标(stdlib / something.so)不完全是规则所做的(build / something.so),所以Make总是认为它必须成为目标。这应该解决它(我使用GNUMake):
STDOBJ=$(patsubst stdlib%.cc,build%.so, $(STDSRC))
all: stdlib
stdlib: $(STDOBJ)
build/%.so: stdlib/%.cc
mkdir -p $(dir $@)
$(CXX) $< -o $@ $(CFLAGS) $(LDFLAGS)
2)我不确定你的意思。如果你想要你描述的构建目录结构,那就可以了。