C Makefiles, multiple compilers - c

I am new to coding so please bear with me. I have searched and have not been able to find a solution for my problem. I working in C and I have multiple files that I have to compile using the c11 compiler and one file that I need to use GNU gcc with. Is there a way to create a makefile that can do this with both compilers or is there a high level way that I am unaware of?
Thanks in advance

The CC make variable tells make what C compiler to use. With GNU make it can be defined globally or on a per-target basis. The following should do what you want (assuming foo.c is the source file you want to compile with gcc):
CC := c11
foo.o: CC=gcc
Demonstration (with clang instead of c11 because I do not have this one):
$ ls
bar.c baz.c foo.c Makefile
$ cat Makefile
all: $(patsubst %.c,%.o,$(wildcard *.c))
CC := clang
foo.o: CC=gcc
$ make
gcc -c -o foo.o foo.c
clang -c -o bar.o bar.c
clang -c -o baz.o baz.c

Related

Compiling any single C code using a Makefile

I am pretty new to Makefiles, so my question might be silly. It would be the following: Can I pass another argument to make so that I can do stuff with this additional argument?
More specifically, if possible, I would want to use this to compile any single C source code into its executable using a Makefile.
For example, if I have two files foo.c and bar.c, I would want to be able to compile them using the same recipe, therefore doing something similar to make compile foo.c or make compile bar.c that compiles them into the foo or bar executables, respectively.
If it is not possible, is there an alternative I can do for simple C programs? It would be useful to save time (not updating the Makefile or not writing gcc -o name name.c every time I want to compile a C file I just created).
Thank you in advance for your patience and time.
If you are dealing with single main file applications, a bash script sounds much simpler, build.sh:
#!/bin/bash
SOURCE=$1
BIN=${SOURCE%.c}
if [[ -z "$SOURCE" || ! -s "$SOURCE" ]]; then
echo "SOURCE is empty"
exit 1
fi
gcc -o "$BIN" "$SOURCE"
and then invoke it like this:
./build.sh foo.c
./build.sh bar.c
I use the makefile below for this. 'make' or 'make all' compiles each .c (eg eg.c) file in the directory to an executable in the same directory (eg eg). 'make eg' compiles just eg.c to eg . There's nothing special about the compiler flags -- CFLAGS -- or linker flags -- LFLAGS -- they're just what I habitually use.
CC = gcc
CFLAGS = -std=gnu11 -Wall -Wextra
LFLAGS = -lm -lrt
OPATH = ./
PROGS += $(patsubst %.c,$(OPATH)%,$(wildcard *.c))
all: $(PROGS)
$(OPATH)% : %.c ; $(CC) $(CFLAGS) $< -o $# $(LFLAGS)
clean:
\rm -f $(PROGS)
Make has built-in rules that knows how to compile a source file into an executable.
So, you don't even have to write a makefile at all (unless you want to use special compiler options). This will work:
$ ls
bar.c foo.c
$ make foo
cc -o foo foo.c
$ make bar
cc -o bar bar.c
If you want to modify the compiler operations, add a makefile that sets the appropriate built-in variables:
$ ls
bar.c foo.c Makefile
$ cat Makefile
CC = gcc
CFLAGS = -O2 -g
$ make foo
gcc -O2 -g -o foo foo.c
$ make bar
gcc -O2 -g -o bar bar.c
how about using this:
================== makefile =====================
CC=gcc
CCFLAGS=-ansi -pedantic -Wall
all : clean foo bar
foo : foo.c
$(CC) $(CCFLAGS) foo.c -o foo
bar : bar.c
$(CC) $(CCFLAGS) bar.c -o bar
clean :
rm -f *.o *.*~ foo bar
====================== end makefile ======================
invoking make as make will run the default target (all in this case) removing all intermediate files and output files and then rebuilding foo and bar
invoking make as make foo will only run the rule for making foo.
invoking make as make bar will only run the rule for making bar.
invoking make as make clean will only run the rule for cleaning the project directory -- removing all intermediate and output files.

Custom C library: can functions in the same library refer to each other?

I've just started to create my own C libraries to keep my commonly used functions tidy. However, I've hit a new problem and I struggled to find information on the best route to take.
I generate my library of two functions using the following:
gcc -I. -c -fpic rand_site.c
gcc -I. -c -fpic rand_spin.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o
Each of these source files contained a single function. I was hoping to create a third function for my library that uses the two functions above but I'm not sure how to use functions from within the same library.
Am I going about this the right way? What is the best practice for doing this?
Yes, you can.
Create a header file rand_site.h and put the declaration of the function defined in rand_site.c in it.
Create a header file rand_spin.h and put the declaration of the function defined in rand_spin.c in it.
Use #include to include the two .h files in the third file, say foo.c.
Then compile foo.c and add it to the library using:
gcc -I. -c -fpic foo.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o foo.o
If you would like to create a second shared library that has foo.o, you can use:
gcc -I. -c -fpic foo.c
gcc -shared -o libfoo.so foo.o -lstatphys
If you would like to create an executable using foo.o, you can use:
gcc -I. -c foo.c
gcc foo.o -lstatphys

Is it possible with -Wall but only display warnings in specific files?

I am writing a project in C using GCC 4.8 and I would like to see all the warnings (hoping to eliminate them) but the problem is I am #including some old, not maintained library which gives me huge wall of warnings in reaction to -Wall option. There is no way I fix those and I just want to ignore it focusing on code I actually write/maintain.
So can I:
gcc -Wall-excluding-OldBlackBox.c -myproject.c ?
Update your makefile so that you have a different gcc -Wxxx line for different files (or groups of files)
result.exe : xxx.o yyy.o
gcc -o result.exe xxx.o yyy.o
xxx.o : xxx.c
gcc -Wall xxx.c
yyy.o : yyy.c
gcc -W yyy.c
first create individual object files and then link them as single Executable.
//compilation with warnings and compilation without warnings
gcc -Wall file1.c file2.c -o foo.o && gcc -w file3.c file4.c -o foo1.o
gcc -o final foo.o foo1.o

Using Make for compiling C

I am trying to learn make to make my compiling easier as I learn C.
I am attempting to do:
gcc -Wall -g 3.c -o 3 -lm
using
CC = gcc
CFLAGS = -Wall -g
clean:
rm -f 3
but I don't know how and where to put -lm in the makefile. I've looked for tutorials online but they haven't specifically addressed the "-lm" option, or if they do it is without little explanation and doesn't work in my situation.
You need a "target" in which to execute the gcc command. Like:
CC = gcc
CFLAGS = -Wall -g
all:
gcc -Wall -g 3.c -o 3 -lm
clean:
rm -f 3
Then you can just replace parts of the "all" command, with your macros; CFLAGS, for example would probably have the "-lm".
It might help if you ran "make -n", that will tell you what make would do if it were to run.
Often you'll see library specific flags in a LIBS variable, e.g.:
CC = gcc
CFLAGS = -Wall -g -I/some/include/directory
LIBS = -lm -L/some/library/directory
all:
$(CC) $(CFLAGS) $(LIBS) 3.c -o 3
The variable you are looking for is called LDLFAGS. From §10.3 of the GNU Make manual:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’.
So, simply do:
LDFLAGS += -lm
Hope it helps.
An extremely good tutorial: Make Tutorial: How-To Write A Makefile
and here is a good generic makefile I wrote:
http://pastebin.com/PCk0gNtE
The part that would most interest you would be this section:
# C Preprocessor Flags
CPPFLAGS +=
# compiler flags
CFLAGS += -ansi -Wall -Wextra -pedantic-errors
# libraries to link to ( m == math )
program_LIBRARIES := m
# LDFLAGS is the variable to hold linker flags
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
GNU make defines a lot of default rules. For C compilation and linking, those rules are:
n.o is made automatically from n.c with a recipe of the form ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’.
n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is ‘$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)’.
So the way to add "-lm" option to the linker is by defining:
LDLIBS = -lm
Then when you run make with your Makefile, you following commands will be run:
gcc -Wall -g -c 3.c
gcc 3.o -o 3 -lm
(note that make will compile your C program in 2 steps, first creating the object file 3.o then linking the object file into the executable 3)
(see http://www.gnu.org/software/make/manual/ for the GNU make manual)

Compiling multiple source files

I have four files containing C code.
Headers.h - (contain all necessary) headers
AddStudent.h - that file include Headers.h also introduce some function delegation
AddStudent.c - contains functions described in AddStudent.h
main.c - contains main()
The question is how to compile the code with cc ?
In your case, your probably just need:
cc main.c AddStudent.c
The right thing to do is make a makefile. Here's a (probably a bit naive) example:
myapp: main.o AddStudent.o
cc -o myapp main.o AddStudent.o
main.o: main.c AddStudent.h Headers.h
cc -c -o main.o main.c
AddStudent.o: AddStudent.c AddStudent.h Headers.h
cc -c -o AddStudent.o AddStudent.c
The best place to learn about make is the GNU Make Manual.
Bonus note - if you're starting to learn C, you might want to check out clang. It gives way better error messages than gcc does, in addition to supporting C99 without special flags and being much faster at compiling.

Resources