Running a C program in Linux - c

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.

Related

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

How come when I try to compile my C program by making a file named for the program it creates an application for it?

I once tried to compile a C program I made that was for a chess game (thanks to YouTube's Bluefever Software for the tutorial), but when I went to compile the program, I executed this line of code:
C:\TDM-GCC-64\>gcc Chess/chess.c Chess/init.c -o chess
The compiling worked (there were no syntax errors or anything), but when I got to my file directory, I saw this (circled in blue):
An unexpected application (but there were no viruses!):
How did this happen? It may had something to do with the line I was compiling, but what is the "intel" behind this?
It is normal for the compiler to generate an application!
What is surprising is the location for the executable, it should have been generated in the parent directory:
C:\TDM-GCC-64\> gcc Chess/chess.c Chess/init.c -o chess
The explanation is interesting:
You are using the Windows operating system, where the filenames are case insensitive.
You instructed gcc to generate the executable into chess, but this is the name of the Chess directory. In this case, gcc generates the executable in the named directory and gives it a name that is the basename of the first source file chess.c -> chess.
Furthermore, the application name really is chess.exe in Windows, but the default setting for the file manager is to not display file extensions. This is a very unfortunate choice. I suggest you change this setting in the Windows/File Explorer Options window to always show file extensions. This will allow you to distinguish chess.c, chess.exe and chess.h more easily.
You have a Makefile in the Chess directory, you should use the make command to build the executable:
C:\TDM-GCC-64\> make -C Chess
Or simply cd to the Chess subdirectory and type:
C:\TDM-GCC-64\Chess> make
That's the file you told the compiler to make.
The -o option to gcc is the output file. In this case, you told it to create an executable file named chess. And that's exactly what was created.
The compiler is automatically creating an executable file while compiling.

Environment variabile in Macro path

I need to define some path to files with macros. How can I use the $HOME environment variable?
I can't find it on the GNU manual, and this doesn't work:
#define LOGMMBOXMAN "$HOME/mmbox/LOGmmboxman"
No it shouldn't and you probably don't want constant-defined settings like that in any case. If you did that and it worked as you're intending to use it, your home directory would be built in as whatever $HOME is for whoever's doing the building. The executable then depends on that specific home directory existing. If that's OK, just #define your own home. I suspect it isn't though, so you need to deduce it at runtime.
For run-time deduction what you want is this, such that:
const char* home_dir = getenv("HOME");
If there is no $HOME defined, you get NULL returned so be sure to test for this.
You can then build your string based on that. You'll need #include <stdlib.h>.
Sounds like you are really asking "how can I set some cpp macro from my environment?"
If sothen you should just be able to add it to CPPFLAGS.
export CPPFLAGS="$CPPFLAGS -D LOGMMBOXMAN=$HOME/mmbox/LOGmmboxman"
Then in your code
#ifndef LOGBOXMAN
#error LOGBOXMAN not defined
#endif
Then make sure your source is built using the CPPFLAGS in the command line to gcc:
$ gcc -c file.c $CPPFLAGS
You can't. You need to use your build system to define a macro with the $HOME value (or equivalent on a non-unix system), i.e. something like this:
gcc -DHOME="/home/username" file.c
Or "/Users/username" for Mac OS X, or "C:\Users\username" (or something) for Windows. Basically, GCC provides the -D flag to define a macro on the command line. You can set up a script (or your build system) to take care of this macro definition for you, or perhaps make a system-dependent include file to define the HOME macro properly.
Then, in your C header, you can do:
#define LOGMMBOXMAN HOME "/mmbox/LOGmmboxman"
Note that, in C, consecutive string literals are concatenated. So this macro expands to:
"/home/username" "/mmbox/LOGmmboxman"
Which C interprets as
"/home/username/mmbox/LOGmmboxman"
EDIT: All that thinking, and I didn't think! D'oh!
As others have pointed out, you probably don't want to do this. This will hard-code your program to work for one specific user's home directory. This will likely cause problems if you want each user to use your program, but for each to keep his (or her) own separate files.
Ninefingers' answer is what you're most likely looking for. In the event that you ever find yourself in need of the above technique (i.e. storing application files in a system-specific place) I will leave my answer unchanged, but I expect it won't help you here.

Including a library (lsusb) in a C program

I am still fairly new to programming with C and I am working on a program where I want to control the power to various ports on a hub I have. That is, however, not the issue I am having right now.
I found a program online that does what I want I am trying to compile it. However it uses #include<lsusb.h>. lsusb is located in a totally different folder than the file I am wanting to run (and not in a sub folder) and when I try to compile it, I, logically enough, get the error that the file lsusb.h is not found.
How can I link to this file so that it can be found?
This is more of a GCC toolchain question than a C question (although most C compilers do use the same Unixy flags).
The braces around the include file (<>) indicate you want the compiler to search its standard search path for the include file. So you can get access to that new include file either by putting it into a directory on your standard include file search path yourself, or by adding its directory to the file search path. With GCC you do the latter by giving gcc the flag -I"directoryname" where "directoryname" is the full file path to where you are keeping that new include file of yours.
Once your compiler finds it, your linker may have the exact same problem with the library file itself ("liblsusb.a"?). You fix that the same way. The flag GCC's linker will want is -L instead of -I.
See the "-I" parameter in the gcc man page. It allows you specify a directory in which to find a header file. See also -l and -L.
Or try #include "../../path_to_the_file/lsusb.h"

Resources