There is a "hello world" project in Eclipse IDE that is supposed to compile against ESP8266 RTOS SDK.
File structure is as follows
I added one C++ class to it and put it into its own folder. Here is the class header
#ifndef MAIN_BLINKER_BLINKER_H_
#define MAIN_BLINKER_BLINKER_H_
class Blinker {
public:
Blinker( int period );
int Period() const;
private:
int period_;
};
#endif /* MAIN_BLINKER_BLINKER_H_ */
and the definitions
#include "Blinker.h"
Blinker::Blinker( int period ) :
period_( period )
{}
int Blinker::Period() const {
return this->period_;
}
Main.cpp file is like this
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "blinker/Blinker.h"
extern "C" {
void app_main()
{
auto blnk = Blinker( 3000 );
int i = 0;
while ( 1 ) {
printf( "[%d] Hello beautiful world!\n", i );
i++;
vTaskDelay( blnk.Period() / portTICK_PERIOD_MS );
}
}
}
It compiles but fails at final stage because the linker (or what is supposed to be a linker in xtensa toolchain) does not see definitions of Blinker methods. This is what I get in the build log
If I put class files next to main.cpp file, the build succeeds. However with time there will be hundreds of files, and without any grouping it will quickly turn into an unmanageable mess.
Alternatively I could put this class into top-level components folder and equip it with empty component.mk file. This would also make the build system happy, however it would force me to use ugly header includes like ../components/blinker/Blinker.h, which I would like to avoid.
So the question is how to make build system aware of .c and .cpp files residing in subfolders of main folder?
you can set COMPONENT_SRCDIRS in "main" component.mk file
see:
https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/api-guides/build-system.html#example-component-makefiles
Try to add blinker/Blinker.cpp to your CMakeLists.txt.
Take a look at
How to add new source file in CMakeLists.txt?
I am a little bit new to cpp. And all the concepts of 'includes' tho are important are pretty new and vague forme. I have a few questions which are related to my main question . The main question is:. I have a program which is a file containing 'main' and other 5 classes let's call it 'PROG'. I put them all in one file using no h files at all. The program is running and all is good. The point is, I now have 'test file ' which should test my program. Test file is separated to h file and cpp file. Is there any way to run everything without changing my program 'PROG'?? I don't want to create h files to my 'PROG' . The problem is, the test file uses a few of the claseess written the program 'PROG'. I thought about writing 'includes' cpp in the test file and putting 'pragma once'. I don't know why it doesn't work. Doesn't pragma once work for ' cpp includes'??
Or basically can anyone answer the general question. Which is in short:. You have a file containing main and classes (which all in cpp file with no h file) . And you want to run it with another file (cpp+ h) but both files use each othrr. Which makes a circular use. Is there a way to run it ?
You might be able to write tests, however they will be run at an unspecified time either before or after your program runs, so won't be able to access std::cout etc. If your program uses any static objects, you won't be able to do this.
It will be much easier to move your main into a main.cpp that #includes definitions of your classes, and compile a separate test_main.cpp that instead runs your tests.
As a sketch of the former
class TestFailure{};
class RunAtStartup
{
template<typename Func>
RunAtStartup(Func f) { f(); }
}
extern double function_to_test(int arg);
static RunAtStartup run_function_to_test([]{
// arrange
int param = 0;
// act
double res = function_to_test(param);
// assert
if(res != 1.0) throw TestFailure();
});
Does this help?
PROG:
class C {
void f();
}
#ifndef TEST
void C::f() {
// implementation
}
#endif // TEST
TEST:
#define TEST
#include "main.cpp"
// Your test code here can have instances to class C
C c;
c.f();
But take cpp/h approach as anyone recommends, which is everywhere.
I'd highly recommend using headers, but if you really don't want to modify your original file, you can #include "main.cpp" from your test file and redefine the main symbol during the inclusion. This allows you to create your own main method for the test program.
In test.cpp:
#define main real_main
#include "mymain.cpp"
#undef main
int main(int argc, const char** argv) {
std::cout << "wah" << std::endl;
int fakeargc = 1;
const char* fakeargv[fakeargc] = { "hoo" };
real_main(fakeargc, fakeargv);
}
In main.cpp:
#include <iostream>
int main(int argc, const char** argv) {
std::cout << "hello world " << argv[0] << std::endl;
return 0;
}
I'm new to codelite and c++. I'm using Linux and the g++ compiler. I've set up a simple project with two source files just to play around with linker errors. The files look like so:
Main.cpp:
#include <iostream>
void Log(const char*);
static int Multiply (int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
Log.cpp:
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
As you can see, Log.cpp simply specifies a function called in main. Both files are in the same directory, "src". So far all my settings are pretty much default, still I get an "undefined reference to `Log(..." error when I try to build this project.
Also, if I comment out the declaration of the Log function at the top of main.cpp, I would expect a compilation error since an undeclared function being called. Yet if I try to compile main.cpp I get no errors.
This is what my workspace looks like
Project settings
Compiler settings
Linker settings
Am I correct to expect the behaviors described above? Is there some setting I have to manually configure?
Hi I'm compiling C++ code using MinGW G++ compiler. I've also added the PATH to the address C:\MinGW\bin; as an environment variable.
I can access G++ from command prompt and compile the code, but I can only execute the file if the .exe file is in the bin folder. (I'm guessing it requires the .dll files).
If the .cpp file is compiled outside of bin folder, it is giving me an error:
The procedure entry point __cxa_throw_bad_array_new_length could not be located in the dynamic link library C:\MinGW\testcode.exe
Is there any way I can compile and also execute the code directly from command prompt if it's in other folders?
This is a program that I worked with:
// Cpp program to illustrate the
// concept of Constructors
#include <iostream>
using namespace std;
class construct
{
public:
int a, b;
// Default Constructor
construct()
{
a = 100;
b = 200;
}
};
int main()
{
// Default constructor called automatically
// when the object is created
construct c;
cout << "a: "<< c.a << endl << "b: "<< c.b;
return 1;
}
If I compile basic code like "Hello World", it is running outside of the bin folder. But for a bit bigger code like the one above isn't executing.
The compilation command that I'm using is:
g++ testcode.cpp -o testcode
I'm going through exercises of a C++ book. For each exercise I want to minimize the boilerplate code I have to write. I've set up my project a certain way but it doesn't seem right, and requires too many changes.
Right now I have a single main.cpp file with the following:
#include "e0614.h"
int main()
{
E0614 ex;
ex.solve();
}
Each time I create a new class from an exercise, I have to come and modify this file to change the name of the included header as well as the class i'm instantiating.
So my questions are:
Can I include all headers in the directory so at least I don't have to change the #include line?
Better yet, can I rewrite my solution so that I don't even have to touch main.cpp, without having one file with all the code for every exercise in it?
Update:
I ended up following Poita_'s advice to generate main.cpp via a script.
Since I'm using an IDE (Visual Studio), I wanted this integrated with it, so did a bit of research on how. For those interested in how, read on (it was fairly, but not entirely, straightforward).
Visual Studio lets you use an external tool via the Tools -> External Tools menu, and contains a bunch of pre-defined variables, such as $(ItemFileName), which can be passed on to the tool. So in this instance I used a simple batch file, and it gets passed the name of the currently selected file in Visual Studio.
To add that tool to the toolbar, right click on the toolbar, select Customize -> Commands -> Tools, and select the "External Command X" and drag it to the toolbar. Substitute X with the number corresponding to the tool you created. My installation contained 5 default pre-existing tools listed in Tools -> External Tools, so the one I created was tool number 6. You have to figure out this number as it is not shown. You can then assign an icon to the shortcut (it's the BuildMain command shown below):
No. You have to include them all if that's what you want to do.
No. At least, not in a way that's actually going to save typing.
Of course, you could write a script to create main.cpp for you...
If you build your code using make, you should be able to do this.
Can I include all headers in the directory so at least I don't have to change the #include line?
Change your include line to something like #include <all_headers.h>. Now, you can let your Makefile auto-generate all_headers.h with a target like:
all_headers.h:
for i in `ls *.h`; do echo "#include <$i>" >>all_headers.h; done
Make sure that all_headers.h is getting deleted when you 'make clean'.
Better yet, can I rewrite my solution so that I don't even have to touch main.cpp,
without having one file with all the code for every exercise in it?
You can do this if you abstract away your class with a typedef. In your example, change your class name from E0614 to myClass (or something). Now, add a line to your Makefile underneath the for loop above that says echo "typedef "$MY_TYPE" myClass;" >>all_headers.h. When you build your program, invoke 'make' with something like make MY_TYPE=E0614 and your typedef will be automatically filled in with the class you are wanting to test.
If you're on Unix system, you can have a softlink that points to the latest excercise.
ln -s e0615.h latest.h
and name your class E instead of E0614, of course
P.S. To the best of my knowledge, you can't do #include xxx*
Don't use one main.cpp which you modify for each exercise. This solution makes use of make's builtin rules, so you only have to type make e0614 and it will generate e0614.cpp, compile, and link it. You can customize each .cpp file (they won't be regenerated as written below) and maintain all of that history to refer to as you complete exercises, rather than erasing it as you move from one to the next. (You should also use source control, such as Mercurial.)
Makefile
e%.cpp:
./gen_ex_cpp $# > $#
You can generate boilerplate code with scripts, because you don't want it to be tedious either. There are several options for these scripts—and I use a variety of languages including C++, Python, and shell—but the Python below is short and should be simple and clear enough here.
Sample generate script
#!/usr/bin/python
import sys
args = sys.argv[1:]
if not args:
sys.exit("expected filename")
name = args.pop(0).partition(".")[0]
if args:
sys.exit("unexpected args")
upper_name = name.upper()
print """
#include "%(name)s.hpp"
int main() {
%(upper_name)s ex;
ex.solve();
return 0;
}
""" % locals()
Make a master include file containing the names of all the headers you want.
It's a really bad idea to include *, even if you could.
You could use conditional compilation for the class name by using concatenation.
// Somewhere in your other files
define CLASS_NUMBER E0614
// in main.cpp
#define ENTERCLASSNUMBER(num) \
##num## ex;
// in main()
ENTERCLASSNUMBER(CLASS_NUMBER)
Don't know about the includes though. As suggested above, a script might be the best option.
writing a makefile rule to pass the name of the executable as a -DHEADERFILE=something parameter to the compiler shouldn't be difficult at all. Something like:
%.exe : %.h %.cpp main.cpp
gcc -o $< -DHEADER_FILE=$<F $>
OTOH, I don't know if #include does macro expansion on the filename.
sed -i 's/\<\\([eE]\\)[0-9]+\\>/\19999/' main.cpp
Replace 9999 with the required number. There might be better ways.
Why not using object mechanisms ?
You can use an Exemplar strategy for this.
class BaseExercise
{
public:
static bool Add(BaseExercise* b) { Collection().push_back(b); return true; }
static size_t Solve() {
size_t nbErrors = 0;
for(collections_type::const_iterator it = Collection().begin(), end = Collection().end(); it != end; ++it)
nbErrors += it->solve();
return nbErrors;
}
size_t solve() const
{
try {
this->solveImpl();
return 0;
} catch(std::exception& e) {
std::cout << mName << " - end - " << e.what() << std::endl;
return 1;
}
}
protected:
explicit BaseExercise(const char* name): mName(name)
{
}
private:
typedef std::vector<BaseExercise*> collection_type;
static collection_type& Collection() { collection_type MCollection; return MCollection; }
virtual void solveImpl() const = 0;
const char* mName;
}; // class BaseExercise
template <class T>
class BaseExerciseT: public BaseExercise
{
protected:
explicit BaseExerciseT(const char* b): BaseExercise(b) {
static bool MRegistered = BaseExercise::Add(this);
}
};
Okay, that's the base.
// Exercise007.h
#include "baseExercise.h"
class Exercise007: public BaseExerciseT<Exercise007>
{
public:
Exercise007(): BaseExerciseT<Exercise007>("Exercise007") {}
private:
virtual void solveImpl() const { ... }
};
// Exercise007.cpp
Exercise007 gExemplar007;
And for main
// main.cpp
#include "baseExercise.h"
int main(int argc, char* argv[])
{
size_t nbErrors = BaseExercise::Solve();
if (nbErrors) std::cout << nbErrors << " errors" << std::endl;
return nbErrors;
}
And here, you don't need any script ;)
try this:-
#ifndef a_h
#define a_h
#include <iostream>
#include <conio.h>
#incl....as many u like
class a{
f1();//leave it blank
int d;
}
#endif //save this as a.h
later
include this in ur main program that is cpp file
#include "a.h"
...your program