1. 程式人生 > >“*** target pattern contains no '%'. stop.”

“*** target pattern contains no '%'. stop.”

機子老了,實在是上不了VS。網上溜了一圈後下了個 codelite 試試,佔資源不多,程式碼補全挺不錯的。

可是昨晚更改了一個工程的一點設定之後編譯就通不過了,無論是Build,Rebuild還是 Clean都是這個錯誤資訊。

test.mk:72: *** target pattern contains no '%'.  Stop.

單詞倒是都認識,可連在一起的意思就丈二和尚摸不到頭腦了。從字尾名.mk猜測估計是卡在make這裡了。看來這次make是跟我過不去了。Google了一下,資訊少得可憐。之前有2人也碰到同樣的錯誤資訊,說法有二:1、make版本問題,3.8.0以後對windows檔名支援有問題;2、還是路徑名中用了中文字元惹的禍。可是都與我的狀況不同啊。路徑名儘量不使用中文這我是知道的,進一步的我連路徑名中的空格下劃線的使用也很小心,再三檢查路徑名沒任何問題。

沒辦法,硬著頭皮啃啃看吧。暈!我對makefile可是連四分之一桶水都沒有啊。拆開test.mk來看,檔案是 Codelite 自動生成的,這個工程只是試驗,內容不多。

##
## Auto Generated makefile by CodeLite IDE
## any manual changes will be erased      
##
## Debug
ProjectName            :=test
ConfigurationName      :=Debug
WorkspacePath          := "E:\Experiment"
ProjectPath            := "E:\Experiment\test"
IntermediateDirectory  :=$(WorkspacePath)/$(ConfigurationName)
OutDir                 := $(IntermediateDirectory)
CurrentFileName        :=
CurrentFilePath        :=
CurrentFileFullPath    :=
User                   :=lwouyang
Date                   :=2013-3-24
CodeLitePath           :="E:\CodeLite"
LinkerName             :=gcc
SharedObjectLinkerName :=gcc -shared -fPIC
ObjectSuffix           :=.o
DependSuffix           :=.o.d
PreprocessSuffix       :=.o.i
DebugSwitch            :=-g 
IncludeSwitch          :=-I
LibrarySwitch          :=-l
OutputSwitch           :=-o 
LibraryPathSwitch      :=-L
PreprocessorSwitch     :=-D
SourceSwitch           :=-c 
OutputFile             :=$(IntermediateDirectory)/$(ProjectName)
Preprocessors          :=
ObjectSwitch           :=-o 
ArchiveOutputSwitch    := 
PreprocessOnlySwitch   :=-E 
ObjectsFileList        :="test.txt"
PCHCompileFlags        :=
MakeDirCommand         :=makedir
RcCmpOptions           := 
RcCompilerName         :=windres
LinkOptions            :=  
IncludePath            :=  $(IncludeSwitch). $(IncludeSwitch). 
IncludePCH             := 
RcIncludePath          := 
Libs                   := 
ArLibs                 :=  
LibPath                := $(LibraryPathSwitch). 

##
## Common variables
## AR, CXX, CC, CXXFLAGS and CFLAGS can be overriden using an environment variables
##
AR       := ar rcus
CXX      := gcc
CC       := gcc
CXXFLAGS :=  -g -O0 -Wall $(Preprocessors)
CFLAGS   :=  -g -O0 -Wall $(Preprocessors)


##
## User defined environment variables
##
CodeLiteDir:=E:\CodeLite
UNIT_TEST_PP_SRC_DIR:=E:\UnitTest++
Objects0=$(IntermediateDirectory)/main$(ObjectSuffix) 

Objects=$(Objects0) 

##
## Main Build Targets 
##
.PHONY: all clean PreBuild PrePreBuild PostBuild
all: $(OutputFile)

$(OutputFile): $(IntermediateDirectory)/.d $(Objects) 
	@$(MakeDirCommand) $(@D)
	@echo "" > $(IntermediateDirectory)/.d
	@echo $(Objects0)  > $(ObjectsFileList)
	$(LinkerName) $(OutputSwitch)$(OutputFile) @$(ObjectsFileList) $(LibPath) $(Libs) $(LinkOptions)

$(IntermediateDirectory)/.d:
	@$(MakeDirCommand) "$(WorkspacePath)/$(ConfigurationName)"

PreBuild:


##
## Objects
##
$(IntermediateDirectory)/main$(ObjectSuffix): main.c $(IntermediateDirectory)/main$(DependSuffix)
	$(CC) $(SourceSwitch) "E:/Experiment/test/main.c" $(CFLAGS) $(ObjectSwitch)$(IntermediateDirectory)/main$(ObjectSuffix) $(IncludePath)
$(IntermediateDirectory)/main$(DependSuffix): main.c
	@$(CC) $(CFLAGS) $(IncludePath) -MG -MP -MT$(IntermediateDirectory)/main$(ObjectSuffix) -MF$(IntermediateDirectory)/main$(DependSuffix) -MM "main.c"

$(IntermediateDirectory)/main$(PreprocessSuffix): main.c
	@$(CC) $(CFLAGS) $(IncludePath) $(PreprocessOnlySwitch) $(OutputSwitch) $(IntermediateDirectory)/main$(PreprocessSuffix) "main.c"


-include $(IntermediateDirectory)/*$(DependSuffix)
##
## Clean
##
clean:
	$(RM) $(IntermediateDirectory)/main$(ObjectSuffix)
	$(RM) $(IntermediateDirectory)/main$(DependSuffix)
	$(RM) $(IntermediateDirectory)/main$(PreprocessSuffix)
	$(RM) $(OutputFile)
	$(RM) $(OutputFile).exe
	$(RM) "../.build-debug/test"

第72行是
all: $(OutputFile)
而$(OutputFile)依賴於$(IntermediateDirectory)。確實,我有改動過$(IntermediateDirectory),這個變數是中間目錄,Codelite 將所有中間檔案和生成檔案都放在這個目錄下邊了。原來的值應該是./$(ConfigurationName)吧,因為我將多個工程放在在同一個工作區內,為了方便除錯想生成時把這些都輸出到同一個輸出目錄下,所以改成了$(WorkspacePath)/$(ConfigurationName)。將$(IntermediateDirectory)的值改回原來的值又可以編譯了。嘿!找對方向了。仔細比對發現$(WorkspacePath)的值是"E:\Experiment\"已經自帶了一個反斜槓,於是把多出來的斜槓去掉,改成$(WorkspacePath)$(ConfigurationName)。試了下,還是不行。莫非還真是路徑支援有問題?這個MinGW自帶的make程式版本是3.8.1。看到makefile最後一行的雙點和聯想到可以編譯的$(IntermediateDirectory)的原來的值,說不定改成相對路徑以避免windows碟符這種奇怪語法。我試著將其改為../../Experiment/$(ConfigurationName)。還別說,編譯通過,這基本達到改動設定的初衷。只是這。。我無語。

但我終究還是氣不過,自己又試了將$(IntermediateDirectory)改成不同的值的情況,其中E:/Experiment/$(ConfigurationName)也可以通過,另外我輸入E:\Experiment\$(ConfigurationName)點完Apply的時候,Codelite自動將路徑中的反斜槓改成了斜槓。看來罪魁禍首不是那些碟符斜槓下劃線什麼的,而是擴充套件$(WorkspacePath)時多出來的不起眼的雙引號。

經過試驗,路徑中包含碟符和下劃線都能夠通過編譯,但路徑中有中文字元時出現亂碼,對字元編碼我無能為力但我可以不在路徑中用中文字元。另外路徑中包含空格也是不行的哦,因為make會把它分開成幾個路徑來看。