Creating CLI apps in C - c

I am wondering how to make a CLI app in C that "constantly runs". What i mean by that us for example i want to just open terminal and type a keyword and a function in a program executes. Like what "ls" is.
When you type ls it lists contents of the current dir. Likewise i want to make a program that when compiled it executes a certant stuff given the keyword is invoken. I dont want to run the executable with ./example, but rather have the command always available.The compiler i use is gcc. I have read that object file needs to be created but i dont know how to use that.
Thanks

What i mean by that us for example i want to just open terminal and type a keyword and a function in a program executes.
Your program doesn't have to "constantly run" in order for you to be able to invoke it without specifying the path... you just have to make sure that the program is located in one of the directories in your PATH, or conversely, that your PATH environment variable includes the directory where your program is located.
So let's say you want to compile hello.c into a command called hello. Here's the code:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
So you'd compile that like:
> gcc -o hello hello.c
Now you should have an executable file called hello in your current directory, and you can run it like:
> ./hello
But you just want to type hello anywhere, right? So, you can add the current directory to your PATH environment variable, e.g.:
> export PATH=$PATH:$PWD
That adds the value of PWD, an environment variable that contains the current directory, to PATH, which is an environment variable that contains a list of directories where the shell will look for executable programs.
If you want to make that change permanent, you'll need to modify one of the scripts that runs when you start up whatever shell you're using. That's a little beyond the scope of this answer, and there's plenty of advice about how to set up your PATH online, so I'll leave that to you.
Another option, instead of adding the directory that contains hello to your PATH, is to move hello to one of the directories already listed in PATH. You can see the full list by doing this:
> echo $PATH
You haven't said what OS you're using, but if it's anything Unix-like there's probably a /usr/local/bin listed in there. .../bin directories generally hold executable programs, and /usr/local is the directory sub-tree where local additions to the OS go. So you could put your program in /usr/local/bin, and then (assuming /usr/local/bin is in your PATH), hello would always be available.

Related

exe file not found after gcc creates output

Hello I am learning c and I have created a simple script. I ran it with gcc simplify.c -o simplify.
Here is the c script
#include<stdio.h>
int main(){
int age = 3;
printf("%i\n", age);
return 0;
}
when I try to run it
$simplify.exe
bash: run: command not found
I get the result shown. What am I doing wrong
Whenever you use a filename as a command, bash will search for it in directorys like /usr/bin. Imagine the situation, in which someone put a executable called ls somewhere unprotected on your computer. Like #some programmer dude pointed out, you habe to explicitly specify the path to your executable. This path can be relative (./simplify.exe) or absolute (/home/username/projects/simplify/simplify.exe).
By the way, on linux systems it is umcommon to use a file ending, espacially ".exe". If you want to use one, I recommend ".elf", which stands for "executable linkable file". (You can do so much more than EXEcuting a file - and down we go the rabbit hole)

How to use Makefile for .c program which needs to be imported to Makefile

I was trying to execute Makefile and wanted to execute a C program with it. First, how can I include test.c file for makefile?
I've placed makefile in root directly as there will be other .c files later added.
Can anyone hep me executing this?
File structure:
Makefile code so far not working (it will work if I place it inside src still not getting the output of file.)
# -o : object file
Test: test.c
gcc -o Test test.c
Glad if anyone can help or suggest anything!
I don't usually follow links but I was curious so I did so. Your problem isn't related to make or makefiles or how your code is built. As best as can be determined from the screenshots, all that is fine.
The problem is that when you try to run the program, it's not found.
When the shell tries to run a program it looks in the directories contained in the PATH environment variable, and only there. It won't look in the current directory, unless the current directory is on the PATH.
So when you type the name of a program without a pathname to tell the shell where to find it, such as Test (by the way it's not a good idea to call your program Test because there is a system program named test on POSIX systems and it can cause confusion), it will search the directories on PATH for Test, and if the program is not found there it will fail.
If you don't want to rely on PATH you need to give the shell the pathname of the program you want to run. So you can run .\Test instead (on POSIX systems it would be ./Test), to tell the shell that you want to run Test from the current directory.

How do I execute my program without ./a.out command?

I have written a c program. I want to pipe the program and I want to make it look meaningful. So instead of writing ./a.out each time, I want to name it changetext. To achieve that, I compiled my program following way: gcc -o changetext myprog.c. To the best of my knowledge, this should replace the use of ./a.out and changetext should do that instead. But I'm getting command not found. I am new to c and unix environment. Any suggestion appreciated.
As I said in a comment, you can either put a dot slash (./) in front of the executable to run it
./changetext
Or you put in in a directory that is referenced in the PATH environment variable. A nice explanation of this safety feature can be found here (thanks to rubenvb):
http://www.linfo.org/dot_slash.html
It says that this is more or less to distinguish built-in commands from user-written commands with the same name. I am not convinced though. The shell could simply prefer built-in names to user-supplied ones, and look in the current directory as well as in the PATH.
But this is the *nix way.
In order to compile and run a program such as your changetext with just the command chanhetext, you must put the binary in a directory listed in your PATH environment variable. It is recommended that you put programs that you made for your own use in the ~/bin/ directory. The command you would use to accomplish this would be the following, assuming ~/bin/ already exists:
gcc -o ~/bin/changetext myprog.c
If it does not exist, you can simply create it, then log out and back in.
If you are tired of doing the ./ before the program name you can always make an alias such as
alias a='./a.out' or alias changetext='./changetext'
this just basically look for everytime you type changetext or a and then replaces it to have the ./ infront of it

Pass Directory Context to Compiler

I'm writing a Java compiler in C just as a recreational project. But, I've noticed that when we compile files in the command line, such as "gcc example.c", the compiler is able to find example.c in the working directory of the terminal without error. How does the compiler know what directory to search example.c for? Does OS find example.c in the directory for the compiler? Also, how may I emulate this action in my C program so that the user can compile their java program from any working directory by calling my compiler such as: "compiler example.java"?
fopen will treat relatives paths as relative to the current directory, not the directory where the executable resides. This is the same with most (or even all) file handling function in most other languages.
So to emulate the behaviour of the Java compiler, all you need to do is to iterate over the file names in argv, fopen(the_file_name), generate code for that file, then fopen(class_file_name, "wb") (where class_file_name is file_name with .java replaced by .class) and write the generated bytecode to that.
Getting the full path of the current directory is neither necessary nor helpful. Note that if you just appended each argument to the current directory name, the code would break for absolute paths, whereas simply doing nothing will do the correct thing both for relative and for absolute paths.
If I understand correctly, you need to obtain the full path of the current working directory. There is a POSIX function getcwd (on Windows _getcwd) that can be used to retrieve current working directory of your program.
Then it should be simple to search this directory and find your sources (if they are present).

Running a C program in Linux

Can someone explain to me why, in particular, we are using ./a.out to run a program?
Is there any meaning behind this?
Can someone please provide an explanation?
The name stands for "assembler output", and was (and still is) the default name for the executable generated by the compiler. The reason you need ./ in front of it is because the current directory (.) is not in $PATH therefore the path to the executable must be explicitly given.
If you mean the ./ part, it's for safety. Windows by default appends current directory to PATH, which is bad (there's a risk of DLL injection, and so on).
If you mean a.out part, it's just a name (which came from name of format a.out), which you can change by modifying gcc -o parameter.
When running an executable like a shell like bash the executable must be in your PATH environment variable for bash to locate and run the program.
The ./ prefix is a shorthand way of specifying the full path to the executable, so that bash does not need to the consult the PATH variable (which usually does not contain the current directory) to run it.
[For a.out (short for "assembler output"), it is the default executable output for a compiler like gcc if no output filename is specified.]
It'd be worth you looking a bit more into C and the way that C programs are compiled.
Essentially, your source code is sent to the preprocessor, where directives like #define and #include are loaded (e.g. into memory). So any libraries you want to use are loaded, e.g.
#include <math.h>
will basically 'paste' the contents of math.h into source code at the point at which it is defined.
Once all this stuff has been expanded out, the compiler turns your source code into object code, which is your source in binary code. a.out is the default name for output if you do not specify a build name.
gcc -o mynewprogram mynewprogram.c
a.out is the default name for the compiler. AFAIK it is because the linking process is skipped and it is not compiled as an object or library.

Resources