How to compile D application without the D runtime? - d

Iv been trying to figure this one out forever, and its starting to annoy me. I understand the D runtime library. What it is, what it does. I also understand that you can compile a D app without it. Like what XoMB does. Well, XoMB defines its own runtime, but there are cases where you dont need to write your own, if you dont need it. I understand that the DigitalMars D compiler (dmd) which is what im using, does alot of things behind the scenes for the runtime, like emiting references to certain things depending on whats needed by your program. And also, things for EVERY program. So you must define these yourself. i decided to experiment, try to figure it out myself and got pretty far. By that i mean getting the linker to spit out less and less errors. For a test i just want to compile a complete bare-bones
app, simply to get things working without the runtime. Or as little of runtime as possible. here is what i have my single source file.
module main;
void _main()
{
int a = 2 + 3;
}
I compile with: dmd -c main.d -defaultlib=
Then link with: link main.obj
And this is the errors i get: OPTLINK : Warning 23: No Stack & OPTLINK: Warning 134: No Start Address
You can see i tried chaingng main to _main to get rid of the no start address error but,
anyway, didnt help. What do i need to do to iron out these last two errors? if i can get it working, i think i can look up what i need to implement to get more features working. But if anyone is willing to to help me out with that, it would be much apreciated!

module main;
extern(C) __gshared void* _Dmodule_ref;
extern(C) int main() {
int a = 2 + 3;
return 0;
}

ldc -nodefaultlib -noruntime
I've had success with that. But you'll still want to add:
extern(C) __gshared void* _Dmodule_ref;
extern(C) int main() {}
Note that while the runtime is optional, it is required for a lot of the features. You'll be missing array slicing, (dynamic arrays?), GC, and plenty of others. If you accidentally use one of those features, you'll get plenty of warnings about how it can't find some obscure symbol name.

Related

C++ runtime symbol lookup error, ubuntu

I have a C++ function doSth that will call a function "checkFrame" from a class "canMsg" as shown below
#include "canMsg.h"
void doSth(char* canFrame){
map<int, double> returnedData;
CANMsg canMsg;
std::cout<<canFrame <<endl;
canMsg.checkFrame(canFrame);
}
During compilation I receive no error, but when I run it, it executes std::cout<<canFrame <<endl; statement and crashes by creating an error
undefined symbol: _ZNSaIcEC1Ev, version GLIBCXX_3.4
Any ideas how to fix this?
Thanks for the replies. The error was due to my attempt to return a locally declared pointer. After I changed the local pointer variable to a static, it works perfect. The basic idea is C++ does not advocate to return the address of a local variable to outside of the function.
Look this for more information.
I think that kind of problem can arise if things are linked in the 'wrong' order. I suggest you try changing the order of whatever libraries you are passing to the linker.
(I don't actually know why the ordering matters - but it sometimes does.)
This error can occur when dependent library(where _ZNSaIcEC1Ev id defined) was compiled for other version of GLIBC (newer version or much older), that you currently have.
Try to recompile that library with your current environment.
Also you can add nice switch to LDFLAGS of your app: -Wl,--no-undefined. Then you can see any undefined symbols at compile time (not sure if it helps in your situation).

Why Are Vtables Not Being Implemented Correctly On Embedded Platform?

I am developing code for an embedded system (specifically, the PSoC 5, using PSoC Creator), and writing in C++.
While I've overcome most hurdles with using C++ , first off compiling in C++ using the compiler flag -x c++, defining the new and delete operators, making sure exceptions aren't thrown with the compiler flag -fno-exception, I've come to a brick wall when it comes to using virtual functions.
If I try and declare a virtual function, the compiler gives me the error undefined reference to "vtable for __cxxabiv1::__class_type_info". The only way to get around this is to use the compiler flag -fno-rtti, which prevents the error and makes it compile successfully. However, if I do that, the embedded program crashes when trying to run the overloaded virtual function, and I'm thinking this is because the vtable does not exist.
I don't see why you shouldn't be able to implement vtables on an embedded platform, since all it is a extra space in memory before or after member objects (depending on the exact compiler).
The reason I am trying to use virtual functions is because I am wanting to use FreeRTOS with C++, and other people have implemented this by using virtual functions (see http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html for the discussion, and https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems for a well written embedded C++ FreeRTOS framework)
The fact that the error message refers to a class named __cxxabiv1 suggests that you are not linking against the correct C++ runtime for your platform. I don't know anything about PSoC, but on more "normal" platforms, this sort of error could happen if you used the gcc (resp. clang) command at link-time instead of g++ (resp. clang++); or under handwavey circumstances if you used -lc++ without -stdlib=libc++ or -lstdc++ without -stdlib=libstdc++.
Use the -v option to examine your linker command line, and try to find out exactly which C++ runtime library it's pulling in. It'll probably be named something like libcxxabi or libcxxrt.
This guy here gives step-by-step instructions for compiling C++ in PSoC Creator; but he never figured out how to link with a C++ runtime library, so all his tips are focused on how to remove C++isms from your code (-fno-rtti, -fno-exceptions,...). I agree that there doesn't seem to be any information online about how to actually use C++ with PSoC.
For this specific error, you could always try defining the missing symbol yourself:
// file "fix-link-errors.cpp"
namespace __cxxabiv1 {
class __class_type_info {
virtual void dummy();
};
void __class_type_info::dummy() { } // causes the vtable to get created here
};
Or many linkers have the ability to define undefined symbols as 0x0 through command-line options such as -C or --defsym. However, that's not only a Bad Idea but also inconvenient, because you'd have to figure out what the actual (mangled) name of the vtable object is, and the linker didn't tell you that. (This being GCC, it's probably something like __ZTVN10__cxxabiv117__class_type_infoE.)
Either of those "solutions" would result in horrible crashes if the program ever tried to do anything with the vtable; but they'd shut the linker up, if that's all you cared about and you knew the program would never actually use RTTI. But in that case, it should be sufficient to use -fno-rtti consistently on your entire project.
What, specifically, goes wrong when you use -fno-rtti?

Same Program code with same compiler leads to different binaries

I have an issue with my code that has some very strange symptoms.
The code is compiled on my computer with the following versions:
a. GCC Version: 4.4.2
b. CMAKE verson: 2.8.7
c. QNX (operating system) version: 6.5.0
And the code has a segfault whilst freeing some memory and exiting from a function (not dying on any code, just on the exit from a function).
The weird things about this are:
The code does it in release mode but not debug mode:
a. The code is threaded so this indicates a race condition.
b. I cannot debug by putting it in debug mode.
The code when compiled on a workmates machine with the same versions of everything, does not have this problem.
a. The wierd things about this are that the workmates code works, but also that the binary created from compiling on his machine, which is the same, is about 6mB bigger.
Now annoyingly I cannot post the code because it is too big and also for work. But can anyone point me along a path to fixing this.
Since I am using QNX I am limited for my debug tools, I cannot use Valgrind and since it is not supported in QNX, GDB doesn't really help.
I am looking for anyone who has had a similar/same problem and what the cause was and how they fixed it.
EDIT:
Sooo... I found out what it was, but im still a bit confused about how it happened.
The culprit code was this:
Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();
where the definition for getMinimumBoundingBox is this:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
and it returns a VectorXd which is always initialised as VectorXd output(6, 1). So I immediately thought, right it must be because the VectorXd is not being initialised, but changing it to this:
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
But this didn't work. In fact I had to fix it by changing the definition of the function to this:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
and the call to this
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
So now the new question:
What the hell? Why didn't the first change work but the second did, why do I have to pass by reference? Oh and the big question, how the hell didn't this break when my co-worker compiled it and I ran it? Its a straight out memory error, surely it shouldn't depend on which computer compiles it, especially since the compiler and all the other important things are the same!!??
Thanks for your help guys.
... the binary created from compiling on his machine, which is the same, is about 6mB bigger
It's worth figuring out what the difference is (even if it's just the case that his build hides, while yours exposes, a real bug):
double-check you're compiling exactly the same code (no un-committed local changes, no extra headers in the include search path, etc.)
triple-check by adding a -E switch to your gcc arguments in cmake, so it will pre-process your files with the same include path as regular compilation; diff the pre-processor output
compare output from nm or objdump or whatever you have to for your two linked executables: if some system or 3rd-party library is a different version on one box, it may show up here
compare output from ldd if it's dynamically linked, make sure they're both getting the same library versions
compare the library versions it actually gets at runtime too, if possible. Hopefully you can do one of: run pldd, compare the .so entries in /proc/pid/map, run the process under strace/dtrace/truss and compare the runtime linker activity
As for the code ... if this doesn't work:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
and this does:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
you presumably have a problem with the assignment operator. If it does a shallow copy and there is dynamically-allocated memory in the vector, you'll end up with two vectors holding the same pointer, and they'll both free/delete it.
Note that if the operator isn't defined at all, the default is to do this shallow copy.
You said you have to change from:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
What was it before?
If it was:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input);
and the copy constructors / assignment operators weren't implemented properly it might have caused the problem.
Please do check how they are both implemented. Here's some info that might help.

Compliler gives error in nonsense function

I am using the Codeblock IDE with MingW, I have an ongoing problem
with the following types of errors. (File || Message)
obj\CEntity.o(.text+0x71a) || In function `ZN7CEntity6OnMoveEff':
OR
obj\CArea.o(.bss+0x0) || In function `ZNSt6vectorI5CTileSaIS0_EEaSERKS2_':
obj\CApp_OnCleanup.o(.bss+0x0):C:\DevCpp\bin\..\lib\gcc\mingw32\3.4.2\..\..\..\..\include\c++\3.4.2\bits\vector.tcc || first defined here
Note that it gives the location as some sort of obj file so I cannot
see where it is in my code.
My C++ is improving a lot but I am still not very good understanding
how the compilers work and I cannot figure out what might be causing
the problem or how to go about solving issues like this. Unlike a code
problem it is really hard to google because the names have just been
scrambled.
Hopefully someone can help because it is holding me back and I just cannot find
or figure out a fix!
(I decided not to post my code because it is many interlinked files and I do not
know where the error is but I am trying to follow the tutorials on http://www.sdltutorials.com/sdl-tutorial-basics. The first few I can get to work
but then the later ones always seem to fail. It is obviously something I am doing wrong
because when I use the sample it works.)
Many GCC distributions (such as the MinGW distros I use) come with a utility names c++filt which will turn a C++ mangled name into something closer to the source code declaration (I think your error messages left out some underscores):
C:\temp>c++filt __ZN7CEntity6OnMoveEff
CEntity::OnMove(float, float)
MSVC comes with a similar utility: undname
However, you may want to update the MinGW you're using. I get nice, demangled names directly in the error output going back to MinGW 3.4.5 (similarly for MSVC going back to VC++6):
class CEntity {
public:
void OnMove(float, float);
};
int main()
{
CEntity ent;
ent.OnMove(1., 2.);
}
Compiled with MinGW 3.4.5:
C:\temp>g++ -o test.exe test.cpp
C:\...\ccwlXEih.o:test.cpp:(.text+0x43): undefined reference to `CEntity::OnMove(float, float)'

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.