How to create Makefile to compile a single arbitrary filename in C - c

I'm very new to C programming and I want to know what to write in a Makefile to compile a single .c file.
Say I have a multiple .c files in one folder )namely sample1.c, sample2.c, sample3.c, etc) and I only want to compile a specific filename.
I want to only type "make sample2" which will compile and have an output called sample2 (pretty much the .c name will be maintained).
I've read several solutions and someone might have suggested this but didn't work.
SRC = $(shell find . -type f -name \*.c)
executable: $(SRC:.c=.o)
gcc -std=gnu99 $# $^
What do I need to do to make it work?

Converting a comment into an answer.
You don't need a makefile for that: make sample2 will compile sample2.c to create the program sample2.
You could use /dev/null as the name of the makefile if you want (or if you need to ignore an existing makefile):
make -f /dev/null sample2
That compiles with the default options, of course. If you want to use more stringent flags, then you might do this (assuming that the existing makefile is expendable):
echo 'CFLAGS = -Wall -Wextra -Werror -std=c11 -O3 -g' > makefile
make sample2
or some variant on that theme, such as:
make -f /dev/null CFLAGS="-Wall -Wextra -Werror -std=c11 -O3 -g" sample2
In short, make knows how to compile single C files into the executable of the corresponding name (minus the .c suffix) without needing any explicit makefile. You can tweak how it compiles that file if need be.

Related

Why gcc compiler giving the complied file a new name?

I have reinstalled mingw in my system and downloaded the gcc compiler.
I was shocked after compiling the first file which was "subject.c" but the name of the compiled file which gcc returned was "a.exe". It should be "subject.exe" but do not know why this happened.
Can anyone please explain the reason behind this ?
expected:
gcc subject.c
ls
subject.c subject.exe
tried:
gcc subject.c
ls
subject.c a.exe
-o can be used to give the name of the output file.
For example,
gcc -Wall -Wextra -pedantic subject.c -o subject.exe
(Do enable your compiler's warnings!)
gcc names its output files, in the absence of other instructions, a.out or a.exe depending on system environment because that is what it's supposed to do.
To override this default behavior, you can use the -o flag which tells gcc that the next argument is the desired name for the output file. For instance:
gcc -o subject.exe subject.c
There is no automatic functionality built into gcc to strip a source file of its file extension and add .exe to the end but this can be done manually with Makefiles or other similar scripts, for instance you can write a Makefile with the following contents:
%.exe: %.c
gcc -o $# $<
Then a command like make subject.exe would be translated to gcc -o subject.exe subject.c, which may be what you're looking for.
There is functionality built into gcc to strip source files of their extensions during different parts of the compilation process, which may have been what confused you. For instance a call like gcc -c subject.c can be expected to produce an object file called subject.o, likewise gcc -S subject.c can be expected to produce an assembly language file called subject.s, however this does not apply to executable files not only for historical reasons, but because programs can be compiled from multiple source files and there is not always a clear way to choose a name for the executable output.

Compile Multiple C Files on Mac?

I am new to C and using GCC. How do I compile multiple C files and then run them? I have multiple miles and each has different functions and they are supposed to run through the main.c file. My friend showed me through Windows but I am having issues figuring out how to do it on Mac.
What I was told:
Compile both files individually first:
gcc -Wall -c .\main.c
gcc -Wall -c .\file.c
Then compile both together into an executable:
gcc -o program file.o main.o
Then run executable with .\program.exe
You should probably investigate makefiles, but this is quite easy. The following should do the trick.
gcc -o program file.c main.c
Feel free to add in whichever -W warning flags you want.
Note also that Macs do not use \ as a directory separator but rather /, and executable files do not typically end in .exe.

Including headers file using GCC

Sorry. I think this question would be very easy to you guys.
I have two c files and one h file, I put those two .c files stack.c and main.c and one .h file stack.h inside a folder named "test" at Desktop.
So they are in C:\Users\user\Desktop\test
However when i try to test this code by writing
gcc -c stack.c sq_main.c -l stack.h
It continuously shows "unkown type name ..."
I think the header file is not included into those two .c files.
Actually I wrote the code
#include "stack.h"
Inside stack.c and main.c
Can anyone tell me how to include header file properly?
You are using GCC wrongly. I guess you are on Linux (or on something emulating it like MinGW ...)
If you insist on giving several commands in a terminal, you'll need to run
gcc -Wall -Wextra -g -c stack.c
gcc -Wall -Wextra -g -c sq_main.c
these two commands are building object files stack.o & sq_main.o (from stack.c & the #include-d stack.h, and sq_main.c & the #include-d stack.h, respectively). The options -Wall -Wextra are asking for all warnings and some extra warnings. The -g option asks for debugging information. The -c option asks for compiling only. Assuming that they are enough for your program, you need to link these object files to make an executable:
gcc -g stack.o sq_main.o -o myprogram
You might need to add -Iinclude-directory options to the compiling commands (the first two), and you might need to add -Llibrary-directory and -llibrary-name to the linking command. Order of arguments to gcc matters a lot. You could also add -H to ask the compiler to show which files are included. And GCC has a lot of other options. Read the Invoking GCC chapter of its documentation.
The .o suffix might be .obj on most Windows systems. You might also need myprogram.exe instead of myprogram. I never used Windows so I cannot help more.
In practice, you should use GNU make and write some Makefile; this answer might inspire you.

Generic makefile that is independent of source file name

I wanted to create a generic makefile that can take the source file name compile it, save it as the object file and executable file. Both files using the original source name. Thank you for your help.
exec: \
compile
./helloworld #I would like to input source outside the make file.
compile: \
helloworld.c
gcc -Wall helloworld.c -o helloworld #<==
echo 'compiling'
touch compile
#I would like makefile to automatically save both object and exec.
#as the source file name.
You can use the $(MAKECMDGOALS) variable thus:
CFLAGS = -Wall
$(MAKECMDGOALS): $(MAKECMDGOALS).o
and then simply call Make like this:
make myfile
If you have Make 3.81 or later, then this can become:
CFLAGS = -Wall
.SECONDARY: # Prevents intermediate files from being deleted
If you're not interested in saving the intermediate object file, then you don't even need a Makefile. You can simply do:
make bar CFLAGS=-Wall
Make has built-in rules that know how to create an executable from a source file, if they have the same name. So you don't even need a makefile at all!
$ ls
foobar.c
$ make foobar
cc foobar.c -o foobar
Not that there's no need to mess with .SECONDARY because make has a direct rule to build an executable from a .c, without compiling the .o first (so there's no intermediate file). Even if it didn't, there's no advantage here to keeping the .o file around so it's not worth the extra effort to do so (IMO).
If you want to change compilers or flags you can have a makefile that consists of nothing other than some variable assignments:
$ ls
foobar.c Makefile
$ cat Makefile
CC = gcc
CFLAGS = -Wall
$ make foobar
gcc -Wall foobar.c -o foobar

compile with -ansi -pedantic -Wall switches automatically with gcc

We are required to compile C source codes using gcc in this manner:
gcc -ansi -pedantic -Wall program.c
I'm wondering how can I 'automate' this so when I enter:
gcc program.c
It will automatically compile with the 3 switches. Is this possible?
You can also use the implicit rules of make, so that you don't have to write a makefile for every program. Make will automatically call the compiler if you say make foo and there exists a foo.c file in the current directory. To add flags to this define the variable CFLAGS in your environment, e.g. in bash add export CFLAGS="-Wall -pedantic -ansi" to .bashrc.
If your program depends on multiple files however you'll have to create a makefile, but for C compilation you can get away with just listing dependancies so long as one of them has the same base name as a target.
For example for this makefile:
# Makefile
foo:foo.o bar.o
running make will execute the commands
gcc $CFLAGS -c -o foo.o foo.c
gcc $CFLAGS -c -o bar.o bar.c
gcc -o foo foo.o bar.o
without you having to add any rules.
To automate the build of any number of build steps / complex parameters, you should use a makefile.
Once you have a makefile you simply need to type: make
alias gcc="gcc -ansi -pedantic -Wall"
But as #Brian said, you really should use a makefile, or better, a build system like CMake or SCons.
A makefile would be the traditional way, especially as part of a larger build process.
If you frequently want to build without a makefile, you could define an alias in your .bashrc or equivalent: alias gcc=gcc -ansi -pedantic -Wall.
You can use a shell script that takes some cues by how its called and invokes make after setting CFLAGS appropriately for the occasional one-off build.
Lets say you have /usr/bin/compile , which is a shell script that looks at $0 to see what name actually invoked it. You then make symbolic links to it named pedantic, fullwarn, etc.
In the shell script itself, something like:
OLDCFLAGS=$CFLAGS
WHATAMI=$(basename $0)
case "$WHATAMI" in
pedantic)
export CFLAGS="-Wall -pedantic -ansi"
make $#
exit $?
;;
c99)
export CFLAGS="-std=c99 ... ... ..."
....
Then, to compile foo.c with the extra naggy flags:
pedantic foo
This is handy, as I said for one-off builds, e.g trying to compile code that someone posted in a question, or working out how to use a new library, etc.
For anything else, just use a makefile, as others have said.

Resources