Compile program using a Makefile with gcc instead of clang - makefile

I am writing a program to spell-check a given text. On my pc I used this Makefile to compile the program:
# compiler to use
CC = clang
# flags to pass compiler
CFLAGS = -ggdb3 -O0 Qunused-arguments -std=c99 -Wall -Werror
# name for executable
EXE = speller
# space-separated list of header files
HDRS = dictionary.h
# space-separated list of source files
SRCS = speller.c dictionary.c
# automatically generated list of object files
OBJS = $(SRCS:.c=.o)
# default target
$(EXE): $(OBJS) $(HDRS) Makefile
$(CC) $(CFLAGS) -o $# $(OBJS) $(LIBS)
# dependencies
$(OBJS): $(HDRS) Makefile
I would like to continue programming on my Raspberry Pi but I only have gcc installed. Is it possible to make this Makefile work for gcc? I tried to change the compiler with:
CC = gcc
but It doesn't work. I get the error message "unrecognised option -Qunused-arguments".

The problem is that the -Q option which Clang accepts isn't an option which GCC recognises.
GCC and Clang are completely separate compilers, and so one shouldn't really expect one of them to understand the other's options. In fact, Clang does make some efforts to be modestly compatible with GCC, in large part to make it possible to use it as a drop-in replacement for GCC. However that compatibility isn't, and probably shouldn't be, complete.
So your solution is simply to change the CFLAGS definition at the same time as you change the CC definition.

Related

Why aren't my variables expanding in my makefile?

I'm using mingw32-make to run my makefile. The contents of the Makefile are the following:
#OBJS specifies which files to compile as part of the project
OBJS = SDLpp.o SDLpp_exception.o SDLpp_window.o
#CC specifies which compiler we're using
CC = g++
#INCLUDE_PATHS specifies the additional include paths we'll need
INCLUDE_PATHS = -IC:\mingw_dev_lib\include\SDL2 \
-IC:\mingw_dev_lib\include\SDL_image \
-IC:\mingw_dev_lib\include\SDLpp
#LIBRARY_PATHS specifies the additional library paths we'll need
LIBRARY_PATHS = -LC:\mingw_dev_lib\lib
#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
# -Wall includes all warnings
# -Wl,-subsystem,windows gets rid of the console window
COMPILER_FLAGS = -Wall
#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image
#LIB_NAME specifies the name of our library
LIB_NAME = libSDLcpp.a
#This is the target that compiles our executable
all : $(OBJS)
ar rvs $(LIB_NAME) $(OBJS)
%.o : %.c
$(CC) $< $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) -c $(LINKER_FLAGS) -o $#
^(the white-space before the commands are tabs)^
When run, the shell outputs
g++ -c -o SDLpp.o SDLpp.cpp
which indicates that the other variables are not being expanding in the first pattern rule. Oddly, only CC is expanding into g++. Why is this happening?
The issue is not one of non-expanding variables. Rather, the makefile is using the default rule instead of the one you provided.
The reason may be that your rule uses *.c, while you likely have *.cpp files, IIRC.

Compiling and linking fortran code with MakeFile using Intel compiler

I have a code that is about 8,000 lines and is contained in the same one big bigcode.f90 file. It compiles without problems from the command line with intel compiler with the options:
mpif90 bigcode.f90 -r8 -O2 -xHost -override-limits -o output.out
I want to split this large file into modules and link them using makefile. Below I am listing the makefile. (So here I have main.f90, and also 8 modules linked to it, such as modparams.o and other 7). So I just broke the bigcode.f90 into 9 files. The problem is that when I compile with the makefile, it complains about things like
subroutine ended with "end" statement instead of "end subroutine"
integer passed to reals
some name conflicts between variable names and subroutine names.
All these may well be bad style. However the original bigcode.f90 had all of these, and it did not prevent it from compiling at all. I want to first replicate the results between the bigcode.f90 and the split version - and then I will make other changes.
I also made a copy of this makefile without any OBJECTS to link (just the single bigcode.f90), and that also compiled without any complains. Could somebody help me understand why is there inconsistency about what the compiler complains when there is one file versus when there are several linked files?
# DEFAULT FLAGS
CFLAGS := -I$(CPATH) -I$(F90_MODULES_PATH)
F90 := mpif90
# ADD ALL LIBRARIES HERE (with -l$LIBRARY_NAME)
LDFLAGS := -llapack -v
# ADD ALL SOURCE FILES HERE (with .o extension)
OBJECTS := modparams.o
OBJECTS += modleeplex.o
OBJECTS += modutilsmain.o
OBJECTS += modecon.o
OBJECTS += modindirect.o
OBJECTS += modijutils.o
OBJECTS += modselectstata.o
OBJECTS += modfcn.o
# ADD ADDITIONAL COMPILER FLAGS HERE
CFLAGS += -fbounds-check
CFLAGS += -ffree-line-length-350
CFLAGS += -r8
CFLAGS += -O2
CFLAGS += -xHost
CFLAGS += -override-limits
# ADD ADDITIONAL MODULE FOLDERS HERE (with -I$PATH_TO_FOLDER)
F90_MODULES += -I.
all: main
main: main.f90 $(OBJECTS)
$(F90) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $< -o $#
%.o : %.f90
$(F90) -c $< $(CFLAGS) $(F90_MODULES) $(LDFLAGS) -o $#
clean:
rm -rf $(OBJECTS) *.mod
When I compile, I get the following, and then a long list of errors.
mpif90 -c modfcn.f90 -I/opt/intel/composer_xe_2013.5.192/mkl/include:/opt/intel/composer_xe_2013.5.192/tbb/include:/opt/intel/composer_xe_20 13.5.192/mkl/include:/opt/intel/composer_xe_2013.5.192/tbb/include -I -fbounds-check -ffree-line-length-350 -r8 -O2 -xHost -override-lim its -I. -llapack -v -o modfcn.o
ifort: command line warning #10006: ignoring unknown option '-ffree-line-length-350'
ifort: command line remark #10010: option '-pthread' is deprecated and will be removed in a future release. See '-help deprecated'
ifort version 13.1.3

Why does Make use ASFLAGS for both gcc and as when their flags aren't compatible?

I want to assemble and link some code for a 32-bit target from a 64-bit host, and I'm trying to use make's implicit rules as much as possible.
If I put -m32 in ASFLAGS it works fine for linking and assembling in one step, as make will use gcc for this. But if one of my executables needs separate linking, everything breaks, because make will then use as for assembling, and as doesn't understand -m32. To solve this I can use --32 instead, but this will of course not work with gcc.
$ cat Makefile
ASFLAGS = -m32
all: prog1 prog2
prog2: prog2.o
$ make
cc -m32 prog1.s -o prog1
as -m32 -o prog2.o prog2.s
as: unrecognized option '-m32'
<builtin>: recipe for target 'prog2.o' failed
make: *** [prog2.o] Error 1
Why does make use ASFLAGS for both gcc and as when their flags aren't compatible? Am I not supposed to specify the architecture this way? Do I really have to hack my way around this (i.e. actually write something in my Makefile), or is there something I've missed?
Since ASFLAGS is used by both LINK.s (gcc) and COMPILE.s (as) as you mentioned, one possible solution is to add following in the Makefile for compiling %.s with $(AS),
EXTRA_ASFLAGS = --32
%.o : %.s
$(AS) $(ASFLAGS) $(EXTRA_ASFLAGS) $(TARGET_MACH) -o $# $<
, or
COMPILE.s += --32
Well, you lied to make and as. If you put in ASFLAGS something that is not an assembler option, you're doing something out of spec.
make cannot know what options the compiler and assembler understand. To deal with this, make provides a way to specify the options for each tool separately: use CFLAGS for the compiler, ASFLAGS for the assembler, LDFLAGS for the link step.
I suggest using make CFLAGS=-m32 ASFLAGS=--32.

Link static library using gcc with gnu make

I'm following Zed Shaw's tutorial "Learn C the Hard Way" and trying to teach myself c programming language.
On my ubuntu desktop, I encountered the linking problem he mentioned in the note of this post.
That is, when linking a static library with gcc, using a command like this:
gcc -Wall -g -DNDEBUG -lmylib ex29.c -o ex29
The linker fails to find the functions in the lib. To link correctly, I have to change the order of source file and lib to this:
gcc -Wall -g -DNDEBUG ex29.c -lmylib -o ex29
And I'm trying to use the makefile offered by Zed to automate unit test. The makefile looks like this:
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/libYOUR_LIBRARY.a
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
The rest part of the makefile that isn't listed here can build the $(TARGET) lib flawlessly.
The problem is Zed append the lib to the $(CFLAGS) and use the implicit rule to compile the test files which leads to a command like this:
gcc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG tests/hashmap_tests.c build/mylib.a -o tests/list_tests
The command fails because of the link problem mentioned before as expected.
The solution I came up with was to write the compilation command explicitly like this so I can change the order:
$(TESTS): $(TARGET)
$(CC) $(CFLAGS) $^ $(TARGET) -o $#
This works fine if there is only one main source file. Unfortunately, I have several out there under the ./tests directory, and a command like this is a total disaster.
My question is, how should I change my makefile to make it work or is there any other way I can do the same work as elegant as expected?
CFLAGS holds compiler flags, like -g -O2. You should not add linker flags to it. CPPFLAGS holds preprocessor flags like -Isrc -DNDEBUG. LDFLAGS holds linker flags, which would include things like -L (capital L) if you need it to find libraries, and -rdynamic. And the LDLIBS variable holds libraries, so you should do this:
CPPFLAGS = -Isrc -DNDEBUG
CFLAGS = -g -O2 -Wall -Wextra
LDFLAGS = -rdynamic
LDLIBS = -lmylib
Now you can use the built-in rules for GNU make to build your program. You can see a list of the build-in rules by running make -p -f/dev/null.
Of course the above are just the default variables make defines and uses with its default rules. You don't have to use them, but in general it's better to follow conventions rather than flaunt them.

make is calling g++ is always re-compiles even when I do not change the source code

I am using make which calls g++ always re-compiles the code, even when I do not change the source code. That happens for all my projects, even for simple ones such as:
[code]
all: main.cpp
g++ -std=c++11 -c main.cpp
[/code]
I believe it should compare the date/time on source and object code. Could some help me with this, I am running using GNU toolchain on Ubuntu 12.04
THX
Edit: sorry guys, I do use Makefile, I edited my question accordingly.
Simplest Makefile
It was already pointed out that your Makefile is probably wrong. The 'all' target is indeed always built (although it may result in a no-op if it has no commands and all dependencies are already satisfied). All you need in your makefile is this:
all: main
Object files
If you expect to have more source file in your build, you should consider creating intermediate object files:
all: main
main: main.o
Tweak the build
Make will automatically find the main.ccp file and turn it into main which is required per the directive above. You can use special make variables to further tweak the compilation, e.g. for debug information inclusion and for warning configuration:
CXXFLAGS = -g -Wall -Werror
all: main
main: main.o
Nitpicking
If you insist on building up the compile rule yourself, you can do it like this:
%.o: %.hpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
CXX: C++ compiler
CPPFLAGS: C preprocessor flags
CXXFLAGS: C++ compiler flags
$#: Target
$<: First dependency
If you don't want to use the standard variables nor pattern matching, you can build up the whole makefile explicitly:
all: main
main: main.o
gcc -o $# $^
main.o: main.c
gcc -g -Wall -Werror -o $# -c $<
$^: Use that one if you want to include all dependencies, for example if you have multiple *.o files to build one binary.
Note: It is a bad idea to write the file names directly into the command as you might forget to update them later.
all: main.cpp
g++ -std=c++11 -c main.cpp
This seems wrong. Why does the rule for all has main.cpp as its target? Shouldn't it be something.exe or something.o? Say
all: main.exe
main.exe: main.cpp
g++ -std=c++11 main.cpp -o main.exe
clean:
del main.exe
Targets are output files and cpp files are source code which should be input to the make system.
g++ would have to "recompile" in general (what happens if you change the header but not main.cpp?)
If you are concerned about long build times, you should use something like Make (which is designed specifically to avoid recompiling when the source hasn't changed)
The compiler will always compile the code. If you want to do conditional compilation (based on file times etc) you will need to use a make system such as Make, CMake, Ant, etc. For the simplest you can set up a small "Makefile" in the directory and use the command "make" to build.
Simple Makefile for compiling "myapp.exe" from "main.cpp", "file1.cpp" and "file2.cpp"
myapp.exe: main.o file1.o file2.o
g++ -o myapp.exe main.o file1.o file2.o
(make knows to use .cpp files to build .o files)
But if you also have header files, then you will need to build dependency chains, for which you may want to look into something more sophisticated like automake, cmake, ant, etc.
---- EDIT ----
Based on your updated post, the problem is that you aren't specifying a target, so Make has to assume it needs to recompile. See my example in the above answer.

Resources