I'm having an issue with xcode. My project has a lexer which should be created (from lexer.l) before compiling anything. Flex should create two files from lexer.l: lexer.c and lexer.h. The latter is included in some other files. What happens now is Xcode does not process lexer.l and then complains about missing lexer.h. lexer.l is include in the compile sources list under build phases. Any thoughts?
One year late I can provide a solution. Maybe someone else can use it.
As I read on some answer on SO Xcode needs some special file extensions to map them to the different programming languages. When you want to compile c++ code f.e. you have to give the lexfile the ending .lpp. Xcode will handle the rest
Related
I'm trying to include multiple Metal shaders in my Xcode project which have different language versions, but I'm unable to figure out how to do it.
I'm trying to do this, so I can support the latest features when available and drop back when not.
In the project's settings I can only find a general specifier for the Metal language revision. I also can't find anything in the MSL reference manual to specify it inside the file.
Is this even possible? If so, how?
Thanks in advance.
In Xcode, go to the Build Phases for the target which builds your app. Disclose the compile sources. Select a .metal file. Double-click in the right-hand Compiler Flags column to edit it. Enter -std=osx-metal1.2 or similar. That specific shader source file will be compiled with that language.
I found this compiler flag by comparing the build transcripts of builds with various settings for the target-wide build setting.
I have a Swift demo project that comes bundled with my framework. I want to ensure that the Swift code in the demo compiles successfully with both Xcode 6 (Swift 1.2) and Xcode 7 (Swift 2.0) without user intervention.
Since there's only marginal preprocessor support in Swift, how can I determine at compile-time which version of Swift or Xcode is being used to compile the code?
Now, here's the important detail:
It has to work automatically!
Open the project in Xcode 6 -> compiles
the Swift 1.2 code.
Open the project in Xcode 7 -> compiles the Swift
2.0 code.
No build settings or other means that require the user to specify, one way or another, which Swift/Xcode version she is using.
I keep thinking: this is such a trivial task, how could that not be possible with Swift?
As a framework developer this is driving me nuts since a successful compile of a Swift project now entirely depends upon the user's version of Xcode, and I can't ask them all to "update to Xcode 6.4" and at a later point having to ask them all over again to "update to Xcode 7.1". This is insane!
The alternative would of course be to have separate demo projects, managing different code bases, one for each version of Swift. And hoping the user will know what project will work with her version of Xcode. Not a real alternative.
The other alternative, to simply not use any of Swift 2.0's enhancement, is unfortunately not possible either. There is syntax, classes and methods that won't work in one or the other Swift version, if only due to the compiler being more picky in newer Xcode versions.
You can accomplish this using some of Xcode's advanced build settings, in particular:
XCODE_VERSION_MAJOR: Which encodes the Xcode major version as a string like "0700".
EXCLUDED_SOURCE_FILE_NAMES: A "fnmatch"-style pattern of source files to exclude by default.
INCLUDED_SOURCE_FILE_NAMES: A "fnmatch"-style pattern of source files to include.
I would not generally recommend doing this, as it will make your project hard to understand for most Xcode users, but if you absolutely want to make it work you can use this technique.
The way you accomplish it is as follows:
For any source files which need to be versioned, name them something like "Thing-Versioned-0600.swift" and "Thing-Versioned-0700.swift". Make sure both files are in the sources build phase.
Use the excluded mechanism to prevent any versioned files from being compiled by default, by adding a project-level build setting: EXCLUDED_SOURCE_FILE_NAMES = *-Versioned-*.swift.
Use the included mechanism to only add back in files that match the current Xcode major version, by adding another project-level build setting: INCLUDED_SOURCE_FILE_NAMES = *-Versioned-$(XCODE_VERSION_MAJOR).swift.
Having 2 versions of the code inside your project won't work since the code would not compile. There is no compiler directive for conditional compiling based on a version.
There is one workaround that could work (did not test it)
First create 3 files named version_current.swift, version_1_2.swift and version_2.swift. Make sure that only version_current.swift is part of your build target.
Then create a new build script phase and place it right above the 'compile sources' phase. In that script you will copy over the content of either the 1_2 or the 2 version over the current.
My scripting knowledge is not so good, so I can't give you much help doing this. You can get the version with code like:
$ xcrun swift -version
And then just execute a copy statement.
But then this will only work for the default Xcode version on your system. When you want to use a different version, you also have to change the default version.
I discovered that all the Swift libraries (libswiftCore.dylib, libswiftCoreGraphics.dylib,...) exist twice in the IPA. After decompressing the IPA, there is one version of theses libraries inside the folder SwiftSupport and the same files again inside Payload/Frameworks.
As far as I found out, the SwiftSupport folder is always generted by Xcode when a Swift-project is built. But where do the Swift libraries in Payload/Frameworks come from and how can I get rid of them?
I think that if your code already uses Swift, you have no set the Flag "Embedded Content contains Swift code" in Build Options to NO, otherwise Xcode will add the libraries because it thinks that you use some frameworks that have swift code
I am experiencing the same issue. I have read some answers which suggest that it isn't a big deal and I have to say that it looks like it isn't.
My app contains 3 targets - main app and 2 today extensions. When I create an archive its size is a whooping 126 MB. Most of it is Swift support libraries which are about 45 MB in my case and they are included twice.
However, when I check the binary size through test flight it is 23.6 MB. Now, this is still a lot considering that my application is a simple utility.
However, it is not too much if you take into account that Swift libraries have to be included. So far I would say that even though these libraries are included twice in the IPA they are not included twice in the actual binary.
This obviously doesn't answer the original question and I am also eagerly waiting for someone to come up with the exact solution, but it might be helpful.
I've found that playing around with 'Embedded content contains Swift' value yielded some good results, and was actually crucial for my app with an Apple Watch extension to pass validation.
I have written an answer about the details for the Apple Watch fix here.
How to build a .bundle from source code?
This might sound like a simple problem but it has been hurdling me for a week...
Here is my problem:
I have a bunch of .c and .h files that are organized in a folder and its sub folders. The source code was written and compiled with gcc make and tested by many other make tools. The source code has some utilities and command line tools and it has more code that serve as library for those utilities and tools. It is the files that serve as libraries that I want to reuse. (By library I don't mean static library or something, I just mean that some .c and .h files in certain subfolders provide functions that can be called by some other .c files. I want to be able to call those functions, too)
Yet my problem is more complex than that: I need to build those .c and .h into a bundle to reuse it. I am not writing my application in C; I am developing in Unity and Unity can only take in .bundle files on Mac OS.
Here is my goal:
Organize the source code folder in a proper way so that I can build them into a bundle in Xcode 4.
Here is where I got stuck:
When building the project I got the following error:
Duplicate symbol _main in
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o
and
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o
for architecture i386
I can relate to this error because I can find lots of main entries in the source code. Most of them are test utilities.
Here is what I tried:
I tried removing all those utility .c files but with no luck. The error is still there. I delete and delete until some files cannot find the definition of the function they are calling. So I had to stop there.
Though I wasn't able to build a bundle I was able to build a C/C++ static library (with an .a extension). After I got the .a file I tried to put it into another Xcode project and tried to build it into a bundle. I could build a bundle in that way, but then I had problem accessing the content of the bundle. How do I call functions defined in a .a static library if that library is hidden in a bundle? I read about Apple's documentation which says:
Note: Some Xcode targets (such as shell tools and static libraries) do
not result in the creation of a bundle or package. This is normal and
there is no need to create bundles specifically for these target
types. The resulting binaries generated for those targets are intended
to be used as is.
(quoted from: https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1)
Here is what I thought about:
I thought about replacing all main with something like main_sth. But the source code was not written by me so I didn't want to modify it. (It just doesn't feel like a proper way of doing things to me...)
I learnt that Xcode has gcc compiler built in. So I guess if gcc can make it, so can Xcode? It's just a wild guess - I am not familiar with Xcode and gcc.
Here is a summary of my questions:
Is there a way to properly organize a pile of code previously compiled and made by gcc make so that they can be built into an Xcode bundle?
Is it meaningful to put a .a library in an Xcode project and build it into a bundle? If it is meaningful, how do I call functions defined in .a after it is built into a bundle?
Is it proper to just replace all main() entries with something else?
Alright I think I have figured out at least one solution to the problem.
The duplicate main error was caused by a bunch of main entries in my source code. When the code was compiled by gcc make, I guess the author defined a sort of compilation order so that duplicate mains won't be an issue. (If you know how to do this, please let me know. I barely know make tools.) But when I just add the entire source code folder into my Xcode project, of course Xcode would complain during linking...
As I was unwilling to modify the source code (because the source code library is not developed by me), I decided to use another strategy to walk around this problem.
If your duplicate main error was reported from your own code, you can stop reading here. But if you are like me, with a bunch of gcc compiled source code and badly need a bundle yet don't know what to do, I may be able to help.
Okay here is what I did:
I set up an empty workspace.
I built a C/C++ static library project.
Import my entire source code folder into the static library project.
Set some header search path for the static library project.
Build the static library project. (Now I have a .a library which I could link against)
I set up another project, with a bundle target.
At the bundle project -> Build Phases -> Link Binary with Libraries, add the .a library that I just built.
At the bundle project -> edit scheme -> Build, add the static library project to the scheme and move it up the list so that it is built prior to my bundle project.
Then add .h files of my library project to my bundle project as references.
After that, add a .c file in my bundle project that basically functions as a wrapper. I picked a function that I want to call in Unity, wrote a wrapper function in the new .c file, and was able to build the bundle.
After several trial and error, I was able to import the bundle into Unity and was able to call the test function from Unity.
I was really excited about this! Though it's not completed yet I think this gives me hope and I am confident I can use the source code now! And the best thing about this solution is that I don't have to modify the library code developed by others. Whenever they update their code, I just update my .a library and that's it!
Though I have listed 11 steps I still feel that there are lots of details that I missed. So here are my references:
I followed this tutorial to build my source code into a static library: http://www.ccnx.org/?post_type=incsub_wiki&p=1315
I followed this blog to link static library against my bundle code and twist build phases and search headers: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/
I followed this doc to import my bundle to Unity3D Pro as a plugin: http://unity3d.com/support/documentation/Manual/Plugins.html
I strongly recommend the second reference because that's what solved my problem!
Though the problem is almost solved there are still a few things that I haven't figured out:
I don't know if a wrapper function is at all necessary. I will try this out tomorrow and come back to update.
-- I am coming back to update: the wrapper function is NOT necessary. Just make sure you have all the headers in your bundle project and you will be able to use all the data structures and call functions defined in your headers.
I haven't used NSBundle class though I read a few docs about it. Previously I was thinking about using that class to access my .a library encapsulated in my bundle, but as I found the solution I wrote above, I didn't try the class out.
Lastly, if you have better solution, please don't hesitate to let me know!
I tried to follow the steps in the accepted answer, but had no luck. In the end, I realised step 10 needed to be modified slightly:
Create a dummy.c under (.bundle) project and the dummy.c can just be totally empty.
Remove the setting for the library you want to link inside Link Binary With Libraries
Instead use -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a or -all_load to Other Linker Flags
PS: And also can use sub-project instead of workspace. and use Target Dependencies instead of Edit Scheme to achieve the same effect.
I know how to build an existing Xcode project using xcodebuild, but I also need to generate Xcode projects from maybe a Python/Shell script. Is there any document somewhere that describes the process?
From personal experience generating xcode projects by hand is a pain; I've never seen a clear format defined anywhere, besides Apple keeps changing/adding stuff to it with each new version of Xcode.
I think the easiest way would be to use cmake/qmake or scons to generate your xcode project for you. For example, using cmake for this is pretty simple: you can have your script generate cmake makefiles, then run "cmake -G xcode" on those and it will create an xcode project for you. Also, since you mentioned python you could probably look into using scons for this purpose.
One possible way is to generate a project with Xcode and recreate the file hierarchy with your script.