How to debug and step into custom language sources transpiled to C++? - c++

I would like to use a custom preprocessor language along with C++. My sources would be first transpiled to valid C++ with my custom transpiler, then compiled with a regular C++ compiler. Example:
my_transpiler -o source_gen.cpp source.mycpp
g++ -o myapp source_gen.cpp
In that scenario, the debug information generated are associated with the source_gen.cpp file. So I could debug and step into source_gen.cpp. But what if I want to step into the original source file source.mycpp ?
Does debugger as gdb or visual studio, or compiler as clang, gcc, or msvc provide mechanisms to map debug information to the original source file?

As was hinted in a comment to the question, the usual approach to this issue is the #line directive. In particular,
# line digit-sequence " s-char-sequenceopt " new-line
Your transpiler should put this directive for each source line in the original file into the generated file:
#line 3 "source.mycpp"
If your C++ compiler generates debug information based on these directives (the ones I've used do), when you step into the code you'll step into the appropriate spot in source.mycpp.

Instead of generation xxx_gen.cpp files, you can create an additional directory for the generated files and keep the file name for the files. If you have a directory hierarchy, you also can duplicate the whole tree.
After compilation you can in gdb set the source path. This will result in finding the "original" files.
The information will only by valid, if each source line will only generate a single target line. :-)

Related

Using clang or g++/gcc to print preprocessed code without including files from system paths

currently I'd like to debug my includes. To do this I want to get the preprocessed code, but without any system header files - just my own code.
I tried it with flag "-E" and "-nostdinc". But then I get errors that for example <string> is missing. How to disable such preprocessing errors?
How to disable such preprocessing errors?
You could create a set of headers files with names matching the standard library headers. Put those headers in the include directory. Let the files be empty.
Using clang or g++/gcc to print preprocessed code without including files from system paths
I can see two other approaches besides the empty header approach:
Instead of using the full pre-processor of the compiler, write your own pre-processor that only does the subset of processing that you want.
Or, write a post-pre-processor that removes the standard header content from the pre-processed result.
(It's not really an answer - just a "hack")
To solve this I created a text file with all system headers by:
rem my GCC STL-PATH
cd Z:\usr\include\c++\10
dir /b > F:\DummySTL\files.txt
Then I executed the following line of code:
for /f "delims=" %F in (files.txt) do copy nul "%F"
This creates an empty text file for every line in the file.
Now I can call gcc or clang just with:
-isystem"F:\DummySTL"
Using clang or g++/gcc to print preprocessed code without including files from system paths
This is not easily possible with GCC. Read about how to invoke GCC.
But you could get all the preprocessed code using g++ -C -E and use some script (perhaps with GNU gawk) to remove the useless parts.
currently I'd like to debug my includes.
I have the habit of generating all the preprocessed code and then use GNU less to look inside it. Disk space is cheap.
Alternatively, consider writing your own GCC plugin doing what you need.

Showing original source when debugging generated code in GDB

I am writing a programming language that compiles to C++, and wish to debug using GDB. When I debug the programs, I (of course) see the generated code. Is there a way to hav GDB instead display the source file that created the generated code?
Is there a way to hav GDB instead display the source file that created the generated code?
Sure: you must emit #line directives into your generated C++, and you need to generate already preprocessed source (which you very likely already do) into .ii files. Feeding .ii file into g++ will suppress preprocessing, and g++ will respect any #line directives it finds and emit appropriate source location debug info. Documentation.

Why does the executable binary file contain paths of included header files?

Why does the compiled and linked executable file contain paths of header files included in my source code? I am using the wxWidgets library and compile with Visual Studio 2013 and gcc. What are these header files used for? If it is a compiler option, how can I disable it to avoid this?
Build configuration: release, static linking.
There may be several explanations for such strings to appear in the executable file:
You may have debugging information bundled in the executable for the debugger to use. Use strip to remove that, or do not use the -g compile option. You should also compile with NDEBUG defined to disable debugging code and assertions. It is usually the case for the Release mode, but you may want to double check.
Some functions may use __FILE__ for tracing or logging purposes. __FILE__ expands to the source file name at the point of macro expansion, which may be a source or a header file. One such function is assert(): it is actually a macro that expands to a test and some error reporting code that includes the current filename.
Some sources may have static source ids in the form of static char arrays to keep track of source code versions. This approach is quite obsolete, but many old sources still have them.
Look for such things in the source files or header files whose name appear in the executable and fix the problems.
wxwidgets has many asserts in its header files (e.g. in wx/string.h as you noticed), all using the wxASSERT macro defined in wx/debug.h
In order to disable these, you can #define wxDEBUG_LEVEL 0 prior to including any wxwidget headers.

Can i compile a c++ file within a c++ file execution without any extra programs or installations?

I was reading on Clang and Ch (c++ interpreters), but its not clear for me, is it possible to run a newly generated .cpp file without any installations? Because i need to run the final program on any pc...
ps. if yes, does anyone have a good example, where a .cpp file is being executed within c++ code?
This is probably impossible or at least very hard. You would have to include the whole compiler (including linker, assembler, optimizer, preprocessor, ...) inside your program and that would make it extremely big.
One way of doing this is with Clang (as you already noted), there is even a demo project called "Clang interpreter" in the source: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/clang-interpreter/
However I once tried to compile this "beast" into my program and gave up halfway, because the file size of the result binary (or binaries with external libraries) gets into tens of megabytes (maybe even a hundred).
My suggestion is to either produce a different script (e.g. bash/sh script, which you could execute on any unix machine) that can be interpreted easily.
As far as I know, it is impossible, because compilation process of a CPP file is like this-
Preprocessing: the preprocessor takes a C++ source code file and deals with the #includes, #defines and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.
Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.
So, there should be intermediate files and executable files.
More can be found here-
https://stackoverflow.com/a/6264256/7725220
Kind of depends on what you mean by "installations".
Yes you can distribute your program with a full compiler, compile the source code and then execute the final result (all from the original exe).

Specify the name of compiled binary (*.exe) within source code in Visual Studio 2008

From this thread
http://www.codeguru.com/forum/showthread.php?p=1863547
It seems this cannot be done with:
#pragma comment(linker, "/out:mycool.exe")
Is there some simple way this can be done without having to use project settings, make files etc?
Added:
Why do I want to do this.
Well this gets into another subject which is probably my next question - working with the IDE.
I have to provide many examples in one project. They are simple single files that demonstrate different ways of doing things and each one should really be a different executable EXample1.exe, Example2.exe.
I only want to paste the source code or hand someone a SINGLE file with everything needed to make the example executable (on a web forum for example. I do not want to attach a 3.6MB project folder just to get a different executable name!
Compiling transcends source code. Source code only exists, and something has to take it and make something of it. Anything you do in source code is really just going to be a directive to the compiler. You might as well use project settings. This stuff isn't standard, because the standard only covers behavior and definitions of source code, not compilers.
g++ takes the output file as a parameter: g++ -o myexe.exe main.cpp. What should it do if it comes across a "output should be this!" directive in the source code?
Same with cl (Visual Studio), it passes the output setting into the command line.
Not to say it's impossible, but I doubt it's worth it to try and come up with a way to do it, let alone make it standard.
To use the linker pragma comment, the output file must NOT be specified in the linker section of the project properties:
project -> properties -> Linker -> General -> Output File
Delete the entry: $(OutDir)\$(ProjectName).exe
then the prama statement will work:
pragma comment(linker, "/out:mycool.exe")
Thanks to JC for the walkthrough
Specifying a complete path is not possible
http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/11a06ecd-dcca-4d81-8626-ba0c5a1835c1/
but the work around is:
What I do is have a header file loacated somewhere near the library file, this header will include the pragma line.
pragma comment(lib, FILE "../libs/mylibary.lib")
if FILE is "C:\Project\SharedLibs\Xvid\latest.h"
then the pragma will include
"C:\Project\SharedLibs\Xvid\libs/mylibary.lib" once it has normalized the uri to remove the ..'s
this will always cause the pragma to include the library with an absolute path created from the path of the accompanying header.
I use this system to include a single header in a project and regardless of the relative paths between the lib and project the lib will always be included cleanly.
Added:
The full path can be specified as long as it is 8.3 format. This can present problems for a path like:
C:\Program Files\Abyss Web Server\htdocs\
Program files is commonly Progra~1
but a folder name with a space is more tricky. In this case it becomes AbyssW~1
The \ must be escaped resulting in \ producing a working pragma of:
#pragma comment(linker, "/out:C:\\Progra~1\\AbyssW~1\\htdocs\\MyApp.exe")
as kibibu showed:
#pragma comment(linker, "/out:\"C:\\Program Files\\Abyss Web Server\\htdocs\\MyApp.exe\"")
also works
If you don't want to stray too far from a stock Visual C++ installation, you should consider using NMake. It can integrate with the IDE using project files, but it can also simply be run from the command-line very easily. It's also far more lightweight than project files for generating an arbitrary number of simple and similar executables.