Helix Core is now P4. Product user interfaces will be updated soon. Learn more >>

P4 API for Go Documentation | 2025.2

# Set up P4 API for Go on Windows

This guide outlines how to set up P4 API for Go 2025.2 on a Windows machine. While there are several approaches to installing P4 API for Go, the steps involved in this guide ensure compatibility between all the apps involved.

- Prerequisites

- Run P4 API for Go

## Prerequisites

Get the following apps and archives before installing P4 API for Go:

- Go language

- Download MSYS2 MINGW64

- Download P4 API for C/C++

- Build OpenSSL libraries

- Download P4 API for Go

- Configure build flags

- (Optional) Check all apps are present and the correct version

### Go language

Install Go version 1.24 or later.

1. Download Go 1.24 or later from the Go website.

2. Using the downloaded archive or installer, run through the steps to install Go.

3. To check if Go has been installed successfullu enter the following into a command line:

       go version

   You should see the following output:

       go version go1.25.1 windows/amd64

### Download MSYS2 MINGW64

Use the MSYS2 MINGW64 terminal for building the P4 API for Go on Windows. This provides a complete environment with all the necessary tools, including the GCC compiler used by MinGW64 and support for CGO (which allows Go to interact with C/C++ libraries).

Building everything, such as OpenSSL, the P4 API for C/C++, and your Go program, using MinG64 ensures compatibility and avoids linker errors that can occur when mixing different compilers.

This guide uses MinGW-w64 exclusively to build the required OpenSSL libraries and compile the final executable to test P4 API for Go.

1. Download the MSYS2 installer from the MSYS2 website.

2. When installing MSYS2, make a note of where you are installing it. For example: `C:\msys64`

3. After installation, go to the Start Menu and open MSYS2 MINGW64. We recommend running the terminal as Administrator.

4. To update the MINGW64 packages, enter:

       pacman -Syu

5. To get the MINGW64 GCC compiler, enter:

       pacman -S mingw-w64-x86_64-gcc

6. To check the GCC compiler has been installed correctly, enter:

       gcc --version

   You should see the following output:

       gcc.exe (Rev8, Built by MSYS2 project) 15.2.0

7. (Optional) To check that Go can run in MINGW64, enter:

       go version

   You should see the following output:

       go version go1.25.1 windows/amd64

### Download P4 API for C/C++

Download the P4 API for C/C++ archive directly from the Perforce portal.

It is important to ensure that the version you download matches:

- Your system architecture (e.g., 64-bit).

- Your GCC compiler (MINGW64).

- The OpenSSL libraries you will build later.

Find your compatible version of P4 API for C/C++ by looking at the filename:

`p4api-openssl<SSLVER>-<GCCVER>-<THREAD>_<EH>.zip`

Where:

- `<SSLVER>` = OpenSSL version

- `<GCCVER>` = GCC version

- `<THREAD>` = `win32` or `posix`

- `<EH>` = `seh` or `sjlj`

This means Windows with OpenSSL 3 ,GCC version 8, `Win 32` and `seh` exception handling , requires the following P4 API for C/C++ version: `p4api-openssl3_gcc8_win32_seh.zip`.

The version of P4 API for C/C++ used in the examples in this guide is `p4api-openssl3_gcc8_win32_seh.zip`.

Another example, Windows with OpenSSL 3 ,GCC version 8, `posix` and `sjlj` exception handling , requires the following P4 API for C/C++ version: `p4api-openssl3_gcc8_posix_sjlj.zip`.

Additionally, the P4 API for Go version must match the P4 API for C/C++ version to ensure compatibility and avoid build or runtime errors. In this guide, the version of P4 API for Go being installed is `2025.1`. This means you must download P4 API for C/C++ found in the `r25.1` folder.

The following steps outline how to get P4 API for C/C++ from the Perforce portal.

1. Go to Perforce archive.

2. Go to `r25.1`. This matches the version of P4 API for Go we are installing.

3. Go to `bin.mingw64x64`. This contains the 64-bit binaries built for MinGW-w64.

4. Download `p4api-openssl3_gcc8_win32_seh.zip`.

   This version of P4 API for C/C++ is built for 64-bit MinGW-w64 using at least GCC 8, supports OpenSSL 3.x, and uses `seh` exception handling, all of which are compatible with your MSYS2 MINGW64 environment and Go.

   If you download a different version of P4 API for C/C++, it will not be compatible with the MINGW64 compiler

5. After downloading `p4api-openssl3_win32_posix_seh.zip`, extract the files.

6. Move the folder to a known location, for example, `C:\p4api`

7. Ensure that all files and subfolders are placed directly inside the `C:\p4api` directory and not inside an additional subfolder created during extraction. For example, the path to the subfolder `lib`:

   1. `C:\p4api\lib` is correct.

   2. `C:\p4api\p4api-2025.1.2810567\lib` is wrong.

### Build OpenSSL libraries

OpenSSL libraries are required because P4Go relies on secure communication with the P4 Server using SSL/TLS. These libraries provide the cryptographic functions and protocols required for that secure connection. Without them, P4 API for Go won’t be able to authenticate or transmit data securely.

Once built, you need to copy the OpenSSL DLLs (in this case `libssl-3-x64.dll` and `libcrypto-3-x64.dll`) to the same folder as your future Go executable to ensure Windows can locate and load them at runtime. Without this step, your application may fail to start due to missing dependencies, and encrypted connections will not be possible.

To build the required OpenSSL libraries:

1. Open MSYS2 MINGW64 as an administrator.

2. Install the required packages to build the OpenSSL libraries. To get these packages, enter:

       pacman -S --needed base-devel mingw-w64-x86_64-toolchain perl

3. Use the MINGW64 terminal to download and extract OpenSSL:

       wget https://www.openssl.org/source/openssl-3.5.2.tar.gz
       tar -xvzf openssl-3.5.2.tar.gz
       cd openssl-3.5.2

   This navigates you to the `openssl-3.5.2 folder`.

4. To configure OpenSSL for MINGW64, run the following command:

       ./Configure mingw64 shared --prefix=/mingw64/openssl-3.5.2

   This sets up OpenSSL to build 64-bit shared libraries (DLLs) using GCC, and installs them to `/mingw64/openssl-3.5.2`.

   You will see the following when the process is complete.

5. To compile and install the libraries, run the following:

       make -j$(nproc)
       make install

   This builds OpenSSL libraries using all CPU cores and installs the headers, libraries, and DLLs to the specified folder (`openssl-3.5.2 folder`).

   This step may take between 5 and 30 minutes.

6. To check that the libraries and headers were installed correctly (specifically `libssl-3-x64.dll` and `libcrypto-3-x64.dll`), enter:

       ls /mingw64/openssl-3.5.2/bin/lib{ssl,crypto}-3-*.dll

   If the files are present, you should see the following output:

       /mingw64/openssl-3.5.2/bin/libcrypto-3-x64.dll
       /mingw64/openssl-3.5.2/bin/libssl-3-x64.dll

### Download P4 API for Go

Download P4 API for Go from either:

- The Perforce website

- GitHub

If you are following the steps for installing P4 API for Go with this guide, you must use git to install P4 API for Go. This is to ensure compatibility with the other apps.

To download P4 API for Go from GitHub:

1. Open MSYS2 MINGW64 as an administrator.

2. Enter `git clone https://github.com/perforce/p4go.git /c/p4go`

This will download and extract P4 API for Go to a folder called `p4go`.

### Configure build flags

Before building P4 API for Go, you need to configure environment variables so Go can locate and link the required headers and libraries. These build flags are as follows:

    go env -w CGO_ENABLED=1
    go env -w CGO_CPPFLAGS="-I<absolute path to P4 API for C++>/include -DOS_NT -g"
    go env -w CGO_LDFLAGS="-L<absolute path to P4 API for C++>/lib -L<OpenSSLPath> -lp4api -lssl -lcrypto -lcrypt32 -lws2_32  -lole32 -lshell32 -luser32 -ladvapi32 -lole32 -pthread -v"

When configuring the build flags, replace:

- `<absolute path to P4 API for C++>` with the absolute path to the P4 API for C/C++

- `<OpenSSLPath>` with the absolute path to OpenSSL libraries matching the OpenSSL version used to build the P4 API for C/C++

For the example in this guide, run the following the configure the build flags:

    go env -w CGO_ENABLED=1
    go env -w CGO_CPPFLAGS="-IC:/p4api/include -DOS_NT -g"
    go env -w CGO_LDFLAGS="-LC:/p4api/lib -LC:/msys64/mingw64/openssl-3.5.2/lib -lp4api -lssl -lcrypto -lcrypt32 -lws2_32 -lole32 -lshell32 -luser32 -ladvapi32 -pthread -v"

These flags do the following:

- `CGO_ENABLED=1`: Enables CGO, allowing Go to call C/C++ code.

- `CGO_CPPFLAGS`: Points to the P4 API for C/C++ headers and defines platform-specific flags.

- `CGO_LDFLAGS`: Links against the P4 API for C/C++ and OpenSSL libraries, plus required Windows system libraries.

This setup ensures your Go build process can correctly compile and link against the Perforce and OpenSSL components.

Check that build flags have been configured by entering the following:

    go env CGO_ENABLED
    go env CGO_CPPFLAGS
    go env CGO_LDFLAGS

If the flags are configured correctly, you will see the following:

    1
    -IC:/p4api/include -DOS_NT -g
    -LC:/p4api/lib -L/c/msys64/mingw64/openssl-3.5.2/lib -lp4api -lssl -lcrypto -lcrypt32 -lws2_32 -lole32 -lshell32 -luser32 -ladvapi32 -pthread -v

When setting `CGO_CPPFLAGS` and `CGO_LDFLAGS`, Go may normalize `/c/...` paths into `C:/...`. This is expected in MSYS2 MINGW64 and does not affect the build as long as the directories exist.

### (Optional) Check all apps are present and the correct version

Go to Shell script to check P4 API for Go prerequisites and copy the code into a new shell script. Save the script with a clear name, such as c`heck_p4go_env.sh`, and run it using MINGW64.

Below is an example of the expected output if everything is configured correctly:

Copy

    === P4Go Environment Check ===
    [Go]
      Expected: >= 1.24
      Found:    1.25.1
      Result:   PASS

    [GCC]
      Expected: >= 8.0 (GCC 15.2 is compatible)
      Found:    15.2.0
      Result:   PASS

    [OpenSSL]
      Expected directory: /mingw64/openssl-3.5.2
      Found directory:    /mingw64/openssl-3.5.2
      DLLs found:         libssl-3-x64.dll, libcrypto-3-x64.dll
      Result:             PASS

    [P4API]
      Expected: /c/p4api/include/p4/clientapi.h and /c/p4api/lib
      Found:    P4API headers and lib folder
      Result:   PASS

    [P4Go]
      Expected: /c/p4go
      Found:    /c/p4go
      Result:   PASS

    [CGO Environment Flags]
      CGO_ENABLED:
        Expected: 1
        Found:    1
        Result:   PASS
      CGO_CPPFLAGS:
        Expected: -IC:/p4api/include -DOS_NT -g
        Found:    -IC:/p4api/include -DOS_NT -g
        Result:   PASS
      CGO_LDFLAGS:
        Expected: -LC:/p4api/lib -LC:/msys64/mingw64/openssl-3.5.2/lib -lp4api -lssl -lcrypto -lcrypt32 -lws2_32 -lole32 -lshell32 -luser32 -ladvapi32 -pthread -v
        Found:    -LC:/p4api/lib -LC:/msys64/mingw64/openssl-3.5.2/lib -lp4api -lssl -lcrypto -lcrypt32 -lws2_32 -lole32 -lshell32 -luser32 -ladvapi32 -pthread -v
        Result:   PASS

    === Check Complete ===

## Run P4 API for Go

With everything in place, create a test folder and a simple Go script to connect to a P4 Server.

1. Create a test folder, for example, `C:\p4test`

2. Create a file called `main.go`. Add the following Go script to this file:

   Copy

       package main

       import (
           "fmt"
           "log"

           "github.com/perforce/p4go"
       )

       func main() {
           client := p4.New()

           client.SetPort("perforce:1234")  // Update with your P4 server address
           client.SetUser("user.name")      // Update withusername for the Perforce connection
           client.SetPassword("password")   // Update with password for authentication
           client.SetClient("workspace")    // Update with the workspace name

           if ok, err := client.Connect(); err != nil || !ok {
               log.Fatalf("Connection failed: %v", err)
           }
           defer client.Disconnect()

           result, err := client.Run("info")
           if err != nil {
               log.Fatalf("Failed to run 'p4 info': %v", err)
           }

           fmt.Println("P4Go is working. 'p4 info' output:")
           for _, r := range result {
               fmt.Println(r)
           }
       }

3. Initialize the Go module:

   `go mod init p4test`

4. Add the P4Go dependency:

   `go get github.com/perforce/p4go`

5. Tidy up the module to ensure all dependencies are resolved:

   `go mod tidy`

6. Build the script:

   `go build -o p4test.exe main.go`

   You may see the following build error: `warning: 'thread' attribute directive ignored [-Wattributes]`

   This comes from `debug.h` in the P4 API for C/C++ headers and is expected when using GCC. It doesn’t affect functionality and can be safely ignored.

7. If the build is successful, you will see a file `p4test.exe` called in `C:\p4test`.

8. Run the script:

   `./p4test.exe`

   This outputs P4 Server information into terminal that starts with the following:

       Wake me up, P4 you go go! P4Go is working!!!
       'p4 info' output:
       map[ServerID:master-1666 allowFetch:2 allowPush:2 a...

P4 API for Go is now set up on your windows machine. You can now rest for eternity.

## Shell script to check P4 API for Go prerequisites

Below is a script that checks your environment before you build P4 API for Go and makes sure everything is the correct version and in place

Save the script with a clear name, such as `check_p4go_env.sh`, add it to a test folder such as `C:\p4test`.

Copy and paste the following into your `check_p4go_env.sh` file.

Copy

    #!/usr/bin/env bash

    echo "=== P4Go Environment Check ==="

    # Expected values
    MIN_GO_VERSION="1.24"
    MIN_GCC_VERSION="8.0"
    EXPECTED_OPENSSL_VERSION="3.5.2"
    EXPECTED_CPPFLAGS='-IC:/p4api/include -DOS_NT -g'
    EXPECTED_LDFLAGS='-LC:/p4api/lib -LC:/msys64/mingw64/openssl-3.5.2/lib -lp4api -lssl -lcrypto -lcrypt32 -lws2_32 -lole32 -lshell32 -luser32 -ladvapi32 -pthread -v'

    # Compare versions
    version_ge() {
        # returns true if $1 >= $2
        [ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]
    }

    # Check Go
    echo "[Go]"
    if command -v go &>/dev/null; then
        GO_VER=$(go version | awk '{print $3}' | sed 's/go//')
        echo "  Expected: >= $MIN_GO_VERSION"
        echo "  Found:    $GO_VER"
        if version_ge "$GO_VER" "$MIN_GO_VERSION"; then
            echo "  Result:   PASS"
        else
            echo "  Result:   FAIL"
        fi
    else
        echo "  Go not found"
        echo "  Result: FAIL"
    fi
    echo

    # Check GCC
    echo "[GCC]"
    if command -v gcc &>/dev/null; then
        GCC_VER=$(gcc -dumpversion)
        echo "  Expected: >= $MIN_GCC_VERSION (GCC 15.2 is compatible)"
        echo "  Found:    $GCC_VER"
        if version_ge "$GCC_VER" "$MIN_GCC_VERSION"; then
            echo "  Result:   PASS"
        else
            echo "  Result:   FAIL"
        fi
    else
        echo "  GCC not found"
        echo "  Result: FAIL"
    fi
    echo

    # Check OpenSSL
    echo "[OpenSSL]"
    OPENSSL_DIR="/mingw64/openssl-${EXPECTED_OPENSSL_VERSION}"
    echo "  Expected directory: $OPENSSL_DIR"
    if [[ -d "$OPENSSL_DIR" ]]; then
        echo "  Found directory:    $OPENSSL_DIR"
        if [[ -f "$OPENSSL_DIR/bin/libssl-3-x64.dll" && -f "$OPENSSL_DIR/bin/libcrypto-3-x64.dll" ]]; then
            echo "  DLLs found:         libssl-3-x64.dll, libcrypto-3-x64.dll"
            echo "  Result:             PASS"
        else
            echo "  DLLs missing"
            echo "  Result:             FAIL"
        fi
    else
        echo "  OpenSSL directory not found"
        echo "  Result: FAIL"
    fi
    echo

    # Check P4API
    echo "[P4API]"
    echo "  Expected: /c/p4api/include/p4/clientapi.h and /c/p4api/lib"
    if [[ -f "/c/p4api/include/p4/clientapi.h" && -d "/c/p4api/lib" ]]; then
        echo "  Found:    P4API headers and lib folder"
        echo "  Result:   PASS"
    else
        echo "  Missing required files or folders in /c/p4api"
        echo "  Result:   FAIL"
    fi
    echo

    # Check P4Go
    echo "[P4Go]"
    echo "  Expected: /c/p4go"
    if [[ -d "/c/p4go" ]]; then
        echo "  Found:    /c/p4go"
        echo "  Result:   PASS"
    else
        echo "  Missing /c/p4go"
        echo "  Result:   FAIL"
    fi
    echo

    # Check CGO flags
    echo "[CGO Environment Flags]"
    ENABLED=$(go env CGO_ENABLED)
    CPPFLAGS=$(go env CGO_CPPFLAGS)
    LDFLAGS=$(go env CGO_LDFLAGS)

    echo "  CGO_ENABLED:"
    echo "    Expected: 1"
    echo "    Found:    $ENABLED"
    [[ "$ENABLED" == "1" ]] && echo "    Result:   PASS" || echo "    Result:   FAIL"

    echo "  CGO_CPPFLAGS:"
    echo "    Expected: $EXPECTED_CPPFLAGS"
    echo "    Found:    $CPPFLAGS"
    [[ "$CPPFLAGS" == "$EXPECTED_CPPFLAGS" ]] && echo "    Result:   PASS" || echo "    Result:   FAIL"

    echo "  CGO_LDFLAGS:"
    echo "    Expected: $EXPECTED_LDFLAGS"
    echo "    Found:    $LDFLAGS"
    [[ "$LDFLAGS" == "$EXPECTED_LDFLAGS" ]] && echo "    Result:   PASS" || echo "    Result:   FAIL"

    echo
    echo "=== Check Complete ==="

Run the script from MSYS2 MINGW64 with the following:

`./check_p4go_env.sh`

Your search for returned results