只能在 makefile 中使用一个目标文件
can only make with only one object file in makefile
所以我正在尝试为交叉编译代码制作自己的 make 文件。我正在使用通配符从一个文件夹中获取 C 文件,但是当我在 csources 文件夹中有多个 C 文件时,它不会创建目标文件。
# 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 文件夹中有多个 c 文件时出现的错误:
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 a c 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
所以我正在尝试为交叉编译代码制作自己的 make 文件。我正在使用通配符从一个文件夹中获取 C 文件,但是当我在 csources 文件夹中有多个 C 文件时,它不会创建目标文件。
# 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 文件夹中有多个 c 文件时出现的错误:
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 a c 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