CMake override libraries from find_package - opencv

I'm running find_package(OpenCV, REQUIRED) to locate a library. It's installed on the build system and the target system, however the target is slightly different in that one part of the library is not available.
So when building, I get back linker flags like -lfoo -lbar. However, bar isn't available on the target machine and I'm not using it anywhere in the application. Of cource, since it was linked in, the runtime linker complains that it cannot be found.
Is there anyway to override the libraries linked in with find_package? I'll probably just do a string replace type of solution, though I'd be thankful for any help there too since I'm a CMake novice.
Thanks

I suppose you can remove undesired libraries from OpenCV_LIBRARIES variable:
list(REMOVE_ITEM OpenCV_LIBRARIES bar)
Alternatively, you can read FindOpenCV.cmake source to check if it supports COMPONENTS keyword.

Related

Compiling objective-c++ on Windows with clang-cl

I have a Qt project that was developed on MacOS. I've been given the job to make it compile on Windows.
My current problem is that compiler (Microsofts LLVM clang-cl) seems to be ignoring objective-c++ files, and the QtCreator is freaking out on #import statement (#import of type library is an unspported Microsoft feature). It also freaks out about a lot of stuff after that, but I'm guessing it's due to the import not being handled properly.
I was led to believe that win32-clang-mvsc was the only QtCreator compiler that supports compilation of objective-c++ files on windows, however, it doesn't seem to support the #import statement.
I've looked around and it seems that I would need GNUstep to be able to compile that on windows, and I'm not entirely sure it would work.
Is it possible to use the whichever compiler GNUstep provides with QtCreator? Or is there some way to use the compiler I'm already using to compile the files with #import statement?
The error I'm getting on the build is that ***.obj file doesn't exists, where *** is the name of the file with the #import statement. I'm guessing the compiler skips it and doesn't generate the .obj file, so something can't find it. I'd guess it was the linker, but I'd expect linker errors then, not a generic file not found error.
You can use the GNUstep Windows MSVC Toolchain to build Objective-C code using Clang on Windows. We’re also using this in a Qt project. You’ll just need to tell your build system to use the necessary flags for Objective-C files (e.g. using QMAKE_EXTRA_COMPILERS if you’re using QMake). This Qt example project for using Objective-C in a Qt project for Android should get you started.
The error you’re seeing about #import is likely because your project is using some clang-cl flags like /TC//TP that force the compiler to treat the file as C/C++ irrespective of its extension. Removing these flags should make this error disappear.
Please open issues in the GitHub project linked above if you need further help with the setup.

Xcode linker problems multiple files Objective-C

I usually work a lot with Objective-C and sometimes I do have multiple files that represent multiple classes.
Sometimes program run and sometimes I get this error:
linker command failed with exit code 1 (use -v to see invocation)
What is the reason for this error? There were different solutions reported in the forum but I want to understand what is the reason to avoid.
The general idea of compiling a program consists of separately compiling each file, and then linking the compiled binaries together. When it says linker command failed it means linking the binaries failed. What the linker error is depends on what the error says. Usually inside the junk there are a couple useful lines that can help you figure out what the issue is. A couple that comes to mind is when a function is defined twice, when a function is called but isn't declared anywhere, or when you import a library that contains a main function (which means main is defined twice) etc.
There are a lot of possible reasons behind this. I list some of those that I experienced.
You accidentally imported a .m file inside a .m file.
The libraries you linked have the same class name and it will cause a conflict.
The libraries you linked are built with different settings(e.g. the target iOS version, code signing, etc.)
The libraries you linked are built for simulator then you used it on a real device.
You forgot to put a semicolon in the end of a declaration in Localizable.strings

Export an `OBJC_CLASS` from one static lib as part of another

I want to create a static library (actually, a framework, but I know how to do that part) that bundles up code from, among other things, another static library. However, the OBJC_CLASS exports from the original library end up as undefined symbols.
For example, in Xcode 5.1.1 (using default settings/choices at every step, unless otherwise specified):
Create a new "iOS Framework & Library Cocoa Touch Static Library" project named LibA.
Build (for either simulator or a real device, doesn't matter).
Create another new "iOS Framework & Library Cocoa Touch Static Library" project named LibB.
Drag libLibA.a from the LibA products to the Frameworks folder in the LibB project tree.
Drag LibA from the include directory next to the static lib to the top level of the LibB project tree.
Edit LibB.h as shown below.
Build (same target as before).
Create a new "iOS Application" (any type) project named AppC.
Drag libLibB.a from the LibB products to the Frameworks folder in the AppC project tree.
Drag LibB from the include directory to the top level.
Drag LibA from the first project's include directory to the top level.
Verify that LibA appears in the Link Binary With Libraries phase.
In any method of any class the wizard generated (e.g., -[MasterViewController awakeFromNib]), add (void)[[LibB alloc] init].
At the top of the .m file you just edited, add #import "LibB.h".
Build.
Here's the LibB.h promised above:
#import <Foundation/Foundation.h>
#import "LibA.h"
#interface LibB: LibA
#end
I get the following error:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_LibA", referenced from:
_OBJC_CLASS_$_LibB in libLibB.a(LibB.o)
"_OBJC_METACLASS_$_LibA", referenced from:
_OBJC_METACLASS_$_LibB in libLibB.a(LibB.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Looking at the files, the problem is obvious:
$ nm -g libLibB.a
U _OBJC_CLASS_$_LibA
0000031c S _OBJC_CLASS_$_LibB
U _OBJC_METACLASS_$_LibA
00000308 S _OBJC_METACLASS_$_LibB
U _OBJC_METACLASS_$_NSObject
U __objc_empty_cache
The symbols for _OBJC_CLASS_$_LibA and _OBJC_METACLASS_$_LibA are exported as undefined.
I can reference methods, C functions and structs, globals, etc. from LibA. Even categories on Foundation objects (as long as I do the category-dummy trick). It's only the class and metaclass objects that I can't figure out how to export.
Here's what I've tried to fix it:
Turn off Dead Code Stripping (in all three projects).
Add -ObjC as an extra linker flag (in all projects). (This makes no sense for static libs, and all it does is give you a warning error telling you exactly that, but everyone suggests it to me.)
Create an "Exported Symbols File" (for LibB). (This also only makes sense for dynamic libs.)
Pass ${PROJECT_DIR}/libLibA.a as an "Other Linker Flags" (for LibB) instead of adding libLibA as a framework (in case -lLibA is processed differently from libLibA.a).
What I've tried that I still think may be on the right path, but I'm not sure:
Try to figure out appropriate libtool options that have no corresponding settings in Xcode. (I can wrap it in a Makefile, or and Xcode custom build step, if necessary.)
Enable "Perform Single-Object Prelink", then add ${PROJECT_DIR}/libLibA.a to "Prelink libraries". I get warnings about duplicate symbols and then success but with an empty libLibB.a, so obviously there's something else I need to do. I've done this with .dylibs and dynamic Frameworks on OS X, and there wasn't anything else I needed to do there… but never with static libs.
Workarounds that I know about (and I'll use one of these if there's no real solution):
Require that anyone who wants to use LibB also has to add LibA to their project. And, in particular, the pre-built copy of LibA that we provide.
Distribute LibB as source to be included in your project, instead of a static lib and headers.
Manually ar libLibA.a and LibB.o, then ranlib like it's 1999 (although the docs say this doesn't work, it seems to).
(None of these are too terrible for my simple test project, but in real life, this is not an open source project, that LibA is actually 80 different libs from 3 different projects, and some of the LibA code builds fat armv7/armv7s (which means ar doesn't work on it…), and we're planning to do the usual hack of lipo'ing together the simulator and native builds and making a framework out of them, all of which makes things more of a problem.
I think I may have solved it with single-object prelink (basically this means it does an ld -r to build a giant object file, then passes that to libtool), although I'm still not sure, and I don't love the solution. So, I will post what I've got as an answer, but hope someone else comes along with a better answer.
To get single-object prelink to work, you need to (in LibB):
Add libLibA.a as a Framework.
Make sure it does not appear in the Link Binary With Libraries build phase.
Set "Dead Code Stripping" to No.
Set "Don't Dead-Strip Inits and Terms" to Yes.
Set `Perform Single-Object Prelink" to Yes.
Set "Prelink libraries" to ${PROJECT_DIR}/libLibA.a
Set "Preserve Private External Symbols" to Yes.
(The second step is what I was doing wrong earlier…)
Unfortunately, this seems to break the dependency rules completely, so that every build recompiles every .m (and .pch) that's part of the target, even if nothing has changed.
Other than that annoyance, this seems to work for both AppC and my real project just fine.
AppC does not need "Preserve Private External Symbols"; my real project does. I believe this is because one of the third-party libraries does an ld -r with an empty -exported_symbols_list explicitly to "transform all symbols to private_extern. Otherwise, class objects don't end up that way. However, I'm not 100% sure I understand this one.
Adding this to Other Linker Flags appears to work
-force_load $(CONFIGURATION_BUILD_DIR)/libLibA.a

Includes fail to resolve correctly in Xcode workspace

I'm having trouble linking to a static library in Xcode 5. I did read the chapter on building and using a static library in the Pro iOS 5 Tools. What it told me to do after creating your static library, was to link against the framework in the Build Phases tab. That part is pretty straight forward. Then it says in the Build Settings, under "Header Search Paths", to add:
$(BUILT_PRODUCTS_DIR)
Then in order to use my static library, I just import it like so:
#import "ConversionCalculator/ConversionCalculator.h"
So this used to work up until yesterday. I tried adding a new static library to my project which didn't seem to work. So I cleaned my project, and tried rebuilding again, but now Xcode complains about #import "ConversionCalculator/ConversionCalculator.h". It says
Lexical or Preprocessor issue. 'ConversionCalculator/ConversionCalculator.h' file could not be found.
I was wondering if anyone has any tips on debugging this. I've looked through different tutorials like this:
http://blog.stevex.net/2012/04/static-libraries-in-xcode/
http://cocoamanifest.net/articles/2011/06/library-management-with-xcode-workspaces.html
http://www.raywenderlich.com/41377/creating-a-status-library-in-ios-tutorial
But I can't seem to find the "golden way" to link to a static lib, or how to troubleshoot why Xcode cannot find my file. My file structure is setup on my machine like so:
Projects\
DistanceCalculator\DistanceCalculator.xcodeproj
ConversionCalculator\ConversionCalculator.xcodeproj
DistanceCalculator.workspace
Like I said, this all used to work too when I followed the tutorial in Pro iOS 5 Tools book. Now I don't know why my workspace cannot find ConversionCalculator when it has used it before. The part I find hard is different articles say different things about the header search path, and I'm not sure what the best way to populate that field is. Any thoughts? Thanks in advance!
Edit:
I'll add that I can build for the device without errors. But when I switch to the iPhone simulator, it gives me that error about not being able to find the file. I also see that I get this warning:
ConversionCalculator was rejected as an implicit dependency for 'libConversionCalculator.a' because its architectures 'i386' didn't contain all required architectures 'i386 x86_64'
Looking at that, I'm not sure what that means. If it means that my library is not being built for all architectures, I just tried creating a Target that builds for all architectures according to the wenderlich article in the above link. That seems to work as when I go to the dervieddata folder, I see for debug, release, and universal, I see the libConversionCalculator.a file. But then when I go back into the workspace and try to rebuild the project for the simulator, I get that could not find file error and the implicit warning.
Edit #2:
I just saw a warning flag on Xcode that says upgrade to recommended Build Settings. Now I get no errors. Not sure what happened... but I guess no errors is good.
I would follow the description available in Xcode's Help topic "Linking Against Your Library" in chapter Configuration Your Application in Introduction to Using Static Libraries in iOS
(you may search within Xcode Help, too).
Except that I would recommend to include your headers from libraries always using angle brackets:
#import <ConversionCalculator/ConversionCalculator.h>
Using double quotes may inadvertently search and find files with the same name in some sub-folder relative to the file where this import directive is written. Only after there was no file in any sub-folder the preprocessor starts searching with the specified header search paths.
Using angle brackets, the preprocessor immediately searches only at the specified header search paths.
So, since you actually want to find headers for the corresponding library, always use angle brackets.
Note: If you follow the recommendation to create a static library project, you don't need to explicitly set a header search path in the target that links agains the library: Xcode will already add a search path:
$(BUILT_PRODUCTS_DIR)/includes
Your library headers are located in
$(BUILT_PRODUCTS_DIR)/includes/<product-name>
which are placed there through the "Copy-Files" phase of the iOS static library target, whose "Destination" is set to "Products Directory" and whose "Subpath" is set to "includes/${PRODUCT_NAME}" per default.
You may change these default settings to other reasonable and sensible values. (if you do, consider the the consequences for Xcode's default search paths!)

What do these Dsymutil Warnings mean in XCode 4.5?

I am linking a static framework for iOS, against an armv7 ios 6 application, I suspect that the original binaries are from XCode 3.x and were compiled with GCC, and that I'm now linking it using CLang compiler. I do not have the source code for the framework, only the binaries:
(null): warning: (armv7) /.../DerivedData/.../armv7/HardwareObjectFile.o unable to open object file
I get 69 warnings like the above, one for every .o file linked into the static framework.
Is this warning serious for any reason? I have simplified the giant path which appears to indicate that the binary files in the library have hardcoded a path in "/Users/somedeveloperthatisntme" that could hardly help but Not Exist since I'm using this library on a computer that doesn't even have a folder named "Users/somedeveloperthatisntme".
Dsymutil appears to be a tool to "manipulate archived DWARF debug symbol files", although I know precisely nothing about what it is and what it does, notwithstanding the thorough documentation from Apple, which tells me what, but never ever, why. What is it doing, and what will this warning mean for me? I suspect I need a new library/static-framework from the vendor to clear this up?
Update: I am unable to solve this and it appears the cause lays with very old binaries compiled by a very old XCODE version, shipped as part of a mobile framework from a third party vendor. The issue in this case would be resolved by having that vendor rebuild their library, something I asked them to do because the warnings drove me nuts, but which they seem unable to do. In the end I ditched their technology and replaced it with something else. (Grin)
These errors are to do with the architectures you are using and the resources you are referencing. I don't understand the reasons myself, but if you want them to go away, go to Build settings, then Build Options and then select Debug information format and select DWARF.
I am on the other side of this, building a library for others to use, and I was able to alter the library project by setting 'GCC_GENERATE_DEBUGGING_SYMBOLS = NO' in the Build Settings to make those warnings go away in an Application project that consumed the output framework.
This isn't a solution to your problem, but if you're in contact with this vendor, you could pass this along.
The other answers contain helpful information but I wish to put the real answer down succinctly:
You can not fix this, and the meaning of the errors is simple: The current linker sees these library files as containing elements that can not be opened.
To solve the warnings, contact the vendor and get a recompiled library that has been rebuilt with a later version of CLANG.
What I did was just delete the /Library/Developer/Xcode/DerivedData folder and it fixed everything for me.
Another reason these warnings could occur is because of incorrect symbol stripping settings for release builds in a project. Contact the author of the framework and tell them to make a new binary with the proper symbol stripping settings.

Resources