Xcode workspace reference project by environment variable - xcode

I need to reference a project in a Xcode workspace by an environment variable. An Xcode workspace file might look like this:
<Workspace
version = "1.0">
<FileRef
location = "group:../../Some/Dir/SomeLibrary.xcodeproj">
</FileRef>
<FileRef
location = "group:SomeApp/SomeApp.xcodeproj">
</FileRef>
</Workspace>
I want the SomeLibrary project to be referenced by an environment variable, so that the workspace file and projects can be used in different developer environments (the lib project is shared between several different projects). Any ideas on how to do this? Is the XML-format documented somewhere?
Thanks! :)

In your XCode 4 Preferences, you'll see a "Locations" tab and in the "Source Trees" section you can put an environment-variable like location (which you can change from machine to machine). And you can use these settings to change paths for the libraries you're trying to include or reference in your projects.
It's not exactly the environment variable from the Terminal command line, but then again most people don't launch XCode from the Terminal and so you shouldn't expect to pick up your $PATH or other UNIX-style environment variables from double clicking on any app, much less the XCode IDE. It's a good alternative.
There's some more information in this related question and here's Apple's documentation on what they are and how to set them up (which is aimed at XCode 3 but the same concepts apply for XCode 4).
Let me know if I can provide more information, and I hope my answer helps!

I think I need to answer this myself. Based on my research it is not possible to use a dynamic location (environment variable, source tree, etc) on workspace projects.
Solution 1:
You CAN achieve what I'm trying to do using symlinks. In my current workspace I've created one application-project, and a project entry which points to a symlink on the local file system. This way one can switch projects and have dynamic locations for the library-projects. I'm not sure if XCode treated this link properly when adding, so I manually added the project entry like this:
<FileRef
location = "group:Libraries/SomeLibrary/SomeLibrary.xcodeproj">
</FileRef>
Where SomeLibrary (IMPORTANT: The folder SomeLibrary need to be the symlink, or else XCode wont be able to find the project contents) is a symlink to my static library project somewhere else on the local file system. This way, developers can have different paths to the library, and one can easily switch versions when needed.
Solution 2:
Adding a static library project as a subproject and using cross-reference. For sub-projects, one can use Source Tree and use dynamic locations.
I haven't tested these solutions widely, so I'll come back with a reply after using it for a while.

Related

Creating Xcode Project Templates in Xcode 8.2.1

How does one go about creating a project template in Xcode 8.2.1? I'm asking this because of how I would like to use such a project template as the basis for the many Xcode projects that I will most likely create in the process of learning how to program in C++ from Bjarne Stroustrup's Programming: Principles and Practices Using C++, Second Edition. Mr. Stroustrup provides his readers with several header files, which I have copied into a GitHub repository, on the book's rudimentary web site, and I would like to figure out how to link them into Xcode's build system.
Someone created a makefile for use with the Darwin base of OS X, but I'd rather be able to use Xcode so that I can learn how to do so while I am learning C++ so that I know how to use it for later projects. I don't know whether I should use this makefile or not, but Apple does provide instructions on 'Building Makefile Projects with Xcode', so should I use those? I've also noticed that other people have similarly asked questions about how to create project templates for older versions of Xcode here, here, here, and here. Would any of the material from these Stack Overflow posts help my prospective answerer or answerers by providing them with some source material for their research?
There seems to be an amazing lack of information on this topic. As far as I know templates have not changed materially since Xcode 4. Templates I made for it still work on Xcode 6.
Like one of the commenters above, I used this post to get started.
I am only developing for macOS (OS X), not iOS.
I also made some file templates, which are much easier; maybe try making one or two of them first. Macro names in file templates do need triple underscores at each end.
In XCode 7.3.1 (and maybe above versions too), you just need to go to Application folder, find XCode and right click on it and pick "Show Package Contents". Then, make your way to:
Contents/Developer/Library/XCode/Templates/..
In here you will find more folders which you mess with. Basically they are the items that appear when you goto XCode->File->New File... Becareful though, cause this is part of the XCode application. Not sure what will happen if you edit or add files wrongly.
ps. You also should quit XCode before opening the package contents.
Hope that helps.
http://robnapier.net/project-templates
This link helps me much,since the macros did not change.
I want to custom a project template. But no automatic tools could be found,I make one my self.
first,drag a template to my desktop from Path below.
Xcode ▸ Contents ▸ Developer ▸ Platforms ▸ iPhoneOS.platform ▸ Developer ▸ Library ▸ Xcode ▸ Templates ▸ Project Templates
( I use the empty template from the link:
https://github.com/tobymao/EmptyApplication.xctemplate)
then,add your files to the *.xctemplate directory .
And edit plist file.
two items needs: Definitions which type should be Dictionary;Nodes which type is Array;
In Definitions for each added file define a correspond Dictionary (name should be filename or filename had PROJECTNAMEASINDENTIFIER as prefix) ,which has key "Path" hold your files' path;
In Nodes ,add all the items defined in Definitions.
and,
if you had your filename has projectname as prefix ,you should change content of your class files,change the classnames to macro FILEBASENAMEASIDENTIFIER
at last ,
move your template directory back, and don't forget to change the identifier in plist.

Netbeans Project from Mac to Windows

I created a Netbeans CPP Project in my Mac and uploaded it into git. The project has collaborators who use Windows.
When I pushed my project into github , I pushed the makefile information too (the whole project). Now the collaborators are getting build errors because the reference contains my Mac filepaths.
The Windows machine have cygwin installed.
How do I resolve it ?
How I do make it platform independent ?
What should I (and collaborators ) do to not affect the other workers ?
ANSWER : Netbeans has an option (in the project properties under c++), to have the file path as absolute or relative. So I all had to do was, set the relative option and push the changes . The project started working for everyone ! VOILA !!!!!!!!
Netbeans has an option (in the project properties under c++), to have the file path as absolute or relative. So I all had to do was, set the relative option and push the changes . The project started working for everyone ! VOILA !!!!!!!!
I've found that the project files generated by NetBeans for C++ are rather unweildy and aren't very maintainable by humans. And while they do tend to reference paths relatively from the root of the project (facilititating copying the project to different directories), there's just too many project files to maintain. And you're sol if they don't work.
I don't know if NetBeans allows you to specify environment variables for paths in the project settings dialogs. The macro/variable stuff is largely undocumented as far as I can tell. But if you know how to do that, then define all your file path dependencies by an environment variable instead of a hardcoded path in the project settings window. Remote developers need only redefine the environment vars on their machine.
But I think a better solution is to not use the NetBeans auto-generated Makefile from Project Settings. Instead, declare your own Makefile and create a NetBeans project type from "an existing Makefile". I've found that works really well.
Then you can have a line at the top of you Makefile as follows:
include common.inc
Where "common.inc" includes all the hardcoded library paths that are machine dependent. Here's an example of mine:
BOOST_INCLUDE := -I/home/jselbie/lib/boost_1_46_1
OPENSSL_INCLUDE := -I/home/jselbie/lib/openssl
And then my Makefile only references these directories by variable name. And so when I move the project around different machines with different configs, I just need to update common.inc.
And then if anyone else wants to use NetBeans to compile my project, they just need to create a NetBeans project from "an existing Makefile" option.
The option for relative file paths is actually NOT in the project properties! Instead, it's in the top menu bar.. choose "Tools" then "options" then click the "C/C++" tab, and the second box down is "File path mode" select "always relative"

How to include a bundle in main project xcode 4.1

[UPDATE 03/04/2015]
The question is now 4 years old, and applies to a specific version of XCode which I have now specified in the subject.
I have searched a lot for this argument, but I couldn't find a solution, I even post on stackoverflow, but I soon deleted the question becuase of very little access.
Now I am trying again.
I have a workspace with two distinct projects A and B.
B has two targets, one that build a static library Blib.a, and one that build a bundle B.bundle. All of them get built in the derived directory.
In project A I can easily add the static library from the build phases. However I cannot find a way to include the bundle. B.bundle is not visible from "copy resource" tab in A.
Therefore I need to add manually, with all that implies.
I also thought about using a script, but I would like to use this as a very last option.
Has someone a solution for this ? Did I miss something ?
thanks
After long investigation, it came up there's no easy way of doing this. The B.bundle is never visible to A project, and there's no settings in workspace to change that.
At this point there are three solutions:
Include the bundle manually from "copy resources->other", I started with this, but everytime there's a change you have to drop and include the bundle again
Create a script to be run in build phase, if everything is built into the PRODUCTS dir you can find the bundle easily and having copied automatically into the app.bundle. This is not a bad solution. If you are using svn the script got included in project, and users have it for free without additional work.
As suggested by Apple tech support, use folder references.Build bundle B into a folder and add such folder to project A using the "Create Folder References for any added folders" option. Xcode 4 will update your bundle into that folder every time you built it.
The added folder will appear as blue once included in your project A.
Thats's it, I personally use the script, because this solution is path independent if you use standard xcode reference variable such as BUILT_PRODUCTS_DIR and so on, and the shell script is just a cp -r-f
[UPDATE 03/04/2015]
I would like to point out that the question is now 4 years old. At that time there weren't many "official" options available. I even spoke with Apple Tech Support, which proposed solution 3 as the only available solution. It is of course very likely that things are now changed, and there is a much better solution. Just to speak, I also like to add that the three above are not "hacks" but "solutions", maybe technically outdated, but they can still be used nowadays. I intend a "hack" as a..."hack", which means it probably not going to work in future software release.
Here is how I did it.
Drag and drop B.bundle from Project B → Products → B.bundle into the Copy Bundle Resources build phase of your app in Project A (select the Create groups options when asked). This will add B.bundle at the root of your Project A outline. You can move it into the Frameworks directory near Blib.a if it you prefer.
Select B.bundle and check its Location in the Identity and Type right panel (Utilities area). By default, Xcode chooses Relative to Project. This is wrong, select Relative to Build Products instead.
The path to B.bundle will now look something like ../../../../../../../../Projects/MyApp/B.bundle. This is not what you want, but you can easily fix it. Open ProjectA.xcodeproj/project.pbxproj in a text editor, search for this path and delete everything in it except for B.bundle. Your project.pbxproj should look like this:
explicitFileType = wrapper.cfbundle; name = B.bundle; path = "B.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
Save your project.pbxproj file. Xcode will automatically reload your project and your app should build just fine.
After searching for a long time and failing many times, I found this resource that has been an absolutely great tutorial to create Static Libraries and include bundles in your main project or even for distribution to 3rd party developers that may consume your library.
Absolutely recommended:
https://github.com/jverkoey/iOS-Framework
In project A, is the product of project B a dependency in your scheme's Build action? I think you might have to set up this dependency (sometimes disabling the automatic dependency discovery option is best) for it to show up and be available for copying into another target. I believe this is because it doesn't really exist (like an image resource file) until it's built and Xcode needs to ensure it's built before working with it from another target.
As of Xcode 5.1.1 I was able to drag and drop B.bundle from the Project Navigator to the Copy Bundle Resources list of project A Build Phases. I assume creating B.bundle target is not an issue.
Switch build to Generic iOS Device. This step is needed to create a non-simulator reference.
Drag the .bundle to the other project's Copy Bundle Resources.
Select the .bundle in the Project navigator of the other project, and change its Location to Relative to Build Products
Make sure your .bundle in added to Target Dependencies of your static library

What is "Source Tree" in the Xcode preferences and what can I do with it?

I've been recently researching how I can manage source files in a project or multiple projects. I've read that Xcode has a built-in support for using svn, and will support git as well, both of which I found to be very useful.
The one thing I couldn't understand clearly is about Source Trees described in Xcode Project Management Guide. Here is my theory, but as I couldn't really verify this from anywhere (as far as I could tell), I would really like if someone could say what I'm missing, if any.
A Source Tree in Xcode preferences is more like a root of a source tree, which is a folder in my local file system.
I can use any files in any of my Xcode projects, even if the files are not in the project folders, if I can specify the files' location related to one of my source trees.
Now someone has the same project folder that is synchronized with mine. She has all files in the project folder, but the files referenced by a relative location to the source tree may exist out of the project folder.
But she has a source tree, with the same Setting Name to mine, (but absolutely in a different folder in her local file system), and if she has the file in the same relative location, then her Xcode can access the file without a problem.
So is this correct, and we use source trees because it enables us collaborating with files outside the project folder?
And even if the files outside the project folder is referenced by a relative path to the project folder itself (not to a source tree), if these files are all managed by SVN so they exist in the same relative location to the project folder in everyone's environments, then I wouldn't need source trees, right?
I never think I am an expert of Xcode, but it seems your question hasn't been answered for a while, so maybe it's worth commenting what I could say:
What you described is pretty much about it. Think is as an environmental variable of an operating system. Typically in a build system made by Autotools, for example, files are referenced by relative paths, such as $PROJECT_HOME/src/common/error.cpp. It doesn't matter where $PROJECT_HOME is in each user's local file system, as long as files are accessible by their relative paths to the user's $PROJECT_HOME directory.
And yes, you don't need to use source tree if the entire folder hierarchy used for a project is referenced by relative paths to the project home and somehow it is certain that everyone has the same files in the same location (for example, because a version control repository contains every files in a chunk as you said).
However, I think it's the best to keep all files in the project home folder, unless they are used across multiple projects, and therefore your version control repository only contains a single root directory (the project home) for your project. If there are files that are best to be shared by multiple projects, then I would have a separate repository for those files. In this case all of your coworkers must use the same protocol, say, having a source tree with the same setting name and put all project homes retrieved from your version control server directly under the source tree (so files outside a project home can be referenced in relation to the source tree for all programmers).
The most of my answer is kind of rephrasing what you already described, but that's how I use the source trees feature in Xcode myself. Maybe others can tell you more about it.

How to transfer Eclipse workspace and project from Windows to Linux and Mac

We have a a product developed on Windows for years. The product is composed of one Eclipse workspace and about 20 projects.
On Windows, we ask every developer check out projects into d:\dev\product folder, and copy a unified Workspace to d:\dev\prod_workspace. This way, whenever a new machine is set, we simply copy files to the same folder, and we can start working immediately.
Now we need to move our development environment to Linux and Mac. But there's no D:\ on Unix. And home folder for Linux is mostly like /home/username and /Users/username for Mac. We found Eclipse keeps absolute path in workspace when referring to projects, so simply copy workspace over does not work anymore. Even when we manually create/configure workspace on a Linux machine, it still cannot be copied over to another user, because the absolute path is changed.
I guess our goal is to allow easy setup of development environment. Do you have any suggestion to move eclipse workspace around?
I develop an Eclipse based product for Mac and WIndows (haven't tried Linux).
The solution I found to work best is to actually go and manually check out the projects in the workspace on each machine directly from source control. While the project structure does convert between platforms, any attaches, such as version-control stuff does not. I am not sure why, but I guess each thing has its kinks.
You may be able to able to hasten things a little by creating a project working set (or whatever it's called, I think it's a PSF file) for a platform, and then reuse it on all platforms.
Another problem is that Eclipse versions are not 100% compatible. One of the problems I have is with manifest files for plugins, which have different semantics (e.g., what to do with exported packages that don't actually exist) in each platform, causing a headache.
Finally, be away that Java on Mac and PC are not identical. In fact, Eclipse has two versions for the Mac. I usually end up running and compiling on Java 5 on the mac, which does have some incompatibilities with Java 6.
I have ported my eclipse project from windows xp to RHEL(never tried Mac)
Your task can be accomplished in the following steps :-
Use workspace variables in your project code rather than absolute path.
Shift your workspace to some location in linux as /Workspace or if you want to keep it user specific make the workspace folder as /home/user_name/Workspace.
There is an option to change all the \ of windows to / in linux. The option can be found under the file menu in eclipse.
Change the settings of where to find classpath directories, the options can be found by just right clicking on the project menu in the project viewer panel.
There is an option to build the project clean from scratch. You just have to click on the option and eclipse would re-compile the project.
Once all this is done, and all your database connections have been successfully ported to linux, you would have a working project running in linux as well.
I can think of two ways to do this:
Use workspace variables in Eclipse to point to the exact location where the workspace sits, if you need that. Then the developer can put everything in the workspace on Windows, Unix, whatever, then define the variable and you're done, or
If compilation is always done from within Eclipse, meaning you don't truly need any absolute paths anywhere, then change the projects to all use relative paths and check the Eclipse classpaths, etc, into source control. Thus, when a developer checks out everything in Eclipse, the classpath and .project file will be at the root level in the project and all paths will be pre-defined.
For option #2, you may need to have multiple .project or .classpath files, and have the developer copy the appropriate one into location. That is, copy .classpath.win into .classpath for Eclipse's use.
If you check out the projects from a source repository, then consider using Team -> ProjectSets to handle these.
Preferences can be saved in a file and loaded.
We tried classpath variables and loathed them. Now we just have everything in single projects in the source repository.
Use the Workspace Preference Transferrer plugin
This allows you to transfer the workspace settings from a given workspace to another via new options in the 'switch workspaces' dialog.
I'll share my own solution:
Zip the workspace. Just zip the entire file and then transfer it over. Then, all you need to do is delete the default drive reference:D:\ ...or whatever ends up appearing in the beginning of your file name. Then all you need to do is drag it over to the new empty workspace on your newly downloaded Eclipse.

Resources