I'm writing a programming language, that convert the source files to C++ and compile they.
I want to add an way to work with a large number of files, compiling they to .o files, making it possible to use makefiles. A Better explanation (thank #Beta):
You have a tool that reads a source file (foo.FN) and writes C++ source and header files (foo.cpp and foo.h). Then a compiler (gcc) reads those source and header files (foo.cpp and foo.h) and writes an object file (foo.o). And maybe there are interdependencies (bar.cpp needs foo.h).
The problem is: my interpreter delete the .cpp and .h after the GCC compile they. Because this, it can't use #include, cause when it will compile, the referenced files don't exist anymore. How I can solve this?
There are two parts to the answer.
First, don't write explicit header files. You know what they should contain, just perform the #include operation yourself.
Secondly, don't write out the .cpp file either. Use gcc -x c++ - to read the code from standard input, and have your tool emit C++ to standard out, so you can run tool foo.FN | gcc -c -o foo.o -x c++ - to produce foo.o.
Related
I'm doing the "Hello World" in the GTKMM tutorial, the "app" uses three files, the main.cc, helloworld.h and helloworld.cc.
At the beginning I thought that compiling the main.cc :
g++ -o HW main.cc $(pkg-config ... )
would be enough, but gives an error (undefined reference to Helloworld::Helloworld), etc.
In other words, it compiles the main and the header, but not the HW class, and this makes sense because the header is included in Main but not the Helloworld.cc. The thing is I'm kinda scared of including it because I read in other question that "including everything was a bad practice".
That being said, when I compile using all the files in the same command:
g++ -o HW main.cc helloworld.cc $(pkg-config ... )
the "app" works without errors.
So, since using the last command works, is compiling in this way a good practice?
What happens if my app uses a big ton of classes?
Must I manually write them all down in the command?
If not, must I use #include?
Is it good practice using #include for all cc used files?
Is normal to list all the cpp/cc files when compiling with g++?
Yes, completely.
How else will it know what source code you want it to compile?
The thing is I'm kinda scared of including it because I read in other question that including everything was a bad practice.
#includeing excess headers is bad practice.
Passing your complete source code to the compiler is not.
Is it good practice using #include for all cc used files?
Absolutely not.
What happens if my app uses a big ton of classes? Must I manually write them all down in the command?
No. You should be using a build system that handles this for you. That could be an IDE which takes all the files in your project and passes them to the compiler in turn, or it could be a CMakeLists.txt/Makefile with a *.cpp wildcard in (although I actually recommend listing source files explicitly, one-by-one; it's not hard).
Invoking g++ manually on the command-line is fine for a quick test, but for real usage you don't want to be clowning around with such machinery.
is good practice using #include for all cc used files
It's not only bad practice, never do it.
In order to create an executable you actually have to do two things:
Compile all the source code files to object files or libraries.
Link all the object files and needed libraries into an executable.
You seem to be missing the point that the link phase is where symbols defined in separate source files are resolved or linked.
Must I manually write them all down in the command?
For the compiler to know about the DEFINTION of the symbols DECLARED in your headers, you must include all source files. Exceptions to this rule can be (but are not limited to) headers containing template metaprogramming (TMP) code that usually exist entirely in header files.
What happens if my app uses a big ton of classes?
Most of the large C++ projects utilize build configuration tools such as CMAKE to handle the generation of makefiles for them.
I have been thinking this problem for a while but still no idea about it, if my project is mainly cpp file, should a c file name as .c, or should be named as .cpp to consistent with other .cpp file?
I just list some advantage and disadvantage (in my current knowledge) of using .c (I don't know if the following idea is correct):
advantage of .c:
fast to know it does not contain c++ content (e.g.:class,std::string)
easy to separate from .cpp file by searching name
disadvantage of .c:
not consistent with other files (because other files mostly .cpp)
may need to rename it as .cpp if I want to change the function as using oop or want to add some oop features into it
some scripts or files may need to add *.c as file input if the original version only handles *.cpp, (e.g.: need to add *.c in Android.mk in android jni)
Also I don't know if compiler handles .c and .cpp in different way,also don't know if it affects other behaviour (e.g.:performance,platform or compiler specific issues...), is anyone have idea about it?
Depends what you mean by "C" code.
Are you going to compile it with a C compiler?
Call it file.c
Or do you just mean "C-like" C++ code? C++ code that, at time of writing, happens to also be valid C?
Call it file.cpp
Rule of thumb - name it according to which compiler you intend to use for it. This keeps your makefiles nice and simple.
So if your "C code" is C++ code that could be compiled as valid C but that's not what you are doing, then name it *.cpp and let your makefile invoke the C++ compiler on it.
If your code is actual C, to be compiled with a C compiler, then name it *.c - and remember the (appropriately-#ifdefed) extern "C" in the header file so that C++ built against it can link successfully.
C++ fully supports c code. So the compiler would be just fine with c code in a .cpp file.
And like Quentin mentioned above. If your c code is never used in a c only project I would leave it in an cpp file.
I always have problems with c++ on this, I spend more time trying to solve dependencies instead of programming when I setup a new project. I search the internet a way to do this automatic, or softwares that do that. In fact, I always program on geany and compile with shell script files...
So, is there a software to manage this? Do IDE's do that?
I always include .cpp files on my main.cpp and then I include the .hpp files on these .cpp. So, if I have a main.cpp, a object.hpp and a object.cpp, I will include the object.cpp in the main.cpp and the object.hpp on the object.cpp. Is there a better way to do that?
Can I just include the .hpp files and in the build script add every .cpp file?
I just cant find the answer on the internet, maybe im doing the wrong question...
I have found a nice article dealing with including files.
Common practice for all c++ header files is to simply define inclusion guards.
#ifndef TEST_H
#define TEST_H
// class definitions goes here
#endif
If there are some cyclic dependencies, consider forward declaration.
Every-time this header is included, the compiler checks, whether symbol TEST_H has been defined already. This basically guarantees, that contents of this file are included only once, and so that there is single declaration of the classes, defined in header file.
Good to know is, that directive "#include <>" does copy and paste all the contents of the included file.
Including .cpp file is not strictly disallowed, and sometimes good choice, it is considered a bad practice. As I mentioned, including file, means that all contents of the file are being duplicated at the place of inclusion. This is okay, for the header file with inclusion guard, but not okay for .cpp file, since every function definition inside this file, will be duplicated.
Not including file in the build script means, that only the those duplicated data are included in the build, otherwise you would end up with multiple function redefinition errors.
If you are looking for IDE, consider:
Visual Studio
Code Blocks
Eclipse
IDE won't do all the work, but you can be significantly more productive using good IDE.
TLDR:
Use inclusion guards
Include all .cpp files in build script.
Do not "#include" .cpp files.
In every .cpp file, include only needed headers, to reduce compilation time.
I see a lot of good suggestions with good practices but your mistake (including .cpp files from a .cpp file) suggest you're missing some concept in the C/C++ build process, I hope a little explanation would help you understand better and avoid the mistake.
Think of .c .cc .cxx .cpp files as modules, a .cpp file is a module, with your implementation of something, .h .hpp are just headers where usually you don't put implementations but declarations to be shared with multiple modules.
Usually each .cpp module is compiled to a binary object g++ -c -o mymod1.o mymod1.cpp then (once all modules are compiled) linked together g++ -o myprog mymod1.o mymod2.o ....
Even if you compile and link with a single command g++ -o myprog mymod1.cpp mymod2.cpp behind the scene g++ handle each module as single object.
I think is important you understand that each module/object know nothing about others, and if you need some other module (your main.cpp) to know something about mymod1.cpp a header file is required .h .hpp (mymod1.h) with the declarations needed to be shared: module global variables, defines, enums, function prototypes or class declarations, then just include mymod1.h in the module(s) where you want to use something of your mymod1 implementation (main.cpp).
Also, you write you're using a shell script to build, that's ok if your project are few files, better would be to use something like make, learn how to use it will require some time but then I bet geany have some facility to build projects based on Makefiles, make is the way to handle C/C++ projects from a long time.
I just started a graphical C++ course and I have problem getting an overview how it is.
we got some starting code, two files; one of type "C++ Source" and another of "C/C++ Header".
its supposed to be a graphical program which fills the screen with color.
also, we are using some custom libraries such as SDL and GLM, in the same folder as those two files there is a folder named gml and loads of subfolders, which I wont get into.
I have downloaded mingw, cmake and Visual Studio 11 beta for c++.
I've tried making a normal Win32 program and also a forms-application for the graphical part, but its always something wrong when compiling.
My question: how are you supposed to handle C++ files? I just got used to java and there its so easy to just open the .java file and paste into your IDE, dealing with C++ makes me really confused.
Hmm... Where to begin...
Somethings that happen behind the scenes in other languages are much more visible in C++. The process of obtaining a binary (say, an executable) from C++ involves first compiling the source code (There are sub-steps of this but the compiler handles them) to obtain object files, then the object files are linked by the linker to generate a binary.
In theory, you could simply #include all the cpp files in a project, and compile them all together and "link" (although there's nothing to link) but that would take a very long time, and more importantly, in complex projects that could deplete the memory available to your compiler.
So, we split our projects into compilation units, and by convention a .cpp file represents a single compilation unit. A compilation unit is the part of your project that gets compiled to generate one object file. Even though compilation units are compiled separately, some code has to be common among them, so that the piece of code in each of them can use the functionalities implemented by the others. .h files conventionally serve this purpose. Things are basically declared (sort of announced) in them, so that each compilation unit knows what to expect when it's a part of a linking process to generate a binary.
There's also the issue with libraries. You can find mainly two kinds of things in libraries;
Already implemented functionality, shipped to you in the form of binary files including CPU instructions that can almost be run (but they've to be inserted in the right place). This form is accompanied by .h files to let your .cpp files know what to expect in the library.
The second type is functionality implemented directly in the .h
files. Yes, this is possible under special cases. There are cases,
where the implementation has to (a weak has to) accompany the
declaration (inlined functions, templated types etc.).
The first type comes in two flavors: A "static library" (.lib in windows, .a in linux), that enters your executable and becomes a part of it during linking, and a "dynamic library", that is exposed to your binary (so it knows about it) but that doesn't become a part of it. So, your executable will be looking for that dynamic library (.dll files in windows and .so files in linux f.x.) while it's run.
So, in order for your .cpp files to be able to receive services from libraries, they have to #include their .h files, to know about what there is in them. Later on, during linking, you have to show the linker where (what path in the file system) to find the binary components of those libraries. Finally, if the library is dynamic, the .dll's (or .so's etc.) must be accessible during run time (keep them in the same folder for instance).
While compiling your compilation units you have to tell the compiler where to find the .h files. Otherwise, all it will see will be #include <something.h> and it won't know where to find that file. with gcc, you tell the compiler with the -I option. Note that, you just tell the folder. Also of importance is that if the include directive looks like #include<somefolder/somefile.h> you shouldn't include somefolder in the path. So the invocation looks like:
g++ mycompilationunit.cpp -IPATH/TO/THE/INCLUDED/FILES -IPATH/TO/OTHER/INCLUDED/FILES -c
The -c option tells the compiler that it shouldn't attempt to make an executable just from this compilation unit, so it creates a .o file, to be linked with others later. Since we don't tell it the output file name, it spits out mycompilationunit.o.
Now we want to generate our binary (you probably want an executable, but you could also want to create a library of yours). So we have to tell the linker everything that goes into the binary. All the object files and all the static and dynamic libraries. So, we say: (Note g++ here also acts as the linker)
g++ objectfile1.o objectfile2.o objectfile3.o -LPATH/TO/LIBRARY/BINARIES -llibrary1 -llibrary2 -o myexecutable
Here, -L option is self explanatory in the example. -l option tells which binaries to look for. The linker will accept both static and dynamic libraries if it finds them on the path, and if it finds both, it'll choose one. Note that what goes after -l is not the full binary name. For instance in linux library names take the form liblibrary.so.0 but they're referred to as -llibrary in the linker command. finally -o tells the compiler what name to give to your executable. You need some other options to f.x. create a dynamic library, but you probably don't need to know about them now.
What is the difference between a .cpp file and a .h file?
Look at this answer. Also a quick google search explains a bit too.
Pretty much .h (header) files are declerations and .cpp (source) files are definitions. It is possible to combine both files into one .cpp file but as projects get bigger and bigger its becomes annoying and almost unreasonable.
Hope that helps.
In C++ there is a notion of a function declaration (the function signature) and a function definition (the actual code).
A header file (*.h) contains the declarations of functions and classes. A source file (*.cpp, *.c++, *.C) contains the definitions.
A header file can be included in a source file using #include directive.
When you define a class in C++, you typically only include the declarations of the member functions (methods in Java lingo), and you put the class definition into a header file. The member function definitions containing the body of each function are typically put outside the class definition and into the source file.
Generally the best thing to do here is to get a book on C++ or C, and to look at some sample code.
Header files (.h) are supposed to contain definitions of classes, methods, and variables. Source file (.cpp) will contain the code. So in your .cpp file you need to include the header file as #include "header-file-name.h".
Then use g++ to compile the .cpp file. Make sure that the path to .h file is correct.
If you are using CodeBlocks or Visual Studio, then just compiling the project and running will do everything for you. You can also add .h or .cpp file from there. You need not worry about anything.
Hope this helps.
I use gcc (running as g++) and GNU make.
I use gcc to precompile a header file precompiled.h, creating precompiled.h.gch; the following line in a Makefile does it:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $#
All was well until i had to run g++ with different command-line parameters.
In this case, even though precompiled.h.gch exists, it cannot be used, and the compilation will be much slower.
In the gcc documentation i have read that to handle this situation,
i have to make a directory called precompiled.h.gch and put
the precompiled header files there,
one file for each set of g++ command-line parameters.
So now i wonder how i should change my Makefile to tell g++ to create
the gch-files this way.
Maybe i can run g++ just to test whether it can use any existing file
in the precompiled.h.gch directory,
and if not, generate a new precompiled header with a unique file name.
Does gcc have support for doing such a test?
Maybe i can implement what i want in another way?
It seems weird to answer my own question; anyway, here goes.
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file:
// precompiled.h
#include <iostream>
#include <vector>
...
#error Precompiled header file not found
This works because if gcc finds a precompiled header, it will not read the .h file, and will not encounter the error.
To "compile" such a file, i remove the error first, placing the result in a temporary file:
grep -v '#error' precompiled.h > precompiled.h.h
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name (mktemp). It was omitted for clarity.
There is a simpler way than introducing an #error in precompiled.h: never create this file at all. Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags).
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". Again, I I don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data.
Then in all other source files, the statement #include "precompiled_stuff" is not a genuine include, but simply loads precompiled data. It's up to you to prepare the precompiled data.
For g++, you need a build rule to create "precompiled_stuff.gch" from a source file whose name doesn't matter to the compiler (but would be "to_be_precompiled.cpp" here).
In Visual C++, the string "precompiled_stuff" equals the value of the /Yu flag and the precompiled data loaded comes from a .pch file with an unrelated name, that you also created from an unrelated source file (again "to_be_precompiled.cpp" here).
Only when building with a compiler without precompiled header support, a build rule needs to generate an actual file called "precompiled_stuff", preferably in the build directory away from the real source files. "precompiled_stuff" is either a copy of "to_be_precompiled.cpp", a hard or symbolic link, or a small file containing #include "to_be_precompiled.cpp".
In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers.