CMake building Static & Dynamic libs on Windows - windows

I know ways to get CMake to generate both a Static & Dynamic library simultaneously (avoiding the mess of multiple build trees and dual-compiles), but they mainly only work on OSX & Linux (where you get a dynamic .so/.dylib, and a static .a). Windows is a bit messier, since you get a static .lib and a dynamic .dll AND .lib, and the two .lib's have the same name but are different.
In a project I'm converting over right now, that's done manually through lots of batch files and makefiles that just place the resulting files in separate subdirectories. How can I achieve this similar behavior in CMake? (e.g. How can I make CMake build the same binary twice, once static and once dynamic, but place the results into two different subdirectories).

Related

Make: Prioritize -L (or: Ignore contents delivered by pkg-config)

I want to make a library that depends on other libraries.
I have been able to make the static .a files of the dependencies and have them along with the header files readily available in a directory. Running them through file confirms that I have successfully compiled these for all architectures.
When I try to make the final library, it tells me
ld: warning: ignoring file /usr/local....dylib, building for architecture-A but attempting to link with file built for architecture-B
It is correct that the library under the mentioned path is only compiled for the host architecture A (installed via package manager). However, in the LDFLAGS I have -L${libdir}/libs (the folder where the libs are) but make only seems to care about the ones in my usr/local/..folder.
Are there other ways to specifically point make to check the {libdir}/libs folder or even make make ignore the paths from pkg-config in case it searches there first, finds the unfit files and never gets to try the ones I passed in my LDFLAGS?
You write ...
I have been able to make the static .a files of the dependencies and have them along with the header files readily available in a directory.
... but this is probably irrelevant because you seem to be trying to build a shared (i.e. dynamic) library. Static libraries and shared ones don't mix very well.
Are there other ways to specifically point make to check the {libdir}/libs folder or even make make ignore the paths from pkg-config in case it searches there first, finds the unfit files and never gets to try the ones I passed in my LDFLAGS?
You are focusing on make, but make doesn't have much to do with it. It is the linker, not make, that performs the search and the actual link. make just executes the link command you told it to execute.
But yes, you can control the linker's library search order by controlling the order of its command-line options. Library directories specified via -L options are searched in the order they appear on the command line, and all of them before the linker's default library directories.* If ensuring a proper order of arguments does not get you the link you want then it is very likely because the linker is ignoring your static libraries because it is trying to build a dynamic one.
However you should be able to bypass the search altogether by specifying a full path and filename of the library you want to link instead of using -L or -l options. For example, instead of -L/path/to -lfoo, you might use /path/to/libfoo.dylib (or /path/to/libfoo.a). You don't normally want to hardcode paths like that, but in this case it might serve a diagnostic purpose to do so.
Note also that it is rarely a good idea to link against dynamic libraries that are not installed in their intended location, especially if the libraries are not part of the same project. It may seem at first to work ok, but it contributes to problems with finding the libraries at runtime (and dynamic libraries do need to be found at runtime, too). The same does not apply to static libraries, but that comes with its own set of advantages and disadvantages.
* There's more to it than that, but this answer is already long. Read the linker docs if you want more detail.

Exclude specific symbols from dSYM

I'm building an iOS project that includes a sub-project whose symbols I would like exclude from the product's .dSYM DWARF file.
The situation is that the sub-project (a static library) contains valuable proprietary code that I would not want an attacker to be able to symbolicate, even if they had the dSYM files used for resymbolicate crash reports for the whole app. The subproject covers a very specific domain and is well tested independently, so I'm not worried about being unable to resymbolicate stack traces in that code. However, I do need to be able to resymbolicate crash reports for the rest of the app, so I need a dSYM (as distributing symbols with the app is not an option).
I've already managed to make sure that all of the relevant symbols are stripped from the binary, and setting GCC_GENERATE_DEBUGGING_SYMBOLS=NO removed a lot from the dSYM, but I'm still seeing class-private C++ method names inside the dSYM file. For reference, I'm using clang.
How could I produce a dSYM for my app without compromising the symbols of this sub-project?
With a bog-standard Xcode workflow, this might be difficult. You could probably do something with a shell script phase which moves the static library to a different filename ("hides" it) and then runs dsymutil on your main app binary to create a dSYM. Because dsymutil can't find the static library, it won't be able to include any debug information for those functions. Alternatively, you can create a no-debug-info version of the static library although this will take a little bit more scripting. A static library is really a zip file of object (.o) files -- you need to create a directory, extract the .o files (ar x mylib.a), strip the .o files, then create a new static library (ar q mylib-nodebuginfo.a *.o I think) and put that in place before running dsymutil.
I know no on way to selectively remove debug information from a dSYM once it has been created, though. It's possible to do but I don't think anyone has written a tool like that.

What is the difference between VC++ project lib directories and linker inputs

I am just approaching C++ development (from a C# background), and i am wondering what is the difference between Library Directories in C++ project settings (in Visual Studio):
and the Linker "Inputs" where i can also supply libraries:
Is there any fundamental difference between these?
This setting got fumbled a bit in VS2010, it was much clearer in previous versions. Where the settings you show in your screenshot were present in Tools + Options. Which shows the core intent, they contain directories that are determined by the setup for Visual Studio and its components. The locations of the CRT, MFC, ATL and SDK libraries.
The Linker + Input + Additional Dependencies setting is the important one, there you say exactly what .lib files the linker should link. You can specify the path of a .lib file and be done. But it is not uncommon that you only specify the name of the .lib file, then edit Additional Library Directories to tell the linker where to search for those .lib files. Which is handy if the install location for, say, Boost isn't always the same or you want to switch from one version of Boost to another.
So in summary:
Linker + Input + Additional Dependencies: add the .lib files you need to link
Linker + General + Additional Library Directories: only use if you didn't specify the path of .libs
VC++ directories: don't mess with it
Do note that the last two bullets only specify directories, not .lib files that the linker should link. The first bullet specifies actual .lib files. What is invariably confusing to starting MSVC programmers is that the linker magically knows how to find important .lib files without specifying them explicitly in the Additional Dependencies setting.
That's unfortunately the non-visual part of Visual C++. There are two distinct ways in which a project can specify .lib files that the linker should link without using the setting. The first one is the project template you selected to get the project started. It uses project property sheets, files that specify default settings for a project. You see them with View = Other Windows + Property Manager. An important one is "Core Windows Libraries", it sets the Additional Dependencies setting to link the essential Windows .lib files, the ones you always need like kernel32.lib and user32.lib. Those settings are "inherited" by your project. Otherwise giving meaning to "NoInherit" if you ever run into it.
The second important way is the #pragma comment directive. Which is used in source code, it injects a linker directive. The "lib" variety is important, that tells the linker to link a .lib file. In addition to what you explicitly specify in the linker's Additional Dependencies setting. A very good example of that one is vc/atlmfc/include/afx.h. Search for "#pragma comment". Note the macro soup that selects the proper mfc .lib file, depending on compiler specific settings. And the bunch of extra Windows .lib files an MFC needs to link.
The C++ build model is filled with a maze of twisty little passages. The IDE tries to make you fall in the pit of success but in the process hides what's important to get to the next level of understanding. It isn't different in C#, to know how to make the Reverse() extension method not consume O(n) storage requires digging in.
Most (not all) libraries come with two sets of files:
Header files are #included in the source code that's using the libraries, to provide declarations for functions, classes, constants or whatever else might be needed
Library files are binary code that contains the code of the library. These are used by the linker when it assembles the final executable

What do you need in a static library?

I want to try making a simple game engine. Just something that handles states, assets, characters/actors and their stats and an inventory. Most of the code I can take from other games I've wrote, but I'm confused on how I then turn it into a static library. Do I need a main.cpp? If so what has to go in it? Under Linux I'm guessing I compile it to .so and add the headers to my include directory and then just link to the .so but what do I do on Windows and Mac?
A .so is not a static library, it's a dynamic one. A static library is, in its most basic, a .o file compiled from a single C file, or a .a file which is simply a collection of .o files.
A static library is different from a shared one in that the object code is linked directly in to the final executable, requiring no dependencies at run time.
Under Unix, the ar(1) command is used to bundle .o files in to a composite .a file. I do not know the comparable utility for Windows.
Once you have the .a file, you will simply need the combination of the .a file and the .h files to build your code. You use the .h files for compiling, and then link against the .a file.
Shared libraries have a specific advantage over static libraries in that if you have multiple, yet different, programs relying on the same libraries, the code from the shared libraries can be shared among all of the programs at the same time, so in that sense they lower the overall impact on the system. Their downside is slower start up times (though that's pretty marginal nowadays). Statically linked libraries can not be shared across independent programs, but if you run the same executable several times, its code will be shared.

Code snippet paths in GCC

Background: Keil C51 on a PC, currently moving to GCC (CrossPack-AVR) on an iMac.
Since I write firmware for micro's I have a lot of 'driver' source files etc. that I need to include with my programs, e.g. a LCD driver, i.e. reusing code. These code snippets (.c and .h files) live sub folders in a /snippets/ folder, i.e. /snippets/lcd/. My /snippets/ used to be in a folder that also had a /projects/ folder for, well, projects or applications. I had considered putting them in a library but I use various architectures so it would not always work.
The Question: How can one set that up in GCC without having to specify absolute paths to the snippets in, for example, the various #include paths etc. so that the source file, of the included snippet, gets re-compiled along with the project that uses/includes it? Thus, if I improve on a snippet, it benefits all projects that is compiled/re-compiled subsequently?
I looked around on google but must be using the wrong search term.
Thanks!
I think make files will do the trick.

Resources