
I'm pretty new to Haskell, but have been having fun learning it. Being a Mac and Windows programmer most of my life, I'm used to using GUIs and IDEs to program and don't really care for using command-line tools. As such, I've been working on getting Xcode to build Haskell files directly and I have something working that I thought others might be interested in. Looking through the "Building/Cross-Compiling/iOS" instructions, it looks like the standard way of building Haskell files is to build them on the command line into a library and then link your C/C++/Objective-C sources against the library. But you don't need to do this. You can directly edit Haskell in Xcode (with very basic syntax highlighting), and build it from Xcode all without ever going to the command-line. Would people be interested in working this way? If so, I'll be happy to post steps to do it. -DC

On Tue, Nov 5, 2013 at 5:05 PM, haskell cafe
I'm pretty new to Haskell, but have been having fun learning it. Being a Mac and Windows programmer most of my life, I'm used to using GUIs and IDEs to program and don't really care for using command-line tools. As such, I've been working on getting Xcode to build Haskell files directly and I have something working that I thought others might be interested in.
Looking through the "Building/Cross-Compiling/iOS" instructions, it looks like the standard way of building Haskell files is to build them on the command line into a library and then link your C/C++/Objective-C sources against the library. But you don't need to do this. You can directly edit Haskell in Xcode (with very basic syntax highlighting), and build it from Xcode all without ever going to the command-line.
Would people be interested in working this way? If so, I'll be happy to post steps to do it.
A couple people indicated off-list that they would be interested in this, so here are the details. I'll send information about getting Xcode to do syntax coloring in a separate email. You can get Xcode to compile source files from any language and link them into your C/C++/Objective-C/Objective-C++ program by using Build Rules. Note that this is different from adding a Run Script Build Phase. This is a Build Rule, not a Build Phase. In Xcode 5: 1) Click on your Project in the Project Navigator 2) Click on the Target in the Project editor 3) Click on the "Build Rules" tab (Note: *Not* "Build Settings" or "Build Phases"). 4) From the "Editor" menu, choose "Add Build Rule" This will create a new build rule in your project. It should look like this: [image: Inline image 1] 5) From the "Process" popup menu (in the new build rule), select "Source Files With Names Matching:" and enter "*.hs" into the text field next to it (leaving out the quotation marks). (Being new to Haskell, I'm unclear on the difference between ".hs" and ".lhs" files. But if ".lhs" files are compiled by ghc, you can do these steps a second time and replace "*.hs" with "*.lhs".) 6) From the "Using" popup menu, choose "Custom Script:" 7) Enter the following for the script: #!/bin/sh ghc -c -odir ${DERIVED_FILE_DIR} ${SCRIPT_INPUT_FILE} The above runs a bourne shell script that simply invokes ghc, tells it to compile the next Haskell source file, and put the .o into Xcode's derived sources folder with all the other .o files that your Xcode project produces. Feel free to add whatever other ghc options you need to compile your files. 8) In the "Output Files" section, click the "+" button. You'll be prompted to enter a filename. Enter this: $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).o That says that the output files from the build rule will be in the Derived Files directory, and they will have a name that's the same as the input file, but instead of ending in ".hs" it will end in ".o" as object files should. This is what allows Xcode to understand dependencies in Haskell. (It's not perfect - it won't recognize when you update a module used by Haskell source file, but it's good enough to recognize that you changed the source file which produces a given object file and will rebuild that object file as appropriate.) 9) Add your Haskell source files to your Xcode project. 10) Be sure to call "hs_init()" and "hs_exit()" in your C/C++/Objective-C/Objective-C++ source so that you can safely call and use Haskell code in your project. 11) Add any libraries that are required to link against the Haskell source. In my simple example, I had to link against libiconv.2.dylib, libHSinteger-gmp-0.5.0.0.a, libHSghc-prim-0.3.0.0.a, libHSbase-4.6.0.1.a, and libHSrts.a. You may need a different set of libraries for your project depending on what your Haskell source does. The description at < http://www.haskell.org/haskellwiki/Using_Haskell_in_an_Xcode_Cocoa_project#Add_Haskell_libraries.2C_compile_and_run> has a pretty good description of how to figure out which ones you need. That's it! Let me know if you need any clarification on any parts of this. -DC

On Tue, Nov 5, 2013 at 5:05 PM, haskell cafe
You can directly edit Haskell in Xcode (with very basic syntax highlighting)
Here's how I got (basic) syntax highlighting for Haskell in Xcode: I should start by saying that unlike my other post, this is totally unsupported and that this involves modifying Xcode's bundle. While it mainly just involves adding a plist file to the bundle and modifying an existing plist, it is still potentially dangerous and you will likely have to re-do it every time you update Xcode. You have been warned. Also, this only adds syntax coloring for keywords, strings, characters, and numbers. Unfortunately, it doesn't do coloring of variables, types, and other identifiers. Xcode doesn't generally color operators, though you could add the built-in ones to the list of keywords if you want it to also color them. Given all that, if you still want to proceed, here's what you need to do: 1) Copy Haskell.xclangspec (included at the bottom of this email) into /Applications/Xcode/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/. (Assuming you've installed Xcode into /Applications/.) This will require admin privileges on the machine you're running Xcode on. 2) Save the following as "~/Desktop/Haskell.plist" (or wherever is convenient for you) : <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" " http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Xcode.SourceCodeLanguage.Haskell</key> <dict> <key>languageSpecification</key> <string>xcode.lang.haskell</string> <key>fileDataType</key> <array> <dict> <key>identifier</key> <string>public.haskell-source</string> </dict> </array> <key>id</key> <string>Xcode.SourceCodeLanguage.Haskell</string> <key>point</key> <string>Xcode.SourceCodeLanguage</string> <key>languageName</key> <string>Haskell</string> <key>version</key> <string>1.0</string> <key>conformsTo</key> <array> <dict> <key>identifier</key> <string>Xcode.SourceCodeLanguage.Generic</string> </dict> </array> <key>name</key> <string>Haskell Language</string> <key>documentationAbbreviation</key> <string>hs</string> </dict> </dict> </plist> 3) Make a copy of the file: /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/DVTFoundation.xcplugindata and put it somewhere safe in case you mess it up in the next step. 4) Using PlistBuddy, add the above into DVTFoundation.xcplugindata (in the same directory as the stuff in step 1), by doing the following on the command-line (this should all be one line) : /usr/libexec/PlistBuddy /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/DVTFoundation.xcplugindata -c 'Merge ~/Desktop/Haskell.plist plug-in:extensions' You may need to use "sudo" to run the above command. (In other words type "sudo /usr/libexec/PlistBuddy …<rest of above command>…") Note that if you saved the above file somewhere other than your desktop, you'll need to change the path in the "Merge" command to match wherever you put it. If you somehow messed it up and need to undo it, you can use the following command to remove what you just added: /usr/libexec/PlistBuddy /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/DVTFoundation.xcplugindata -c 'Delete :plug-in:extensions:Xcode.SourceCodeLanguage.Haskell' Again, you'll probably need to use 'sudo' to run that command, too. 5) Once you've done the above, you'll notice Xcode's "Editor" > "Syntax Coloring" menu now includes "Haskell" as an option. Simply open your Haskell source file and choose "Haskell" from the "Syntax Coloring" submenu! Here is the Haskell.xclangspec. It's probably not perfect. I created it by looking at the C and Fortran .xclangspec files and copying their format. I used the information from the Haskell Language Spec < http://www.haskell.org/haskellwiki/Language_and_library_specification>. If you have suggestions for changes, let me know, or just post them: // Haskell ( /****************************************************************************/ // MARK: Haskell Keywords /****************************************************************************/ { Identifier = "xcode.lang.haskell.keyword"; Syntax = { StartChars = "abcdefghijklmnopqrstuvwxyz"; Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'"; Words = ( "case", "class", "data", "default", "deriving", "do", "else", "foreign", "import", "if", "in", "infix", "infixl", "infixr", "instance", "let", "module", "newtype", "of", "then", "type", "where", "_", ); Type = "xcode.syntax.keyword"; AltType = "xcode.syntax.identifier"; // non-keywords are identifiers }; }, /****************************************************************************/ // MARK: Haskell Coloring /****************************************************************************/ { Identifier = "xcode.lang.haskell"; Description = "Haskell Coloring"; BasedOn = "xcode.lang.simpleColoring"; IncludeInMenu = YES; Name = "Haskell"; Syntax = { IncludeRules = ( // processed in order "xcode.lang.haskell.comment.singleline", "xcode.lang.haskell.comment", "xcode.lang.string", "xcode.lang.character", "xcode.lang.number", "xcode.lang.haskell.keyword", ); Type = "xcode.syntax.plain"; }; }, { Identifier = "xcode.lang.haskell.comment.singleline"; Syntax = { Start = "--"; End = "\n"; IncludeRules = ( "xcode.lang.url", "xcode.lang.url.mail", "xcode.lang.comment.mark" ); Type = "xcode.syntax.comment"; }; }, { Identifier = "xcode.lang.haskell.comment"; Syntax = { Start = "{-"; End = "-}"; IncludeRules = ( "xcode.lang.url", "xcode.lang.url.mail", "xcode.lang.comment.mark" ); Type = "xcode.syntax.comment"; }; }, )
participants (1)
-
haskell cafe