1

Is there any possible way to compile C program in a more efficient manner than running whole command.

gcc -g -Wall file_name.c -o file_name.out

For example to use make command in this way: make argument.c

I want the make command to run this command gcc -g -Wall argument.c -o argument_no_extension.out

I was trying to learn vim but to compile program I have to write down whole command or have to use arrow keys to run it again . But vs-code task.json which have the following arguments:

"gcc","-g", "${relativeFile}", "-o","${fileBasenameNoExtension}.out", "&&", "clear" , "&&" , "./${fileBasenameNoExtension}.out"
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 5
    the keyword you are looking for is certainly *makefile* – Cid Mar 12 '20 at 08:27
  • Yes , I know makefile is used to run make command but I don't know how to make a makefile for this purpose. – Utkarsh Singh Mar 12 '20 at 08:29
  • 3
    Conventionally, apart from the default output from the C compilers `a.out`, programs don't have an extension on Unix systems. You don't have to type `ls.out` or anything like that. You can type `make file_name` and it will compile from `file_name.c`. You can set the compilation options, too. If you really insist on `.out` extensions, you can write a rule to create a `.out` file from a `.c` file. – Jonathan Leffler Mar 12 '20 at 09:00
  • In short you are asking me to drop .out extension and just name executable based on file_name . – Utkarsh Singh Mar 12 '20 at 09:10

3 Answers3

2

As mentioned in the comments you can already do

make file_name

and it will, using default build rules (so you don't even need a Makefile), build an executable called "file_name" if there is a C source file called "file_name.c"

if you really do need the executable to have the .out extension you could create a Makefile that looks like this

CFLAGS=-g -Wall

%.out: %.c
        $(CC) $(CFLAGS) -o $@ $^

This defines a rule that for anything that ends in ".out" it will build it from the corresponding ".c" file. So if you type

make file_name.out

as above it will build "file_name.out" if you have a "file_name.c"

Chris Turner
  • 8,082
  • 1
  • 14
  • 18
  • Sir can you please explain $@ and $^ and thanks for answering . As mentioned in other comment i don't think .out extension is necessary for making an executable . I have also tried an alternative method by making a bash script "gcc -g -Wall $1.c -o $1 " . Can you tell me advantages of make over a bash script. – Utkarsh Singh Mar 13 '20 at 09:08
  • 1
    `$@` is replaced with the filename on the left hand side of the rule - the thing you're building. `$^` is the files on the right (the dependencies). – Chris Turner Mar 13 '20 at 09:44
  • 1
    As for why to use `make` - it's a standard tool used by programmers for decades and unlike your script, it knows when it needs to build something or not. If you try `make something` twice, it will only compile "something" once where as your script will re-compile everything. You'll find it indispensable when you have multiple source and header files compiling into one executable – Chris Turner Mar 13 '20 at 09:49
  • What does %.out: %.c do? – Utkarsh Singh Mar 13 '20 at 11:38
  • That was covered in the answer – Chris Turner Mar 13 '20 at 12:12
  • I tried to make a "makefile" with your instruction and passed file_name.out as argument to make command but it throws error: *** No rule to make target 'helloworld.out'. Stop. but when i tried "make helloworld" then it generated an executable with helloworld but then i again tried "make helloworld.out" again then it generated helloworld.out using copy command on previous executable (helloworld) . – Utkarsh Singh Mar 13 '20 at 12:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/209571/discussion-between-utkarsh-singh-and-chris-turner). – Utkarsh Singh Mar 13 '20 at 13:30
  • Sounds like you called the file the wrong name - it should be called "Makefile" (with a capital M) – Chris Turner Mar 13 '20 at 14:12
  • No, actually it was Makefile only – Utkarsh Singh Mar 13 '20 at 14:48
0

Just create a Makefilewhich should contain the command as you shown

gcc -g -Wall file_name.c -o file_name.out

Place this Makefile in the directory where the source code is there. Then open the command line and change the directory to the location where this Makefile is there.

Then execute this command

make

No need to give make argument.c

Vishnu CS
  • 748
  • 1
  • 10
  • 24
  • But problem arises when i need to compile file of different name such as fact.c or stackoverflow.c then every time i have to make a separate make file but i want to make a general make file which accepts name of file as argument for make command and just execute gcc command . – Utkarsh Singh Mar 12 '20 at 08:40
  • For that you have to create some script for running the makefile. Can u please have a look into this link https://stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line – Vishnu CS Mar 12 '20 at 08:45
  • Well, that's not what your question asks for. – MadScientist Mar 12 '20 at 23:34
  • @MadScientist Sorry I was unable to explain my question well . Sir i checked your profile you seems to be a veteran emacs user . Currently i am learning vim , should i try emacs also . If yes , then why? – Utkarsh Singh Mar 13 '20 at 09:04
  • I'm not sure SO comments are the best place to discuss. Emacs vs. vi is one of the oldest arguments out there among programmers... I can't answer in 500 characters. vi is good to learn, at least enough to get around, since it's installed everywhere. If you need an editor for real work you should try Emacs and see. I've found that preference is somewhat personal. Some people like modal editing. Some don't. Some like a single editor that runs for days/weeks with lots of buffers, some like stopping/starting. Emacs has some fantastic modes, including Viper if you like vi modal editing. – MadScientist Mar 13 '20 at 13:43
  • Sorry for asking such question in comments which are completely off topic but I just wanted a one-to-one interaction with a emacs user and their view on vim . But thanks for providing with such a precise explanation in the given word limit. – Utkarsh Singh Mar 13 '20 at 14:55
0

you could create a Makefile similar to:

CFLAGS := -Wall -Wextra -Wconversion -pedantic -std=gnu11 -ggdb

%.out : %$(parm).c
    $(CC)  $(CFLAGS) $^ -o $@

Then to run the Makefile for a specific *.c file use:

make -Dparm=<desired file name>
user3629249
  • 16,402
  • 1
  • 16
  • 17