I looked into using tgmath.h to deal with the CGFloat typedef float/double mess when dealing with arm64.
This answer has a pretty good description of how to use it, except that it didn't work at all for me. No matter what, my code was still calling the math.h functions.
After spending some time looking at all of the project compiler settings, I found that disabling the "Modules" feature (#import vs #import - iOS 7) makes it all work. More specifically, the option in the project settings is called Enable Modules(C and Objective-C) in the Apple LLVM 5.1 - Language - Modules dropdown.
To see a quick example of this issue, download a project that uses tgmath, such as MBProgressHUD, and see what happens when you enable the modules project setting. The tgmath.h calls get replaced with regular math.h calls.
My question is:
Why do modules prevent tgmath from being imported properly?
Is there a way to get around it and use both tgmath and modules? I would like to still be able to use them.
I'm not sure what's causing the issue, but as a workaround you could at least disable modules for only the file(s) where you're using tgmath.h:
Navigate to the target's Build Phases tab in Xcode.
Under the Compile Sources phase, locate the source files.
Double-click the source file and type -fno-modules in the Compiler Flags popover to disable Clang modules for that file.
At least this way you would still get the benefits of modules in most of your project. (This is assuming, of course, you don't need tgmath.h in the majority of your source files.)
It might already be in your math library under the name ctgmath: Link
Related
I have code for a VST plugin and need to port some of it to an iOS app.
I have tried building the OSX version and using the lib.a and it doesnt work. When I open the iOS version of it, Xcode shows that it is missing the tagret.
If I copy the code directly into Xcode with all the JUCE modules, and I set the header search paths, I get compilation errors on things like no such type for String
After this latest JUCE update, Xcode would give the same errors until I updated the JUCE file itself, so I think the JUCE build settings or configuration of the new version is doing something differently. How can I get this code into a different Xcode project, so that I can use it?
Can I compile it as a library and use the objects through the header?
JUCE is designed to be included in projects generated by the Introjucer / Projucer (the JUCE project management tool). Without this, the correct preprocessor definitions will not be set up.
If you really needed to include JUCE source code inside your program, you could manually set up these preprocessor definitions (take a look at the AppConfig.h header from a generated project to get an idea of how much work this will be), but you'd really be going against the normal "JUCE way".
Simply including the headers and linking against the library will not work without considerable effort, as the include structure is ... odd ... and there isn't any library to link against directly anyway (the generated projects contain all the JUCE source normally, so there's no need).
Adding the JUCE source files (i.e. .cpp and .mm) to be compiled in a project directly will result in compilation errors, as they need to be compiled in a very specific order which is mandated by the header file (the header files #include certain implementation files after setting up their dependencies).
In short, if you can at all I would advise generating the project with the Projucer and adding other source files in as you need them, rather than the other way around.
First of all, my project builds fine initially.
Then I integrate VideoStream SDK for iOS into a standalone app, and it works.
Then I integrate VideoStream SDK into my actual project, and set up search paths for header files for the library, but then my project gets these issues:
I'd have a look if one of your source header files has the same name as a standard C++ or C header file. Quite possibly this prevents inclusion of the standard header file that defines struct tm. Look if there is a file "time.h" or "locale.h" or something like that has become part of your project.
I have not seen this solution posted ANYWHERE after so much time googling since the time I posted, but I disabled Always Search User Paths under Search Paths of Build Settings, and the project built.
Base on this question
Why don't iOS framework dependencies need to be explicitly linked to a static library
I read the selected answer and still don't understand so I made an example project
Test Project on Github
In the test project, I remove all framework from Link Binary With Libraries and File navigation for both main project and the static library (including Foundation.framework and UIKit.framework too), basically, both project link to 0 frameworks.
Questions are
In static library, it's including MapKit/MapKit.h without referencing the Mapkit.framework to the project, why is its still working?
In main project, I remove UIKit.framework and Foundation.framework from the project, why is it still working?
Since it's working for now, will there be any issue later?
Thank you for your comment.
P.S. By working, I mean I can run on the simulator and I can archive the main project without any error.
Edit 25/07/2014
I tried with the real app that I'm working on, it's the same.
I highlight Foundation, UIKit, CoreData and 10 another frameworks in File Navigation, well, all of them.
Uncheck the target in Utilities Panel --> Target Membership
Build : Pass, Run : Pass
Every functionality of my app is still working as expected. I don't get this.
Check your project build settings. Underneath LLVM 5.1 — Language — Modules you should see the option 'Link Frameworks Automatically'. In your case it sounds like it's set to 'YES', the default.
In that case, instead of producing an error when you reference a class that the compiler doesn't know, it'll figure out which Framework contains that class and link it. In your code it'll be MKMapView or one of the other MapKit classes that triggers the linkage.
EDIT: from the relevant 'What's New?' document:
Auto Linking is enabled for frameworks imported by code modules. When
a source file includes a header from a framework that supports
modules, the compiler generates extra information in the object file
to automatically link in that framework. The result is that, in most
cases, you will not need to specify a separate list of the frameworks
to link with your target when you use a framework API that supports
modules.
Another way of looking at it is that the compiler is smart enough to mutate #import to #import when the framework has been built appropriately. All system frameworks have been.
To elaborate #Tommy's answer, a framework that supports modules satisfies the following 2 conditions:
Under Build Settings > Packaging
Define Modules is set to YES
Module Map File exists.
So, if you're certain that the framework you're using in your code modularizes like that, you can choose to not explicitly add it in the link phase as it will be automatically added as long as in the project file, under Apple Clang - Language - Modules, The option Link Frameworks Automatically is set to YES.
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!)
I'm working on an open-source project that can optionally use a closed-source framework. If the closed-source framework is included in the project, there will be additional functionality. But if the framework isn't included in the project, the project should still compile properly.
How do I check at compile-time if the framework is included in the project?
Basically, I want to do something like this:
#ifdef _MY_FRAMEWORK_EXISTS
#import <MyFramework/MyFramework.h>
#endif
I've seen older questions from 2 years ago like this one, but no answer has surfaced so I might be missing something new now.
I DON'T want to check at run-time via NSClassFromString(), because this will fail at compile time when I try to import MyFramework and it doesn't exist.
You can check for the presence of a header file using the __has_include language extension.
http://clang.llvm.org/docs/LanguageExtensions.html#include-file-checking-macros
However, that only tells you if the header file is installed. It can't tell you if "Link Binary With Libraries" has linked to its framework.
I recommend reading the Mac Developer Library : Framework Programming Guide (which includes a section on Weak Linking).
What do you mean by "exists" or "included in the project"? Do you mean added to the "Link Binary With Libraries" build phase (as described by Including Frameworks)? All that does is affect the linking, not the compilation, build phase. To see this, build. Then, search for -framework in the build log of Xcode's Log Navigator.
So, yes, if you want to affect the compilation of the code you provided, you could manually define the macro _MY_FRAMEWORK_EXISTS.
I don't really understand what you are trying to do. Can you explain what you want at a higher level? Perhaps, there's a better way to go about it.
"Minimal overhead" is nice, but too much magic might be confusing. For example, Xcode's magic hides what really happens when including a framework.
I also recommend checking out how the Facebook SDK for iOS works for high & low-level ideas. It might do the kinds of things you want to do.