How can I run an executable file without the "./" using a MakeFile? - linux

I want to run my program with an executable without the "./"
For example lets say I have the makefile:
all: RUN
RUN: main.o
gcc -0 RUN main.o
main.o: main.c
gcc -c main.c
So in order to run the program normally I would say in the terminal "make" then put "./RUN" to invoke the program.
But I would just like to say in the terminal "make" then "RUN" to invoke the program.
So to conclude I would just like to say >RUN instead of >./RUN inside the terminal. Is there any command I can use to do this inside the Makefile?
When I just put "RUN" in the terminal it just says command not found.

It is a matter of $PATH, which is imported by make from your environment.
You might set it in your Makefile, perhaps with
export PATH=$(PATH):.
or
export PATH:=$(shell echo $$PATH:.)
but I don't recommend doing that (it could be a security hole).
I recommend on the contrary using explicitly ./RUN in your Makefile, which is much more readable and less error-prone (what would happen if you got a RUN program somewhere else in your PATH ?).
BTW, you'll better read more about make, run once make -p to understand the builtin rules known to make, and have
CC= gcc
CFLAGS+= -Wall -g
(because you really want all warnings & debug info)
and simply
main.o: main.c
(without recipes in that rule) in your Makefile

change your makefile to
all: RUN
RUN: main.o
gcc -o RUN main.o && ./RUN
main.o: main.c
gcc -c main.c
just put ./filename in your makefile

Related

How to configure GCC to show all warnings by default?

I think it will be good and not much bad if -Wall flag is switched on by default. How do I configure GCC like this?
Is there any drawbacks to this other than the fact that a lot of warnings will flood your terminal when you are compiling some large program from source?
Add these lines to your ~/.bashrc if you use bash as your shell.
alias gcc='gcc -Wall'
Update:
you can refer to this question on https://superuser.com/questions/519692/alias-gcc-gcc-fpermissive-or-modifying-configure-script
If you use make, you need to overwrite make's variables CC and CXX from within the .bashrc:
export CC="gcc -wall"
export CXX="g++ -wall"
juzzlin suggested that a good method would be to write a wrapper for gcc. Marc Glisse also suggested that writing one is the best way to achieve what I want. So that's just what I did.
I made a bash script that calls gcc for me:
#!/bin/sh
echo -n "Compiling $1..."
gcc -Wall -Werror -o $(basename $1 .c).out $1
a=$?
if [[ "$a" -eq 1 ]]; then
echo "Failed!"
else
echo "Done."
echo "Executing:"
./$(basename $1 .c).out
fi
Then I copied the script to /usr/bin and made it executable:
sudo cp car /usr/bin
chmod +x /usr/bin/car
(The name of the script is car which stands for "Compile And Run")
So whenever I want to compile a source file and run it, I will type:
car mysourcefile.c
As discussed in the comments (although it's not a direct answer to your question), using a Makefile has many benefits. It provides a place where to put your build commands, that will alway stay up to date if you only build with make. It also ease running tests at each build.
Writing tests is a good habit, even when you're just working on a small and unsignificant piece of code for homeworks. It allows you to spot some dumb mistakes that you would otherwise miss, and to be sure you don't break your existing code by modifying it (especially the last minute modification).
An example of such a Makefile (here I have nothing to build apart from the test because it's a header only component):
all:
g++ -O2 -Wall -Werror -std=c++11 test_polynomial.cc -o test_polynomial -lgmp
g++ -O2 -Wall -Werror -std=c++11 test_g2polynomial.cc -o test_g2polynomial
./test_polynomial --log_level=test_suite
./test_g2polynomial --log_level=test_suite
clean:
rm -f test_polynomial test_g2polynomial
Note: The example is not a very good one as I don't even factorize the build options in CFLAGS. If I want to add a flag, I have to add it in both commands !
Another benefit is that you always run make to build, whatever the language, the dependencies or even the build system (when working on a project using scons or another build system, I still write a Makefile doing all the commands I do when building and testing !).
This allows my personal addition on it (but here we're completely off-topic): I have a build script named autobuild looping on make each time I write a file in vim. I code in screen and run autobuild in a small window at the bottom of my screen. This way, each change is built and tested as soon as I write the file.

How to make a Makefile for a program for assembly Language?

I've come across this task to build a Makefile for a program in assembly language I made (nothing fancy, like a hello world). The program is in Linux 32 bits and I'm using NASM assembler. So far I can only find Makefiles for programs for C, I'm aware that there's not much difference from one to another but I'm not familiar with this thing. What I have is this:
Program: main.o
gcc -o Program main.o
main.o: main.asm
nasm -f elf -g -F stabs main.asm
I can't tell whether this is correct or, if it does, how it works. I can't try the code because this computer doesn't have Linux. I really would like to know what's going on in the code.
First of all, read an introduction to Makefile.
Your Makefile is read by the make program on invocation. It executes either the given rule (e.g. make clean) or executes the default one (usually all).
Each rule has a name, optional dependencies, and shell code to execute.
If you use objects file you usally start your Makefile like that:
all: main.o
gcc -o PROGRAM_NAME main.o
The dependency here is main.o, so it must be resolved before the execution of the code. Make searches first for a file named main.o and use it. If it doesn't exist, it search for a rule permitting to make the file.
You have the following:
main.o: main.asm
nasm -f elf -g -F stabs main.asm
Here the rule to make main.o depends on main.asm, which is your source file so I think it already exists. The code under the rule is then executed and has to make the file matching the rule name.
If your nasm invocation is correct, then the file is created and the code of the all (or Program as you named it) is executed.
So your Makefile should work, you just have to test it to be sure :) It is barely the same as invoking:
nasm -f elf -g -F stabs main.asm && gcc -o Program main.o
As a side note, you can still test this on windows as long as you have all the tools installed. The cygwin project provides an environment where you can install make, gcc and nasm.

Linux - can you compile AND run a program in one terminal line?

For example, a program named program.c
g++ program.c -o programName
./programName
Is there any way to consolidate these two lines?
Yes, you could write...
g++ program.c -o programName && ./programName
Which will only attempt to run your program if compilation succeeded.
For a more general approach, you could write a bash script..
#!/bin/sh
g++ $1 -o $2 && ./$2
Then you could do (provided it's on your PATH, it's executable and it's called mycompile)...
mycompile program.c programName
To make this program available on your PATH, you can pop it in your bin directory or any directory under echo $PATH. If you don't wish to do that, open your ~/.bashrc file and add its parent directory to your PATH with PATH="$PATH:your/new/dir" (keep in mind all scripts in that folder will be now reachable).
Ensure it's executable (check with ls -l mycompile), if not, you can add that permission with chmod +x mycompile.
Like this:
g++ program.c -o programName && ./programName
Notice that the commands will run sequentially, that is: one after the other.

How redirect time gcc output to a file?

I am using the command :
time gcc -lm test.c > time.txt
to determine the compilation time etc. and then write them to a file.BUt when i use the above command nothing gets printed into the file?
Where am i going wrong?
It depends on what shell you use. In bash, time is a builtin and cannot be redirected. You have to use a subshell to redirect its standard error:
(time gcc -lm test.c ) 2> time.txt
The problem here is that there are two command time. One is a bash built-in command and the other one is a usual Unix command.
$> type time
time is a shell keyword
$> type `which time`
/usr/bin/time is /usr/bin/time
If you want to use the bash built-in, you should write as choroba wrote:
(time gcc -lm test.c ) 2> time.txt
But, if you want to be sure that your script works even if the built-in is not present, you better try to enforce the usage of the real time command:
`which time` -o time.txt gcc -lm test.c
For more information about time do not hesitate to do man time.

bash alias - running two commands

How do I make an alias in my .bashrc such that I can run two commands with arguments?
For example, compile source and run.
gcc-run -lm example.c
would run
gcc -lm example.c
./a.out
The closest I found was this question but it doens't have any arguments.
If you want to pass an argument, you can't use an alias. You need to use a shell function. It sounds like you want something similar to
gcc-run () {
gcc "$#"
./a.out
}

Resources