Valac missing generated header - header-files

I have two files, client.vala and lib.vapi.
The VAPI defines a class (that would usually talk to C code):
class Toplevel.Sub.CClass
{
public uint i;
}
And client.vala uses the class:
class Toplevel.Sub.UserClass
{
public Toplevel.Sub.CClass c_class;
}
int main()
{
var cls = new Toplevel.Sub.UserClass();
cls.c_class.i = 0;
return 0;
}
When I attempt to compile the program, I get an error:
$ valac client.vala lib.vapi
/tmp/bug/client.vala.c:7:20: fatal error: client.h: No such file or directory
compilation terminated.
error: cc exited with status 256
Compilation failed: 1 error(s), 0 warning(s)
The compiler seems to want a header generated for the functions in client.vala.
Is this a bug or am I missing something?

You've discovered something I didn't know about the Vala compiler. client.h is the default C header name generated by the compiler when no alternative is provided. It has used the basename of the source Vala file. You can change this using the cheader_filename CCode detail. Change what you have in your VAPI to:
[CCode (cheader_filename = "my_real_c_header.h")]
class Toplevel.Sub.CClass
{
public uint i;
}
and you will see the include is now #include "my_real_c_header.h"
By the way if you compile with valac client.vala --vapididr . --pkg lib you will see the header is included as #include <my_real_c_header.h>. Personally I think VAPIs should be used with the --pkg option.
If you are literally using Toplevel.Sub.CClass to 'usually talk to C code' then you have misunderstood the purpose of a VAPI. I take 'talk to' to mean calling various C functions and collecting the results so they can be presented in a more Vala friendly way to the rest of your program. So it is a wrapper interface.
A VAPI contains instructions to the Vala compiler to translate names into the right names for the C interface. For example you might have a very simple C function, void top_level_do_something (), that you want to use in Vala. In Vala it helps to use a namespace so the VAPI could be:
[CCode (cheader_filename = "my_real_c_header.h")]
namespace TopLevel {
[CCode (cname = "top_level_do_something")]
public void do_something ();
}
You can then call this in Vala with TopLevel.do_something () and the compiler would write this out as top_level_do_something () in C.
Take a look at Writing a VAPI Manually for more details.

Related

SimpleINI library - can't compile a code with SI_NO_CONVERSION defined

I use SimpleINI library on Linux. There is the following comment:
// Defines the conversion classes for different libraries. Before including
// SimpleIni.h, set the converter that you wish you use by defining one of the
// following symbols.
//
// SI_NO_CONVERSION Do not make the "W" wide character version of the
// library available. Only CSimpleIniA etc is defined.
// SI_CONVERT_GENERIC Use the Unicode reference conversion library in
// the accompanying files ConvertUTF.h/c
// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires
// ICU headers on include path and icuuc.lib
// SI_CONVERT_WIN32 Use the Win32 API functions for conversion.
When I try to compile the following code:
#define SI_NO_CONVERSION
#include "SimpleIni.h"
int main()
{
CSimpleIni ini;
return 0;
}
I get the compilation error: ‘CSimpleIniA’ was not declared in this scope It looks like SI_NO_CONVERSION is not defined in SimpleIni.h. Could you explain what's going on ?
SimpleIni.h only defines SI_Case and SI_NoCase when either of SI_CONVERT_GENERIC, SI_CONVERT_ICU or SI_CONVERT_WIN32 is defined. This leaves SI_Case and SI_NoCase undefined when (only) SI_NO_CONVERSION is defined, which causes the CSimpleIniTempl template instantiation to fail, with the related compile errors. This is an oversight/bug in the library and should be reported to the author.
As a workaround, adding the missing definitions before #include "SimpleIni.h" gets the code to compile.
#define SI_NO_CONVERSION
#define SI_Case SI_GenericCase // ***
#define SI_NoCase SI_GenericNoCase // ***
#include "SimpleIni.h"
// ... etc ...
The doc you included says it all:
Only CSimpleIniA etc is defined [when SI_NO_CONVERSION is defined].
Below is an edited version of the first example in the README.md. The SI_ASSERT macro is defined in the header file but the ASSERT_EQ and ASSERT_STREQ macros, referenced in the example, are not. It's almost unforgivable that someone's examples don't compile.
As I mentioned in a comment, this is not a well-maintained project. The instructions for building and testing don't work in a very obvious way. Seems like the developer has files in his working copy that aren't in the git repository. Inexcusable.
Additionally, I get extra compilation errors when I define SI_NO_CONVERSION. Don't use this project. Use something else instead.
#include "SimpleIni.h"
int main () {
CSimpleIniA ini;
ini.SetUnicode();
SI_Error rc = ini.LoadFile("example.ini");
if (rc < 0) { /* handle error */ };
const char* pv;
pv = ini.GetValue("section", "key", "default");
ini.SetValue("section", "key", "newvalue");
pv = ini.GetValue("section", "key", "default");
}
You compile this with something like g++.

error when using extern "C" to include a header in c++ program

I am working on a school project which requires to work with sheepdog. Sheepdog provides a c api which enables you to connect to a sheepdog server.
First i create c source file(test.c) with the following content :
#include "sheepdog/sheepdog.h"
#include <stdio.h>
int main()
{
struct sd_cluster *c = sd_connect("192.168.1.104:7000");
if (!c) {
fprintf(stderr, "failed to connect %m\n");
return -1;
}else{
fprintf(stderr, "connected successfully %m\n");
}
return 0;
}
then i compile with no error using the following command
gcc -o test test.c -lsheepdog -lpthread
But what i need is to use it with c++ project so i created a cpp file(test.cpp) with the following content :
extern "C"{
#include "sheepdog/sheepdog.h"
}
#include <stdio.h>
int main()
{
struct sd_cluster *c = sd_connect("192.168.1.104:7000");
if (!c) {
fprintf(stderr, "failed to connect %m\n");
return -1;
}else{
fprintf(stderr, "connected successfully %m\n");
}
return 0;
}
now, when i compiled using the following command :
g++ -o test test.cpp -lsheepdog -lpthread
I got this error :
You can't just wrap extern "C" around a header and expect it to compile in a C++ program. For example, the header sheepdog_proto.h uses an argument named new; that's a keyword in C++, so there's no way that will compile as C++. The library was not designed to be called from C++.
I agree with #PeteBecker. From a quick look around Google, I am not sure there is an easy solution. Sheepdog is using C features and names that don't port well to C++. You might need to hack sheepdog fairly extensively. For example:
move the inline functions out of sheepdog_proto.h into a new C file, leaving prototypes in their place. This should take care of the offsetof errors, e.g., discussed in this answer.
#define new not_a_keyword_new in sheepdog/sheepdog.h
and whatever other specific changes you have to make to get it to compile. More advice from the experts here.
As sheepdog was not designed to be useable from C++ you should build a tiny wrapper in C language to call the functions from sheepdog and only call the wrapper from your c++ code. Some hints to write such a wrapper:
void * is great to pass opaque pointers
extractors can help to access badly named members. If a struct has a member called new (of type T), you could write:
T getNew(void *otherstruct); // declaration in .h
and
T getNew(void *otherstruct) { // implementation in a c file
return ((ActualStruct *) otherstruct)->new;
}
Depending on the complexity of sheepdog (I do not know it) and the part you want to use, it may or not be an acceptable solution. But it is the way I would try facing such a problem.
Anyway, the linker allows mixing modules compiled in C and in C++, either in static linking or dynamic linking.

How c++ includes all functions in specific file without any inclusion of that file?

I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.

Linking errors from MATLAB Mex library

I am having troubling compiling a MATLAB Mex library - specifically, the 'Correlation Clustering Optimization' code from this website.
I am trying to compile on an OSX machine, and am using the supplied mexall function. This runs the following line:
mex -O -largeArrayDims CXXFLAGS="\$CXXFLAGS -Wno-write-strings" QPBO.cpp QPBO_extra.cpp QPBO_maxflow.cpp QPBO_wrapper_mex.cpp QPBO_postprocessing.cpp -output QPBO_wrapper_mex
The error occurs at linking time with the following output to the MATLAB command line:
ld: duplicate symbol QPBO<int>::GetMaxEdgeNum() in QPBO_extra.o and QPBO.o
collect2: ld returned 1 exit status
mex: link of ' "QPBO_wrapper_mex.mexmaci64"' failed.
Judging from this, the function GetMaxEdgeNum is appearing in both QPBO_extra.o and QPBO.o. However, it is only actually defined in a header file, QPBO.h. I therefore suspect that both source files which include it are including it as a symbol in their object files, causing a problem at link time.
(Further information: Each source file also includes a file #include "instances.inc" at the very end of the file. instances.inc apparently seems to include some specific instantiations of the templated QPBO.)
Is there an obvious mistake I am making here? What can I do to increase my chances of being able to compile this code?
EDIT
This is the definition of the problematic GetMaxEdgeNum function in QPBO.h:
template <typename REAL>
inline int QPBO<REAL>::GetMaxEdgeNum()
{
return (int)(arc_max[0]-arcs[0])/2;
}
EDIT 2
Some more details about my machine:
OSX 10.6.8
MATLAB R2012a (also have R2011b)
g++ 4.2 or g++ 4.0 (or g++ 4.6 via MacPorts)
I've added some details on what I really want from an answer in my 'bounty description' below.
EDIT 3
There's a bit of consensus that instances.inc may be causing the trouble. This is included at the end of each cpp file, and it contains the following:
#include "QPBO.h"
#ifdef _MSC_VER
#pragma warning(disable: 4661)
#endif
// Instantiations
template class QPBO<int>;
template class QPBO<float>;
template class QPBO<double>;
template <>
inline void QPBO<int>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "int";
type_format = "d";
}
template <>
inline void QPBO<float>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "float";
type_format = "f";
}
template <>
inline void QPBO<double>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "double";
type_format = "Lf";
}
It seems like the issue is that some template code is in .cpp files.
Remove the #include instances.inc declarations from the .cpp files.
Move all code from QPBO.cpp, QPBO_extra.cpp, QPBO_maxflow.cpp and QPBO_postprocessing.cpp to the header file qpbo.h.
You'll have now a single .cpp file qpbo_wrapper_mex.cpp and a single header qpbo.h
mex the file (in matlab) using:
>> mex -O -largeArrayDims qpbo_wrapper_mex.cpp
Should work...
Changing GetMaxEdgeNum to a static function, or putting it in an anonymous namespace will probably fix your problem.
The reason is, as you suggest, that it has external linkage in both object files, which results in a nameclash. My suggested solutions gives it internal linkage.
After edit:
Does it change anything if you define the method inside the class definition?
Like this:
template <typename REAL>
class QPB0 {
...
public:
inline int GetMaxEdgeNum()
{
return (int)(arc_max[0]-arcs[0])/2;
}
...
};

How to auto-include all headers in directory

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