Cross linking issue

I will be grateful if someone can answer my question.

I created a source file with a single function and built it using pgcpp on windows and generated an .obj file. When I use this function (with the generated .obj file) in my program (which is compiled using MSVC 2012), I always get LNK 2019: unresolved external symbol error. Does it mean that .obj files compiled using pgcpp are not linkable with .obj files compiled with MSVC? I just confirmed that the same issue exists with GCC on Linux.

If this is not possible, how should I call a function compiled using pgcpp from my program which is compiled using MSVC (or GCC on Linux)? In pgcpp, Is there a way to generate binary compatible object files with startard OS compilers?

I also tried putting the object files into a static link library and tried to link with that one. Unfortunately, I am still getting the same linker errors in both platforms.

Thanks,
Nadir

Hi Nadir,

I checked with our C++ developer, and object files generated by PGI C++ on Windows are not interoperable with object files generated by VS2010 C++. I believe the same is also true for Linux with GNU C++, due to differences in the C++ runtime libraries.

Best regards,

+chris

Hi Chris,

Thanks for the answer. Is there any way to call the function inside the PGI compiled object file from the object file compiled with other compiler. When I try generating a static/dynamic link library and trying to call the function from there, I am getting the following linker errors:


undefined reference to __pgi_uacc_dataenterdone' undefined reference to __pgi_uacc_dataona’
undefined reference to __pgi_uacc_computestart' undefined reference to __pgi_uacc_enter’


What might be the library file I need to link with to avoid those linker errors? I used recursive ldd to query the external dependencies, but those symbols are also not located in those libraries.

Hi Nadir,

Those symbols are defined in the PGI runtime. If you compile something with PGI C++, you will need to link in a series of runtime libraries to resolve internal references created by the C++ compiler.

If you pass -v to pgcpp, the driver should show you the steps involved in compiling and linking a C++ program. In particular, the link step will show you which libraries are needed for C++:

/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /proj/pgi/linux86-64/14.3/lib/trace_init.o /usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtbegin.o /proj/pgi/linux86-64/14.3/lib/initmp.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /proj/pgi/linux86-64/14.3/lib/pgi.ld -L/proj/pgi/linux86-64/14.3/lib -L/usr/lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.6 /tmp/pgcppvzgi-9Y4rxrl.o -rpath /proj/pgi/linux86-64/14.3/lib -o hello -lzceh -lgcc_eh --eh-frame-hdr -lstdz -lCz -lpgmp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.4.6/crtend.o /usr/lib64/crtn.o

Here, everything that starts with a “-l” indicates a runtime library.

Depending on which flags you are passing, you may need additional libraries. I notice that some of the undefined symbols you referenced here are actually defined in libaccg.a (pull in via -laccg).

Hopefully this helps.

Best regards,

+chris

Hi Chris,

Thanks a lot for your helps. I am now able to link fine with the dynamic library built with PGI wth my GCC built executable. However, I am getting the runtime error:

Accelerator Fatal Error: No CUDA device code available

I am not getting that error when I run the same code using the PGI compiler only. I also couldn’t find that error in the documentation. Could you also help me on this?

Best regards,
Nadir

Hi naadir/cparrott,

I’m having the exact same problem (“No CUDA device code available”) after linking to libaccg.so, libaccg2.so, libaccn.so, libaccapi.so in /opt/pgi/linux86-64/14.3/libso/.

Was anyone able to solve this problem?

You need to add nordc option.
-ta=tesla:nordc

http://stackoverflow.com/questions/38213176/c-linking-a-pgi-openacc-enabled-library-with-gcc

Just to complete any confusion

  1. pgcpp is no longer a PGI product, on windows or Linux.
    On Linux, we now offer pgc++ which IS compatible with g++.
    Currently no C++ PGI compiler on Windows.

  2. pgcpp uses a different “name-flowering” algorithm than VC++
    and g++. Therefore, symbols will never match or link to those objects.

  3. pgcc is compatible with VC++ and g++, because C does not
    flower the symbols, and the languages use a common API.

So If the objects you wish to link to VC++ or G++, are to be compiled by
PGI, they need to be modified to be C programs.

dave