I am compiling scientific code that performs numerically intensive calculations. My process is the following:
Code targeted for the CPU is compiled by the Intel C++ Compiler
Code targeted for the GPU is compiled by NVCC
The object files are then linked using the Intel C++ Compiler
To do this, I have written a makefile to perform the necessary steps, and everything is carried out on the command line. Now, I wish to add on a GUI to the program, using Qt, but without using Qt Creator. As a test, I am trying to compile the "Hello World! Desktop application" given here: https://wiki.qt.io/Getting_Started_on_the_Commandline
My interpretation is as follows:
#include <QtGui\QtGui>
#include <QtWidgets\QApplication>
#include <QtWidgets\QLabel>
void test_qt()
{
QApplication app();
QLabel label("Hello, world!");
label.show();
app.exec();
}
I call the function in a main.cpp file. In my makefile, I link with Qt5core.lib, Qt5Gui.lib and Qt5Widgets.lib, and as per the makefile rules, this is compiled with the Intel C++ compiler. However, it gives the following error:
error: expression must have class type
app.exec();
^
My question is as follows:
How can I edit my makefile to compile Qt code? I will be needing signals and slots, so moc may be needed according to Can I use Qt without qmake or Qt Creator? but I will not be using uic.
Update based on the discussion below:
Looking at the QApplication constructor reference, it would appear that it is initialized with the command line arguments argc and argv obtained in main(). This makes it possible to pass Qt-specific flags to the Qt infrastructure. Thus, it cannot be created with no arguments as in your example -- you need to pass argc and argc from main.
As for compiling the files containing signals and slots - these features are not standard C++, so they need to be preprocessed by a tool that knows what they mean. If I understand correctly, moc converts these Qt-specific features into standard C++ code which must then be compiled using your compiler. So:
Use a naming convention for your Qt-specific cpp files so you can create a makefile pattern to process them with moc. ex: file.moc.cpp
Create a dependency on file.cpp in your makefile, which depends on file.moc.cpp
Create a rule for creating .cpp files from .moc.cpp files and invoke moc in that rule.
Call your normal compiler on the .cpp files. Don't forget your include directories, etc.
Make sure you do not check in these generated files, as they will change each time your .moc.cpp file changes. Maybe dump them in a temp directory that is ignored by your revision control? You may want to search around to see how other sample projects do it.
Side Note: declaring app without the parentheses could lead to a case of The Most Vexing Parse.
https://en.wikipedia.org/wiki/Most_vexing_parse
When an object is declared, but the parentheses are empty, the compiler ends up interpreting the line as a a function prototype for a function that takes no arguments and returns a QApplication.
Related
I am trying to write a plugin for a popular program whose code and compilation process I do not have control over. The program is written in C. However, I have written parts of my plugin in C++, since I use the QT5 library for graphics capabilities. The functions that the C program calls are written in C.
When the C program tries to load the plugin (shared library), it produces this error:
dlopen('build/libfoo.so') failed: build/libfoo.so: undefined symbol: _ZTV13JoystickPanel
JoystickPanel is a class in the C++ part of the program.
I've tried rewriting parts of the program in C, but the error was unaffected. I know that I could rewrite the entire program in C, but I'd rather not have to switch to another, more C-friendly GUI framework. I've also opened up libfoo.so in a text editor and search for JoystickPanel, but it appears to be mangled as _ZN13JoystickPanel.
Are there any compiler options or solutions that I'm missing?
I have no idea what _ZN13JoystickPanel means, since it's not apparently a valid mangled C++ name. It should perhaps be _ZN13JoystickPanelE, which would translate to JoystickPanel. That'd be symbol name for sure, but without much meaning anyway. You must have truncated something: I tried quite a bit and just can't generate an object file that would include _ZN13JoystickPanel as the complete symbol. It's just a prefix, there should be a "second half" attached to it - was there?
But _ZTV13JoystickPanel is the vtable for the JoystickPanel class. It's missing because you didn't provide implementations for all the virtual methods of the JoystickPanel class. Most likely, you didn't invoke moc properly, or forgot to compile and link its output.
You need to show a complete build script for your plugin at the very least (the .pro file, or CMakeLists.txt). You'll also need to provide a github link to your project (I presume it's open source).
The symbols you want to find in the compiled output are at least _ZTV13JoystickPanelD#Ev - virtual destructors, where # is a digit, _ZTV13JoystickPanel - the virtual method table,
Those symbols may be absent when compiled with optimization and/or LTCG, but also absent will be references to them.
You may wish to delete the build folder and rebuild your project, just to be sure. qmake is bad at dependency generation for the makefiles it produces, so if you use it, I suggest switching to cmake + ninja.
Apparently, I'd forgetten to put the #include "moc_controller.cpp" line at the bottom of a file that needed it.
For anyone else chasing this issue while using Qt on CMake, consider making sure that the proper lines are added.
If I have a class that declares a Qt signal:
class Test
{
signals:
void TestSignal();
}
This works fine in Qt. But Resharper C++ gives me the warning:
Function 'void Test::TestSignal()' is not implemented
This is correct but pointless since Qt doesn't want the function to be implemented. Is there any way to implemented this signal so that Resharper doesn't complain?
I tried:
class Test
{
signals:
void TestSignal() = {};
}
but get the build error:
error : Not a signal declaration
As AcerExtensa explained, the MOC tool generates implementations of Qt signals. To silence the warning, you can include the generated source files into your solution so that ReSharper would see implementations of signals in your header. You are right though that this warning is useless, I've filed https://youtrack.jetbrains.com/issue/RSCPP-20044 to silence the "Function is not implemented" inspection for Qt signals.
Qt doesn't want the function to be implemented
This statement is wrong. Qt is Framework and not Language. If you don't define your function you will get error from compiler.
Qt has tool called MOC (Meta Object Compiler). MOC is a code generator. It parses the header files and generates an additional C++ file that is compiled with the rest of the program. That generated C++ file contains all the information required for the introspection(signals/slots mechanism).
So to make your code work you need first of all include Q_OBJECT def in your class and your class should inherit from QObject or one of its subclasses (e.g., QWidget) so Qt can use it QMetaObject's. If your compiler or better to say your DevEnv don't know how to generate moc's files you need to do it yourself and then include moc file in your project source tree or include it directly at the end of your source file like:
#include "yoursourcefilename.moc"
You can read mor about Qt Meta Object system here: The Meta-Object System
The code in question is a JNI interface between a Java and a native code.
The h file is produced by the javah utility, whereas the cpp file is created by human.
If the Java part is renamed then javah produces function prototypes with the corresponding names, like it should. However, nothing makes sure the functions in the cpp file are renamed as well - all compiles as usual. The problem will only arise when the Java code invokes the native API at runtime.
How could one catch a mismatch between the h file produced by javah and the implementation cpp file produced by human during the compilation?
How about referring to the generated function declarations somewhere in the C++ code?
E.g. in (say) generated_check.cpp create a function that calls your prototypes with dummy parameters (but never call it):
#include "generated.h" // your javah output
static void neverCalled() {
// Compiler errors here mean that the functions have changed:
Java_com_example_package_MyClass_myFunc1(0, 0, 0);
Java_com_example_package_MyClass_myFunc2(0);
}
Edit, in response to your comments:
Another (or complementary) approach would be to create a script that runs as part of your build process and have it back up the old generated.h before javah is run, and cause a build error if the new generated.h is different to the old one. It could even run a diff program to give you an error message to pinpoint the change.
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).
Question: what is the best way to convert a .c/.h based project (which is forcefully compiled as C++ via the makefiles) to a .cpp/.hpp based project?
Obviously, this is a triple-step process. The first would be to rename everything with *.c at the end to *.cpp; the second would be to rename everything with *.h at the end to *.hpp. What I'm getting caught up on is the third step- somehow building a list of what the files /were/ named (ie, myfile.c), then iterating through every single affected file and replacing every instance of the old filename with the new (myfile.c -> myfile.cpp). Obviously this would have to be done so the source files can still find everything that they need.
The source code in question consists of around 2700 individual source files.
The reason why I'm doing this is mostly because I'm porting said software package to Mac OS X, and that involves Xcode. Things are getting bloody messy trying to keep track of precisely what is C, C++, and the associated headers for either (then overriding the compiler for C++ compilation). It would be much simpler if everything C++ was *.cpp (with the associated headers being *.hpp), since then I can just leave Xcode at the default compiler setting as per the file extension and everything should work without any fancy intervention on my end.
I should probably also note that I know precisely what files need to be converted, because they already compile properly and in a sane fashion if I'm overriding Xcode to compile as C++. That's not a problem- my issue is trying to figure out how to batch rename everything then run through all the files and update the #includes.
Thank you in advance!
-Keven Tipping
You don't need to mess with the headers. filename.h is a perfectly good name for a C++ header.
If you're not using the old makefile, but creating a new XCode project, then you have only one step:
Rename *.c to *.cpp
If the makefile was written right (using rule patterns and not specific per-file rules), there shouldn't be any changes needed there either.
There's no reason to rename those C language header and source files to C++ and there are many reasons not to. Just three of the many:
Reason #1: C and C++ are diverging, different languages. Force-compiling a C file as if it were C++ risks introducing a bug.
Reason #2: Xcode can handle C, C++, and C and C++ mixed together.
Reason #3: C++ can easily call C routines. All you need to do is wrap the declarations of those C functions inside an extern "C" { /* C declarations here */ } construct.