Static Libraries and the statically-linked MSVC++ runtime - dll

For building a static library, is the static C runtime statically linked at compile time (of the library) or at final EXE compile time?

According to Hans, the CRT (C Runtime) is not linked while compiling a static LIB using MSVC. It is linked at final EXE compile time.
However, even though this is true. You still cannot mix C runtimes in static libraries. They all must use the same exact runtime (or the system runtime MSVCRT.dll)

Related

FindHDF5 picks static library while shared one is requested

I have compiled hdf5-1.8.21 to have both static and shared libraries. In the project I use
set (HDF5_USE_STATIC_LIBRARIES FALSE)
find_package(HDF5 REQUIRED)
to just select the shared library version but it does not work. It contradicts with the documentation in FindHDF5.cmake. I do not know the reason for it.
Make sure do target_link_libraries for you binary/library with static HDF5 library target HDF5_LIB_TARGET and not HDF5_LIBSH_TARGET

How to test static library with XCTest while specifying pagezero_size and image_base linker flags?

I'm creating a framework that links against a static library using the linker flags -pagezero_size and -image_base
The library is LuaJIT compiled for 64 bits on Mac OS X, and my framework is just an ObjC wrapper for LuaJit plus a bridge to load other frameworks and passing classes and instance objects back and forth.
Everything works fine, but now I want to start writing tests for my framework before I start making some modifications, but the problem is that Xcode complains that pagezero_size is only for the main executable. i.e. adding the flags to the test target throws the error:
ld: -pagezero_size option can only be used when linking a main executable
Any ideas how to run tests for a static library that needs to be linked using -pagezero_size and -image_base?

Xcode: automatic link static library dependency to Project

I've workspace with two project: static lib and cocoa application. Static library link some system frameworks(libcrypto.dylib) and include dynamic lib's .h files(openssl/bn.h openssl/rsa.h). My static library compiles successfully.
Cocoa application uses this static library and at compile time gives an error: "undefined symbols, symbols not found" (bn, new rsa etc).
But when I include libcrypto.dylib also into cocoa application project then there is no error.
Question: Xcode can do this automatically, by taking dependency from the static link library?
Thanks.
The answer is unfortunately no. It is common practice to include each single static library in the project that requires the code. That is just the way it is done.
There is an interesting article on how to handle multiple static libraries in an XCode project.

Difference between modules and shared libraries?

The title mostly covers it, what is the difference between a module and a shared library? I just found this distinction in CMake's add_library command, where they say:
SHARED libraries are linked dynamically and loaded at runtime. MODULE libraries are plugins that are not linked into other targets but may be loaded dynamically at runtime using dlopen-like functionality.
But I can load a shared object using dlopen(), can't I?
The difference is that you can link to a SHARED library with the linker, but you cannot link to a MODULE with the linker. On some platforms.
So... to be fully cross-platform and work everywhere CMake works, you should never do this:
# This is a big NO-NO:
add_library(mylib MODULE ${srcs})
target_link_libraries(myexe mylib)
To be fair, on Windows, they're both just dlls, and so this code might actually work. But when you take it to a platform where it's impossible to link to the MODULE, you'll encounter an error.
Bottom line: if you need to link to the library, use SHARED. If you are guaranteed that the library will only be loaded dynamically, then it's safe to use a MODULE. (And perhaps even preferable to help detect if somebody does try to link to it...)
I think the distinction being made is that shared libraries are specified by the developer at compile-time and must be present for the application to run, even though their methods are loaded at runtime. A module, i.e. plugin, adds additional support at runtime but isn't required. Yes, you can dlopen() a shared library but in that case it would not have been specified as a required part of the program and functions instead as a module.
Another difference is in how ..._OUTPUT_DIRECTORY and ..._OUTPUT_NAME are handled:
Module libraries are always treated as library targets. For non-DLL platforms shared libraries are treated as library targets. For DLL platforms the DLL part of a shared library is treated as a runtime target and the corresponding import library is treated as an archive target. All Windows-based systems including Cygwin are DLL platforms.
For example, this means that if you compile a SHARED library on Windows, LIBRARY_OUTPUT_DIRECTORY will be ignored, because it's looking at ARCHIVE_OUTPUT_DIRECTORY and RUNTIME_OUTPUT_DIRECTORY instead.

MSVC 2008 - Unresolved External errors with LIB but only with DLL, not with EXE project

I have a DLL that I am trying to link with a libjpeg LIB using MSVC 2008 that is generating Unresolved External Symbol errors for the libjpeg functions. I also have a test project that links with the exact same libjpeg library file and links without error and runs fine too.
I have triple-checked my LIB path and dependent LIBS list settings and literally copy and pasted them from the EXE project to the DLL project. I still get the errors. I do have the libjpeg include headers surrounded by extern "C" so it is not a name mangling issue and the unresolved external warnings show the "missing" libjpeg functions as undecorated (just a leading underscore and the # sign parameter byte count suffix after each name).
What could make the linker with the DLL project be unable to find the functions properly when the test EXE project has no trouble at all? I'm using the pre-compiled 32-bit static multi-threaded debug library which I downloaded from ClanLib.
Thanks,
Robert
After a lot of experimentation I found the solution. It turns out the problem was due to a difference in the calling convention used by the DLL and the LIB projects (In MSVC 2008 this is set on the Project Properties, "Configuration Properties -> C/C++ -> Advanced" setting. The DLL project was set to __stdcall and the LIB was __cdecl. Recompiling LIBJPEG with __stdcall fixed the problem.