UNIX cc executable location - c

When I compile a .c file using the cc command, it creates an a.out executable. I've noticed that it creates the a.out file inside my current directory. Is there a way to make the a.out file be created in the same directory as the .c file wherever I happen to be on the system?
for example if my current path is ~/desktop and I type in the command:
cc path/to/my/file/example.c
It creates the a.out file in the ~/desktop directory. I would like it to create the a.out file in path/to/my/file/a.out

You will have to use the -o switch each time you call cc:
cc -o path/to/my/file/a.out path/to/my/file/example.c
or you can make a wrapper script like this:
mycc
#!/bin/bash
dirname=`dirname "$1"`
#enquoted both input and output filenames to make it work with files that include spaces in their names.
cmd="cc -o \"$dirname/a.out\" \"$1\""
eval $cmd
then you can invoke
./mycc path/to/my/file/example.c
and it will, in turn, call
cc -o "path/to/my/file/a.out" path/to/my/file/example.c
of course you can put mycc in $PATH so you can call it like:
mycc path/to/my/file/example.c

You can give the "-o" flag to define the output file. For example:
cc path/to/my/file/example.c -o path/to/my/file/a.out

Yes, with -o.
cc path/to/my/file/example.c -o path/to/my/file/a.out

It may be not what you're looking for, but you can easily redirect the output of a compilation using the -o siwtch like this:
cc -o /a/dir/output b/dir/input.c
I don't know, how to archieve, what you want (auto replacement), but I guess you can do it with some bash like this: (I'm poor in scripting, untested and may be wrong):
i = "a/path/to/a/file.c" cc -o ${i%.c} $i
This should compile a file specified in i into an output file in same dir, but with the .c-suffix removed.

Related

Script to create a static library from all .c file in my working directory

I am trying to write a script that create a static library call libwork.a in the working directory from all the .c files in the directory:
#!/bin/bash
gcc -c *.c | ar cr libwork.a *.o
But as I run my script, it only creates the object files. The libwork.a does not get created. I tried both sourcing and executing my script but it still only creates object files only.
Why is it not creating the archive?
You are piping the messages printed by gcc (most surely none) to ar (which does not read anything). This is nonesense, ar should run after gcc.
The file listing generated by "*.o" is passed before "gcc" finished.
The solution is to remove that pipe and simply run the commands one after the other.
#!/bin/sh -e
gcc -c *.c
ar cr libwork.a *.o
Note the "-e". This tells the shell to abort if one of the commands fails, so if gcc fails ar will not execute.
Also, have a look at this one:
#!/bin/bash
gcc -Wall -pedantic -Werror -Wextra -c *.c
ar -rc libwork.a *.o
ranlib libwork.a

running my code using terminal Ubuntu

I've watched tons of videos about how to use sublime text 3 I do what they say but it doesn't work. When i type "subl test.c" in terminal it opens up a a file called test.c in sublime text 3 when i use the command gcc -c test.c everything is fine too, but when I try to run the code using ./test it says bash: ./test: No such file or directory
Bash says that there is no such file or directory because you haven't created a file called 'test'. You should specify an output filename, i.e. you should type gcc test.c -o your_out_filename. Then you may run your program using ./your_out_filename. Without -o flag gcc will create a a.out by default, so your out_filename will be a.out.
You have to use the following command to create a file called test:
gcc test.c -o test
If you don't use the -o option (gcc test.c) your created file will be a.out.
The option -c of gcc only compiles your file and doesn't link it to a program which you can run. The result of the -c option is only an object file called test.o.
Therefore the easiest way is the one I have mentionend above (-o option).
You have to run:
gcc -o output test.c
output is the file you have to do ./output in terminal for it to execute

When compiling C code in the linux terminal, what is the difference between make <filename> and cc <filename>?

I'm new to C, and I understand that both of those commands accomplish the same thing, but does one of them do something different than the other along the way?
First of all, if you are using make then for hello.c you will call make as make hello and not make hello.c. Also, note that make is most of the times used with a Makefile. Nonetheless, you can build executable binary from single source file using make as you have shown.
If the executable (hello) does not exist, then both will have same effect - create the executable from source file.
However, if the executable already exists, then make will run the build commands only if it thinks that the source code has changed after last build, whereas cc will always do the build.
For example:
$ make hello
cc hello.c -o hello
$ make hello
make: 'hello' is up to date. # make does not think source file has changed
$ touch hello.c # Update the timestamp of hello.c
$ make hello
cc hello.c -o hello # make thinks source file changed. Builds again
$
However, cc will not check if the source has changed or not. It will always do the required build.
$ cc hello.c -o hello
$ ls -l hello | cut -d ' ' -f '8-'
12:18 hello
$ cc hello.c -o hello # Build again without changing source
$ ls -l hello | cut -d ' ' -f '8-'
12:21 hello # hello was built again
$
Above description was for GNU make and GNU cc. Not sure about other implementations.
P.S.: make is not a compiler. It only calls the compiler when it thinks it should, as seen in the example above. Whereas cc is a compiler.
P.S. If you run cc hello.c, the excutable is named a.out, and not hello.
make(1) is a program that will run commands. You create a file named "Makefile" in a directory. The Makefile has a recipe with a specific syntax that is beyond the scope of this answer. You then invoke the make command in the directory with the file named Makefile
cc $filename will invoke a C compiler upon the $filename
cc or gcc or clang will invoke the compiler.
make is used when you have many files to compile.
In make you will give name of .o file and include header file location.

Use of -g and -o options in gcc command in c programming

Suppose there are 2 c program named abc.c and xyz.c . Now we want to work with the 2 executables at a time. So we change the name of the ./a.out using
gcc -g abc.c -o abc
gcc -g xyz.c -o xyz
Even gcc -o abc abc.c works.
What does the -g and -o in the above commands specify or describe?
What is the significance of -g and -o in the command for renaming ./a.out file.
Thanks in advance.
-g means to leave debugging information in the output file, it's unrelated to renaming.
-o means to put the result in the specified file instead of the default filename (abc.o for object files, a.out for linked executable files).
From https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html:
-g
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
-g starts becoming useful once you use debuggers such as gdb and lldb. When you attach to a running program and advancing one line at a time printing/altering the state as it changes.
if we specify -g option while compiling, debugging symbols will be available in the output file which will be useful when you try to debug using GDB.
If we won't specify -o option, the output will be placed in default a.out file. So if we run
gcc a.c - output will be in a.out
gcc b.c - output is a.out which is replacing old a.out file
If you want the output not to be a.out file, you can give -o option while compiling
gcc abc.c -o a
-o and -g options are not related.

Generic makefile that is independent of source file name

I wanted to create a generic makefile that can take the source file name compile it, save it as the object file and executable file. Both files using the original source name. Thank you for your help.
exec: \
compile
./helloworld #I would like to input source outside the make file.
compile: \
helloworld.c
gcc -Wall helloworld.c -o helloworld #<==
echo 'compiling'
touch compile
#I would like makefile to automatically save both object and exec.
#as the source file name.
You can use the $(MAKECMDGOALS) variable thus:
CFLAGS = -Wall
$(MAKECMDGOALS): $(MAKECMDGOALS).o
and then simply call Make like this:
make myfile
If you have Make 3.81 or later, then this can become:
CFLAGS = -Wall
.SECONDARY: # Prevents intermediate files from being deleted
If you're not interested in saving the intermediate object file, then you don't even need a Makefile. You can simply do:
make bar CFLAGS=-Wall
Make has built-in rules that know how to create an executable from a source file, if they have the same name. So you don't even need a makefile at all!
$ ls
foobar.c
$ make foobar
cc foobar.c -o foobar
Not that there's no need to mess with .SECONDARY because make has a direct rule to build an executable from a .c, without compiling the .o first (so there's no intermediate file). Even if it didn't, there's no advantage here to keeping the .o file around so it's not worth the extra effort to do so (IMO).
If you want to change compilers or flags you can have a makefile that consists of nothing other than some variable assignments:
$ ls
foobar.c Makefile
$ cat Makefile
CC = gcc
CFLAGS = -Wall
$ make foobar
gcc -Wall foobar.c -o foobar

Resources