c++xcodemacosbuildskia

How to link the Skia library for a C++ project with Xcode


Skia is a graphics library (skia.org). The documentation explains how to build the library after cloning the project via git. But the documentation is unclear as of this date, how to build a C++ project with Xcode which uses the Skia library.

I tried all what is written in the documentation, but can't find a way of how to link the skia library in a C++ Xcode project.


Solution

  • How to Solve the Problem:

    Add Library Search Path

    This screenshot shows how and where to do these steps:

    Add Skia Library Path Image

    1. In the Project Navigator click the icon of your project.
    2. In the panel on the left of the main window division next to the Project Navigator: Click on to your project icon again to open project global info and settings.
    3. In the navigation bar on top of the main window division: Click on "Build Settings"
    4. Make sure the view filters below are set to "All" and "Combined" so you don't miss any settings.
    5. In the option search form enter "Library search path" to find the entry for "Library Search Paths"
    6. Double klick the Entry "Library Search Paths" to receive the popup in which you can specify search paths to libraries which shall be linked.
    7. Inside the popup double click an empty line to enter the path to your libskia.a library file which you built earlier. (Note: I used the static build option to create a static library. If you want to link a dynamic .so library, the settings are slightly different)

    Statically Link with libskia.a

    The following steps should be performed inside the same main window division as the steps before.

    1. In the option search form enter "other link" to find the entry for "Other Linker Flags"
    2. Add the Flag -lskia to statically link the libskia.a library when building the project.

    Make Sure Header Include Paths Are Set

    The following steps should be performed inside the same main window division as the steps before.

    1. In the option search form enter "header search" to find the entry for "Header Search Paths"
    2. Double klick the Entry "Header Search Paths" to receive the popup in which you can specify search paths to header files which shall be included. Adding "[path to your Skia directory]/skia/include" and setting search mode on the right to "recursive" should be sufficient for the example below.

    Add Mac OSX Specific Dependencies of Skia

    The following steps should be performed inside the same main window division as the steps before. This screenshot shows where to do these steps:

    Add Skia Mac OSX Specific Dependencies Image

    1. In the panel on the left of the main window division next to the Project Navigator: Click on to your target to open target specific info and settings.
    2. In the navigation bar on top of the main window division: Click on "Build Phases"
    3. Under "Link Binary With Libraries", click the + sign.
    4. Add the following Mac OSX specific Skia dependencies:

    Testcode

    You may test these settings with the following example code:

    #include "SkSurface.h"
    #include "SkPath.h"
    #include "SkCanvas.h"
    #include "SkData.h"
    #include "SkImage.h"
    #include "SkStream.h"
    
    int main (int argc, char * const argv[]) {
      // hard coded example program parameters
      const char filePath[] = "/Users/[yourUserName]/Desktop/skiaTestImage.png";
      int width = 256;
      int height = 256;
    
      // create canvas to draw on
      sk_sp<SkSurface> rasterSurface = SkSurface::MakeRasterN32Premul(width, height);
      SkCanvas* canvas = rasterSurface->getCanvas();
      
      // creating a path to be drawn
      SkPath path;
      path.moveTo(10.0f, 10.0f);
      path.lineTo(100.0f, 0.0f);
      path.lineTo(100.0f, 100.0f);
      path.lineTo(0.0f, 100.0f);
      path.lineTo(50.0f, 50.0f);
      path.close();
      
      // creating a paint to draw with
      SkPaint p;
      p.setAntiAlias(true);
    
      // clear out which may be was drawn before and draw the path
      canvas->clear(SK_ColorWHITE);
      canvas->drawPath(path, p);
      
      // make a PNG encoded image using the canvas
      sk_sp<SkImage> img(rasterSurface->makeImageSnapshot());
      if (!img) { return 1; }
      sk_sp<SkData> png(img->encodeToData());
      if (!png) { return 1; }
    
      // write the data to the file specified by filePath
      SkFILEWStream out(filePath);
      (void)out.write(png->data(), png->size());
      
      return 0;
    }
    

    Appendix

    Compiling With the Terminal

    You may accomplish the same by writing a make file or by invoking the g++ compiler directly in the terminal. Here is an example:

    g++ -std=c++11 main.cpp -framework CoreFoundation -framework \
     CoreGraphics -framework CoreText -framework CoreServices - \
     L[path_to_your_Skia_library]/skia/out/Static_m58 -lskia - \
     I[path_to_your_Skia_library]/skia/include/core -\ 
     I[path_to_your_Skia_library]/skia/include/config -\
     I[path_to_your_Skia_library]/skia/include/utils -\
     I[path_to_your_Skia_library]/skia/third_party/externals/sdl/include -\
     I[path_to_your_Skia_library]/skia/include/gpu -\
     I[path_to_your_Skia_library]/skia/src/gpu -o main
    

    How I found the solution

    Finding all this stuff out took me around 12 hours. If you are interested in the steps which finally lead to the solution, I'll explain them here. Just let me know.