Is it possible? I have my file with custom debug predefines, and I want to include it on my side but skip on repository side (without differences in XCode project file).
You cannot conditionally include a file based in its existence so the best thing to do would be to include an empty file on the repository side and attempt to avoid it being added when you add content to it on 'your' side. Sounds like a disaster waiting to happen. Why are these defines so private?
To your direct question: No. XCode does not have conditional file inclusion.
To your intent: You would be better off making a separate build configuration. Each build configuration (Debug, Release, Distribution, etc.) contains a separate set of compiler settings, and optionally a set of user-specified definitions.
See Fine-Tune Your Builds in the XCode 4 User Guide.
Related
In the project I'm working on, I need to process certain filetypes with a custom command (building assemblies, namely, due to certain plugin / toolchain limitations, which are beside the point). This is configured from our premake script:
filter { "files:*.extension" }
buildcommands("blah.exe %(FullPath) --my --args")
buildoutputs("$(OutDir)%(FileName).obj")
The project will fail to build unless I set the Properties -> Custom Build Tool -> Link Objects property to No for each individual *.extension item. (These should not be linked as part of the custom step anyway.)
How can I configure this particular property from our premake script without resorting to hacks? (e.g. Anything similar to xcodebuildsettings)
Looks like a more recent master of premake supports a linkObjects file configuration function that does just that (not yet in the docs). Up we date...
Until then, one possible hack is to use buildmessage("false") then do a find-replace all in the generated project files for the Message XML tag to LinkObjects.
I'm currently trying to make splint available as an external tool in Visual Studio 2010.
It has problems with finding all includes for the file, since it seems that the INCLUDE variable is only set at build time and I haven't found any other possibility to extract the include files in any way.
My question: Would there be any way to extract the IncludeDir field from the current file's project's Properties page, ideally with the VC++'s AdditionalIncludeDirectories?
Note also that AdditionalIncludeDirectories is per file, as it can be changed for individual source files as well as on the project level, and if it contains macros it can evaluate differently for each source file too!
I'm not familiar with driving the MSBuild objects via the API, but that's used by the IDE. Whether that way or by simply running MSBuild.exe, you need to get it to figure out all the properties, conditions, etc. and then tell you the result. If everything is well behaved, you could create a target that also uses the ClCompile item array and emits the %(AdditionalIncludeDirectories) metadata somehow such as writing it to a file or passing it to your other tool somehow. That's what's used to generate the /I parameters to CL, and you can get the same values.
If things are not well behaved in that necessary values are changed during the detailed build process, you would need to get the same prelims done just like the ClCompile target normally does, too. Or just override ClCompile with your own (last definition of a target is used) so it certainly is in the same context.
Either way, there are places where build script files can be automatically included into all projects, so you can add your stuff there or use a command argument (I think) to MSBuild to add another Include.
—John
Duplicating a target in Xcode is a great way to create multiple app or framework/library products that have somewhat different features using the same codebase as a result of conditional code controlled by environmental variables set within the target build settings or related schemes. First duplicate your known-working basic version, then set the environmental variables each target will use, then start splitting up your code behavior with inline preprocessor #ifdef statements.
However, any duplicated target will be named "Original Target Name copy". This can be renamed, but the info.plist will also have this name, it may also appear in a couple of essential build settings, and it can be a tedious and error-introducing process to remove all references to the non-informative "copy" version of the duplicated target name depending on how you do it. When I create iOS frameworks this seems to be especially prone to introducing issues.
My question is whether there is any technique for duplicating a target which allows you to specify the new target name at the time of duplication, so there is never a temporary wrong target name or any files being created which contain that temporary wrong name. Or, alternately, if there is some way to use the "refactor" functionality to fix this is an automated way.
If there is some kind of wrong assumption contained within the question that explains why this feature hasn't been included in Xcode, let me know. I'm using 4.3.
Unfortunately, I'm pretty darn sure there's not any current UI for this, although I strongly agree that it would be a huge improvement; I can't speak for everyone, but I pretty much never want a target named Foo copy. I would suggest filing a Radar.
You could, with some effort, use CMake for that. It's a build system generator.
It may be difficult at first to learn and setup the project, and some things are (currently) not easily possible for Xcode (like resource adding) but it would make creating new targets with a basic configuration very easy.
Basically, you write CMakeLists.txt files in your source tree to define your libraries and targets, then define the source files, etc., then generate the Xcode project each time.
Adding a new target would be very easy:
ADD_EXECUTABLE( Target_Name Source_Files )
SET_TARGET_PROPERTIES( Target_Name PROPERTIES COMPILE_DEFINITIONS Your_Additional_Defines )
Rerun CMake. (Its not even required to close the Xcode project)
Disadvantages:
Takes time to setup.
Sometimes research is necessary to get some things to work
Some things are currently not well supported via CMake
In Xcode 6 (not sure about earlier versions) duplicating a target will still generate the " copy" appendage and rename all localized menus for example. But, it is reversible by updating the Product Name under Packaging in Build Settings / All. Info.plist will still have to be taken care of as well as Scheme naming though.
Doubleclick on the target to at least rename thetarget ... still looking to rename the product, but that's not so important if you can rename everything else (like the displayname etc))
select project in Navigator panel
select Target you want to duplicate
right mouse click and choose "Duplicate"
Rename Target in XCode: click on selected Target and inline edit starts.
Open Terminal and go to your project directory/folder
Run svn status to see the changes XCode just has made.
XCode has created new Infocopy.plist file and has added under version control if you use one. Typically you want to choose different name so follow these steps:
Cancel version control addition: $> svn revert Infocopy.plist
Rename it: $> mv Infocopy.plist YourNameInfo.plist
Add it to version control: $> svn add YourNameInfo.plist
Set the new name in your new Target Build Settings named "Info.plist File"
Rename target file properly: $> mv OrigTargetCopy.xcscheme YourTargetName.xcscheme
Add the new target file under version control: $> svn add YourTargetName.xcscheme
Rename you Product in your new Target Build Settings named "Product Name"
Very likely you will also want to set new "Preprocessor macros" Build Settings for your new Target.
Set proper values your YourNameInfo.plist
Set Target assignment for target specific files. Typically YourNameInfo.plist shall be part only of you new target. There may be plenty of other similar files (icon, splash screen, other graphics, etc).
Please tell me what is the most efficient way? I need to save at least compiler / linker settings and source files structure.
I need to save at least compiler / linker settings
the easy way to do this is to move the settings from the target/project settings to an xcconfig file. the xcconfig file may then be (re)used to define the build settings for multiple targets and/or projects. to do this:
create a new xcconfig file for each tier, target, and each configuration where you have defined settings (e.g. Project_Debug, Project_Release, Target_Debug, Target_Release), and follow these steps for each tier/combination:
open the build configuration settings pane for the project
specify one configuration.
hide the settings which are not defined at that level. in Xcode 3, that means you only want the bold settings to be visible.
select all visible settings
dragon drop (sic) the selection to the appropriate xcconfig file
assign the xcconfig file to the configuration/tier you took it from
finally, delete all the definitions in the build settings pane which you just copied to the xcconfig
repeat until all settings have been exported to separate/appropriate xcconfigs
to make life easier, you may #include one xcconfig into another xcconfig.
since an app is different from a framework, you'll have a few settings to change, delete, or move back to the framework target.
now nothing should be defined in the target or project levels (apart from your framework specific stuff), and you may easily apply the same set of build settings to any target.
and source files structure...
the easiest way here is to:
create a new target in your project (yup - of the app variety).
for each build phase in the framework:
verify the app has a similar build phase (e.g. compile sources, or copy resources)
select all the items in the framework's build phase
get info
add the references to the corresponding build phase of the app target by checking the box for the app target in the info panel (this approach assumes the references are added to the default phase for the type of reference, you may have a little extra ordering to do at this stage if your reference->target phase relations deviate from the defaults)
repeat
add your main entry
build and sort out the rest manually
you may want to clone the Xcode project first (as easy as duplication with git) -- and definitely make sure you have your project/sources under scm.
if you'd rather not maintain these in parallel, then move it all over to a static library, then just link each target to the static lib.
gooood luck!
(the question was initially asked regarding Xcode 3 - some differences will exist in Xcode 4. the process should be the same in Xcode 2)
That the logical follow-up for the my previous question: "How to check all projects in solution for some criteria?"
I was given quite a good answer to use CustomAfterMicrosoftCommonTargets, CustomBeforeMicrosoftCommonTargets. They do work, so I decided not to stop in the middle.
Issue is that I don't want machine-wide tasks. It's not a good idea neither for me (it will affect other builds. sure, this can be handled, but still), nor for my teammates (I don't want to let them put something in system folders... ), nor for build server.
What is needed: solution to be built from scratch out of source control on clean machine with either Visual Studio or MSBuild.
It appeared that Custom*MicrosoftCommonTargets are regular properties.
So, how to specify this property? It works pretty fine when to set it from command line.
That's strange, but it appears that bit of magic present here: property passed as command line parameter to one build is transitively passed to all nested builds!
That's fine for build server. But this won't work with Visual Studio build. And even declaring solution-level property won't help: neither static, nor dynamic properties are transfer to nested builds.
...I have a hacky idea to set environment variable on before solution build and erase it on after. But I don't like it. Any better ideas?
I use a bit different technique then #Spider M9. I want that all projects in solution tree/all subdirectories from current directory use extended build throw Custom*MicrosoftCommonTargets. I don't like to be forced to change every new project to import custom targets/props.
I place special file, let's say msbuild.include, in the root directory and my custom targets loader for every project tries to find it in ., ..\, ..\..\, and so on. msbuild.include contains flags that triggers execution of custom actions. If loader can't find this file it disables loading all custom targets and stoppes. This gives me ability to use my build extensions with projects from work repositories and to not use with opensource projects.
If you are interested in I can publish loader. It's a pretty simple and elegant solution.
For example I can sign any assembly in all projects in all subfolders with my key.
I always set up every project to import a standard .props file. Use the GetDirectoryNameOfFileAbove property function (see MSDN) to find it. Do this as the first line of every project file. Once established, you can redirect from that file to other imports. Another trick is to have that standard import (that would obviously be under version control) import conditionally another .props file only if it exists. This optional file would not be in version control, but is available for any developer to create and modify with their own private/temporary properties or other behavior.