Basically I am trying to make a simple make file that creates a lexer.o and then a driver.o file combining them into an executable.
Code below shows what has been tried. Running it in Windows powershell using GNU make.
.PRECIOUS = driver.cpp lexer.h lexer.cpp
lexer.o: lexer.cpp lexer.h
g++ -o $# -c lexer.cpp
driver.o: driver.cpp lexer.h
g++ -o $# -c driver.cpp
lex.exe: lexer.o driver.o
g++ -o $# $^
clean:
$(RM) *.o lex.exe
Here is what output is given. I was expecting it to create the lexer.o file, but instead it cannot "find" the file it was supposed to create.
g++ -o lexer.o -c lexer.cpp
process_begin: CreateProcess(NULL, g++ -o lexer.o -c lexer.cpp, ...)
failed.
make (e=2): The system cannot find the file specified.
make: *** [lexer.o] Error 2
It ended up just being a G++ installation problem. I swapped over to Ubuntu and reinstalled everything and it worked fine.
Related
I am trying to run some old Fortran code of my project team in ubuntu 16.04. I have not done any modifications to the existing code. All I have done is installed gfortran, opened a terminal, and gone to the file location using the cd command. Here I have many files, but just consider these two: a script file compile.sh, and a makefile remail.make.
In compile.sh:
make -f remail.make
In remail.make:
SOURCE_APPLI= ../SOURCES_COUNTERFLOW/
$(SOURCE_APPLI)grcom.f
TARGET = remail.e
OBJECTS = $(SOURCES_f77:.f=.o)
COMPILE = f90
.f90.o :
$(COMPILE) -o $*.o -c $*.f90
.f.o :
$(COMPILE) -o $*.o -c $*.f
$(TARGET) : $(OBJECTS)
$(COMPILE) $(OBJECTS) -o $#
del :
$(DELETE) $(OBJECTS)
When I run compile.sh, I get this error:
f90 ../SOURCES_COUNTERFLOW/grcom.o -o remail.e
make: f90: Command not found
make: *** [remail.e] Error 127
I have installed fort77 and gfortran-4.8 compilers.
What is the reason for this error?
The problem was that I was not using the correct executable.
For example, In my case, I installed fort77 and gfortran-4.8 and the executable was saved in the name as fort77 and gfortran-4.8.
The reason for my error was that I was calling these two executables as fort77 and gfortran instead of fort77 and gfortran-4.8.
When I called fort77 and gfortran-4.8 correctly in the terminal, it works!!
I have a makefile to create a library, and I need it to create a 80% library or a complete library, which means a library with 80% of the functions or a library with all of the functions.
When I call make, the "all" rule should create the 80% library (so far so good), and when I call "make complete" the "complete" rule should create the 100% library (still easy), and it should not relink in any case, here I have a problem.
WHAT GOES WELL:
here is what I have :
all: $(NAME)
$(NAME): $(OBJS)
ar -rc $# $^
complete: $(NAME) $(MORE_OBJS)
ar -rc $^
%.o : %.c
gcc -I. -c -o $# $<
.PHONY: complete
so if I run make it goes:
>make
gcc -I. -c -o function01.o function01.c
gcc -I. -c -o function02.o function02.c
gcc -I. -c -o function03.o function03.c
gcc -I. -c -o function04.o function04.c
ar -rc libtest.a function01.o function02.o function03.o function04.o
and make again:
>make
make: Nothing to be done for 'all'.
perfect. then with make complete:
>make complete
gcc -I. -c -o function_05.o function05.c
gcc -I. -c -o function_06.o function06.c
ar -rc libtest.a function05.o function06.o
or of course:
>make fclean
rm *.o
rm libtest.a
>make complete
gcc -I. -c -o function01.o function01.c
gcc -I. -c -o function02.o function02.c
gcc -I. -c -o function03.o function03.c
gcc -I. -c -o function04.o function04.c
ar -rc libtest.a function01.o function02.o function03.o function04.o
gcc -I. -c -o function_05.o function05.c
gcc -I. -c -o function_06.o function06.c
ar -rc libtest.a function05.o function06.o
WHAT GOES WRONG:
but if I prompt make complete again:
>make complete
ar -rc libtest.a function05.o function06.o
I don't recompile but I relink the library.
I've tried a lot of approach, with the target-specific assignment, re-ordering the targets and the rules in many different combination, but I didn't find any way of doing it. am I missing something or is it indeed hard?
also, I can't put the additional functions in another file with its own makefile and use "make -C" to make it and then add it to the library, everything has to be in this makefile and the sources at the root
make complete will always run, because the target name is complete and no file named complete is ever created. So as far as make knows that file is not up to date and needs to be rebuilt.
There is no straightforward way to do this because make doesn't support multiple different recipes creating the same target.
You can fake it out by using a sentinel file to inform make whether the target exists or not. To do this, you need to create the file complete so make can use it to track whether or not it needs to be rebuilt. Try:
complete: $(NAME) $(MORE_OBJS)
ar -rc $^
#touch $#
First, I should admit makefiles are something that I'm very inexperienced at, so I apologize if this is an error that I should have been able to solve myself, but I have spent several hours on this, including reading the various answers on this site, and have been unable to discover a solution.
With that said, I have created the following makefile to compile my code on a Linux machine; it completes the sub compilations just fine, but when it comes to making the output itself, xPlatST, it throws an error.
g++ -std=c+=11 -g -Wall -pthread -c -o xPlatST.o xPlatST.cpp
g++ -std=c+=11 -g -Wall -pthread -c -o stdafx.o stdafx.cpp
g++ -std=c+=11 -g -Wall -pthread -c xPlatST xPlatST.o stdafx.o -L../hwloc
g++ error: xPlatST: No such file or directory
make: *** [xPlatST] Error 1
I believe it seems to think that the xPlatST is one of it's compilation files and thus can't find it, but for the life of me I can't work out why.
hwloc is a third party library, and should be unrelated to this issue. The code compiles just fine when compiled from the command line directly.
My files are xPlatST.cpp, xPlatST.h, stdafx.cpp, stdafh.h
Code is as follows:
CXX = g++ -std=c++11
INCLUDES =
LIBS = -L../hwloc
CXXFLAGS = -Wall -g -pthread
OBJS = xPlatST.o stdafx.o
xPlatST: ${OBJS}
${CXX} ${CXXFLAGS} ${INCLUDES} -c $# ${OBJS} ${LIBS}
clean:
-rm xPlatST *.o
Any help would be greatly appreciated; thank you in advance.
Your assumption is correct. Your recipe is trying to use xPlatST as a source. Change the -c into a -o in your rule:
${CXX} ${CXXFLAGS} ${INCLUDES} -o $# ${OBJS} ${LIBS}
The -c flag tells the compiler to take all files, compile, and assemble them into an object file (.o). The -o flag specifies the destination file.
I am trying to understand makefile.
I took atmega168 bootloader's makefile and simplified it to this:
CC = avr-gcc
override CFLAGS = -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
atmega328: ATmegaBOOT_168_atmega328.hex
%.elf: ATmegaBOOT_168.o
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -Wl,--section-start=.text=0x7800 -o $# $<
clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
%.hex: %.elf
avr-objcopy -j .text -j .data -O ihex $< $#
When I ran $ make atmega328 I get:
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -Wl,--section-start=.text=0x7800 -o ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168_atmega328.hex
rm ATmegaBOOT_168_atmega328.elf ATmegaBOOT_168.o
Why cannot I remove CC or CFLAGS?
I understand some basics of makefile. I read a lot on the internet, plus went through gnu manual, but I cannot understand the very first output with ATmegaBOOT_168.c. What/How has generated first command?
Was there used some second makefile? If yes, how to find its location?
UPDATE:
If I rename ATmegaBOOT_168.c to ATmegaBOOT_1681.c. Running $ make atmega328 gives:
make: *** No rule to make target 'ATmegaBOOT_168_atmega328.hex', needed by 'atmega328'. Stop.
but the rule is present.
CC and CFLAGS are variables used in the built in implicit rules of GNU make. When you run make, it reads your makefile a bit like:
No target given, so we'll make the first: atmega328. This requires a .hex file.
The .hex file can be generated from a .elf file per the last rule.
.elf files can be generated by the %.elf rule (which here looks like you've broken the pattern, as there's no % in the dependencies).
There's no rule for .o in this file, so the default recipe $(CC) $(CPPFLAGS) $(CFLAGS) -c is used. Since a .c file is found, this rule is applicable and generates the first command. The rule could have been written (as shown in suffix rules):
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
Backtrack up this list, now that the source has been found, and run the commands.
If the implicit rule variables are left unset, you will typically get programs built for your host system using cc.
I'm using CentOS 6.5. When I do a make, I typically see the full gcc/g++ commands that the Makefile is executing, like
...
gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I/opt/emacs/emacs-24.3/lib -I../src -I/opt/emacs/emacs-24.3/src -g3 -O2 -MT pthread_sigmask.o -MD -MP -MF .deps/pthread_sigmask.Tpo -c -o pthread_sigmask.o pthread_sigmask.c
...
But in some systems, I only see:
$ make
Building test1.o...
Building test2.o...
...
Is it possible to change the "Building ..." messages back to the full gcc/g++ command output?
The output that you see when you run make with a given makefile
depends on how the makefile is written. You will see the
output that the author of the makefile wants you to see.
If a command in a recipe in the makefile is prefixed with #,
then make will not echo the command. So if my makefile is, e.g.
foobar: foobar.o
gcc -o $# $<
foobar.o: foobar.c
gcc -c -o $# $<
then the output of make will be:
gcc -c -o foobar.o foobar.c
gcc -o foobar foobar.o
But if I change the makefile to:
foobar: foobar.o
#echo "Linking foobar"
#gcc -o $# $<
foobar.o: foobar.c
#echo "Compiling foobar"
#gcc -c -o $# $<
then the output becomes:
Compiling foobar
Linking foobar
So to see the output that you would prefer to see you will have to edit the
makefile, removing the #-prefixes from the commands you expect to see
and deleting entirely the commands that print the "Building..." messages.
At least, this is what you would need to do if the makefiles that bother
you in this way build the target using recipes that directly invoke gcc/g++. It
is possible that they build their targets using recipes that invoke some intermediate
tool that doesn't echo the compiler commands and instead emits the "Building..."
messages. Without seeing the makefile(s) I can't say.