My project uses a Settings.h to store common configuration settings like the server url etc. I have been tasked to create a new app from this code where only few parameters such as the server url , icon etc are different.
I have a new target in my xcode workspace for this. I have 2 Settings.h in separate folders like
awesomeProject/Settings/Settings.h
oldProject/Settings/Settings.h
The Settings.h is included in a few places in the project (not loaded via .pch). I have tried setting header search path for both the targets and this didn't work (as in the compiling awesomeProject target included the oldProject's Settings.h).
Is there a way to #include Settings.h based on the target without resorting to sprinkling #ifdef .. #endif constructs ?
If I understand right and you have separate targets to that need to include different header files so you should be able to set the 'Header Search Paths' differently and get the correct file. You said you tried this but you might want to try doing a clean and full rebuild.
I would try to leverage preprocessor to accomplish your goal. One option is to define in build settings for each target macro SETTINGS_H, which will be "awesomeProject/Settings/Settings.h" or "oldProject/Settings/Settings.h" depending on the target. Then in source code you can #include SETTINGS_H. Of course, you might need to tweak header search path to be able to find each header.
Honestly speaking, #include SETTINGS_H is a tad ugly for my taste, so I prefer another approach. You can keep single "Settings.h" file, but use macros for constant values. For example, in "Settings.m"
NSString *const kServerURL = SERVER_URL;
and in target build settings add to GCC_PREPROCESSOR_DEFINITIONS
SERVER_URL='#"http://stackoverflow.com"'
You might need to play with quotation marks to achieve the desired effect. To organize project better, you can move macros' definitions to .xcconfig file and keep separate .xcconfig files for each target.
Related
I am working with multiple targets in Xcode 8.2, Everything is good except handling files.
To import files, I have used different pch for each target but facing issues in using different class files.
How to work with other target files in the source, it throws an error on build app. When I try to add Preprocessor Macros in Build Settings but I can't find the Preprocessor Macros section in Xcode 8. Is there any alternative to this? please suggest some other approaches to handle different target files in the same source.
Thanks in Advance.
Select the target and go to build setting.
There search for "Preprocessor Macros" you will be able to find out.
Set the macros for particular target.
Use #ifdef in the code to check whether macros is defined or not, based on macros definition write the code for specific target.
That particular code will be reflected to that target only.
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.
Why isn't ProjectName-Prefix.pch created automatically in Xcode 6 ?
Is the precompile header no longer needed ?
Where should I write the code that was in ProjectName-Prefix.pch before ?
Without the question if it is proper or not, you can add PCH file manually:
Add new PCH file to the project: New file > Other > PCH file.
At the Target's Build Settings option, set the value of Prefix Header to your PCH file name, with the project name as prefix (i.e. for project named TestProject and PCH file named MyPrefixHeaderFile, add the value TestProject/MyPrefixHeaderFile.pch to the plist).
TIP: You can use things like $(SRCROOT) or $(PROJECT_DIR) to get to the path of where you put the .pch in the project.
At the Target's Build Settings option, set the value of Precompile Prefix Header to YES.
I suspect because of modules, which remove the need for the #import <Cocoa/Cocoa.h>.
As to where to put code that you would put in a prefix header, there is no code you should put in a prefix header. Put your imports into the files that need them. Put your definitions into their own files. Put your macros...nowhere. Stop writing macros unless there is no other way (such as when you need __FILE__). If you do need macros, put them in a header and include it.
The prefix header was necessary for things that are huge and used by nearly everything in the whole system (like Foundation.h). If you have something that huge and ubiquitous, you should rethink your architecture. Prefix headers make code reuse hard, and introduce subtle build problems if any of the files listed can change. Avoid them until you have a serious build time problem that you can demonstrate is dramatically improved with a prefix header.
In that case you can create one and pass it into clang, but it's incredibly rare that it's a good idea.
EDIT: To your specific question about a HUD you use in all your view controllers, yes, you should absolutely import it into every view controller that actually uses it. This makes the dependencies clear. When you reuse your view controller in a new project (which is common if you build your controllers well), you will immediately know what it requires. This is especially important for categories, which can make code very hard to reuse if they're implicit.
The PCH file isn't there to get rid of listing dependencies. You should still import UIKit.h or Foundation.h as needed, as the Xcode templates do. The reason for the PCH is to improve build times when dealing with really massive headers (like in UIKit).
You need to create own PCH file
Add New file -> Other-> PCH file
Then add the path of this PCH file to your build setting->prefix header->path
($(SRCROOT)/filename.pch)
I'll show you with a pic!
Add a new File
Go to Project/Build Setting/APPl LLVM 6.0-Language
To add .pch file-
1) Add new .pch file to your project->New file->other->PCH file
2) Goto your project's build setting.
3) Search "prefix header". You can find that under Apple LLVM.
4) Paste this in the field $(SRCROOT)/yourPrefixHeaderFileName.pch
5) Clean and build the project.
That's it!!!
If you decide to add a .pch file manually and you want to use Objective-C just like before xCode 6 you will also have to import UIKit and Foundation frameworks in the .pch file. Otherwise you will have to import these frameworks manually in each header file. You can add the following code anyway as it tests for the language used:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
Use :
$(PROJECT_DIR)/Project name/PrefixHeader.pch
For add new PCH file follow bellow steps :
(1) Add New fiew - Select iOS - Other and PCH File
(2) add path of this PCH file to your Project - BuildSetting - Apple LLVM 6.0 Language
Add Set Prefix Header Path YourApplicationName(root-path)/filename.pch
I often see open source code importing third-party libraries in Xcode / Objective-C implementation files like this:
#import <ThirdPartyLibrary/utilities.h>
but when I drag & drop the file structure and files of such a library in my project, all these imports are corrupted and Xcode does not know where the files are.
I end up hand-modifying every import to look like:
#import "utilities.h"
And include appears it is relative to the current physical folder on the file system. When a library split its files in folders on file system and I drag-drop it in Xcode, Xcode creates groups for the folders. But for import, I have to specify the folder name. Problem is when I am in a folder, for example:
http/httpTools.h
Then when httpTools.h wants to import utilities.h from the root, I have to change
#import <ThirdPartyLibrary/utilities.h>
to
#import "../utilities.h"
which is a chore. After doing this for 5 hours I thought damn, there must be a better way. Can someone explain what is the secret to teaching Xcode a new framework location that can be imported with angle brackets? The framework btw is source code. Not compiled. Just the naked code.
Specify the include path using the compiler flag -I, or the Xcode build settings alias HEADER_SEARCH_PATHS. Of course, you can use build variables when doing so.
Just stumbled upon the same issue, there are two types of search paths in Xcode:
Header Search Paths
User Header Search Paths
If you add your own include folders into Header Search Paths, you can use angled brackets.
Ok, here's what I've tried.
I have the header files in two separate directories IRL. They're named the same, but are in two different locations.
I want to only include the relevant header file for each target. Lets say for ease of explaination that the header file is called "Config.h".
So I have:
${PRODUCT_DIR}/Header1/Config.h
and
${PRODUCT_DIR}/Header2/Config.h
These files appear in the LHS of Xcode as well in two different groups (Header1 and Header2 which point to the IRL folders).
So now all I need to do is to make Xcode choose the right one from the right folder for each target.
Target1
and
Target2
I have tried adding the path to the User Header Search Paths for each target, but its still choosing the wrong one. I've also tried toggling "Always search user paths" which also doesn't seem to have an effect.
So my question is, is this because they're in the Project directory? Or is it because they're in Xcode in the file manager on the LHS, so therefore Xcode is copying them into the build folder?
The strange thing is it seems to be choosing the header files from the folder with the last name alphabetically...
In previous versions of Xcode I'm sure you could choose which headers to copy into the build folder.
Anyway.. does anyone know how I can fix this so that I can have it select the proper header file for the target?
Many thanks.
The problem I was having was 2 fold:
You need to remove the header files from the project. If they're in Xcode, in the file manager, then they will automatically be included in the project.
You need to use relative paths to your folders in "User Header Search Paths". I was using ${PROJECT_DIR}/path/to/header/folder which gave the right path, but didn't seem to work properly. Changing the entry to ./path/to/header/folder instead worked fine.
I have 4 targets in 1 proyect and more than 40 headers, the best solution in XCode 8
I think the best solution is change the following tag:
Always Search user Paths
To yes an all was fine for me: