Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
macosxrelease [2012/12/23 06:37]
socapex
macosxrelease [2013/04/02 03:00] (current)
socapex [Problems and Improving the Workflow]
Line 1: Line 1:
-====== Releasing ManaPlus for Mac OSX ======+====== ​Compiling and Releasing ManaPlus for Mac OSX ======
  
  
-This is a beginner'​s guide to help new OSX developers quickly grasp the Xcode project included with ManaPlus. If you are experienced with Xcode, please feel free to skip directly to the end (improving ​the workflow). If you wish to help with the releases of ManaPlus, you are reading the right thing. I will try my best to be thorough and make sure I cover most of what I did, what needs to be done and what could be improved. I am no expert on building software for the Mac, so please be patient and point out anything stupid I did.+This is a beginner'​s guide to help new OSX developers quickly grasp the Xcode project included with ManaPlus. If you are experienced with Xcode, please feel free to skip directly to the end ([[#Problems and Improving ​the Workflow]]). If you wish to help with the releases of ManaPlus, you are reading the right thing. I will try my best to be thorough and make sure I cover most of what I did, what needs to be done and what could be improved. I am no expert on building software for the Mac, so please be patient and point out anything stupid I did.
  
 ===== The Xcode Project ===== ===== The Xcode Project =====
Line 13: Line 13:
  
 Now you can right click on the ManaPlus Folder in the Project Browser and select 'add files to "​ManaPlus"​ …' You can navigate to the src folder and add the needed files. You will see that they are darker, since Xcode keeps track of the files in your project. It is a good indicator you are doing the right thing! Now you can right click on the ManaPlus Folder in the Project Browser and select 'add files to "​ManaPlus"​ …' You can navigate to the src folder and add the needed files. You will see that they are darker, since Xcode keeps track of the files in your project. It is a good indicator you are doing the right thing!
 +
 +If files were removed, they will be red inside your ManaPlus folder. Simply delete them.
  
 == Updating localization == == Updating localization ==
  
-Unfortunatelysince ManaPlus has certain problems in compiling ​through the usual CMakeI wasn'​t ​able to setup nice workflow for the translations ​(see things to improve). Soyou will have to download a nightly build (for example the windows one) and overwrite the Xcode > locale folder with the one from the nightly ​build. ​This should ensure you have the latest translations.+No need to do anything special hereI have include an automatic script to automagically compile the localizations. Make sure you have gettext installed ​through ​macports. 
 + 
 +Now that everything is up to date, you can try to hit Run to test out the build. If it failsit is probably because you didn'​t ​add everything needed, or that new library has been added (see [[#Working with libraries]]). 
 + 
 +Your app is located inside the Derived Data folder Xcode creates. To find itgo to Xcode > Preferences... > Locations and click the little arrow beside ​the Derived Data path. You can also change the path, and I highly recommend adding to your finder favorites. Navigate to the Build/​Products/​Debug/​ and there is your debug app. 
 + 
 +===== Building a Release ===== 
 + 
 +If all went well and the app works fine, use Product > Build For > Archive to create a release ​build. ​It will be located in the release folder next to your debug app. Do this for both ManaPlus and ManaPlus-10.6.
  
-Now that everything is up to date, you can try to hit Run to test out the buildIf it fails, it is probably because you didn't add everything needed, or that a new library has been added (I will cover libraries later).+I used [[http://​www.araelium.com/​dmgcanvas/​|DMGCanvas]] ​to create the .dmg image. You can use the software free, with limited functionality. It is quite enough for what we need. Open both release.dmgcanvas and release 10.6.dmgcanvas. The file is probably not pointing ​to the correct application locationSelect the ManaPlus.app and in the file info panelpoint it to the correct release path (do the same for the 10.6 version). What is nice with DMGCanvas ​is that from now on, you wont need to do anything else. It will always include the latest version of your built app.
  
-Your app is located inside the Derived Data folder Xcode creates. To find it, go to Xcode > Preferences... > Locations ​and click the little arrow beside the Derived Data path. You can also change the path, and I highly recommend adding to your finder favoritesNavigate to the Build > Products > Debug and there is your app.+Click build and save your dmg files somewhereUpload ​and hopefully all should workCongratulations,​ you have built a release for ManaPlus on OS X!
  
  
 ===== Working with libraries ===== ===== Working with libraries =====
  
-Libraries are probably one of the trickiest part of releasing a build. I have included all the modified dynamic libraries (.dylib) and static ones (.a) inside the Xcode libs folder. You will need to download the SDL, SDL_mixer, SDL_image, SDL_net and SDL_ttf frameworks separately and add these in your /​Library/​Frameworks folder.+Libraries are probably one of the trickiest part of releasing a build. I have included all the modified dynamic libraries (.dylib) and static ones (.a) inside the Xcode/libs folder. You will need to download the SDL, SDL_mixer, SDL_image, SDL_net and SDL_ttf frameworks separately and add these in your /​Library/​Frameworks folder.
  
 If for some reason, the ManaPlus project adds a new dependency, you will have many options to choose from. You can find the source code of the library and compile it inside a framework using Xcode. Then add this framework to your project and also add it to the Build Phases > Copy Files area (the framework one). If for some reason, the ManaPlus project adds a new dependency, you will have many options to choose from. You can find the source code of the library and compile it inside a framework using Xcode. Then add this framework to your project and also add it to the Build Phases > Copy Files area (the framework one).
Line 33: Line 43:
 and the library will be located inside your /​opt/​local/​lib folder. There may be both a dynamic library and a static one (.dylib and .a respectively). If you don't want headaches, **use the static library**. Still, I will explain for both, and the issues of dynamic libraries in case a static version is not available. and the library will be located inside your /​opt/​local/​lib folder. There may be both a dynamic library and a static one (.dylib and .a respectively). If you don't want headaches, **use the static library**. Still, I will explain for both, and the issues of dynamic libraries in case a static version is not available.
  
-If you are using a dynamic library (for whatever crazy reason), read on. If you have a static library and are mentally sane, skip to the static library ​section.+If you are using a dynamic library (for whatever crazy reason), read on. If you have a static library and are mentally sane, skip to the [[#Static Libraries]] ​section.
  
 == Dynamic libraries == == Dynamic libraries ==
Line 55: Line 65:
 </​code>​ </​code>​
  
-As you can see from the first line, this library was edited by myself. What I did here, using the install_name_tool to change the location where are application will look for the file. Since the files are packaged inside the ManaPlus.app/​Contents/​SharedSupport,​ I need to tell OSX to look for them there (and not /​opt/​local/​lib).+As you can see from the first line, this library was edited by myself. What I did here, using the install_name_tool, is to change the location where our application will look for the file. Since the files are packaged inside the ManaPlus.app/​Contents/​SharedSupport,​ I need to tell OSX to look for them there (and not /​opt/​local/​lib).
  
 To do so, simply run this command on YourNewLibrary.dylib:​ To do so, simply run this command on YourNewLibrary.dylib:​
Line 66: Line 76:
 <​code>​install_name_tool -change /​usr/​lib/​YourNewLibrary.dylib @executable_path/​../​SharedSupport/​YourNewLibrary.dylib "​$TARGET_BUILD_DIR/​$PRODUCT_NAME.app/​Contents/​MacOS/​$PRODUCT_NAME"</​code>​ <​code>​install_name_tool -change /​usr/​lib/​YourNewLibrary.dylib @executable_path/​../​SharedSupport/​YourNewLibrary.dylib "​$TARGET_BUILD_DIR/​$PRODUCT_NAME.app/​Contents/​MacOS/​$PRODUCT_NAME"</​code>​
  
-Be sure to change /usr/lib to /​opt/​local/​lib if that is where your library was pointing to (if you installed the lib using MacPorts for example). Now things may get a bit complicated (if it wasn't already). First of all, libraries in /usr/lib are libraries included by default on OSX. You need to analyse the compatibility version of the libraries included with older versions of OS X.+**Be sure to change /usr/lib to /​opt/​local/​lib if that is where your library was pointing to** (if you installed the lib using MacPorts for example). Now things may get a bit complicated (if it wasn't already). First of all, libraries in /usr/lib are libraries included by default on OSX. You need to analyse the compatibility version of the libraries included with older versions of OS X.
  
 If we take libcurl.4 for example, I had to include it because OS X 10.6 doesn'​t provide the compatibility version 7.0.0. Now this is all good, but the library itself has dependencies. Fortunately,​ Snow Leopard provided all the dependencies at the correct compatibility vesions, so I didn't have to include libcurl'​s dependencies inside the application bundle. Lets look at some other scenario... If we take libcurl.4 for example, I had to include it because OS X 10.6 doesn'​t provide the compatibility version 7.0.0. Now this is all good, but the library itself has dependencies. Fortunately,​ Snow Leopard provided all the dependencies at the correct compatibility vesions, so I didn't have to include libcurl'​s dependencies inside the application bundle. Lets look at some other scenario...
Line 87: Line 97:
 </​code>​ </​code>​
  
-I had to add all the necessary dependencies to the project, because they where all pointing to /​opt/​local/​lib,​ which means they were installed through macports, and a user without it wont have these dependencies ​available. As a rule of thumb, if the lib is in /usr/lib, then it should be fine, but if it is in /​opt/​local/​lib you will have to include its dependencies. You can do it all manually, or use shell scripts provided in the libs folder (libs-change.sh and libs-id.sh). I found these on the internet but can't recover the source...+I had to add all the necessary dependencies to the project, because they where all pointing to /​opt/​local/​lib,​ which means they were installed through macports, and a user  wont have these libraries ​available. As a rule of thumb, if the lib or dependency ​is in /usr/lib, then it should be fine. If the library ​is pointing too /​opt/​local/​lib you will have to include its dependencies ​**that are also pointing to /​opt/​local/​lib**. You can do it all manually, or use shell scripts provided in the libs folder (libs-change.sh and libs-id.sh). I found these on the internet but can't recover the source...
  
-To change all the ids of your dylibs inside the folder to @executable_path/​../​SharedSupport/​Libraries.dylib, run the libs-id.sh script:+So first, add your library .dylib and all its dependencies to a temporary folder, and make sure they don't have more dependencies. Also copy the shell scripts inside this folder. 
 + 
 +To change all the ids of your dylibs inside the folder to @executable_path/​../​SharedSupport/,​ run the libs-id.sh script:
 <​code>​./​libs-id.sh</​code>​ <​code>​./​libs-id.sh</​code>​
  
-For the other script, first **uncomment the first part** and comment the second, and run it the same way you did with libs-id. This will create a text file called changes. You can review the changes that are to be made. Then, comment the first part of the script, uncomment the second and run it again (./​libs-change.sh). Now all your /​opt/​local/​lib dependencies should be changed to @executable_path/​../​SharedSupport/​. Hurray!+For the other script, first **uncomment the first part** and comment the second, and run it the same way you did with libs-id. This will create a text file called changes. You can review the changes that are to be made to make sure all is working. Then, comment the first part of the script, uncomment the second and run it again (./​libs-change.sh). Now all your /​opt/​local/​lib dependencies should be changed to @executable_path/​../​SharedSupport/​. Hurray
 + 
 +To view the result, you can run 
 +<​code>​otool -L *</​code>​ 
 +inside your folder, you will see all your libraries information. If all is well, add these to the Xcode/lib folder and also drag the dependencies inside your Xcode project in Frameworks/​dependencies. You **do not** need to add a script line to Build Phases > Run Scripts for dependencies. Only for the one library ManaPlus now requires (which you did earlier). 
 + 
 +Whew! What a ride. Now you can check out the length of my Static Library section... To see how all of this isn't require when you use a .a library. 
 + 
 +== Static Libraries == 
 + 
 +So you are sane and have decided to use Static Libraries. I learned about these after going through the pain of linking all my macports dynamic libraries [sigh]. So lets get started. You have a NewLibrary.a inside your /​opt/​local/​lib directory. Copy that file to the Xcode/lib folder inside the manaplus directory. Take the file and drag it into your Xcode project in the Frameworks section. It should automatically be added to the Summary > Linked Libraries section and also the Build Phases > Link Binary With Libraries area. You need to **remove it** from the Build Phases > Link Binary With Libraries section. This is because Xcode is broken, and if you leave it there, Xcode will point to a .dylib if it can find one (for more information on this, you can google '​perian-and-xcode-dylib-f.e.t.i.s.h'​ and remove the dots, the wiki doesn'​t like that word). 
 + 
 +You will also have to add the full path to the library in the Build Settings > Other Linker Flags section as so: 
 +<​code>​$(SRCROOT)/​libs/​NewLibrary.a</​code>​ 
 + 
 +Just add it before or after the existing ones. The $(SRCROOT) will transform to the correct path to your project. 
 + 
 +Et voila! You are done. The library will get included inside the application bundle, along with everything it needs (I don't think you even need to add its dependencies...). Now your glad you didn't use a dynamic library, aren't you. 
 + 
 +== Conclusion == 
 + 
 +Use static libraries. 
 + 
 +Oh, and finally, to make sure all went well, compile the application,​ navigate to its location. Right click and select Show Package Content. Navigate to the executable (Contents/​MacOS/​ManaPlus). In terminal, type 'otool -L ' with the space, and drag the ManaPlus executable onto the terminal to get its full path. Now press enter, you should not see any library that points to /​opt/​local/​lib,​ and if you used a static library, you shouldn'​t see it either. 
 + 
 +===== Problems and Improving the Workflow ===== 
 + 
 +If you wish to improve the building experience, here are some good places to start. 
 + 
 +  * Find a way to reference the src directory, instead of hard-linking to the source files. This would let us skip the "​finding and removing files" phase. 
 +<​del> ​ * Create a bash script in the Build Phases to compile the localization files and copy them inside the app bundle. This would allow us to forget about dragging new translations inside the locale folder. It would also ensure everything is always up to date.</​del>​ //done// 
 + 
 +That's pretty much it for now!
Print/export
Languages