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
}