Use clang preprocessor to concatenate C++ source files into one [duplicate] - c++

This question already has answers here:
Merge C++ files into a single source file
(8 answers)
Closed 2 years ago.
In the context of a coding contest, I must copy/paste all my C++ code in a single html input form, the code being compiled remotely. With the code getting bigger, I'd like to split the code into several files.
So, I have several C++ source files, one is main.cc and some others headers such as f.h.
I'd like these source files to be concatenated in a single source file allinone.cc with so that i can compile with clang++ allinone.cc.
I guess this can be achieved using clang preprocessor.
A minimal example would be:
main.cc
#include <iostream>
using namespace std;
#include "f.h"
int main() {
f();
}
f.h
#pragma once
#include <iostream>
using namespacestd;
void f() {
cout <<
}
The closest I could get is with :
clang -E -nostdinc main.cc | grep -v "^#" > allinone.cc
which produces:
#include <iostream>
^~~~~~~~~~
1 error generated.
using namespace std;
using namespacestd;
void f() {
cout <<
}
int main() {
f();
}
The -nostdinc option successfully avoids including code from standard includes. However, the original #include <iostream> disappears and the namespace specification is repeated.
Is there a way to invoke clang preprocessor to achieve the concatenation described in a straight forward manner?

clang -nostdincdoes another thing, not what you expect. This key disables the standard include directories from the include search paths. So, you get the error since the preprocessor is unable to include the file -nostdinc, could not find it in the known include search paths.
What you want is impossible to achieve. You should use cat your files and clean the result manually or use a special software that can remove #include. I suggest you just use a combinations of grep, sort, uniq and place removed and filtered #include into the top of the concatenated file.

Related

Getting Started with ANTLR4 and C++

First time question asker here, so bear with me. So I've got a grammar file from the grammars repository that I'm trying to use with C++. (Developing on macOS). I have no issue generating the lexer and parser using ANTLR. But after that, I have no idea how to run/use the resulting .cpp and .h files. I understand that there is an antlr runtime that I must download, and I have done so from the antlr.org website (gives me two folders, antlr4-runtime and lib), but my novice understanding of C++ seems to be preventing me from getting any further than that. How do I use the runtime to work with these files? I'm not using an IDE, just g++ from the command line. Thank you for any help!
I found this guide helpful: Getting Started with ANTLR in C++. (Ah, saw #ggorlen's comment after.)
If you scroll down on that page to a little past halfway, there's a section titled How to Use ANTLR in C++. I think that's where you are.
I'll copy that example over as SO generally prefers this. Say this is your main.cpp:
#include <iostream>
#include "antlr4-runtime/antlr4-runtime.h"
#include "antlr4-runtime/SceneLexer.h"
#include "antlr4-runtime/SceneParser.h"
#include "ImageVisitor.h"
using namespace std;
using namespace antlr4;
int main(int argc, const char* argv[]) {
std::ifstream stream;
stream.open("input.scene");
ANTLRInputStream input(stream);
SceneLexer lexer(&input);
CommonTokenStream tokens(&lexer);
SceneParser parser(&tokens);
SceneParser::FileContext* tree = parser.file();
ImageVisitor visitor;
Scene scene = visitor.visitFile(tree);
scene.draw();
return 0;
}
You want to include your lexer and parser .h (header) files instead of the SceneLexer/Parser in the example, and also include antlr4-runtime.h. Then run g++ on all your .cpp files, e.g.
$ g++ main.cpp YourLexer.h YourParser.h

Instantiating & using c++ class using header & implementation files [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I'm basically trying to instantiate an object from a class in c++ and use one of the member functions. This feels like a pretty standard problem, but all of the solutions I find online are either simple bracket issues, or scope resolution stuff that seems really obvious, or massively complex examples that shroud what's actually going on in over-complexity. I really appreciate anyone that Might be able to help me understand what I'm doing wrong with these files.
The errors I get are
undefined reference to Test::Test()'
undefined reference to Test::msg()'
I have three files, a main, a Test.hpp, and Test.cpp.
main.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
int main(){
Test var;
var.msg();
return 0;
}
Test.hpp
#ifndef TEST_HPP
#define TEST_HPP
class Test{
public:
Test();
void msg();
};
#endif
Test.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
Test::Test(){
cout << "instantiated\n\n";
}
void Test::msg(){
cout << "Hello\n\n";
}
Considering you use codeblocks as your IDE just go to: project settings -> project build options -> search directories -> add and locate where your .cpp and .h files are. Then it will ask you if you want to keep this as relative path. Say no.
If you using some other ide its almost the same proccess, just comment me and i will provide you the steps.
Btw there is no need to include iostream in main since you have already included it in test.

undefined reference to function code blocks

main.cpp
#include <iostream>
#include <string>
using namespace std;
void echo(string);
int main()
{
echo("hello");
cout << "Hello world!" << endl;
return 0;
}
print.cpp
#include <iostream>
#include <string>
void echo(string code){
cout << code;
}
After compiling the code in code blocks 12.11, it gives me that error:
undefined reference to `echo(std::string)
I use windows 7 x64.
I have added the directory; Project>build options > search directories and added the current working directory.
All the files are in one console project in code blocks
I believe you should read up a bit more on namespaces usage. You are missing std in print.cpp.
Generally, while starting to learn cpp or getting a grip of the language you should always try writing full names of the classes along with the namespaces. Eventually with practice and some oversights (like now) you will learn why you really need them. In a nutshell namespaces are great:
When you are writing code over multiple files
Compartmentalize your code into separate blocks.
Also, using namespace std; should be used within cpp files mostly (otherwise headers get mangled up.
Anyways, try changing your code to this:
#include <iostream>
#include <string>
void echo(std::string code){
std::cout << code;
}
Then your results will look like this:
> g++ main.cpp print.cpp -o a.out
> ./a.out
helloHello world!
You should get more than that linker error, since you use string without any namespace in your print.cpp file. And if that source file doesn't compile it can't be linked with, and you will get the linker error you have.
Change to e.g.
void echo(std::string code) { ... }
And you do try to link with the object file created from print.cpp ?
I know this is old, but for anyone looking to solve this issue, the following may be a solution for you. If you have g++ follow c++ 11 under project->build options (check your options anyway) then you must check that box for all files you make in the project for the error to be cleared up. I had that annoying undefined reference thing too but now it is gone!
Try "Project/Properties/Build Targets tab". There you should find "Build target files" field. In that filed find "print.cpp" and click the checkbox (now the compiler will build print.cpp).
Some usefull information on Project management in CB
http://www.codeblocks.org/docs/main_codeblocks_en.html
When dealing with strings in C++ its best to sue std::string and your code seems to be wrong with a changes like using std::cout instead of plain cout another thing you need to be careful is linking your files especially files in different directories you need to tell code blocks were to find this print.cpp by going to build option and go for the search tab directory and point to where print.cpp is other wise the other approach is to just build a project which will have the main.cpp and and then add print.cpp class to current project I hope this will be of some help

Getting fatal error for iostream

I wanted to write a simple clang plug-in. So I just executed a "PrintFunctionNames" plug-in provided in llvm-clang. But when i tried to execute a command :
" clang -cc1 -load ../../Debug+Asserts/lib/libPrintFunctionNames.so
-plugin print-fns some-input-file.c "
it gives me 1 fatal error :
fatal error: 'iostream.h' file not found
#include<iostream.h>
^
1 error generated.
I also tried using -I option providing a path for include directory of 'iostream' but it's still gives me the same error.
I tried it like:
'clang++ -I//usr/include/c++/4.6 -cc1 -load
../../../../Release+Asserts/lib/libPrintFunctionNames.so -plugin
print-fns ak.cpp '
So how do I make this work?
Don't add .h at the end.
#include <iostream>
That should fix it.
iostream belongs to C++ not C. So you should include it as
#include <iostream>
Additionally since you are programming in C++ you should name your source file ending with .cpp not .c to make it clear to the compiler and everyone else, that you want to use C++. Also you might need to invoke clang++ in your first compiler call (but I am not sure about that in context of plugins)
After the C++ language was standardized by the ISO, the header file named iostream.h was renamed to iostream. Change your program to use #include <iostream> instead and it should compile.
You will also need to add using namespace std; statement after each include (or prefix each reference to an iostream function/object with std::).
You can start by using this
#include <iostream>
using namespace std;
Once you are more comfortable with namespaces, you can remove the using statement & instead either use std::cout, std::cin etc or have a
using std::cout;
using std::cin;
etc.
I meet the same question,
template.cpp
g++ template.cpp
compare<int>com1(3,7);
List item
compare<double>com2(12.34,56.78);
compare<char>com3('a','x');
cout<<",the max value:"<<com1.max()<<endl;
cout<<",the max value:"<<com2.max()<<endl;
cout<<",the max value:"<<com3.max()<<endl;
return 0;
the question is up code segment composing not OK, use the shift + table typing next time.

Yet another linker issue

I'm having a linking issue with a basic C++ program. No, I'm not including .cpp files!
This is what's happening.
main.cpp:
#include "header.h"
#include <iostream>
int main() {
std::cout << "Hello!";
}
header.h:
#ifndef _HEADER_H
#define _HEADER_H
class Something {
public:
printContents();
};
#endif
something.cpp:
#include "header.h"
#include <iostream>
Something::printContents() {
cout << "This class's Contents!!";
}
What's happening is that I get a compiler error going: multiple definitions of some standard C function, such as strtod:
g++ -o ... main.o
build/....main.o: In function
`strtod':
../MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/stdlib.h:318:
multiple definition of `strtod'
build/..something.o:...something.cpp:(.text+0x0):
first defined here collect2: ld
returned 1 exit status
If I get rid of #include <iostream> in one of the two occasions and get rid of the couts, it will compile. What's going on? I'm using g++ and NetBeans to compile.
I tried in the command line:
g++ *.h *.cpp -o program
and the same thing happened.
Please note that _HEADER_H is an illegal name in C++ user code - names beginning with the underscore and an uppercase letter are reserved for the C++ implementation. This does not normally cause noticeable problems, but when you use what may be a common name in the implementation like HEADER in this context, it well might.
Modify,
Something::printContents()
{
std::cout << "This class's Contents!!";
}
NOTE: Specify the return datatype.
One of your problems is right here:
I tried in the command line: g++ *.h
*.cpp -o program
Don't pass your header files... Try something like this:
g++ *.cpp -o program
I could not reproduce your exact problem. I get this to compile and link nicely with the following few notes:
Add a void return type to the printContents-function (So it says void printContents(); in the header and void Something::printContents() { in the implementation-file)
Use std::cout rather than just cout. cout is not defined in the scope it is used
Make sure header.h ends with a blank line
Use HEADER_H rather than _HEADER_H (like Neil Butterworth says)
I use the command line g++ main.cpp something.cpp to compile.
I see a couple of problems. You shuold define the returning value of the function
printContents()
and you must write
std::cout
if you don't write
using namespace std;
The problem was in a multi-installation of MinGW. I had one already installed, and when I got Qt on my computer, it had installed it's own MinGW. Bummer, I ported the code to my university's servers and it ran OK.
Bummer!!
Thanks everybody for the help, I will definitely follow your guidelines in the future.
Header names - no underscores
Correct return type
Real code in the forums!
Leo Bruzzaniti