Mingw and make variables - c

I'm trying to compile an open source project on windows under mingw/msys.
The makefile contains (among others) this line
#${MAKE} --no-print-directory -C . -f physfs.make
physfs.make contains (among others) these lines:
ifndef CC
CC = gcc
endif
when I ran make I get the following error:
Creating obj/Debug/physfs
physfs.c
make[1]: cc: Command not found
make[1]: *** [obj/Debug/physfs/physfs.o] Error 127
make: *** [physfs] Error 2
If I comment the ifndef / endif pair leaving CC = gcc intact, the build works. If instead of make I issue this command:
make -e CC=gcc
the build works as well. But when I run the following command in msys:
echo $CC
nothing is displayed.
I think there is something basic about how environment variables work in MSYS and make that I don't understand.
Could please some help me troubleshoot this issue, so I can understand why simple 'make' command complains and why the ifndef block doesn't function as I expect it to function.

CC is one of several implicit variables automatically defined in a make session, so the line ifndef CC should never evaluate to true.
This explains why you see nothing on the command line for echo $CC. The MSYS environment has no concept of CC.
If you want to see the value of variables from within a make session, you can always use the info function:
$(info $(CC))
This will echo the value of the CC variable to the console at the point when that line in the makefile is evaluated.

Related

Makefile in C: all vs target -std=c1x error

I am working on a C homework assignment and I came across a simple yet specific error when creating my Makefile.
My initial Makefile was simple:
all: numbers.o
gcc -Wall -pedantic -std=c1x numbers.c -o numbers
clean:
rm *.o
For whatever reason, despite the C program compiling correctly in the terminal, I repeatedly get the following error:
gcc: error: -std=c1x: No such file or directory
Makefile:2: recipe for target 'all' failed
The problem was actually because I had copied the gcc line from a pdf file. Thanks to the comment by raspy:
For sure it has nothing to do with target name. It looks like gcc did not treat the switch as a switch, but rather as a file name. Have you copied this command from somewhere? It happens that the - is not a simple dash but some dashy-looking Unicode character, most notably converted in word processors.

Why the implicit make rule is not working?

I have a source file asd.c and the build in rule for compiling and linking this file is not working for some reason.
Here is my super simple makefile:
asd.exe: asd.o
I am getting the following errors
cc -c -o asd.o asd.c
process_begin: CreateProcess(NULL, cc -c -o asd.o asd.c, ...) failed.
make (e=2): The system cannot find the file specified.
<builtin>: recipe for target 'asd.o' failed
mingw32-make: *** [asd.o] Error 2
several possibilities :
there is no file asd.c in the directory containing the makefile/Makefile
you do not have cc or it cannot be found through PATH. Just enter cc by hand in a shell to check
you start make from an other directory, e.g. make -f elsewhere/makefile, in that case asd.c cannot be found
Note that if you only have the line asd.exe: asd.o that will build the executable named asd.o
You can change your makefile like that :
CC = gcc
asd.exe: asd.c
<tab>$(CC) -o asd.exe asd.c
Your simple makefile should suffice, the most probable thing is that make(1) is unable to execute the default rule to compile a .c file, the default compiler is named cc and to change it to use gcc instead, you should change your Makefile to this:
CC=gcc
asd.exe: asd.o
that should work. You can also create a link to cc from gcc (that doesn't hurt, and normally cc is an alias of gcc on sites that have gcc installed as the only compiler)
Indeed, you could make asd just by saying
make asd.exe
with no makefile at all, as there's an implicit rule to generate an executable directly from its .c source file. But also you need to specify the compiler if you don't have cc, so the command should be:
make CC=gcc asd.exe
or, if you are going to always use gcc as your favourite compiler, just create an environment variable CC and assign it gcc in login environment (I'm assuming you are in Windows ---for the .exe extension--- and you know how to include a new environment variable in it)

What is wrong with my makefile for C?

I am currently learning C. I tried to make a makefile, but for some reason, it doesn't work. When I type "make" into the console, the following warnings are printed into the console:
makefile.c:1:1: warning: type specifier missing, defaults to 'int'
[-Wimplicit-int]
CFLAGS=-Wall -g
^~~~~~
makefile.c:1:9: error: use of undeclared identifier 'Wall'
CFLAGS=-Wall -g
^
makefile.c:1:15: error: use of undeclared identifier 'g'
CFLAGS=-Wall -g
^
makefile.c:4:13: error: expected ';' after top level declarator
rm -f ex1
Here is the makefile's code:
CFLAGS=-Wall -g
clean:
rm -f ex1
The code is expected to compile the file ex1.c . Why doesn't my makefile work?
When you run make it tries to figure out what you want it to do.
By default it looks for a file called Makefile or makefile (and for GNU Make, it first looks for GNUMakefile). If it finds such a file, it assumes it is a makefile and reads it.
It seems that here make finds something that looks a bit like a makefile, but then guesses what to do with it. In your case it finds your file makefile.c which it assumes is a source file containing C code, so it uses its built-in rules for processing C source files and tries to compile it with the C compiler. That fails, because your makefile is not a C program! (You lied by naming it makefile.c)
You can either tell make to read that file explicitly (even though it has an unconventional name) by running make -f makefile.c, or you can just give it a sensible name (either Makefile or makefile) so that it gets found automatically when you run make.
When make processes a makefile the first target it finds is the default target. In your makefile the first target is clean so when make runs it will run the rules for the clean target. If you want it to run a different target then either put another target first in the makefile, or specify a target explicitly, e.g. make ex1 (which will cause make to see the file ex1.c and use its built-in rules for compiling a C source file into an executable).
Makefiles are instruction to make, and they are not programs in the same sense as a c-program. From the error messages it looks like you have named your Makefile as a c-source code file, so
Rename your make file to Makefile
mv makefile.c Makefile
Your makefile does not specify what to make -- it only has a clean tag, but not to worry, if your source code is in a single file then make can figure it out, just;
Specify what you want to make
$ make ex1
or alternatively have an entry in your Makefile to do the same, like
CFLAGS=-Wall -g
ex1: ex1.c # This will tell make that ex1 is compiled from ex1.c
clean:
rm -f ex1
A Makefile is not a C file.
You shall rename it from makefile.c to Makefile (mv ./makefile.c ./Makefile)
After on, in your CFLAGS, use -W -ansi -Werror and don't forget to remove the -g when your done, otherwise, your program will be slower on execution.
And then, as it's not a C file, don't try to compile it with gcc
Just type
make
or any other rule you got preceded by make, as
make re; make clean
if you wanna compile the whole thing, then clean trash files (*.o and auto-saves depending on your rules aswell).
Makefile doesn't have extension. Change makefile.c to makefile then try.
Suppose you want create makefile for file1.c & file2.c, here file1.c is depend on file2.c create makefile as given below
makefile: file1.c file2.c
gcc -o makefile file1.c file2.c
And you can just compile using command
make makefile
I resolved the problem by doing the following:
See your all characters in your file, specially in "clean", does not change color even though you saved.
I don't think you saved correctly.
Open gedit and paste your code, then press ctrl + S to save it and then name it to Makefile, not Makefile.c. Makefile is makefile type.
When you save, check file Makefile by clicking the file property. If you see Type: maketype is Ok or see all the characters in your file, the "clean" will change color from grey to another color.
Finally, in terminal, write make clean, not make Makefile. It will run like it does in the "learnCthehardcode" course.

GNU Make "Abort trap: 6" after gcc call however call is valid when executed alone

I am using GNU Make to build a C/C++ project that many people will use. The makefile attempts to be general because there are many optional files in this project and each user selects those files through a MATLAB interface which are then provided to the makefile via command line arguments (make target OPTS='XYZ' etc...).
When I use the makefile it correctly identifies the correct object dependencies, then proceeds to find the source prerequisites for those objects and build them. However, every time it tries to execute an object rule I get an error saying "Abort trap: 6" right after the gcc call.
The Makefile is as follows
vpath %.c $(PATH) $(OBJ_DIR)
# Pick compilers
CC1=g++
CC2=gcc
LNK=g++
# Assign variables for c/cpp implicit rules
CXXFLAGS= $(CCFLAGS) $(DEFINES) $(INCLUDES)
CFLAGS = $(CCFLAGS) $(DEFINES) $(INCLUDES)
# Assign various user-defined values
OUTPUT = -o $(USER_LIB)
C_OBJECTS = $(patsubst %.c,$(OBJ_DIR)/%.o,$(C_SOURCES))
CPP_OBJECTS = $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(CPP_SOURCES))
OBJECTS = $(C_OBJECTS) $(CPP_OBJECTS) $(SIM_OBJECTS)
# User Library Dependencies and Compilation Rules
$(USER_LIB): $(OBJECTS)
$(LNK) $(LINKERFLAGS) $(CCFLAGS) $(DEFINES) $(INCLUDES) $(OUTPUT) $(OBJECTS)
$(OBJ_DIR)/%.o: %.c
$(CC2) $(CFLAGS) -c -o $# $<
and an example of what I get is:
gcc -g -D(the defines) -I(all the includes) -c -o obj1/xyz.o ../common/xyz.c
make: *** [obj1/xyz.o] Abort trap: 6
However if I take that EXACT same gcc call and run it on the command line (just copy and paste) the file is correctly compiled and the object file placed in the obj1 folder.
I tried to look at 'make -d' to see if I could find anything either. Since that output is crazy long, the gist of it is the following:
... output truncated for brevity ...
gcc -g -D(the defines) -I(all the includes) -c -o obj1/xyz.o ../common/xyz.c
Putting child 0x104f13cc0 (obj1/xyz.o) PID 24557 on the chain.
Live child 0x104f13cc0 (obj1/xyz.o) PID 24557
Reaping losing child 0x104f13cc0 PID 24557
make: *** [obj1/xyz.o] Abort trap: 6
Removing child 0x104f13cc0 PID 24557 from chain.
at which point the output ends. I also tried running make -k to see what happens after the first error. Every single source file produces the same result. Again, each source file is compilable with the exact call that make uses when done independently.
I'm completely lost on this one at this point and theres very little information about what "Abort trap: 6" means in this context.
I am running Mac OSX 10.7 with gcc-4.2 installed through Xcode.
I realize there isn't a rule for .cpp files currently, I do not at present have any .cpp source files to compile, though in the future there likely will be which is why there is support structure for it so far.
Thank you in advance for anyone who can help me.
EDIT: Added one proceeding line from the "make -d" output.
EDIT: Added solution (moved to an answer)
With help, answered my own question.
SOLVED:
First see #MadScientist's comment for what "Abort trap: 6" is.
Given that clue I realized I use a variable that could be confused with a system variable, $(PATH).
It appears Make was not interpreting the following line how I expected it:
vpath %.c $(PATH) $(OBJ_DIR) <------ Bad
It looks like there is some interference with the system variable $(PATH) which may have been causing problems. Simply changing the vpath variable to $(SRC_PATH) eliminates the conflict with the system variable and any potential interference, thus fixing the problem.
vpath %.c $(SRC_PATH) $(OBJ_DIR) <------ Good
Lesson Learned: Be careful with variable names and know what your environment variables are.
Credit to #MadScientist for pointing out what "Abort trap: 6" means and suggesting environment issues.
if there is an assert method in your code you can get that error (abort trap : 6).
for example:
assert(numberOfItems >= 0);
and if the
numberOfItems < 0
you will get such an error when you call the makefile

GCC Compiling options syntax

I am trying to gprof my program. I want a line-by-line profiling.
However, I can't seem to get the syntax right. I am using "make" and not "gcc" so please help only with suggestions that fit make. I wouldbe very grateful if you can give me the full "make" syntax.
Based on this website:
http://sourceware.org/binutils/docs/gprof/Output-Options.html[^]
http://sourceware.org/binutils/docs/gprof/Line_002dby_002dline.html[^]
Here is what I am inputting:
make USE_LOCAL_HEADERS=0 LDFLAGS='-L.' BASE_CFLAGS=-m32 CFLAGS='-fopenmp -pg -l -g'
The output is:
/usr/bin/ld: cannot find -l-g
collect2: ld returned 1 exit status
make[2]: *** [build/release-linux-ppc64/ioquake3.ppc64] Error 1
make[2]: Leaving directory `/r/home7/yasir/minoru/cfe2/yasirTemp/ioquake3dev/svfb_201110271440/ioquake3dev_clean'
make[1]: *** [targets] Error 2
make[1]: Leaving directory `/r/home7/yasir/minoru/cfe2/yasirTemp/ioquake3dev/svfb_201110271440/ioquake3dev_clean'
make: *** [release] Error 2
I need option "-l", "-g" and "-pg".
-pg enables profiling, -g includes symbol names which help interpreting the profile generated.
The -pg option needs to be passed to compiler and linker.
The -l command does not make sense in the way you are using it, as it needs a library name as parameter, so as long as you do not provide one, leave the -l away.
Also during development I'd recommend the -Wall option to enable all warnings during compilation.
So you might try this make command:
make USE_LOCAL_HEADERS=0 LDFLAGS='-L. -pg' BASE_CFLAGS=-m32 CFLAGS='-fopenmp -pg -g -Wall'
You can pass most of those as environment variables, make "should" do the right thing and use them for the compiler:
$ USE_LOCAL_HEADERS=0 \
LDFLAGS='-L.' \
BASE_CFLAGS=-m32 \
CFLAGS='-fopenmp -pg -g' \
make
That will USE_LOCAL_HEADERS, LDFLAGS, BASE_CFLAGS and CFLAGS as environment variables which make and gcc can see. You may have to edit your Makefile to combine them in the correct ways for what you want.
make is simply a "to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them" (man make). It looks like make cannot make sense of your arguments; it doesn't actually get to run any commands before it encounters an error.
I'm sorry I can't help you any further, but your problem is within your make file or similar. You should read up on what a make file is, and how to gprof your program and understand the difference between make and gcc, and reevaluate what you are trying to do. Make may not be useuful to you.

Resources