Separate compilation - c++11

I am learning C++ by S. Lippman 5th edition book. I reached chapter 6 where I can't understand separate compilation. In book is written "As an example, assume that the definition of our fact function is in a file named
fact.cc and its declaration is in a header file named Chapter6.h. Our fact.cc
file, like any file that uses these functions, will include the Chapter6.h header. We’ll
store a main function that calls fact in a second file named factMain.cc. To
produce an executable file, we must tell the compiler where to find all of the code we
use. We might compile these files as follows:
$ CC factMain.cc fact.cc # generates factMain.exe or a.out
$ CC factMain.cc fact.cc -o main # generates main or
main.exe
Here CC is the name of our compiler, $ is our system prompt, and # begins a
command-line comment. We can now run the executable file, which will run our main
function"
Where I have to compile these files($ CC factMain.cc fact.cc # generates factMain.exe or a.out
)? I use Codeblocks 16.01. Thank you.

The commands:
$ CC factMain.cc fact.cc # generates factMain.exe or a.out
or
$ CC factMain.cc fact.cc -o main # generates main or main.exe
are what you enter into your terminal to compile all the files that you specify in the command-line prompt (in your case factMain.cc and fact.cc).
The -o flag at the end of your second command signifies the name that your executable will have. (If you do not have a -o flag then the name of your executable will be a.out)
In order to find your executable, just look in your present working directory within terminal.
The command for this is:
ls
You should find your executable listed amongst all the files that are in that working directory.

Related

Compiling an assembly source on Mac OS and converting file to object/executable

I'm very new to programming and I had a question about compiling of assembly language on Mac OS. I know that to convert my .c to an .s I should use gcc -m32 -S. However, I already wrote my own .s file. I was wondering if it was possible to convert the .s I've made so that my Mac can compile it.
The thing is I want to compile both the .c and .s to verify that they both return the same value.
Have you simply tried to pass an .s file to the compiler? If it is written correctly, then it will just be transformed into an object file and/or an executable.
Here's a minimal example that should work:
$ cat 1.s # two lines of a program
.global _main # MacOS expects symbol names decorated
_main: retq # a single return instruction in `main`'s body
$ gcc 1.s # compile it
$ ./a.out # run the resulting program
After generating assembly code with extension .s use this command:
gcc -o executable-binary-file-name assembly.s
For example, if your assembly file is named as my.s and you want your executable name as my then use command:
gcc -o my my.s

How is C++ compiled

I am working on some (very) low level programming but not everything is completely clear to me. I start by creating a .cpp (or .c) file which is run through gcc to create an elf or object file but what is an object file? I get object files when I use the "as" compiler but how are these used and what is the purpose of having an object file when we could have a straight binary?
There is a very clear explanation of this question on the this site. I pasted it down below as well. But I strongly suggest you take a look at the diagram on the website. That will give you a much better high-level understanding of what is going on.
Compiling a source code file in C++ is a four-step process. For example, if you have a C++ source code file named prog1.cpp and you execute the compile command
g++ -Wall -ansi -o prog1 prog1.cpp
the compilation process looks like this:
The C++ preprocessor copies the contents of the included header files into the source code file, generates macro code, and replaces symbolic constants defined using #define with their values.
The expanded source code file produced by the C++ preprocessor is compiled into the assembly language for the platform.
The assembler code generated by the compiler is assembled into the object code for the platform.
The object code file generated by the assembler is linked together with the object code files for any library functions used to produce an executable file.
By using appropriate compiler options, we can stop this process at any stage.
To stop the process after the preprocessor step, you can use the -E option:
g++ -E prog1.cpp
The expanded source code file will be printed on standard output (the screen by default); you can redirect the output to a file if you wish. Note that the expanded source code file is often incredibly large - a 20 line source code file can easily produce an expanded file of 20,000 lines or more, depending on which header files were included.
To stop the process after the compile step, you can use the -S option:
g++ -Wall -ansi -S prog1.cpp
By default, the assembler code for a source file named filename.cpp will be placed in a file named filename.s.
To stop the process after the assembly step, you can use the -c option:
g++ -Wall -ansi -c prog1.cpp
By default, the assembler code for a source file named filename.cpp will be placed in a file named filename.o

Linking variables into executable in Makefile

I like to understand how we can link a global variable into an executable using Makefile.
I compile few C source files and create an executable from it. I compute the md5sum of this executable and want to attach it to another executable and make it available as a global variable in the other executable. By doing this, I can check in the second executable whether the first one has been modified and if it is then I could change some operation.
Although I can do it in the second executable at the beginning of its execution but I would like to stick with this approach as I could learn how to create global variables and link to binary directly in Makefile.
md5sum.c: program_1
echo 'const char md5sum_program_1[] = "'$$(md5sum program_1)'";' > md5sum.c
OBJECTS2 = ... md5sum.o
program_2: ${OBJECTS2}
${CC} -o $# ${CFLAGS} ${OBJECTS2} ${LDFLAGS} ${LDLIBS}
The first line says that the source file md5sum.c depends on the first program, program_1; when md5sum.c does not exist or is older than program_1, the command is executed. The command creates the definition of a global variable md5sum_program_1 and initializes it with the output from md5sum.
The OBJECTS2 macro includes all the object files needed for program_2 plus md5sum.o. The last command links the program.

Don't understand gcc that well, but I can't find why it's not working

I'm trying to compile a simple "hello world"
file_name
#include <stdio.h>
void main () {
printf ("Hello World\n");
}
then I try: gcc file_name and I get "File not recognized. File format not recognized"
I however am 100% sure I did the exact same thing a few weeks back (just to see if it works, as now) and it worked, so I just don't get it.
gcc -ver // returns 4.6.1 if this helpes
Also how is gcc -o supposed to work ? The manual (man gcc) is just gibberish at times (for me)
Let's say you program is saved as helloworld.c. Typing gcc -o myprog helloworld.c would compile helloworld.c into myprog. That way, when you want to run the program, all you type in the command line is ./myprog
gcc tries to guess the language used (e.g. C or C++) based on the extension of the file, so you need to ensure you have the proper file extension (usually .cpp for C++ and .c for C dource files). Alternatively, read the manual if there is a command line option to explicitly state the format (regardless of the extension).
As for the "-o" command line parameter: the name specified after that option is the name of the object file created from the compiled source file. The object files are then linked together to form an executable

How to write Makefiles to get a relative path in debug symbols?

I have a structure of code like this:
project_dir/
source1.c
subdir/
source2.c
The Makefile calls subdir/Makefile, so that the file subdir/source2.c is compiled in this way:
gcc -g -someoptions source2.c
and symbols in GDB link to source2.c instead of subdir/source2.c (with the result that GDB can not find symbols in source files). How should I write a Makefile or what options to use in gcc to get symbols using the relative path to the project main directory (or eventually the absolute path)?
I can not use:
cd .. && gcc -g -someoptions ../subdir/source2.c
because I would have to change references to header files in all files in subdir.
Your question is platform-specific (e.g. on Linux GDB should just work(TM), so I assume you are not on Linux).
One option is to build like this:
gcc -g ${PWD}/source2.c -o ...
Another option is to use GDB dir command to add ${TOP}/project_dir/subdir to the list of directories that GDB will search for sources.

Resources