Linker errors when optimization greater than -O1 (clang++) - c++

I have a moderately large C++ / ObjC++ project in XCode, which compiles/links/runs just fine at -O0 (in Debug config), as well as with -O1, but anywhere above -O1 I get two very strange linker errors:
"std::__1::vector<BufferBinding, std::__1::allocator<BufferBinding> >::~vector()", referenced from: ... LevelSystem.o
"std::__1::vector<TextureHandle, std::__1::allocator<TextureHandle> >::~vector()", referenced from: ... LevelSystem.o
Oddly, vector<BufferBinding> and vector<TextureHandle> are used in many places in different object files, but I am only getting linker errors for my 'LevelSystem.cpp'. FWIW, LevelSystem.o is included via a separately compiled static library...
Unfortunately I have not been able to come up with a small code snippet to reproduce this problem, so rather then expecting a concrete solution I was just hoping for any advice for possible places to look or steps to debug further.
Compiling with
clang++ -x objective-c++ -arch arm64 -std=c++1y -stdlib=libc++ -fobjc-arc -O2 (...)
I know this is very little to go on, but Im just posting here in case anyone has experienced this kind of thing in the past and can point me in the right direction.
Thanks!
EDIT:
TextureHandle is a pimpl-y class, so really contains nothing more then a pointer to a forward-declared struct.
BufferBinding contains only an id<MTLBuffer> (and a few ints) which is ARCed, which is suspicious, but then again TextureHandle exhibits the same problem without having any ObjC pointers...

Related

passing GCC flag -std=c++11 CXXFLAGS or CXX or CFLAGS

I really need some help with a basic question here please. I am about to give up forever on learning GCC as it seems like the basics just do not make sense to me. I have read hundreds of posts and can not figure out how to get a basic -std=c++11 call to work passed via configure
In this example I have compiled gcc 5.3 and most programs compile ok, for example compiling httpd from source works no problems. But I keep getting errors relating to what I think is -std=c++11. All the posts I read say to pass -std=c++11 and I have tried
CXXFLAGS=-std=c++11
CXX=-std=c++11
CFLAGS=-std=c++11
but the errors persist.
I am now attempting to compile aspell, and get the following error,
In file included from /home/mybin/include/algorithm:62:0,
from /home/atmp/aspell-0.60.6.1/common/string.hpp:13,
from /home/atmp/aspell-0.60.6.1/common/indiv_filter.hpp:12,
from /home/atmp/aspell-0.60.6.1/modules/filter/email.cpp:9:
/home/mybin/include/bits/stl_algo.h: In function ‘void std::random_shuffle(_RAIter, _RAIter)’:
/home/mybin/include/bits/stl_algo.h:4448:8: error: ‘rand’ is not a member of ‘std’
+ std::rand() % ((__i - __first) + 1);
algorithm seems to have installed correctly from the gcc5.3 compile.
Please point me in the right direction to troubleshoot these types of errors.
Did I miss a compile option when compiling GCC?
std::rand is defined in <cstdlib>, and it has nothing to do with C++11, this header was there a long time ago. Check that it is #included in the source.

atexit() undefined with freestanding CLang

I'm trying to compile and link some C++ code using CLang, with the following command line:
clang.exe -nostdinc -MD -fno-use-cxa-atexit -fno-rtti -fno-exceptions -fsigned-char -fno-stack-protector -fPIC -m64 -Wall -Werror -Wno-unused-function -Wno-unused-label -Wno-ignored-attributes
(I left out the output, includes, defines, etc. These are fine)
The issue I'm having is that during linking, I get the error
error: L0039: reference to undefined symbol `atexit'
I've spent quite some time on this issue already, but can't for the life of me seem to figure out how to properly resolve this.
My research so far has shown that atexit is defined in stdlib.h, but I can not use the standard library in this situation (this isn't my decision either, and is completely mandatory for this particular project).
As far as I can tell this issue is only now arising due to the fact that we now suddenly have static objects in our code which is compiled this way, which leads the compiler trying to register con/destructors to be executed for these objects, which requires a call to __cxa_atexit (which we've disabled because it was also giving undefined reference errors because of the same reason) or atexit.
I've also tried defining an arbitrary atexit function in my code, but apparently the linker doesn't want to have anything to do with this (which does seem rather strange to me).
So the question I have is: How can I get the linker to not whine about atexit, while not having to include the standard library?
Thanks a bunch in advance!
For future visitors, user damvac was able to help out!
Here's my comment about the issue being resolved:
It seems I forgot to add extern "C" to the definition of atexit (I only added it to the declaration), this seems to have resolved the issue! Thanks everyone who replied, and thank you davmac for providing the solution!
atexit (and the whole concept of "exiting" in general) do not exist in a freestanding environment, so you can't call it in your code.
To get the compiler to not generate support code that calls it, you need to compile all your source files with -ffreestanding to specify that you are using/generating freestanding code.

Undefined reference to operator new

I'm trying to build a simple unit test executable, using cpputest. I've built the cpputest framework into a static library, and am now trying to link that into an executable. However, I'm tied into a fairly complicated Makefile setup, because of the related code.
This is my command line:
/usr/bin/qcc -V4.2.4,gcc_ntoarmle_acpp-ne -lang-c++ -O2 -g -g -o Application/UnitTests/Tests/symbols/UnitTestExe -Wl,--start-group Application/UnitTests/Tests/../.objs/main.o Application/UnitTests/lib/libcpputest.a -Wl,--end-group -lm
I'm getting many errors like the following:
Application/UnitTests/lib/libcpputest.a(CommandLineTestRunner.o): In function `CommandLineTestRunner::parseArguments(TestPlugin*)':
Application/UnitTests/cpputest/src/CppUTest/.objs/../CommandLineTestRunner.cpp:114: undefined reference to `operator new(unsigned int, char const*, int)'
I can't figure out what's causing this. Don't I get operator new for free with C++?
You probably need to link with the C++ support runtime library. This happens automatically when you invoke g++. On Linux, this is achieved by adding the -lstdc++ flag to the linker. You have to figure out how to do the same on your platform.
Maybe you're calling gcc, the C compiler instead of g++, which is the C++ compiler.
There's very little information in your question to work from, but it looks like some code uses some form of placement new, and while that special operator new is declared (the compiler finds it and compiles the code using it), the linker can't find its definition.
(Since this old answer of mine seems to still get attention: See here for an extensive discussion on declaration vs. definition.)
You need to rebuild your code from scratch, including the library. I got this error because I inadvertently copied object files compiled on another machine (with the rest of the source) to my machine. Most likely this disturbs the linking step since there are now two types of object files, native (for modified source files) and non-native (all others). I am guessing here, but the operator 'new' means slightly different things on different architectures and that's why you are getting this error.
p.s. I know this is way too late for a useful answer but I'm still posting this for the record.
For QNX 6.5.0 I have specified flag -lang-c++ for qcc (gcc) to avoid the error.
Like the original post, in my case this error happened while trying to link a software using CppUTest framework.
In my case, the source of the problem seems to be related to the fact I disabled the MEMORY_LEAK_DETECTION compile option of CppUTest. I enabled it again, which solved the problem.
Sometimes adding -lstdc++ is not enough. You should add it to the right place. For example I had list like this, not working:
target_link_libraries(cfr2 pthread m stdc++ "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" )
But this one works fine:
target_link_libraries(cfr2 pthread m "${CMAKE_SOURCE_DIR}/compressor/libcompressor.a" stdc++)
It'd be great if someone explained it in the comment section.

Undefined symbol _main when trying to build logstalgia on mac

I have been trying to build the logstalgia project (http://code.google.com/p/logstalgia/) on my Mac (10.5). Rather than having to link it to the system libraries correctly, I have built and added all of the dependencies to the project. I am new at this, but I do think I have done this correctly, mostly because I have had two of my friends who are much more experienced say so.
Adding the frameworks removed all of the compile errors, but I still get a linker error. It seems to not be able to find the main() function. I have verified I included main.cpp in the sources to be compiled (using XCode) and that there are no accidental double declarations. I have also verified that the main function is correctly declared (no missing brackets, etc).
It is as though XCode does not link in the correct order. Any help would be really appreciated, I am really excited to be down to a single error! (Hope fixing this does not open a floodgate).
Thanks,
Hamilton
PS - I can definitely provide a zip of the Xcode project if anyone is willing to look!
Checking Dependencies
Ld "/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Debug/Untitled" normal i386
cd "/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled"
setenv MACOSX_DEPLOYMENT_TARGET 10.5
/developer/usr/bin/g++-4.0 -arch i386 -isysroot /developer/SDKs/MacOSX10.5.sdk "-L/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Debug" -L/sw/lib "-L/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/../../pcre-7.9/.libs" -L/opt/local/lib -L/sw/lib "-F/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Debug" -F/Users/hamiltont/Downloads/logstalgia-0.9.2 -F2/src/SDL.framework "-F/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled" -filelist "/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Untitled.build/Debug/Untitled.build/Objects-normal/i386/Untitled.LinkFileList" -mmacosx-version-min=10.5 -framework OpenGL -lpcre -lSDL -lSDL_image-1.2.0 -prebind -o "/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Debug/Untitled"
Undefined symbols:
"_main", referenced from:
start in crt1.10.5.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I got this error to go away. If I understand, essentially SDL re-names the main function, so that it can do some stuff, then run your application, then clean up. Turns out that if you are building in Xcode, you must use ObjectiveC to compile your application.
In Xcode, telling the linker to try and use SDL_main(), rather than just main() does not work (for some technical reasons that are a bit beyond me). So, you include a few Objective C files. In Oc, you get the benefit of being able to say explicitely what the name of your main class is. Hence, the Objective C files you include seem to do nothing more than let Xcode know to look for SDL_main().
In summary, this really had nothing to do with Logstalgia, but was entirely a problem with getting SDL to link correctly in Xcode. This link is talking about this problem exactly. The SDLMain.h and SDLMain.m are Objective C files. If you can't find them, try googleing "Setting up SDL templates in Xcode." I installed the templates in Xcode, used one of them to create an empty project that would compile, link, and run (and promptly do nothing!) and then I added the project files I wanted to the pre-configured project.
Thanks!
Double-check the link file list to make sure main.cpp's object file is present there:
/Users/hamiltont/Downloads/logstalgia-0.9.2 2/Untitled/build/Untitled.build/Debug/Untitled.build/Objects-normal/i386/Untitled.LinkFileList
You might also want to preprocess the main.cpp to make sure main isn't getting inadvertently renamed (via a rogue macro) or omitted (via a rogue #if).

GCC debugger stack trace displays wrong file name and line number

I am trying to port a fairly large C++ project to using g++ 4.0 on Mac OS X. My project compiles without errors, but I can't get GDB to work properly. When I look at the stack by typing "bt" on the GDB command line, all file names and line numbers displayed are wrong.
For example, according to the GDB stack trace, my main() function is supposed to be in stdexcept from the Mac OS X SDK, which does not make any sense.
What could cause GDB to malfunction so badly? I've already checked for #line and #file statements in my code and made sure that the code only has unix line endings. I've also cleaned and rebuilt the project. I've also tried debugging a Hello World project and that one did not have the same problem.
Could the problem have to do with one of the third party libraries I am linking and the way those are compiled? Or is it something completely different?
Here are two exemplary calls to gcc and ld as executed by Xcode. AFAIK all cpp-files in my project are compiled and linked with the same parameters.
/Developer/usr/bin/gcc-4.0 -x c++
-arch i386 -fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -fpermissive -Wreturn-type -Wunused-variable -DNO_BASS_SOUND -D_DEBUG -DXCODE -D__WXMAC__ -isysroot /Developer/SDKs/MacOSX10.5.sdk
-mfix-and-continue -fvisibility-inlines-hidden -mmacosx-version-min=10.4 -gdwarf-2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D__WXDEBUG__ -D__WXMAC__ -c "/Users/adriangrigore/Documents/Gemsweeper
Mac/TSDLGameBase.cpp" -o
"/Users/adriangrigore/Documents/Gemsweeper
Mac/build/Gemsweeper
Mac.build/Debug/Gemsweeper
Mac.build/Objects-normal/i386/TSDLGameBase.o"
/Developer/usr/bin/g++-4.0 -arch i386
-isysroot /Developer/SDKs/MacOSX10.5.sdk
"-L/Users/adriangrigore/Documents/Gemsweeper
Mac/build/Debug"
-L/Developer/SDKs/MacOSX10.5.sdk/usr/local/lib
-L/opt/local/lib "-F/Users/adriangrigore/Documents/Gemsweeper
Mac/build/Debug"
-F/Users/adriangrigore/Library/Frameworks
-F/Developer/SDKs/MacOSX10.5.sdk/Library/Frameworks
-filelist "/Users/adriangrigore/Documents/Gemsweeper
Mac/build/Gemsweeper
Mac.build/Debug/Gemsweeper
Mac.build/Objects-normal/i386/Gemsweeper
Mac.LinkFileList"
-mmacosx-version-min=10.4 /opt/local/lib/libboost_program_options-mt.a
/opt/local/lib/libboost_filesystem-mt.a
/opt/local/lib/libboost_serialization-mt.a
/opt/local/lib/libboost_system-mt.a
/opt/local/lib/libboost_thread-mt.a
"/Users/adriangrigore/Documents/Gemsweeper
Mac/3rd
party/FreeImage/Dist/libfreeimage.a"
"/Users/adriangrigore/Documents/Gemsweeper
Mac/3rd
party/cpuinfo-1.0/libcpuinfo.a"
-L/usr/local/lib -framework IOKit -framework Carbon -framework Cocoa -framework System -framework QuickTime -framework OpenGL -framework AGL -lwx_macd_richtext-2.8 -lwx_macd_aui-2.8 -lwx_macd_xrc-2.8 -lwx_macd_qa-2.8 -lwx_macd_html-2.8 -lwx_macd_adv-2.8 -lwx_macd_core-2.8 -lwx_base_carbond_xml-2.8 -lwx_base_carbond_net-2.8 -lwx_base_carbond-2.8 -framework SDL -framework Cocoa -o "/Users/adriangrigore/Documents/Gemsweeper
Mac/build/Debug/Gemsweeper
Mac.app/Contents/MacOS/Gemsweeper Mac"
Please note that I have already asked a similar question regarding the Xcode debugger here, but I am reposting since I just learned that this is in fact not Xcode's fault, but a problem with GCC / ld / GDB.
Edit: My project makes use of the following third-party libraries: SDL, Boost, wxWidgets. I am not sure if this matters for this problem, but I just wanted to mention it just in case it does.
I've tried compiling an Xcode SDL project template and did not experience the same problem, so it must be due to something special in my project.
Second Edit: As I just found out, I made a mistake while searching files with the string "This is an automatically generated". I just found several dozen files with the same string, all belonging to FreeImage, one of the third party libraries I am using. So, the problem seems to be related to FreeImage, but I am not still not sure how to proceed.
I got those symptoms, when my gdb version didn't match my g++ version.
Try to get the newest gdb.
Your cpp files certainly have debug symbols in them (the -gdwarf-2 option).
Do you use a separate dSYM file for the debug symbols? Or are they inside the object files. I would first try to use DWARF in dSYM files and see if that helps (or vice versa)
The third party libraries appear to be release builds though (unless you renamed them yourself of course) e.g. I know for sure boost uses the -d monniker in the library names to denote debug libraries (e.g. libboost_filesystem-mt-d.a).
Now, this shouldn't really pose a problem, it should just mean you can't step into the calls made to third party libraries. (at least not make any sense of it when you do ;) But since you have problems, it might be worth a try to link with debug versions of those libraries...
Are you compiling with optimization on? I've found that O2 or higher messes with the symbols quite a bit, making gdb and core files pretty much useless.
Also, be sure you are compiling with the -g option.
Can it be that you are using SDL? SDL redefines main so your main will be named SDL_main and that the SDL parts might be heavy optimized so down there you'll have problem getting good gdb output.
...just a thought
Read this
For a test, you could check if addr2line gives you expected values. If so, this would indicate that there's nothing wrong with the ELF generated by your compile/link parameters and casts all suspicion on GDB. If not, then suspicion is still on both the tools and the ELF file.
I've tried compiling an XCode SDL
project template and did not
experience the same problem, so it
must be due to something special in my
project.
Correct. Your project settings are the thing that is different.
You will need to disable the debug optimizations in the Xcode project settings for the debug build. Xcode unfortunately makes GDB jump to weird lines (out of order) when you would expect it to move sequentially.
Go to your project settings. Set the following
1) Instruction Scheduling = None
2) Optimization Level = None [-O0]
3) ZERO_LINK = None
Your problems should go after after doing this.
Here is the project settings screen that you need to change the settings on:
From your flags the debug information should be in the object files.
Does your project settings build the executable in one location then move the final executable to another location when completed? If this is the case then gdb may not be finding the objectects files and thus not correctly retrieving the debug information from the object files.
Just a guess.
I encountered this several years ago when transitioning from the Codewarrior compilers to Xcode. I believe the way to get around this is to put the flag "-fno-inline-functions" in Other C Flags (for Dev only).
This problem was more pronounced on the PowerPC architecture for us.
What about if you remove the "-fvisibility-inlines-hidden" and "-mfix-and-continue" flags?
I've never had the "fix and continue" feature work properly for me.
WxWidgets do also define their own main if you use their IMPLEMENT_APP() macro
From here
As in all programs there must be a "main" function. Under wxWidgets main is implemented using this macro, which creates an application instance and starts the program.
IMPLEMENT_APP(MyApp)
See my answer here
I have now downloaded and compiled the FreeImage sources and yes, the file b44ExpLogTable.cpp is compiled into libfreeimage.a. The problem looks like the script gensrclist.sh just collects all .cpp files without skipping the one with a main in. That script generates a file named Makefile.srcs but one is already supplied. (running it on my Leopard failed, some problem with sh - it worked if I changed sh to bash)
Before you have changed anything this gives an a.out
c++ libfreeimage.a
The file Makefile.srcs has already been created so you should be able to remove the file b44ExpLogTable.cpp from it. Then do
make -f Makefile.osx clean
make -f Makefile.osx
When this is done the above c++ libfreeimage.a should give the following error
Undefined symbols:
"_main", referenced from:
start in crt1.10.5.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I have a new thing you can try.
Just before your own main you can write
#ifdef main
# error main is defined
#endif
int main(int argc, char *argv[]) {
this should give an error if you have some header that redefines main.
If you define an own you might get an warning where a previous definition was made
#define main foo
int main(int argc, char *argv[]) {
You can also try to undef just before your main
#undef main
int main(int argc, char *argv[]) {