I have a makefile which uses xcodebuild to build Xcode project. My question is
Is it the settings in a makefile (which uses xcodebuild) or the settings in the Xcode project going to be used when calling the makefile to build a project?
For example, if I have some settings in a makefile such as:
SDKROOT =/Developer/SDKs/MacOSX10.5.sdk ARCHS="i386 x86_64"
CXXFLGS =-I/Users/XXYY/dev/Frameworks/Headers -DUNIX (just an example to show where to check header files, this is different from what is set in the Xcode project)
target:
xcodebuild build -target $@ -configuration Release
... ...
Will the setting here (SDKROOT and CXXFLGS) be used?
If the answer is yes, then I can set up my Xcode project (called project A) to link to some of my own frameworks put in $(HOME)/Library/Frameworks, then ship it to users.
At the same time, when I build this project A, I can set it to link to the frameworks which is build the same time as I build project A in my makefile.
This way, when users open my project A, the frameworks will be linked to their $HOME/Library/Frameworks. (The framework will be asked to copy there )
or Maybe I can ask how I can set the search path for my own frameworks when I try to give out a project (which uses my own frameworks)? The process in the makefile will be: first build my frameworks, then my project (obviously, my project will link to the new build of the framework).
If I set the path for the framework to link to myframeworkfolder/build/Release/*.frameworks, this path needs to be reset when the project is copied to other users. If I set the path for the framework to link to , for example, /Library/Frameworks, then other users don't need to change the path. Anyone has suggestions what I should do this right? Or should I set the path for my framework to /Library/Frameworks, then when I finish building the framework, copy it to /Library/Frameworks, then build my project. Is it the right way to do it?
Thanks.
Wow -- lots of questions packed into this one question! Lets try and tackle them one-by-one:
Will the setting here (SDKROOT and CXXFLGS) be used?
No, you've successfully made makefile variables, but they will not get picked up by the xcodebuild command in your build target -- you would need to set those values as additional build parameters on the xcodebuild command. From the manual page for xcodebuild, we see that this assignment format for build config overrides has been distilled down to [setting=value ...] from the full command format:
xcodebuild [-project projectname] -scheme schemename [-configuration configurationname] [-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=value ...] [-userdefault=value ...]
This implies that you have to set build settings in a key-value styled format in the xcodebuild command. It is important to note that build settings have a hierarchy -- some are defined by the SDK that can then be overridded at the project level, which can be further overridden at the target level, which can then be overridden by the xcodebuild settings section, and can be overridden one last time by use of a xcodebuild specific -xcconfig file.
That's just...great...With so many places to inject build setting indirection, how are we supposed to make this work?
This is where you as the project designer have to start making decisions about how your code, build products, and frameworks will be used, reused, and even abused by others. The more shared or common a build setting, the higher up in the configuration it should go, such that it will be applicable to the widest set of targets. SDKROOT for example is one such build setting that would likely be set at the project-level build settings as it is very likely that consumers of this project will want to use the same SDK as you to build out or consume these frameworks. You, of course, have to make the decision about if a setting should be so-called 'global' to all targets and promote/demote your build configurations carefully. As there isn't much detail about your apps/frameworks/use cases in your source question, there is little specific guidance the SO community will be able to provide. Instead I'll point you in the direction of best practices and leave it to you to apply those best practices to your situation.
Now, back to the makefile...If you were going to run this build directly from the terminal, with those custom command-line settings applied, your xcodebuild command would look something like this:
xcodebuild -project Testing.xcodeproj -target Testing SDKROOT='/Developer/SDKs/MacOSX10.5.sdk' ARCHS='i386 x86_64' CXXFLGS='-I/Users/XXYY/dev/Frameworks/Headers -DUNIX'
When run, the first few lines of output from the xcodebuild command would look like this:
Build settings from command line:
ARCHS = i386 x86_64
CXXFLGS = -I/Users/XXYY/dev/Frameworks/Headers -DUNIX
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk
This command can then be ported into your make file with relatively few alterations:
xcodebuild -project Testing.xcodeproj -target Testing SDKROOT=${SDKROOT} ARCHS=${ARCHS} CXXFLGS=${CXXFLGS}
The ${FOO} notation is makefile variable replacement syntax -- go ahead and paste that new xcodebuild line into your makefile, then fiddle with the values of your variables, and finally invoke make. You'll see those same first few lines of xcodebuild output as before and they'll reflect the changes you've made to the makefile variables.
Congrats! You've now passed your makefile variables into Xcodebuild!
A potential pitfall: Your SDKROOT variable seems to be using the old-school /Developer folder for its SDK reference. It is unclear if you intend to build from this directory against the older 10.5 SDK or not, but I'd hazard a guess that this is simply leftover from the pre-Mac App Store versions of Xcode. Unless your project has a specific dependency on 10.5, consider upgrading your SDKROOT path to more modern SDKs in their newer location:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
You then turn to a series of questions about Frameworks and the desire to make them accessible to others.
What I suspect you are really doing is making a series of Application-level frameworks that you want to make available to others in their own projects.
Considering Machine Security
If this is the case, then installing those compiled frameworks to the System or User Frameworks Library is probably not what you want to be doing. First, the /Library/Frameworks folder requires the app have root access to the machine which of course would pose a non-trivial security risk to machines. The user's Frameworks folder (~/Library/Frameworks) is only slightly more secure, but it is also such an uncommon use case that such a folder doesn't exist by default! In reality, there are relatively few situations in which it would make sense to promote a framework to the entire system or entire user.
Instead, since you are really just looking for a guaranteed known location, you probably want to have your build products copy to a folder inside the project directory itself. Then regardless of where your users copy the project folder, relative references to subfolders of the main project folders will always be correct!
Naturally, there are a couple of options:
Depending on your project's needs one of those options may prove to be easier to maintain in the long run -- which one will depend entirely on your project and how you anticipate your users will consume your frameworks. One thing is absolutely certain, unless you absolutely need root access for your frameworks, it is best to avoid those Library/Frameworks directories all together.
Hopefully this gets you pointed in the right direction, and if you have any followup questions toss at comment at the end of this answer and I'll see if I can clarify, elaborate, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With