Skip to content

Instantly share code, notes, and snippets.

@vytskalt
Created May 10, 2025 19:02
Show Gist options
  • Select an option

  • Save vytskalt/db78de9748dde72f6a3a2b600f2940a8 to your computer and use it in GitHub Desktop.

Select an option

Save vytskalt/db78de9748dde72f6a3a2b600f2940a8 to your computer and use it in GitHub Desktop.
Building Skia without a build system. For educational purposes only, don't actually use this
#!/usr/bin/env bash
# Set these environment variables:
# - ZLIB_LIB: path to directory containing libz.a
# - LIBPNG_INCLUDE: path to libpng include directory
# - LIBPNG_LIB: path to directory containing libpng.a
# Skia version: 5b8860c391f7c3d5b09b62e0d58c45cb6fa814f0
CXX="zig c++"
AR="zig ar"
#CXX="clang++"
#AR="ar"
mkdir -p temp/
function buildBase() {
local objfiles=""
mkdir -p temp/base/
for file in src/base/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/base/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
$AR rcs temp/base/libbase.a${objfiles}
}
function buildSkcms() {
mkdir -p temp/skcms/
# Helpful: https://github.com/libpag/skcms/blob/2d0ea94be31ed31438c3c7a57752a601ba83ff2c/CMakeLists.txt
$CXX -c modules/skcms/skcms.cc -o temp/skcms/skcms.o -DSKCMS_DISABLE_SKX -DSKCMS_DISABLE_HSW
$CXX -c modules/skcms/src/skcms_TransformBaseline.cc -o temp/skcms/skcms_transformbaseline.o
$AR rcs temp/skcms/libskcms.a temp/skcms/skcms.o temp/skcms/skcms_transformbaseline.o
#zig c++ -c modules/skcms/src/skcms_TransformHsw.cc
#zig c++ -c modules/skcms/src/skcms_TransformSkx.cc
}
function buildCore() {
local objfiles=""
mkdir -p temp/core/
for file in src/core/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/core/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile -DSK_DISABLE_LEGACY_PNG_WRITEBUFFER
done
$AR rcs temp/core/libcore.a${objfiles}
}
function buildSksl() {
local objfiles=""
mkdir -p temp/sksl/
for file in src/sksl/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/sksl/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/sksl/ir/
for file in src/sksl/ir/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/sksl/ir/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/sksl/transform/
for file in src/sksl/transform/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/sksl/transform/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/sksl/analysis/
for file in src/sksl/analysis/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/sksl/analysis/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/sksl/tracing/
for file in src/sksl/tracing/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/sksl/tracing/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/sksl/codegen/
$CXX -I. -c src/sksl/codegen/SkSLRasterPipelineBuilder.cpp -o temp/sksl/codegen/skslrasterpipelinebuilder.o
objfiles="${objfiles} temp/sksl/codegen/skslrasterpipelinebuilder.o"
$CXX -I. -c src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp -o temp/sksl/codegen/skslrasterpipelinecodegenerator.o
objfiles="${objfiles} temp/sksl/codegen/skslrasterpipelinecodegenerator.o"
$AR rcs temp/sksl/libsksl.a${objfiles}
}
function buildImage() {
local objfiles=""
mkdir -p temp/image/
for file in src/image/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/image/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
$AR rcs temp/image/libimage.a${objfiles}
}
function buildShaders() {
local objfiles=""
mkdir -p temp/shaders/
for file in src/shaders/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/shaders/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/shaders/gradients/
for file in src/shaders/gradients/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/shaders/gradients${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
$AR rcs temp/shaders/libshaders.a${objfiles}
}
function buildEffects() {
local objfiles=""
mkdir -p temp/effects/
for file in src/effects/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/effects/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/effects/colorfilters/
for file in src/effects/colorfilters/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/effects/colorfilters/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/effects/imagefilters/
for file in src/effects/imagefilters/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/effects/imagefilters/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
$AR rcs temp/effects/libeffects.a${objfiles}
}
function buildText() {
local objfiles=""
mkdir -p temp/text/
for file in src/text/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/text/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
mkdir -p temp/text/gpu
for file in src/text/gpu/*.cpp; do
local base=$(basename -- "$file")
local name=${base%.*}
local objfile="temp/text/gpu/${name,,}.o"
objfiles="${objfiles} ${objfile}"
$CXX -I. -c $file -o $objfile
done
$AR rcs temp/text/libtext.a${objfiles}
}
function buildPorts() {
mkdir -p temp/ports/
$CXX -I. -c src/ports/SkDebug_stdio.cpp -o temp/ports/skdebug_stdio.o
$CXX -I. -c src/ports/SkMemory_malloc.cpp -o temp/ports/skmemory_malloc.o
$CXX -I. -c src/ports/SkOSFile_stdio.cpp -o temp/ports/skosfile_stdio.o
$CXX -I. -c src/ports/SkOSFile_posix.cpp -o temp/ports/skosfile_posix.o
$CXX -I. -c src/ports/SkGlobalInitialization_default.cpp -o temp/ports/skglobalinitialization_default.o
$AR rcs temp/ports/libports.a \
temp/ports/skdebug_stdio.o \
temp/ports/skmemory_malloc.o \
temp/ports/skosfile_stdio.o \
temp/ports/skosfile_posix.o \
temp/ports/skglobalinitialization_default.o
}
function buildUtils() {
mkdir -p temp/utils/
$CXX -I. -c src/utils/SkEventTracer.cpp -o temp/utils/skeventtracer.o
$CXX -I. -c src/utils/SkMatrix22.cpp -o temp/utils/skmatrix22.o
$CXX -I. -c src/utils/SkPatchUtils.cpp -o temp/utils/skpatchutils.o
$CXX -I. -c src/utils/SkCustomTypeface.cpp -o temp/utils/skcustomtypeface.o
$CXX -I. -c src/utils/SkDashPath.cpp -o temp/utils/skdashpath.o
$CXX -I. -c src/utils/SkShadowUtils.cpp -o temp/utils/shshadowutils.o
$CXX -I. -c src/utils/SkShadowTessellator.cpp -o temp/utils/skshadowtessellator.o
$CXX -I. -c src/utils/SkPolyUtils.cpp -o temp/utils/skpolyutils.o
$AR rcs temp/utils/libutils.a \
temp/utils/skeventtracer.o \
temp/utils/skmatrix22.o \
temp/utils/skpatchutils.o \
temp/utils/skcustomtypeface.o \
temp/utils/skdashpath.o \
temp/utils/shshadowutils.o \
temp/utils/skshadowtessellator.o \
temp/utils/skpolyutils.o
}
function buildCodec() {
mkdir -p temp/codec/
$CXX -I. -c src/codec/SkCodec.cpp -o temp/codec/skcodec.o
$CXX -I. -c src/codec/SkSampler.cpp -o temp/codec/sksampler.o
$CXX -I. -c src/codec/SkImageGenerator_FromEncoded.cpp -o temp/codec/skimagegenerator_fromencoded.o
$CXX -I. -c src/codec/SkCodecImageGenerator.cpp -o temp/codec/skcodecimagegenerator.o
$CXX -I. -c src/codec/SkPixmapUtils.cpp -o temp/codec/skpixmaputils.o
$CXX -I. -c src/codec/SkGainmapInfo.cpp -o temp/codec/skgainmapinfo.o
$AR rcs temp/codec/libcodec.a \
temp/codec/skcodec.o \
temp/codec/sksampler.o \
temp/codec/skimagegenerator_fromencoded.o \
temp/codec/skcodecimagegenerator.o \
temp/codec/skpixmaputils.o \
temp/codec/skgainmapinfo.o
}
function buildEncode() {
local objfiles=""
mkdir -p temp/encode/
$CXX -I. -c src/encode/SkPngEncoderBase.cpp -o temp/encode/skpngencoderbase.o
$CXX -I. -c src/encode/SkPngEncoderImpl.cpp -o temp/encode/skpngencoderimpl.o -I$LIBPNG_INCLUDE
$CXX -I. -c src/encode/SkICC.cpp -o temp/encode/skicc.o
$CXX -I. -c src/encode/SkEncoder.cpp -o temp/encode/skencoder.o
$AR rcs temp/encode/libencode.a \
temp/encode/skpngencoderbase.o \
temp/encode/skpngencoderimpl.o \
temp/encode/skicc.o \
temp/encode/skencoder.o
}
buildBase
buildSkcms
buildCore
buildSksl
buildImage
buildShaders
buildEffects
buildText
buildPorts
buildUtils
buildCodec
buildEncode
$CXX -I. \
-L$ZLIB_LIB -lz \
-L$LIBPNG_LIB -lpng \
-Ltemp/base -lbase \
-Ltemp/skcms -lskcms \
-Ltemp/core -lcore \
-Ltemp/sksl -lsksl \
-Ltemp/image -limage \
-Ltemp/shaders -lshaders \
-Ltemp/effects -leffects \
-Ltemp/ports -lports \
-Ltemp/utils -lutils \
-Ltemp/codec -lcodec \
-Ltemp/text -ltext \
-Ltemp/encode -lencode \
main.cpp -o main
#include <iostream>
#include <fstream>
#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkData.h"
#include "include/encode/SkPngEncoder.h"
int main() {
SkImageInfo info = SkImageInfo::Make(1920, 1080, kBGRA_8888_SkColorType,
kUnpremul_SkAlphaType);
sk_sp<SkSurface> surface = SkSurfaces::Raster(info);
SkCanvas *canvas = surface->getCanvas();
canvas->clear(SK_ColorRED);
sk_sp<SkImage> image = surface->makeImageSnapshot();
sk_sp<SkData> data =
SkPngEncoder::Encode(nullptr, image.get(), SkPngEncoder::Options());
std::ofstream out("output.png", std::ios::out | std::ios::binary);
if (out) {
out.write(reinterpret_cast<const char *>(data->data()), data->size());
out.close();
} else {
std::cerr << "Failed to open file for writing\n";
return 1;
}
std::cout << "output.png saved";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment