Pruning a static library in c++ - c++

I am trying to expose a single well defined class by building a static library and then shipping the built library with a few header files that define that class and the interfaces needed to use it. I have that working but the problem I am running into is the library is gigantic. It has every single object file from the whole project and all I need is a subset. If I make a simple main.cpp file and include and use that single class then I get a output file that is only as big as the 20% of the library I am using. Is there a way to tell the linker to start from a given place and prune everything else like in the executable case?
EDIT: I forgot to mention that I am using gcc on cygwin and linux (though I would like a solution that worked with visual studio as well, we generally use that for development but deploy primarily on linux)

Make a shared library. It behaves like an executable from the point of view of linking etc. It should do the discarding you mentioned you saw on the executable.

You have to split the project up. Take out the files needed for the library and make that a separate project just building the lib.
The remaining project (with main.cpp in) needs to call the new lib project to get the lib
Details depend on what tools and OS you are using to manage the project (e.g. Visual Studio or make or ... )

You haven't told us what toolchain you are using but since you say project, I'm guessing you are using the MS toolchain.
The MS toolchain includes every object from a project into the static library. What you want to do is break your single class into a separate project. You can continue to have a super-project that includes that class so you don't have to modify any of your existing projects.
Now, if you want to take this to the next level, you should consider putting each member of the class into it's own translation unit (i.e. .cpp file). This way, if a user of the class only needs a few parts of the class, they will only need to link in the parts they need.

Related

Keep compile definitions when using CMake-built library that has custom target_compile_defintions

Situation:
I am developing a C++ library managed by CMake that I intend to use in multiple projects. The library has some compile-time configuration that propagates to the defintions of custom "defines" using (e.g.) target_compile_definitions(my_library PUBLIC "CUSTOM_DEF_OPTION"). These definitions affect the generated code both in cpp files and headers.
When I am linking this library to another library or executable as part of the same CMake project (using target_link_libraries(my_executable my_library), the PUBLIC defintions are properly carried over to the compilation of the executable.
Problem:
However, this does not work in case the library is used in some external project, managed e.g. by Visual Studio or Eclipse, because the compile definitions are not carried over. This results in discrepancies between the effective header code and already-built library.
Therefore, I need to find a way how to easily apply the PUBLIC compile definitions in the projects using this library.
Question:
I was thinking about using CMake's configure_file(...) to generate a special header file that would contain the definitions and will be included in the library project instead of using target_compile_definitions. It seems I need to manually craft the template file and logic, which duplicates already existing logic for adding target compile defintions.
Is this a correct approach? Is there a way to generate such file automatically? Is there some other more-elegant approach that would work?

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.

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.

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

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.

Lib Files and Defines

I'm using a couple of external libraries and I'd rather not have to include all their source and header files in my main source directory or in my project file. One option would be to compile the libraries as lib files and link them like that. However I'm not sure the defines get evaluated before or after the lib file gets created (which one is it?). If it's before then obviously I can't just pack them because they might not work properly on different compilers or systems.
So if I can't pack the libraries as lib files, is there any way for me to link in the c or cpp source files? Probably not, since they would have to be compiled first, but maybe I'm wrong.
Edit: Here's a follow-up question, based on answers. Do you think it'd be too much of a hassle to have a makefile that creates the lib files? I'd still rather not add the sources to my project or in my source directory.
Library is a binary file, so all defines obviously already in.
Just to make order, defines are evaluated as 1st stage of compilation process - the step is called preprocess. At this stage, for each cpp files created one file containing all #include'ed in it files recursively and all macros are evaluated.
Any way 3rd party should not depend on your compilation flags with one exception - release/build lib. Only in this case you need 2 versions of 3rd lib.
As regarding to question if to compile 3rd party libs once or each time while compiling your code it depends. If you are doing it only for itself than do what looks an easies way for you, but if we're talking about development team and the project to be maintain for a long time, than more things are to be considered.
SO we're talking about some solid solution for a team and we want to compile library several times.
In this case I personally strive to compile 3rd part library once and use it many times. This reduces compilation times for each build for each developers, which means faster development.
Nice, but where you hold these libs. I like phisycal separation - 3rd party library and my code not in same tree. This can avoid some not intentional errors. A good build system, and most of time it's mandatory, should be re-buildable. This means that if you checkout your code after year, you can compile and receive exactly same binaries.
Once I used some external read only tree on my machine. This tree was managed only by me.
To make my sources re-buildable, each next version of 3rd party library put in direcoty containing it's version and my source tree was updated to point to this point. If you build on several machines, than the read only tree should be visible on all these machines.
Additioanal solution is to check if your SCM tool (I suppose you use one) gives you some ability to combine several sub-tries from repository in one checkhout. For each 3rd party library there's one sub-tree. This way 3rd party libraries are available on all machines your build. I currenly use these method on subversion - it's called svn:external. On CVS AFAIK it's called cvs modules. Additional advantage that the libraries are managed by source control system, so you can track all changes done to 3rd party libs.
defines get evaluated even before compiling. They are dealt with by the pre-processor, that prepares the code for the compiler to use. So yes, they are evaluated before the libraries are created.
You can't link against source code. You can only link with object files, static libraries, or dynamic libraries (shared object files/DLLs).
Using dynamic linking can be a good option, especially if the externals are large and/or you'll be using them in many executables.