Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 858
arqam Avatar asked Dec 05 '22 14:12

arqam


1 Answers

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:
  • CoreServices.framework
  • CoreGraphics.framework
  • CoreText.framework
  • CoreFoundation.framework

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.

like image 121
nuiun Avatar answered Jan 08 '23 12:01

nuiun