这是makefile:
LIBDIRS += ./libRelease
LIBDIRS += ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/Skia
LIBDIRS += ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/LibTess
LIBDIRS += ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/SQLite
STATICS = $(wildcard $(LIBDIRS:=/*.a))
TARGETA = libRuntimeCoreJava.a
TARGETD = libRuntimeCoreJava.so
TARGETD1 = $(TARGETD).1
TARGETD2 = $(TARGETD).1.0
TARGETD3 = $(TARGETD).1.0.0
AR = ar cqs
AR_EXTRACT = ar -x
LINK = g++
SYMLINK = ln -f -s
LDFLAGS = -shared -Wl,-soname,libRuntimeCoreJava.so
EXTRACT =
all : $(TARGETD) $(TARGETA)
$(TARGETD) : clean
mkdir -p ./obj ./libRelease
$(foreach lib, $(STATICS), cp $(lib) ./obj;)
$(eval EXTRACT := $(wildcard ./obj/*.a))
echo $(EXTRACT)
$(foreach lib, $(EXTRACT), $(AR_EXTRACT) $(lib);)
$(foreach lib, $(EXTRACT), rm -f $(lib);)
#$(CXX) $(LDFLAGS) $(OBJS)
#$(SYMLINK) $(TARGETD) $(TARGETD1)
#$(SYMLINK) $(TARGETD) $(TARGETD2)
#$(SYMLINK) $(TARGETD) $(TARGETD3)
$(TARGETA) :
$(eval OBJS:=$(wildcard ./obj/*.o))
echo $(OBJS)
#$(AR) $(TARGETA) $(OBJS)
clean :
rm -rf ./ob
这是输出:
[matt6809@hogganz400 ArcGIS2]$ ls -l ./obj
total 23332
-rw-rw-r-- 1 matt6809 matt6809 191324 Mar 7 09:18 libCommon.a
-rw-rw-r-- 1 matt6809 matt6809 8427134 Mar 7 09:18 libGeometryXLib.a
-rw-rw-r-- 1 matt6809 matt6809 88580 Mar 7 09:18 libLibTess.a
-rw-rw-r-- 1 matt6809 matt6809 3401554 Mar 7 09:18 libMapping.a
-rw-rw-r-- 1 matt6809 matt6809 3558746 Mar 7 09:18 libpe_s.a
-rw-rw-r-- 1 matt6809 matt6809 412634 Mar 7 09:18 libpe++_s.a
-rw-rw-r-- 1 matt6809 matt6809 597808 Mar 7 09:18 libsg_s.a
-rw-rw-r-- 1 matt6809 matt6809 3523726 Mar 7 09:18 libSkia.a
-rw-rw-r-- 1 matt6809 matt6809 730064 Mar 7 09:18 libSQLite.a
-rw-rw-r-- 1 matt6809 matt6809 814234 Mar 7 09:18 libSymbolDictionary.a
-rw-rw-r-- 1 matt6809 matt6809 2128742 Mar 7 09:18 libSymbolXLib.a
[matt6809@hogganz400 ArcGIS2]$ make
rm -rf ./obj
mkdir -p ./obj ./libRelease
cp ./libRelease/libCommon.a ./obj; cp ./libRelease/libGeometryXLib.a ./obj; cp ./libRelease/libMapping.a ./obj; cp ./libRelease/libpe_s.a ./obj; cp ./libRelease/libpe++_s.a ./obj; cp ./libRelease/libsg_s.a ./obj; cp ./libRelease/libSymbolDictionary.a ./obj; cp ./libRelease/libSymbolXLib.a ./obj; cp ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/Skia/libSkia.a ./obj; cp ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/LibTess/libLibTess.a ./obj; cp ./SharedArcGIS/DepFilesLinux64/LibReleaseLinux64/SQLite/libSQLite.a ./obj;
echo
#g++ -shared -Wl,-soname,libRuntimeCoreJava.so
#ln -f -s libRuntimeCoreJava.so libRuntimeCoreJava.so.1
#ln -f -s libRuntimeCoreJava.so libRuntimeCoreJava.so.1.0
#ln -f -s libRuntimeCoreJava.so libRuntimeCoreJava.so.1.0.0
echo
#ar cqs libRuntimeCoreJava.a
为什么EXTRACT为空?输出显示libs被复制到.obj文件。
答案 0 :(得分:3)
这是因为规则变量扩展和shell命令执行发生在两个不同的阶段。
订单如下:
首先,尝试构建先决条件:
$(TARGETD) : clean ... clean : rm -rf ./obj
然后展开配方(换句话说,构造命令而不执行它们)
$(TARGETD) : clean mkdir -p ./obj ./libRelease $(foreach lib, $(STATICS), cp $(lib) ./obj;) $(eval EXTRACT := $(wildcard ./obj/*.a)) echo $(EXTRACT) $(foreach lib, $(EXTRACT), $(AR_EXTRACT) $(lib);) $(foreach lib, $(EXTRACT), rm -f $(lib);)
请注意,此时clean
已清除./obj
,因此wildcard
函数不返回任何内容。
所以食谱变成了:
$(TARGETD) : clean mkdir -p ./obj ./libRelease cp ./libRelease/libCommon.a ./obj; cp ...echo
实际上最后一行是你在输出中看到的。
答案 1 :(得分:2)
规则中的每个命令行都被视为“配方”,每个配方都会调用要运行的新shell实例。因此,当您在一个配方中为EXTRACT设置一个值并尝试在另一个配方中读取它时,您正在从两个不同的shell实例中读取它们,并且它们之间没有值。解决这个问题的一种方法是将命令加入到单个配方中,如下所示:
$(TARGETD) : clean
mkdir -p ./obj ./libRelease; \
for lib in $(STATICS) do; cp $$lib ./obj; done; \
EXTRACT=`ls ./obj/*.a`; echo $$EXTRACT; \
for lib in $$EXTRACT do; $(AR_EXTRACT) $$lib done; \
for lib in $$EXTRACT do; rm -f $$lib; done; \
因此,当您设置EXTRACT时,它将可用于配方中的所有命令。
有关详细信息,请参阅http://www.gnu.org/software/make/manual/make.html#Recipes
答案 2 :(得分:1)
makefile规则中的每个命令都在自己的子shell中执行;变量不能从一个命令存活到下一个命令。