I was trying to compile an openMP example and he refuses to compile saying "undefined reference to 'OSCR_init', undefined reference to `OSCR_getarg_int' and several other functions. Then I located these functions in the file OmpSCR.h, that came in another folder, searched inside it and saw that these funcions were defined externally, I believe that in omp.h. I included the file with "include " in the example source (OmpSCR.h was already included) hoping that it would solve the question, but nothing improved. I do have omp.h, it came with the os. Can it be a version conflict? I got the example file from OMPSCR_v2.0.tar.gz What should I do?
An "undefined reference" error means that no definition of the function was found at link time. A declaration in a header (such as omp.h) doesn't provide an implementation for the function; it just tells the compiler that the function exists somewhere. You have to link your program with a library that actually provides the function's implementation.
Basically, you just need to link your program to an OpenMP library. The way to do this depends on which compiler and which OpenMP implementation you're using, neither of which you've specified, so I can't provide specifics. (But if you happen to be using GCC, you should use the -fopenmp option for both compiling and linking.)
Related
I am giving Gwan a whirl.
Having made it through example code, I started a small project with more than one source file. I now have two problems:
I got a linking error at server startup:
Linking main.cpp: undefined symbol: _ZN7GwanUrl9concatAllEv
(the main file #includes the two other files; all the files are in the csp directory)
As an alternative to having all the files in the /csp directory, I would like to make a library outside of the /csp directory while still using some of the gwan functions. sadly, a tonne of errors follow -- WHEN I GCC from commandline not via G-WAN Startup.
In file included from /home/ec2-user/gwan/include/gwan.h:22,
from Xbufstream.h:10,
from Xbufstream.cpp:10:
/usr/include/time.h:199: error: ‘size_t’ does not name a type
.....
Anyone knows what the gwan g++ argument string looks like?
(odd the 1. and 1. its 1. and 2. in the editor)
First, this is not a linker issue: you have "undefined symbol" rather than "unresolved symbol" as an error.
This is simply an #include issue.
define the main() function in your script.cpp file.
there's a G-WAN folder dedicated to user-defined include files called /gwan/include but you can as well use /csp/my_include.hpp... if you are using the right syntax:
For example, having #include "toto.hpp" in /csp/hello.cpp lets me reach C++ functions defined and implemented in the gwan/include/toto.hpp file (or defined in toto.hpp and implemented in a pre-compiled library linked to your script with #pragma link).
If you rather use #include <toto.hpp> then the SYSTEM INCLUDE PATH will be searched instead (and this will work providing that your library was correctly installed).
If you want to use #include "toto.hpp" for a custom folder that was not setup in the system, you can use G-WAN's #pragma include "../my_folder" directive to specify its PATH or you can explicitely specify it in each include: #include "../my_folder/toto.hpp".
Nothing fancy there, only C/C++ dependancy rules apply (and G-WAN really helps by providing alternate ways that do not involve system settings).
For libraries (see the G-WAN examples for SQLite, Cairo, mySQL, cURL, etc.) you can either use pre-installed libraries that exported their location in SYSTEM variables... or put your library in the /gwan/libraries folder and their include file in the /gwan/include folder.
When writing your own libraries, remember that they need to be pre-compiled. This means that you obviously cannot use G-WAN symbols since your compiler may #include "gwan.h" (to have the definitions) but your linker will not know from where G-WAN symbols can be found. The way around is to always use the G-WAN API from the G-WAN scripts. Your custom libraries must either be general-purpose or buffer any payload intended to be used by G-WAN. No-double copy is needed since G-WAN provides the set_reply() call to let G-WAN use persistent replies built without the reply xbuffer provided by G-WAN servlets.
Now, a last word about linking (which was not the cause of your trouble but could participate to the confusion). If you mix C and C++, use extern C {} to wrap your C++ prototypes called from C (otherwise you will really have "unresolved symbols").
With all this information, you should be ready to face every possible situation.
the issue of referencing gwan.h symbols inside #include files can also be solved by moving all code into the header file, whether its .h or .hpp
its ungraceful but a fix nevertheless. and good enough for the simple extension i wanted.
looking into the /libraries/sqlite3/sqlite.h helped.
#gil, thanks for your time.
UPDATE After some digging I found this to be a part of some workaround that passed a file handle from C++ to Fortran using a stub for OPENPIPE. OPENPIPE simply returns an externally declared file handle, doing absolutely nothing with a pipe. OPENHOLDFILENAME actually creates a file, but I'm still confused about what DFWIN has to do with this. Was it required to provide a function declaration for OPENPIPE? If so, they why was it also declared as EXTERNAL in the Fortran code?
I was given the task of compiling legacy Fortran on the GCC toolchain. I've already successfully compiled a few of the source files, but have hit a snag regarding the DFWIN module which links up to some Win32 API functions. It apparently uses some Win32 pipe functions, and I need to replace this with a modern equivalent that works with gfortran (the old compiler was Compaq Visual Fortran).
First, I see the DFWIN module included, as well as some external functions:
USE DFWIN
EXTERNAL OPENPIPE
EXTERNAL OPENHOLDFILENAME
Here is an example of how OPENPIPE is used:
OPEN(UNIT=INN,FILE=
1 '\\.\pipe\input.txt',
1 FORM='FORMATTED',STATUS='old',readonly,
1 USEROPEN=OPENPIPE)
What module can I use to replace these calls on modern Windows/Linux systems using gcc/gfortran?
EDIT: Our priority is to get this running on Windows, but in the future we want to deploy on Linux as well.
I have the following problem - I'm trying a sort of bastardized build of the poco library for C++ (ie, using a premake-generated makefile instead of the poco makefile because I'm building on windows without msvc)
I've actually managed to get all the libraries built into .a files. The problem arises when I try to actually use classes - and then gcc swears up and down that it can't find the reference. This despite the fact that I have checked the libraries with ar -t and seen that the classes in question do indeed exist there.
In general, what could be the problem? I have a library that at least claims to have the requisite .o files, yet the references are still undefined.
For example, I have an undefined reference to Poco::XML::InputSource::InputSource(std::istream&), yet "InputSource.o" is in the linked library, and the requisite ctor is in the header file.
Some context:
My program uses libary libfl.a (flex library).
I compile it under linux:
gcc lex.yy.c -lfl
I have mingw compiler installed i586-mingw32msvc-gcc (simple 'hello world' stuff compiles without problem)
I use ubuntu (probably does not matter)
I want to compile under linux for windows (produce binary .exe file which would be usable on windows)
My problem and questions:
When I try compiling my program
i586-mingw32msvc-gcc lex.yy.c -lfl
I get errors:
[...] undefined reference to '_yywrap'
[...] undefined reference to '_WinMain#16'
Do I understand correctly that I have to compile the content of libfl.a also with i586-mingw32msvc-gcc to be able to use it in this cross-compilation?
In the source code there is function yywrap(), but not _yywrap(). Why I get error for function with underscore _?
Whats up with the _WinMain#16? (no usage in source code)
My goal would be to understand what is happening here.
If I get it to work, then its bonus points :)
Any help is appreciated
Yes, certainly. And here's why:
C++ encodes additional semantic information about functions such as namespace/class affinity, parameter types etc. in the function name (that is called name mangling). Thus C++ library names are somewhat different from what you see in the source code. And each compiler does it in it's own way, that's why generally you're unable to link against C++ functions (C function names don't get mangled still) of a library built with a different compiler.
Judging to mangling style, the undefined symbols are brought in by the Microsoft C++ compiler. I don't know exactly about why it needs WinMain, but after you recompile the libs with it, all these errors likely will be gone. And yes: maybe the WinMain() thing rises from msvc using it instead of main(), which presence is obligatory for a well-formed program? ;)
I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.