只能使用makefile中的一个目标文件

所以我正在尝试为交叉编译代码制作自己的make文件。 我从通配符文件夹中获取C文件,但是当我在csources文件夹中有多个C文件时,它不会创build对象文件。

# Macros linux_compiler = gcc win32_compiler = i686-w64-mingw32-gcc win64_compiler = x86_64-w64-mingw32-gcc program = main cfolder = csources headerfolder = hsources objectfolder = osources csources = $(wildcard $(cfolder)/*.c) hsources = $(wildcard $(headerfolder)/*.h) osources_linux = $(patsubst $(cfolder)/%.c,$(objectfolder)/%_linux.o,$(wildcard $(cfolder)/*.c)) osources_win32 = $(patsubst $(cfolder)/%.c,$(objectfolder)/%_win32.o,$(wildcard $(cfolder)/*.c)) osources_win64 = $(patsubst $(cfolder)/%.c,$(objectfolder)/%_win64.o,$(wildcard $(cfolder)/*.c)) # First target all: clearscreen $(program)_win64 $(program)_win32 $(program)_linux $(info $(program) created $(csources)) # Use to force compile the program force: clean clearscreen $(program)_win64 $(program)_win32 $(program)_linux $(info $(program) forcible created) $(program)_linux: $(osources_linux) $(objectfolder)/$(program)_linux.o $(linux_compiler) $(objectfolder)/$(program)_linux.o $(osources_linux) -o $(program)_linux $(program)_win32: $(osources_win32) $(objectfolder)/$(program)_win32.o $(win32_compiler) $(objectfolder)/$(program)_win32.o $(osources_win32) -o $(program)_win32 $(program)_win64: $(osources_win64) $(objectfolder)/$(program)_win64.o $(win64_compiler) $(objectfolder)/$(program)_win64.o $(osources_win64) -o $(program)_win64 $(osources_linux): $(csources) $(hsources) $(linux_compiler) -c $(csources) -o $(osources_linux) $(osources_win32): $(csources) $(hsources) $(win32_compiler) -c $(csources) -o $(osources_win32) $(osources_win64): $(csources) $(hsources) $(win64_compiler) -c $(csources) -o $(osources_win64) $(objectfolder)/$(program)_linux.o: $(program).c $(linux_compiler) -c $(program).c -o $(objectfolder)/$(program)_linux.o $(objectfolder)/$(program)_win32.o: $(program).c $(win32_compiler) -c $(program).c -o $(objectfolder)/$(program)_win32.o $(objectfolder)/$(program)_win64.o: $(program).c $(win64_compiler) -c $(program).c -o $(objectfolder)/$(program)_win64.o clearscreen: clear clean: rm $(objectfolder)/*.o 

我不太了解makefile,我认为这应该可以工作,但是不会生成任何目标文件。

 $(osources_win64): $(csources) $(hsources) $(win64_compiler) -c $(csources) -o $(osources_win64) 

而我得到的错误,当我有更多的一个c文件在cfolder中:

 x86_64-w64-mingw32-gcc -c csources/log.c csources/SDL_add.c -o osources/log_win64.o osources/SDL_add_win64.o x86_64-w64-mingw32-gcc: error: osources/SDL_add_win64.o: No such file or directory makefile:132: recipe for target 'osources/SDL_add_win64.o' failed make: *** [osources/SDL_add_win64.o] Error 1 

解:

 ############################################################################### ## This is the makefile for the application within the SDL2 (game) engine ## ## This will crosscompile your code to linux and windows (32 and 64 bit) ## ## Started development in 19-02-2016 ## ## Version = 1.00 ## ## Status = Operational ## ## Author = Marijn van Tricht ## ## ## ## === Log ================================================================= ## ## ## ## 20-02-2016 - Version 1.00 created ## ## ## ############################################################################### ############################################################################### ## Read below to understand the makefile ## ############################################################################### ## ## ## === Functions =========================================================== ## ## ## ## generic format of a target ## ## Target: Dependencies ## ## <TAB> Command ## ## ## ## Target: ## ## Target is a function, when make is called it will automaticly select the ## ## first target. ## ## ## ## Dependencies: ## ## Here there's a list of files or function needed to execute the command. ## ## When a depencie is a function it will execute that function before it ## ## will make the target. ## ## ## ## Command: ## ## Here the information is provided which will be pasted in the terminal. ## ## ## ## === Compiling =========================================================== ## ## ## ## One of those commands could be to compile your code. general thats what a ## ## makefile is made to do. ## ## ## ## In the simplest form the command to compile a program is a compiler like ## ## gcc or g++ and ac or cpp file as an argument. ## ## For example: ## ## gcc main.c ## ## ## ## this will generate a program called a.out ## ## ## ## === Parameters ========================================================== ## ## ## ## With this command you can give a lot of parameters. ## ## For example -o main will change the output filename to main.out so, ## ## gcc main.c -o main will result in a file called main.out ## ## ## ## All the parameters used by this makefile are described and listed below. ## ## ## ## -o <filename> | This will change the output name of function to be ## ## | filename ## ## ## ## -c | This will compile to the program to objectfiles. This ## ## | can than later be compiled again with the compiler to ## ## | a program. The change is that the objectfiles won't be ## ## | deleted by the compiler. ## ## ## ## === Macros ============================================================== ## ## ## ## Macros can copy paste lines in your code for example you could make a ## ## macro for the compiler you'll use. You can do that by adding the ## ## following: ## ## Compiler = gcc ## ## ## ## This can then be pasted into the code by using $(compiler). ## ## So Macros can be defined be the = sign and can be pasted by $(macro). ## ## ## ## === Specific functions ================================================== ## ## ## ## There are a few Specific functions you can use in a makefile those are ## ## used in the sameway as macros do a list of specific functions that are ## ## used in this makefile are listed below. ## ## ## ## $(info <text>) | The <text> will be printed in ## ## | the terminal ## ## ## ## $(wildcard <folder>/*.<format> | This will select all the ## ## | .<format> files in the selected ## ## | <folder> ## ## ## ## $(patsubst <replace>,<with>,<file(s)>) | With this we can replace the ## ## | name(s) of some file(s) ## ## ## ############################################################################### # Macros linux_compiler = gcc win32_compiler = i686-w64-mingw32-gcc win64_compiler = x86_64-w64-mingw32-gcc linux_flags = -lSDL2 win32_flags = -lSDL2main -lSDL2 win64_flags = -lSDL2main -lSDL2 program = main cfolder = csources/ headerfolder = hsources/ objectfolder = osources/ csources = $(wildcard $(cfolder)*.c) hsources = $(wildcard $(headerfolder)*.h) osources_linux = $(patsubst $(cfolder)%.c,$(objectfolder)%_linux.o,$(wildcard $(cfolder)*.c)) osources_win32 = $(patsubst $(cfolder)%.c,$(objectfolder)%_win32.o,$(wildcard $(cfolder)*.c)) osources_win64 = $(patsubst $(cfolder)%.c,$(objectfolder)%_win64.o,$(wildcard $(cfolder)*.c)) # First target all: clearscreen $(objectfolder) $(program)_win64 $(program)_win32 $(program)_linux $(info $(program) created) # Use to force compile the program force: clean clearscreen $(objectfolder) $(program)_win64 $(program)_win32 $(program)_linux $(info $(program) forcible created) $(program)_linux: $(osources_linux) $(objectfolder)$(program)_linux.o $(linux_compiler) $(linux_flags) $(objectfolder)$(program)_linux.o $(osources_linux) -o $(program)_linux $(program)_win32: $(osources_win32) $(objectfolder)$(program)_win32.o $(win32_compiler) $(objectfolder)$(program)_win32.o $(osources_win32) -o $(program)_win32 $(win32_flags) $(program)_win64: $(osources_win64) $(objectfolder)$(program)_win64.o $(win64_compiler) $(objectfolder)$(program)_win64.o $(osources_win64) -o $(program)_win64 $(win64_flags) $(objectfolder)%_linux.o: $(cfolder)%.c $(linux_compiler) -c $? -D LINUX -o $@ $(objectfolder)%_win32.o: $(cfolder)%.c $(win32_compiler) -c $? -D WIN32 -o $@ $(objectfolder)%_win64.o: $(cfolder)%.c $(win64_compiler) -c $? -D WIN64 -o $@ $(objectfolder)$(program)_linux.o: $(program).c $(linux_compiler) -c $(program).c -D LINUX -o $(objectfolder)$(program)_linux.o $(objectfolder)$(program)_win32.o: $(program).c $(win32_compiler) -c $(program).c -D WIN32 -o $(objectfolder)$(program)_win32.o $(objectfolder)$(program)_win64.o: $(program).c $(win64_compiler) -c $(program).c -D WIN64 -o $(objectfolder)$(program)_win64.o $(objectfolder): mkdir $(objectfolder) clearscreen: clear clean: rm $(objectfolder)*.o 

您需要一些通用规则来在每个平台中创建对象文件。

 $(objectfolder)/%_linux.o: $(cfolder)/%.c $(linux_compiler) -c $? -o $@ $(objectfolder)/%_win32.o: $(cfolder)/%.c $(win32_compiler) -c $? -o $@ $(objectfolder)/%_win64.o: $(cfolder)/%.c $(win64_compiler) -c $? -o $@ 

看看这个例子:

 sakkath ~ $ gcc -c file1.c file2.c -o file1.o file2.o gcc: error: file2.o: No such file or directory sakkath ~ $ 

您不能为-o指定两个参数,并且如果您尝试两次使用“-o”标志,则会发生这种情况:

 gcc: fatal error: cannot specify -o with -c, -S or -E with multiple files compilation terminated. 

当您不使用-c时,您可以指定多个文件的唯一原因是因为链接阶段被调用,并且根据定义,通过将多个文件链接在一起来生成一个可执行文件。 但这只是“-o”的一个参数。 你得到错误的原因是因为gcc正在将你试图指定的文件解释为“-o”的第二个参数作为附加的输入文件。 考虑一下:

 gcc file1.c -o main file2.c 

这将不会创建两个输出文件,但将会如同您以这种方式调用它一样(参数的顺序基本上不重要):

 gcc file1.c file2.c -o main