g++ linking .so libraries that may not be compiled yet - c++

Im helping on a c++ application. The application is very large and is spread out between different sub directories. It uses a script to auto generate qt .pro files for each project directory and uses qmake to then generate make files. Currently the libraries are being compiled in alphabetical order.. which is obviously causing linking errors when a library its trying to link isn't built yet.. Is there some kind of g++ flag i can set so it wont error out if a library its trying to link hasn't been built yet? or a way to make it build dependencies first through the qt .pro file?
NOTE:
This script works fine on ubuntu 10.10 because the statements to build the shared libraries didnt require that i use -l(libraryname) to link to my other libraries but ubuntu 11.10 does so it was giving me undefined reference errors when compiling on 11.10.

Have you looked into using Qt Creator as a build environment and IDE? I've personally never used it for development on Ubuntu, but I have used it on Windows with g++, and it works great there. And it appears its already available as a package in the repository.
Some of the advantages you get by using it are:
Qt Creator will (generally) manage the .pro files for you. (If you're like me, you can still add lots of extra stuff here, but it will automatically add .cpp, .h, and .ui files as they are added to the project.)
You can set up inter-project dependencies that will build projects in whatever order they need to link.
You can use its integration with gdb to step through and debug code, as well as jump to the code.
You get autocomplete on Qt signals and slots, as well as inline syntax highlighting and some error checking.
If you're doing GUIs, you can use the integrated designer to visually layout and design your forms.
Referring back to your actual question, I don't think it's possible for a flag to tell gcc to not error when a link fails simply because there is no way for the linker to lazily link libraries. If its linking to static libraries (.a), then it needs to be able to actually copy the implementation of that code into the executable/library. If its dynamically linking (.so), it still needs to verify that the required functions actually exist in the library. If it can't link it during the linkage step, when can it link?
As a bit of an afterthought, if there are cyclic dependencies in your compile process (A depends on B, B on C, and C on A), then you might need to have a fake version of a library get built first, which only has empty stubs for the implementation of each function, and the full definition for each class or object. Then, build everything else while linking to that, and at the end, build the real version of the fake library, and link it to all the other versions that were already linked. I think this would only work on dynamic linking, though.

You could use a subdirs project to have control over the build order (no matter whether the other dev wants it or not :) ).
E.g.
build_all.pro
TEMPLATE=subdirs
CONFIG+=ordered
SUBDIRS=lib2/lib2.pro lib1/lib1.pro app/app.pro
The lib1.pro, lib2.pro, ... are your generated pro files.
Then run qmake once for the build_all.pro and also run make in that directory. This will build lib2 before lib1 and then app.

Related

vcpkg-built google protobuf and grpc won't statically link to application

Tools and versions:
Visual Sudio 2017, Google Protobufs 3.11.3, gRPC 1.27.1, vcpkg 2020.02.04, on Microsoft Windows
I used vcpkg to build the Windows native C++ versions of gRPC and protobuf (and other dependencies) for Windows (x86). Everything builds successfully.
When I build my application I include "libprotobuf.lib" as a linker input. However, it doesn't get linked. Instead, my program will only run if the "libprotobuf.dll" is present for the program to load. I don't know of another way to specify that the library should be statically linked.
During the build of my application, I see a lot of warnings like this:
include\google\protobuf\duration.pb.h(220): warning C4251: 'google::protobuf::Duration::_internal_metadata_': class 'google::protobuf::internal::InternalMetadataWithArena' needs to have dll-interface to be used by clients of class 'google::protobuf::Duration'
This page mentions the warnings and says that static linking is the default but it seems like vcpkg isn't building it that way or I need to reference the library a different way.
I've also seen this page that offers a solution. That helped a bit. It made Visual Studio recognize unresolved externals, so at least it was trying to statically link the .lib file(s). With that in place I've tried various combinations of .lib files for protobuf, grpc, and dependencies but I still can't get a successful build - and the compiler warnings are still generated.
I feel like I'm missing something (a pre-processor define maybe) during the vcpkg build that would build the headers or libraries differently. I've tried to change some of the build settings but they're always overwritten when vcpkg generates cmake files for the build.
Or I'm missing the right combination of library files to reference from my project.
Has anyone gotten this to work? If you have examples of building the libraries for static linking via vcpkg, or the correct way to link the libraries in VS2017 project, could you share your information?
Finally got a chance to come back to this. The problem came down to two things:
1. Realizing that you can specify a triplet (as noted in original question).
2. Finally realizing using the static libraries also meant I had to switch my application to static c runtime libraries instead of shared dlls.
I can't switch my application. I've done testing with this non-static mode operation though. I haven't seen any problems, but does anyone else use protobufs (and gRPC this way) - it doesn't appear to be recommended.

Haxe - Create a C++ Stand-alone executable

I have written a haxe program that tries to communicate with a remote server. I was able to compile to the C++ target successfully. The executable runs just fine on my system. However, when I try to run the same on another windows box, it fails with the following error
Error: Could not load module std#socket_init__0
I then installed haxe and hxcpp which worked like a charm. I was able to run the exe. I understand now that there is dependency on hxcpp.
That still did not solve my problem as I want to create a stand-alone application. After some research I found a file (ExampleMain.CPP) with the following instructions that I think might solve my problem. However, I am a novice and do not quite follow. Can some one walk me through with this? Thanks
ExampleMain.CPP
This is an example mainline that can be used to link a static version.
First you need to build the static version of the standard libs, with:
cd $HXCPP/runtime
haxelib run hxcpp BuildLibs.xml -Dstatic_link
Then the static verion of your application with (note: extra space before 'static_link'):
haxe -main YourMain -cpp cpp -D static_link
You then need to link the above libraries with this (or a modified version) main.
You may choose to create a VisualStudio project, and add the libraries from
$HXCPP/bin/Windows/(std,regexp,zlib).lib and your application library.
Note also, that if you compile with the -debug flag, your library will have a different name.
Linking from the command line for windows (user32.lib only required for debug version):
cl ExampleMain.cpp cpp/YourMain.lib $HXCPP/bin/Windows/std.lib $HXCPP/bin/Windows/zlib.lib $HXCPP/bin/Windows/regexp.lib user32.lib
From other OSs, the compile+link command will be different. Here is one for mac:
g++ ExampleMain.cpp cpp/Test-debug.a $HXCPP/bin/Mac/regexp.a $HXCPP/bin/Mac/std.a $HXCPP/bin/Mac/zlib.a
If you wish to add other static libraries besides these 3 (eg, nme) you will
need to compile these with the "-Dstatic_link" flag too, and call their "register_prims"
init call. The inclusion of the extra static library will require the library
in the link line, and may requires additional dependencies to be linked.
Also note, that there may be licensing implications with static linking
thirdparty libraries.
I'm not sure, but it seems that you are taking the same extra steps hxcpp does for you already. When you compile your standalone application it is actually standalone and doesn't have a dependency on hxcpp per se - but it has a dependency on the standard libraries within hxcpp you may have used. For instance, if you use regular expressions, you will need the regexp.dll that hxcpp has for it, as you noted. The haxe standard library is in the std.dll and the zlib is if you used compression from the zip packages.
If I am not mistaken, the default is to reference these components dynamically. In order for your application to be standalone as you suggest, you simply have to copy these dll's alongside your binary.
If you want to link to these library components statically, automatically from your haxe code, just import the types from the cpp.link package. This instructs hxcpp to automatically bring its libraries as part of the compilation, linking it statically into your binary instead of dynamically. No extra steps are necessary!
Short answer: add import cpp.link.StaticStd; and any other library components in the link package somewhere to your code. It can be anywhere as long as it's imported, it will be linked in.

how can I staticaly link qt application in windows using mingw

http://qt-project.org/doc/qt-4.8/deployment-windows.html say:
Before we can build our application we must make sure that Qt is built statically. To do this, go to a command prompt and type the following:
cd C:\path\to\Qt
configure -static <any other options you need>
doing so result in:
'configure' is not recognized as an internal or external command,
operable program or batch file.
is there any step by step guide explaining how can I configure my QT project so that it produces statically linked binaries?
Also, this guide seem to expect user to have full msvc compiler, I am using MinGW so I have no setenv batches
Make sure you've downloaded the .zip variant of Qt sources (4.8.5). The .tar.gz one is missing configure.exe, at least for Qt 5.
It should work then.
Note that there are two levels of "staticness":
Qt itself as a static library.
Qt's (and your application's) dependency on the C/C++ runtime.
Since you likely want both, you must coerce Qt itself to statically link with the C/C++ runtime library. I've not done it for mingw yet, but it will require changing the relevant qmake.conf. This change will propagate to the code you build using such tweaked Qt, so your application will statically link to both Qt and to the C/C++ runtime.
Using MSVC2012 and link time code generation, after UPX-ing the executable, the size is ~3mb for a small application using the gui and network modules. Just to give an idea of how big it will be. It'll likely be larger when using mingw.

How can I compile a C++ project (with g++) to use on other computers?

This may be obvious, but I want to make sure what to do before I do anything rash. I want to compile my C++ program, libraries and all, to a release executable such that the file can be run on any computer (running the same OS). Right now, I'm on Mac OS X (10.7.4) and I need to be able to run my executable on other Macs. The problem is I am using the OpenCV library in my project, and I only have it installed on this computer. Is there a way to compile with g++ such that if I open this program on a computer that doesn't have the OpenCV library installed, it will work anyway? As in, build all the dependencies into the executable. Or does this happen automatically?
I am also quite new to the ".o" object files, so can those have anything to do with it? I would prefer a way to get it all into a single file, but I'll settle for a package as long as it works.
Thank you.
To expand on molbdnilo's answer, you'll need to create an application bundle (see the Apple Bundle Programming guide). You'll need to move your console application to MyApp.app/Contents/MacOS/MyApp. There's also a Frameworks directory in which you'll need to add the OpenCV library as a framework. See the OpenCV Wiki for some information on the OpenCV framework. A framework (at its simplest) is pretty much a dynamic library wrapped in a particular directory structure.
I would suggest looking into using Xcode on the mac as it simplifies the construction of bundles and linking to frameworks compared to doing it yourself via scripting and Makefiles.
There are two ways to do this. You can static link if you aren't going to run into licensing issues with any of the libraries you are linking to. This is pretty easily handled by using g++ -o myApp -static -lopencv myapp.cpp However, this also depends on static libraries existing for the libraries you want to link to. Most distribute static libs with the shared libs these days.
The other way is to distribute the shared libraries and tell your application to force it to look in a certain spot for the shared library using -rpath. Note: I am telling you the Linux way to do this, it will probably work on a Mac but I have no way to test.
So say all of your shared libraries are in the same directory as your executable, you can compile with: g++ -rpath ./ -lopencv -o YourApp yourApp.cpp
I hope this helps.

Static linkage usage in c++ linux: do I need to recompile everything each time I change library?

I have a program which statically links to another library in linux using -L(mylib.a) when compiling (using eclipse cdt).
To my meager understanding, the fact that the link is static means that the library is inserted into my binary. Does this mean that if I make a change to mylib I need to recompile my binary?
I assume so, but I wanted to make sure, as it is a big overhead in time. Note that if a change was made to mylib, then eclipse recognizes that it needs to be recompiled, but it doesn't recognize that the binary itself needs to be recompiled, even though it links to the mylib.
If you did not change the interface of the library (i.e. the headers), only a re-link is enough.
Yes, You should rebuild your code with the modified library to produce the binary which links to the new and updated library.
The building of a project can be broken in to two milestone phases:
Compilation:
During this stage the compiler compiles each Translation Unit. It checks the source code for valid syntax etc and produces object files.These object files contain the assembly code output of the source code.
Linking:
During this stage the linker links together the object files and the libraries to generate an executable.
When a application or project uses a static library it includes the header file which is typically called as library interface which contains the list of api and other construct which the application uses.The application also needs to link against the library file.
Obviously, if the interfaces are intact ie the library header file included by your application is unchanged, a compilation is not required but you just need to link to the updated library.
However, I dont think there is a way to just relink updated libraries through eclipse IDE so you should rebuild your project which would essentially do the needful.
i.e:
recompile your project and relink the new library to it or
just relink the new library to your project.