func buildFn()

in cmd/cpp/functions_framework/main.go [120:201]


func buildFn(ctx *gcp.Context) error {
	vcpkgPath, err := installVcpkg(ctx)
	if err != nil {
		return err
	}

	vcpkgCache, err := ctx.Layer(vcpkgCacheLayerName, gcp.BuildLayer, gcp.CacheLayer)
	if err != nil {
		return fmt.Errorf("creating %v layer: %w", vcpkgCacheLayerName, err)
	}

	mainLayer, err := ctx.Layer(mainLayerName)
	if err != nil {
		return fmt.Errorf("creating %v layer: %w", mainLayerName, err)
	}
	if err := ctx.SetFunctionsEnvVars(mainLayer); err != nil {
		return err
	}

	buildLayer, err := ctx.Layer(buildLayerName, gcp.BuildLayer, gcp.CacheLayer)
	if err != nil {
		return fmt.Errorf("creating %v layer: %w", buildLayerName, err)
	}

	fn := extractFnInfo(os.Getenv(env.FunctionTarget), os.Getenv(env.FunctionSignatureType))
	if err := createMainCppFile(ctx, fn, filepath.Join(mainLayer.Path, "main.cc")); err != nil {
		return err
	}
	if err := createMainCppSupportFiles(ctx, mainLayer.Path, ctx.BuildpackRoot()); err != nil {
		return err
	}

	installLayer, err := ctx.Layer(installLayerName, gcp.LaunchLayer)
	if err != nil {
		return fmt.Errorf("creating %v layer: %w", installLayerName, err)
	}

	vcpkgExePath := filepath.Join(vcpkgPath, "vcpkg")
	cmakeExePath, err := getToolPath(ctx, vcpkgExePath, "cmake")
	if err != nil {
		return err
	}
	ninjaExePath, err := getToolPath(ctx, vcpkgExePath, "ninja")
	if err != nil {
		return err
	}

	// vcpkg is not retrying downloads at this time. Do that manually.
	for i := 1; i < 32; i *= 2 {
		if err := warmupVcpkg(ctx, vcpkgExePath); err == nil {
			break
		}
		ctx.Logf("Downloading basic dependencies failed [%v], retrying in %d seconds...", err, i)
		time.Sleep(time.Duration(i) * time.Second)
	}

	args := []string{
		cmakeExePath,
		"-GNinja",
		"-DMAKE_BUILD_TYPE=Release",
		"-DCMAKE_CXX_COMPILER=g++-8",
		"-DCMAKE_C_COMPILER=gcc-8",
		fmt.Sprintf("-DCMAKE_MAKE_PROGRAM=%s", ninjaExePath),
		"-S", mainLayer.Path,
		"-B", buildLayer.Path,
		fmt.Sprintf("-DCNB_APP_DIR=%s", ctx.ApplicationRoot()),
		fmt.Sprintf("-DCMAKE_INSTALL_PREFIX=%s", installLayer.Path),
		fmt.Sprintf("-DVCPKG_TARGET_TRIPLET=%s", vcpkgTripletName),
		fmt.Sprintf("-DCMAKE_TOOLCHAIN_FILE=%s/scripts/buildsystems/vcpkg.cmake", vcpkgPath),
	}
	if _, err := ctx.Exec(args, gcp.WithUserAttribution, gcp.WithEnv(
		fmt.Sprintf("VCPKG_DEFAULT_BINARY_CACHE=%s", vcpkgCache.Path),
		fmt.Sprintf("VCPKG_DEFAULT_HOST_TRIPLET=%s", vcpkgTripletName))); err != nil {
		return err
	}
	if _, err := ctx.Exec([]string{cmakeExePath, "--build", buildLayer.Path, "--target", "install"}, gcp.WithUserAttribution); err != nil {
		return err
	}

	ctx.AddWebProcess([]string{filepath.Join(installLayer.Path, "bin", "function")})
	return nil
}