Linking libpng with Borland C++ - c++

I made a program on Mac OS X using OpenGL and dynamically linking libpng. I'm now trying to port it to Windows. Whenever I try to compile and link my ported program in Borland it gives me this error and about 10 more that are the same, but with a different '_png_create_read_struct':
Error: Unresolved external '_png_create_read_struct' reference from C:\PROGRAMMING\PNGTEST.OBJ
I assume it's because I have not properly set up libpng with Borland C++ 5.5.1 for Win32. I've put png.h and pngconf.h into the include folder into C:\Borland\BCC55\Include, and I have put libpng12.dll.a, libpng13.a, libpng13.dll.a, libpng.a, libpng.dll.a, libpng12.def, libpng.def, libpng12.la, and libpng.la into C:\Borland\BCC55\Lib (there is probably no need for them all, but as a noob I have no idea which ones are needed and not).
Do I need to put a libpng.obj file in there too? And if so how would I make/get one? I have tried using makefile.bc32 to set up libpng, yet that gives me a missing separator error.
Here are my command-line options:
bcc32 -tW pngtest.cpp -lpng
I include png.h in my code. What am I doing wrong or is there an even better way to load images with alpha that doesn't need libpng, or even a better compiler to get for Windows?

You're probably better off with the MinGW compiler than Borland. Borland is not well supported any longer.
You could also download DevC++ and see if it has a libpng package in its addon mechanism.
DevC++ is an IDE that uses the MinGW C/C++ compiler.
That said, if you feel you must use BCC, you'll either have to
a) Build libpng with Borland. This is the best solution if you're going to use borland.
b) Use, I think, Impdef to create an import library from libpng.dll. You'll find impdef.exe or imp(something).exe in the borland bin directory.
Note that some libraries will not work with impdef as there is static code linked to the dll that causes it to fail without the proper runtime.

First of all, I would not have "polluted" the BC55 installation with third-party libraries; it will make moving the project to other build environments much more difficult. It would have been better to place them in a folder within your project.
Secondly do you know that the export library you are attempting to link is built for BC55? The .a extension suggests a GNU library (Borland libraries conventionally use .lib extension), in which case it would not link with BC55 which uses a different object file format. If this is the case you will need to rebuild the library as you attempted to do, so I suggest that you should really be asking a question about the problem you had with doing just that. I wonder whether the makefile is written for Borland make or GNU make, since they have differing syntax?
The command line option -lpng might be correct for GCC (where it will link libpng.a), but is meaningless to BCC. The -l option merely passes the text that follows to the linker. The linker command line, requires that the complete name be passed, and if no extension is provided, .lib is added implicitly.

You should probably just use coff2omf to convert the library. The DLL files are almost certainly in "Microsoft" COFF format.
See COFF2OMF.EXE, the Import Library Conversion Tool.

Related

Linking a MinGW library to a MSVC app with a C interface

I'm trying to link to the OpenAL soft library as compiled with the Media Autobuild Suite, and I'm getting the following error from Visual Studio:
libopenal.a(source.cpp.o) : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0xA
My application is in C++ and compiled directly in Visual Studio 2019 (however, with the VS2017 toolset). OpenAL soft is written in C++ but exposes a C interface, and the MAB Suite compiles using MinGW/gcc and generates a libopenal.a static library file.
I've read from multiple other questions such as From MinGW static library (.a) to Visual Studio static library (.lib) and How to use libraries compiled with MingW in MSVC? that object files compiled with different compilers are generally not compatible for C++ due to name mangling, but often are compatible with C linkage. Because C does not use name mangling, and because the ABI is (usually) OS-dependent, libraries with a C interface compiled on the same platform are generally compatible.
Nevertheless, I've been running into linker errors, namely the LNK1143 above. I've confirmed that the included headers use extern "C" { to hint C linkage and that the target platform (x64) is the same for both builds. I also linked to libgcc.a as this answer recommends, and did not get any linker errors for it.
Does this mean the claim that C interfaces are generally compatible across compilers is not true? Or is this a special case in which it's not working? If the latter, what could be causing the linking to fail? Would I have better luck if I recompiled as shared libraries (dlls) instead of static libraries (even if I still use MinGW's .a files instead of .lib)?
I cannot change compilers from MSVC for my main app. I intend to use more libraries from the MAB Suite in the future, so I'd prefer to stay with MinGW for those dependencies if possible because I don't want to recompile all 70+ by hand.
Any help is appreciated. Thanks in advance.
Mixing compilers is tricky and prone to issues.
In some very simple cases it may work, but there are definitely a number of cases where you will run in to issues, for example:
if the different components use different runtime libraries
if memory management is being mixed (e.g. forget about freeing memory allocated with malloc() in MSVC using free() in MinGW)
when using exception handling in C++
My advice to do it all with the same compiler (and even the same version of this compiler).
Specifically in your case OpenAL can be built with MinGW-w64. So maybe you should look into that instead of downloading some prebuilt version from the web.
Or - somewhat easier - use MSYS2 and use its pacman package manager to get its own MinGW-w64 build of OpenAL.
I figured out what works for me, so I'll share.
I was not able to link a static library between compilers as I originally attempted. My understanding is that the extra info kept in the lib to allow link-time code generation is compiler-specific. Brecht Sanders's answer outlines a few possible reasons why the code wouldn't be compatible.
I was, however, able to link to a shared library, with a few extra steps.
Using the same suite (see the question), I compiled as shared and got libopenal.dll, libopenal.dll.a, and libopenal.def. In my case, the .def file was generated by the suite. Accoding to this answer, you can generate a .def file with gcc using:
gcc -shared -o your_dll.dll your_dll_src.c -Wl,--output-def,your_dll.def
Trying to link to libopenal.dll.a still gave me errors (I don't know exactly why, and I already discarded the logs.) What I did instead was generate a .lib file from the .def file. In Visual Studio's built-in terminal:
lib /machine:x64 /def:libopenal.def
This generated a libopenal.lib file in the working directory. Linking to this file worked perfectly, and I was able to successfully load the dll at runtime.
I've tested this same method with many other MinGW-compiled libraries from the suite, including libavformat, libavcodec, libavutil, libavdevice, swresample, and swscale, and thus far all of them have worked.
Kind of convoluted, but it seems to work well for me, so I hope this helps anyone else with the same problem.

In C++, what is wx.h?

The existing code is calling some sort of wx header file and my DEV C++ compiler just says there's no such file.
Code:
#include<wx/wx.h>
Compiler error:
[Error] wx/wx.h: No such file or directory
So my question is -
What is wx.h
How do I install it in my compiler so that I can use it?
Do I need to change my compiler or DEV C++ would do fine?
What is wx.h
It is the header file of a library. The GitHub project should have some instructions on how to fetch the dependencies and how to install them.
How do I install it in my compiler so that I can use it?
Normally you have to download the dependency, build it (following some instructions), and then you need to use the header in your project and link the library. The exact steps depend on each library and each compiler.
Do I need to change my compiler or DEV C++ would do fine?
In principle, no. Some libraries only work with some compilers, though.
Note that Dev-C++ is not a compiler, it is an IDE that comes with a port of GCC (as far as I know).
It seems that you are using WxWidgets framework but your compiler doesn't know where to find its headers, and apparently also libs which you would face with on a next step.
You, need to add to your compiler flags the output of wx-config --cxxflags. And also to your linker flags the output of wx-config --libs.
Assumption is of course that WxWidgets is installed on your PC

Programming language that doesn't require a runtime/dependency to be installed

I want to know a programming language that doesn't require a runtime/dependency to be installed on the target system. My primary target is Windows XP and above.
I tried Autohotkey but it dosent have many advance functions.
Firstly, please confirm that does 'C++' requires to install a runtime/dependency on the target system is is Win XP or later. Secondly, please suggest me an alternative to C++ that doesnt require a dependency to be installed.
UPDATE: I will be using CodeBlocks! Does the C++ code compiled with that requires a dependency?
UPDATE: Sorry for the misconception, by CodeBlocks I mean the default compiler of CodeBlocks (ie: GNU GCC Compiler or MinGW).
Everything usually depends on the project, not the language. For example, programs compiled in Visual Studio's C++ uses some runtime libraries to work properly. However, you can configure the project in such way, that these libraries are included in the executable file, thus not needing additional dependencies. Delphi works similarly.
Here's the setting for Visual Studio Project:
If you choose option with "DLL", your program will require runtime DLLs. Otherwise it will be standalone, the runtimes will be incorporated into your binary file.
Edit: In response to question edit
I'll repeat myself: it depends on project, not the compiler or IDE.
If you want to create a program that does not require anything else in order to run, except for base operating system (no .NET, no Java, no Perl, no runtime libraries, etc), then your best bet is to use C or C++ and compile your program as single statically compiled executable.
It is rather difficult to achieve in practice, but it can be done.
Codeblocks is not a compiler, but an IDE, that can use different compilers.
The most common one is MinGW.
To complie with minGW so that all the standard libraries are statically linked you shold configure your project (see "project settings") so the the linker options include the -static flag.
You can even be more specific by stecifying
-static-libgcc
-static-libstdc++

Using 3rd Party Libraries in C++

I'm totally spinning my wheels with getting a couple of 3rd party libraries to work with my c++ programs. I'm looking for some general advice (40,000 foot level) about the general steps that one needs to take when implementing libraries.
First, some specifics: I am using code::blocks in Windows as my IDE. I like this IDE and really don't want to switch to anything else if I don't have to (I've tried visual c++ and also some things in linux). The libraries that I am trying to use are GMP and crypto++.
OK. What I think I know is this: After downloading the library, I unzip the file to a folder. I've been unzipping directly to C:\ with each zip file extracted to its own folder (e.g. c:\cryptopp and c:\gmp). I think that the next step is to build the library, but this is where I get totally stuck. How is this done? There are no executable files among those extracted. From what I can tell, I believe that I do this in code::blocks, but I have no idea how?
Finally, assuming that I can get this done, which I believe creates the .lib files, the last step before actually using the library in my code, is to link into the library. This part, I believe that I understand.
So, my question is broad: do I understand this process overall? And if so, how do I go about building these libraries, if in fact that it the thing that I am missing.
Thanks very much for indulging my ignorance. I'm totally rudderless right now and despite hours and hours on google, I'm making no progress. Also, feel free to correct anything that I have stated as fact that is not correct. Thanks a lot!
Usually libraries have a special file called makefile in them, and are built with a utility called Make (or one of it's variations, whatever works uder windows).
Usually all you have to do is to run Make in the directory where you have unpacked the source files, and it will do the rest itself.
If those libraries you mention (GMP and crypto++; disclaimer: I'm not familiar with either of them) don't have project files for code::blocks then you may still be able to compile them under Windows with MinGW.
If you have installed MinGW you use the MinGW shell to navigate to the appropriate directories which would be /c/cryptopp/ and /c/gmp in your examples - The MinGW shell works like a Unix shell, and has different naming conventions.
Then you need to compile the libraries. Check whether there's a Makefile in those directories, if there isn't you can check whether there's a configure script, which will generate the Makefile. If you have the Makefile you can type make which will compile the libraries with MinGW's port of the GCC compiler.
When the compilation is complete you should have a library in the form of a .a file (say libcryptopp.a) that you can link to your project. In code::blocks you would set the linker path (the -L command line option in GCC) to C:\cryptopp\bin or wherever the library has been compiled, and then add libcryptopp.a to the list of libraries you want to link (this is associated with the -l option in GCC). The convention is to leave out the lib prefix and the .a extension, so you would just add cryptopp to your library list. In the end your linker options should look like -LC:\cryptopp\bin -lcryptopp along with the
Also, to be able to use the libraries you need to add the path to the headers directory to the include path of your project. This is associated to the -I command line option in GCC, so your compiler's command line options would have something like -IC:\cryptopp\include somewhere.
Of course, all of the above assumes that you use code::blocks with GCC. If you're using it with VisualC++ then the principles are the same, but the specific steps differ.

PKG_CHECK_MODULES for somelib++

I am trying to make my autotools project in C++ link against library, that originates as C library (libsomelib.so), but also has bindings to c++ (libsomelib++.so). I ma trying to use PKG_CHECK_MODULES to check if this package is installed, and use autotools to link against it. However both libs come in one package (c++ version requires configure flag), and have only one .pc file, in which independently of configuration settings there is only line
Libs: -L${libdir} -lsomelib
without any mentioning of ++ version. There is also no separate ++.pc file that i noticed at other programs. Therefore automatic linking against ++ version is impossible. I thought about manually adding -lsomelib++ to linking flags, but that's rather ugly (and it will not work if somebody compiled it without --with-cxx flag). I could also test for it's existence by AC_SEARCH_LIBS, but since it's C++ library it's not so straightforward.
Is missing ++.pc file mistake of package distributor or is it some deeper idea, and i don't know how to use it?
If somebody is really qurious i will say that package in question is ossp-uuid.
Yes, the missing ++.pc usually hints towards an omission on behalf of the packager.
BTW: If simple (DCE) UUIDs are sufficient, you could consider e2fsprogs/util-linux's libuuid (in case you run this OS).