Copy a file using a makefile at runtime - makefile

I used to compile my programs with batch scripts on windows but I recently discovered makefiles which are much more efficient.
I had this line in my .bat file that copied some dlls to the current directory at runtime and it worked perfectly.
copy C:\lib\glfw\glfw.dll
I tried the same line in my makefile and even tried the alternative cp but my terminal prints this error even tho the file is IN the location I specified
process_begin: CreateProcess(NULL, copy C:\lib\glfw\glfw.dll, ...) failed
make (e=2): The system cannot find the file specified.
make: *** [core.exe] Error 2
Here is the full makefile that I am using. Mind you, absent the copy line it works like a charm.. what am I doing wrong or is this possible?
EXEC = core.exe
OBJS = src/obp.o
CC = g++
CFLAGS = -W -Wall
LIBS = -lSOIL -lglew32 -lglfw -lopengl32
LDFLAGS =
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $# $(OBJS) $(LIBS)
copy C:\lib\glfw\glfw.dll
clean:
rm -f $(EXEC) $(OBJS) *~

It looks like you are running this from an MSYS (or MinGW) environment, which does not know about copy. Instead, you can use
cp C:\lib\glfw\glfw.dll .
If you want to avoid the *nix like cp, then you could use xcopy as follows:
xcopy //Y C:\lib\glfw\glfw.dll
Note the double // which is required to escape the /.
Or you could run this in a regular MS-DOS environment, in which case your clean target will not work because rm will not be found and you should use del.
With your current setup, any built-in DOS command will not be found. See Choosing the shell to read about how make determines which shell to use.

You may need to double the backslashes in order for make to understand what you want:
copy c:\\lib\\glfw\\glfw.dll
Make comes from a Unix background where the file separator is /, so it's sometimes a bit awkward to use it in a Windows environment.

Related

Compile error - Make error: *** multiple target patterns. Stop

I have a problem with a makefile that's part of a repository. I already posted this question but don't know how to add some code lines after, so I'm trying it here.There is a problem with the makefile that has the common make rules. When I run make, I get the following error: C:\Mios32/include/makefile/common.mk:143: *** multiple target patterns. Stop.
Here's the code from common.mk file from line 142 to 144:
# rule to create .elf file
$(PROJECT_OUT)/$(PROJECT).elf: $(ALL_OBJS)
#$(CC) $(CFLAGS) $(ALL_OBJS) $(LIBS) $(LDFLAGS) -o$#
I'm guessing it's a problem with all_objs, cause these lines right before seem to work:
# rule to create a .hex and .bin file
%.bin : $(PROJECT_OUT)/$(PROJECT).elf
#$(OBJCOPY) $< -O binary $#
%.hex : $(PROJECT_OUT)/$(PROJECT).elf
#$(OBJCOPY) $< -O ihex $#
# rule to create a listing file from .elf
%.lss: $(PROJECT_OUT)/$(PROJECT).elf
#$(OBJDUMP) -w -h -S -C $< > $#
# rule to create a symbol table from .elf
%.sym: $(PROJECT_OUT)/$(PROJECT).elf
#$(NM) -n $< > $#
Here's some additional lines with all_objs:
# list of all objects
ALL_OBJS = $(addprefix $(PROJECT_OUT)/, $(THUMB_OBJS) $(THUMB_CPP_OBJS) $(THUMB_AS_OBJS)
$(ARM_OBJS) $(ARM_CPP_OBJS) $(ARM_AS_OBJS))
# list of all dependency files
ALL_DFILES = $(ALL_OBJS:.o=.d)
And here's some additional lines with Project_out and project:
# where should the output files be located
PROJECT_OUT ?= $(PROJECT)_build
# default linker flags
LDFLAGS += -T $(LD_FILE) -mthumb -u _start -Wl,--gc-section -Xlinker -M -Xlinker -
Map=$(PROJECT_OUT)/$(PROJECT).map -nostartfiles -lstdc++
# default rule
all: dirs cleanhex $(PROJECT).hex $(PROJECT_OUT)/$(PROJECT).bin
$(PROJECT_OUT)/$(PROJECT).lss $(PROJECT_OUT)/$(PROJECT).sym projectinfo
# create the output directories
dirs:
#-if [ ! -e $(PROJECT_OUT) ]; then mkdir $(PROJECT_OUT); fi;
#-$(foreach DIR,$(DIRS), if [ ! -e $(PROJECT_OUT)/$(DIR) ]; \
then mkdir -p $(PROJECT_OUT)/$(DIR); fi; )
I'm pretty new to the whole Make and Makefile topic, so I'm having a hard time figuring out the problem. I appreciate every help.
You should be clear in your question what OS you're working on. It seems from the error message above you're working on Windows. The makefile you're trying to use is very clearly targeted at a UNIX system like GNU/Linux or possibly MacOS.
If you are not familiar with the differences between Windows and UNIX (which are vast and deep) you will definitely have a lot of learning to do before you can even start to get this working.
To use UNIX environments on Windows you need to use something like WSL, or Cygwin, or at least install a MinGW shell environment. When you do that you need to be using UNIX paths, not Windows paths. Windows paths use backslashes (which are escape sequences in UNIX) and drive letters (which have no equivalent in UNIX) and in makefiles in particular the : character is special to make so using paths with drive letters is a problem.
You can debug your makefile by adding $(info ...) functions to show you the value of variables:
# rule to create .elf file
$(info PROJECT_OUT = $(PROJECT_OUT))
$(info PROJECT = $(PROJECT))
$(info ALL_OBJS = $(ALL_OBJS))
$(PROJECT_OUT)/$(PROJECT).elf: $(ALL_OBJS)
#$(CC) $(CFLAGS) $(ALL_OBJS) $(LIBS) $(LDFLAGS) -o$#

Getting rid of QMAKE-generated makefile's output spam

If I would write makefile by hand , I can do something like this
CXX = #g++
%.o: %.cpp makefile
#echo Compiling $< ...
$(CXX) -c $(FLAGS) $<
This would hide the executed command (thanks to #) but leaves all diagnostic and compiler's output. It would remove huge lists of parameters out of output log, but also would leave a comprehensive message.
I'm unable to reproduce this behaviour with Qmake, because all I can supply is a variable named QMAKE_CXX, content of which it would paste as a compiler, no way to insert a line break to my knowledge. Using these commands results in output like this
Compiling main.cpp...; #g++ -c -o main.o main.cpp
Can I organize output similar to manual compiler while using only QMAKE project file?
Should be something like this:
QMAKE_CXX = #echo "Message" && $$QMAKE_CXX
QMAKE apparently got undocumented QMAKE_UIC and QMAKE_MOC, with former being broken in some versions. Also an undocumented CONFIG += silent which replaces command lines with similar messages and uses same principle.

GNU make is adding white space after -I (shared directory) option

I'm trying to use armclang compiler through a GNU makefile, but there is a clash between both tools when using -I option.
For armclang compiler, the -I means "Adds the specified directory to the list of places that are searched to find included files.Syntax -Idir" without a space.
For GNU makefile ‘-I dir’ has the same meaning (but with a space).
in My makefile I have the following:
$(aarch32_bootobj): %.o: %.s
#echo " [ASM ] $<"
#armclang --target=armv8a-arm-none-eabi -Icommon/shared -c $< -o $#
When Running the Makefile, I'm getting the following Warning and Error :
armclang: warning: argument unused during compilation: '-I common/shared'
aarch32/shared/bootcode.s:32:10: error: Could not find include file 'boot_defs.hs'
Where boot_defs.hs exists under common/shared
When running the same armclang command outside the makefile, it works. therefore I'm assuming that makefile has formatted the -Icommon/share option and added automatic space just after the -I.
Is there any way to run the armclang command correctly? in other worlds, is it possible to let the makefile parse the -Icommon/shared without any automatic formatting?
I have been trying a lot of tricks to workaround that without any success.
Thanks a lot In advance.
GNU make doesn't split the -Icommon/shared option, and even if it did armclang would be able to parse that. If you remove the # from the armclang call in the Makefile, you'll see exactly what make does and that the -Icommon/shared parameter remains intact.
Your problem is with armclang; see this bug on the tracker. It doesn't pass -I flags to its integrated assembler. A workaround, then, should be to pass -no-integrated-as to armclang:
#armclang -no-integrated-as --target=armv8a-arm-none-eabi -Icommon/shared -c $< -o $#
If that doesn't work, replace the .include directive with #include and either rename your asm files to .S (upper-case S), which indicates that they need C preprocessing, or pass armclang the -x assembler-with-cpp flag. The behavior of this is documented here.

MY computer can't find my makefile on Cygwin (windows)

I'm trying to run the make utility of cygwin, and it keeps telling me that "***No targets specified and no Makefile found. Stop"
I don't get it. This is my makefile if it helps, it's called Makefile.mak:
TestSet.out: TestSet.o Set.o
g++ -o TestSet.out TestSet.o Set.o
TestSet.o: TestSet.cpp Set.h SetInterface.h
g++ -c TestSet.cpp
Set.o: Set.cpp Set.h SetInterface.h
g++ -c Set.cpp
clean:
rm TestSet.out TestSet.o Set.o
This is my makefile if it helps, it's called Makefile.mak
Well that's your problem then.
That isn't one of the names that make looks for by default.
You either need to rename the file or use make -f Makefile.mak
See http://www.gnu.org/software/make/manual/make.html#Makefile-Arguments
You should also make sure you have the man-pages installed for Cygwin, then you can run man make and you will see:
If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that order.
That would also have answered your question, because it says nothing about files named Makefile.mak

Makefile clean not removing *.o files?

I wonder why this won't delete/clean *.o files generated when running make?
# UNIX Makefile
CXX = g++
LD = g++
CXXFLAGS = -g
testlfunction: lfunction.o lfunctionlist.o lprocessor.o testlfunction.o
$(LD) -o $# $^
clean:
rm *.o testlfunction
before it use to be
$(RM) *.o testlfunction
but it didn't work also ;(
Why is this?
To check what really happens, run "make clean" and examine the output of that command.
Is it nothing? Then there might be a file called "clean" in the current directory. Remove it and try again.
Does it start with "rm ..."? Then it seems to be normal.
In all other cases, tell us the exact output you get.
To check whether the commands are really run, insert some "echo" commands before and after the "rm" command. Are they executed?
And finally, did you distinguish between tab characters and spaces? In Makefiles the difference is important. Commands must be indented using tabs.
One way that make clean can 'fail' to execute anything is if there is a file called clean in your directory, possibly the result of running make -t clean. This would create a file, so when you next ran make clean, it would appear up to date - it has no dependencies, so there is no reason to run the action.
If you use GNU Make, ensure that you have the line:
.PHONY: clean
That will stop make -t from creating clean and will ensure that the actions are run.

Resources