Order of linked libraries in XCode - xcode

In an XCode project I have linkend a library (libpng) and a framework (opencv). The framework already contains an older version of my library.
Now when I go to XCode in "Link Binary With Libraies", if I put opencv first and libpng second, my code will use the what is in opencv, i.e. the older version.
My question: Is it possible to know at compile time which version of libpng my project will use? I want to know for sure that even if somebody messes with the order my libraries are linked, I still use the proper one.
What I tried already is to check with compile directives the version of libpng, something like this:
#if PNG_LIBPNG_VER_MINOR !=6
#error "Wrong libpng version. Required is 1.6.9."
#endif
But this is not a solution since the header where PNG_LIBPNG_VER_MINOR is declared is always the correct one. It's just in the code that the wrong methods might be called.
Thanks!

Is it possible to know at compile time which version of libpng my project will use?
Not in this case. A translation's parameters are different from the linker's. There is no guarantee.

Related

Figuring out the target MacOS SDK version in CMake?

I have code that I want to conditionally compile depending on the target SDK version, so that I can use newer features if possible. This can be done by checking the __MAC_OS_X_VERSION_MIN_REQUIRED macro, which tells us the target SDK version, in the source code.
Typically, performing conditional compilation on that macro suffices, and everything is nice and good. However, when targeting a newer SDK version, I would like to use features from a new library (specifically the UniformTypeIdentifiers library) that is not available on an older SDK version. This means that the target_link_libraries() in CMake has to account for this, i.e. link the new library if targeting a newer SDK version, and skip the new library otherwise.
I can't seem to find any way to figure out the target SDK version in CMake. What is the proper way to do this?
Things I have tried:
Checking CMAKE_OSX_DEPLOYMENT_TARGET. This flag is what CMake uses to pass the -mmacosx-version-min flag to clang, that makes it use a particular deployment target. However, it turns out that this may not necessarily be defined. When not defined, clang doesn't get the flag, but since clang is given something like -isysroot /Applications/Xcode-13.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk, the framework sets __MAC_OS_X_VERSION_MIN_REQUIRED to something default (12.3), and so the source code is able to still perform conditional compilation.
Checking if the library exists by using find_library() (e.g. find_library(UNIFORMTYPEIDENTIFIERS_LIBRARY UniformTypeIdentifiers)). This does not work when users want to target a lower version (e.g. by setting CMAKE_OSX_DEPLOYMENT_TARGET), since the new library will still exist.
Essentially, I would like a way for CMake to figure out the deployment target that ultimately gets chosen (i.e. something equivalent to __MAC_OS_X_VERSION_MIN_REQUIRED), so that it can decide whether or not to link with the new library.
How should I do this?
Context:
I'm trying to resolve an issue in my library here.
I also have a testing branch set up to check CMAKE_OSX_DEPLOYMENT_TARGET and the compiler command in the CI builds: GitHub CI builds MacOS 10.15 (without the new library, with CMAKE_OSX_DEPLOYMENT_TARGET) and 11 (with the new library, with CMAKE_OSX_DEPLOYMENT_TARGET), and Circle CI builds MacOS 12 (with the new library, but without CMAKE_OSX_DEPLOYMENT_TARGET).
I couldn't find a way to determine this via some CMake variable, so I rolled by own compilation test for it:
include(CheckCXXSourceCompiles)
check_cxx_source_compiles(
"
#include <Availability.h>
#if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || !defined(__MAC_11_0) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_11_0
static_assert(false);
#endif
int main() { return 0; }
"
NFD_USE_ALLOWEDCONTENTTYPES
)
This ensures full consistency with the check in the source code, at the cost of a slightly longer time to configure the build.

unresolved reference to boost::program_options::options_description::options_description

First off I know there are several posts similar to this,but I am going to ask anyway. Is there a known problem with boost program_options::options_description in Debian "Buster" and Boost 1.67 packages?
I have code that was developed back in Debian 7, system upgraded to 8.3 then 8.11 now using Boost 1.55.
Code builds and runs. Now upgrade system to Debian Buster with Boost 1.67 and get the link errors for unresolved reference to options_description(const std::string& , unsigned int, unsigned int) along with several other program_options functions. All unresolved, expect the options_description, are from boost calling another boost function, so not even directly called from within my code. boost_program_options IS in the link line.
I AM not a novice and understand link order and this has nothing to do with link order.
I am going to try getting the source code for boost and building to see if that works, if not I will be building a system from scratch and testing against that.
Since this is all on a closed network simply saying try a newer version of boost or Debian is not an option because I am contractually obligated to only use Debian "Buster" and Boost 1.67 as the newest revisions, so if the package is unavailable (newer) in Buster it is out of the question, without having a new contract be drafted and go through approvals which could take months.
So to the point of this question, is there an issue with the out of the box version of Boost in Buster?
I don't think there's gonna be an issue with the package in Buster.
My best bet is that either
you're relinking old objects with the new libraries - and they don't match (did you do a full make clean e.g. to eliminate this possibility?).
Often build systems do not do complete header dependencies, so the
build system might not notice that the boost headers changed,
requiring the objects to be be rebuilt.
if that doesn't explain it, there could be another version of boost on the include path, leading to the same problem as under #1 even when rebuilding.
You could establish this by inspecting the command lines (make -Bsn or compile_commands.json e.g. depending on your tools). Another trick is to include boost/version.hpp and see what BOOST_VERSION evaluates to
Lastly, there could be a problem where the library was built with different compiler version or compiler flags, leading to incompatible synbols (this is a QoI issue that you might want to report with the Boost Developers).
This is assuming ABI/ODR issues, in case you want to validate this possibility.

How does one find what C++11 features have been implemented given a GLIBCXX version

Given a GLIBCXX version of the stdc++ library (example GLIBCXX_3.4.17) given this version, where would one find documentation which specifies what features have been implemented?
Further is there a way to which given the SO NAME version will provide the this same document.
I am working on an embedded system which has an existing version of libstdc++; unfortunately the supplied cross compiler (g++) is at a greater version than what the stdc++ library on the target supports. Upgrading the stdc++ library on the target is not an option. Before I write a lot of code, to only find that it does not run on the target; I would like to know beforehand what is and is not supported.
I have found the GNU Documentation to be useful; however, I am hoping there is a document in which one can get what has been implemented given the symbol version and/or the SO NAME and I just have somehow missed it.
Thanks for any help in advance
given this version, where would one find documentation which specifies what features have been implemented?
You can map a GLIBCXX_A.B.C symbol version to a GCC release by checking
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
N.B. that won't be precise, because e.g. GCC 5.1 and GCC 5.2 both use GLIBCXX_3.4.21 in the shared library. To tell them apart check the __GLIBCXX__ macro defined by the libstdc++ headers, also documented on that page.
The manuals for libstdc++ releases are at
gcc.gnu.org/onlinedocs/gcc-[X.Y.Z]/libstdc++/manual/
e.g.
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/libstdc++/manual/
Within that manual is a status table showing the implementation status for each standard, the table for C++11 support in GCC 5.3.0 is at
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/libstdc++/manual/manual/status.html#status.iso.2011
Before I write a lot of code, to only find that it does not run on the target; I would like to know beforehand what is and is not supported.
It's not enough to simply avoid using features that aren't supported by the library on the target system. If you link with the cross-compiler then it will depend on the libstdc++.so from that cross-compiler, and will fail to run on the target system if it only has an older libstdc++.so
Upgrading the stdc++ library on the target is not an option.
Then you either need to link statically (creating large executables) or downgrade your cross-compiler to match the target. Or at least force it to use the headers and dynamic library from the same version as found on the target (by overriding the header and library search paths to point to copies of the older files), although that might not work, as the newer g++ might not be able to compile the older headers if they contain some invalid C++ that the older g++ didn't diagnose.

StgCreateDocfile, etc. on MacOS 10.9.5

I'm having trouble linking an Xcode project using the AAF SDK, with Xcode 5.1.1 on MacOS 10.9.5. When I link the main dynamic library, these symbols come up missing:
_StgCreateDocfile
_StgCreateDocfileOnILockBytes
_StgOpenStorage
_StgOpenStorageOnILockBytes
AssertProc
I can't find a definition for them anywhere in the entire source tree for the SDK. The first four appear to be part of Structured Storage on Windows. A Structured Storage library is provided in the SDK and I'm already linking that.
Can anyone tell me of a Mac system library that defines these? Or is there a linker argument that pulls in a library for them? Thanks for any help.
A late answer (!), but in case anyone comes across this... The solution is either:
To use the makefiles with the AAF SDK to generate the AAF dylib,
which works fine. or...
If you use Xcode to build the AAF SDK, ensure the correct
#defines are kept, namely:
_DEBUG OM_DEBUG OM_STACK_TRACE_ON_ASSERT OM_USE_SCHEMASOFT_SS OM_STRUCTURED_STORAGE
Note that DEBUG=1 is absent (it is added by default by Xcode) - if defined, this brings in AssertProc. Define NDEBUG on release builds and omit the debug defines.
The Stg... functions are part of the MS implementation of Structured storage as you stated, but should not be referenced on a Mac, the Schemasoft implementation being used.

Mac multiple dylibs

I know this question is not specific to crypto++. But I compiled crypto++ on a Mac OS X using Qt. After building I see 4 files with the dylib extention:
libcryptopp.1.0.0.dylib
libcryptopp.1.0.dylib
libcryptopp.1.dylib
libcryptopp.dylib
What is the difference between them? Which one is actually used to compile against my application?
The multiple files exist in case your application needs to link to a specific version of it. Of course, you have just one version of the library, so it doesn't seem helpful, but consider these on my system:
libnetsnmp.15.1.2.dylib
libnetsnmp.15.dylib
libnetsnmp.25.dylib
libnetsnmp.5.2.1.dylib
libnetsnmp.5.dylib
libnetsnmp.dylib
Only .25, .15.1.2 and .5.2.1 are actual files, the rest are symbolic links for either. In your case, they're probably all symlinks except 1.0.0, so you case use either.
If you look carefully, there's just one actual dylib (libcryptopp.1.0.0.dylib) and 3 links to that one. These give you the version info for the library.
If you want to link to a specific version you can specify that, else if you always expect your app to work with the latest version, you can point to libcryptopp.dylib.

Resources