-1

I just got started writing some C programs.

To start with I was just running them through VS code. Nice and easy, I just had to press a button and bam, there it was.

But now I need to pass files as arguments to my program, which creates the need of running it from the command line.

The way I do it now, is using this two step process, (which I think is just the basic way of doing it):

ask@Garsy:~/Notes/ethHack/crpytifiles$ gcc test.c -o test

and then running the file:

ask@Garsy:~/Notes/ethHack/crpytifiles$ ./test 

This is a bit tedious in the long run. Is there any way I could do this process in one step?

And perhaps also without creating the executable?

It would be really cool if I could just run it as you normally would with a python or java file, one command, and the thing runs.

Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
Garsty100
  • 133
  • 9

4 Answers4

4

You could do that with a makefile. More about GNU Make here.

all:
  gcc test.c -o test
  ./test

The file should be called Makefile or makefile (it can have different names,just keeping it simple), and you can run it by executing:

make

Assuming you have GNU Make installed and test.c is located in the same directory with makefile.

alex01011
  • 1,670
  • 2
  • 5
  • 17
  • 2
    I'd rather make compilation, running and, possibly, linkage as separate targets. Will scale better as the project grows. – bereal May 09 '21 at 18:39
  • 1
    @bereal And that is the proper way of doing it. I just kept it simple since he is a beginner, no variables or other recipes. – alex01011 May 09 '21 at 18:41
  • A `Makefile` could be avoided, e.g. by using alternative build automation tools (like [ninja](http://ninja-build.org/)...) or a simple `compile_and_run` shell script – Basile Starynkevitch May 09 '21 at 20:29
2

This is a bit tedious in the long run. Is there any way I could do this process in one step?

Yes. You could create a shell function (or an alias if your shell supports alias arguments, which bash does not), e.g.:

ccr() { gcc "$1" -o x.$$ && ./x.$$; rm -f x.$$ }

$ ccr hello.c
Hello, world!
$

which will compile the script, run it if compilation succeeded, then remove the compiled binary.

And perhaps also without creating the execuable?

No (well, not easily). Executing binaries is offloaded to the exec*() function family, and the operations performed are complex and, I suspect, incompatible with stdin operations. So you cannot send the executable to a pipe and execute it from the pipe.

What you can do is use a C interpreter, albeit it is not exactly the same thing.

LSerni
  • 55,617
  • 10
  • 65
  • 107
1

As @alex01011 correctly stated, what you need is a Makefile, and his solution should work. What I want to suggest here is a better Makefile.

First make already know how to use build test from test.c in the simple case. It will add parameters to the preprocessor, compilation and linker steps from Makefile variables, so it is better to use the built-in command for better fleksibility.

# Tell make that `all` and `run` is technically not files that will be built
.PHONY : all run

# These flags are passed to the compiler, we always want to compile with 
# warnings when developing
CFLAGS= -Wall

# `all` is the first rule, so that is the one that will be build not    
# specifying anything on the command line
# `all` also depends on `test` so that will be built from `test.c` calling 
# `make` or `make all` 
all: test

# `make run` will run your command. `run` depends on `all` to make sure the 
# program exist before calling `./test`
# Note the the indent must be made with a tab and not spaces
run: all
       ./test

If your program is composed of more files, things get a lit more complicated, but still easily manageable:

# Example of a Makefile for a project that is composed of the files 
# test.c foo.c, bar.c, foo.h and bar.h
# The main-function is in test.c, and the generated program will be
# called `test`
#  
.PHONY: all run
CFLAGS= -Wall


all: test

# foo.c includes foo.h therefore foo.o depends on foo.h in addition to foo.c
foo.o: foo.h 

# bar.c includes bar.h therefore foo.o depends on bar.h in addition to bar.c
bar.o: bar.h 

# test.c includes both foo.h and bar.h 
test.o: foo.h bar.h 

# test should be linked with foo.o and bar.o in addition to test.o
test: foo.o bar.o

run: all
       ./test

Now typing make run will automatically build and link test, if needed, and the run ./test if there was no errors.

Other variables you may set in addition to CFLAGS are CC, CPPFLAGS, LDFLAGS, LOADLIBES and LDLIBS.

Often you also want to have a clean targets in your Makefile for typing make clean to remove generated files. See info make for more details.

HAL9000
  • 2,138
  • 1
  • 9
  • 20
  • A `Makefile` could be avoided, e.g. by using alternative build automation tools (like [ninja](http://ninja-build.org/)...) or a simple `compile_and_run` shell script – Basile Starynkevitch May 09 '21 at 20:28
  • @BasileStarynkevitch, yes, in the same way a `ninja` script or a shell script can be avoided by using a makefile. Choose the right tool for the job. Shell scripts hasn't build in knowledge on how to compile/and link files, nor does it have dependencies, or automatic rebuild of files that are older than their dependencies. Ninja has dependencies and automatic rebuild, but no builtin commands for compilation or linking. Ninja should typically be used with a frontend to create ninja-files. For small projects `make` is often simpler. – HAL9000 May 09 '21 at 20:56
1

I am wondering that nobody is issuing the general comparison between an IDE and shell. So yes IDE may give you some comfort. But you will be happy if you learnt the fundamentals of linking & Co from scratch - otherwise the configuration of the IDE can get pretty challenging, when you start stuff that does not work out of the box.

The rest are helpful tips to increase the efficiency on the shell - like make or other automation builders. Shell editors provide additional tools and plugins to increase your workflow - eg with vim as an shell editor (and some plugins) you come pretty close to an IDE. This includes syntax highlight, code check, compile and run of the program, etc... just my 2 cents

  • I think i'm pretty aware about the differences. This question was moreso asked out of the urgency of me running those commands, and being a bit bored with it – Garsty100 May 10 '21 at 09:02