How to Cross-Compile Go Applications for ARM64 with CGO_ENABLED=1
Introduction If you're developing Go applications and want to run them on ARM64 architecture, especially within environments like AWS Lambda, cross-compiling can be a bit tricky, particularly when you involve CGO. In this guide, I'll walk you through the process of cross-compiling your Go application with CGO_ENABLED=1, targeting ARM64 architecture from an AMD64 Jenkins agent. Understanding the Need for Cross-Compilation Cross-compiling is essential when you're developing applications on a different architecture than the one they're intended to run on. For instance, you might be developing on an AMD64 system (like most PCs) but want your application to run on an ARM64 architecture, such as AWS Lambda functions. Using CGO_ENABLED=1 specifies that you want to enable CGO, which allows Go to call C libraries. This is particularly useful if your application relies on native libraries, like the libpcsclite.so.1 shared library we mentioned in the context of AWS. Installing and Setting Up Required Libraries In your situation, you had previously encountered runtime errors due to missing shared libraries in AWS Lambda. You solved these errors by installing the necessary libraries and copying them into the execution environment. The steps you followed were: cp /usr/lib64/libpcsclite.so.1 ./lib/ cp /usr/lib64/libpcsclite.so.* ./lib/ These steps are crucial to ensure that the Go application has all the dependencies it needs when executed. However, for cross-compilation with CGO support, you need to ensure that your environment is appropriately set up. Step-by-Step Guide to Cross-Compile for ARM64 Step 1: Install the ARM64 Cross-Compiler To cross-compile for ARM64, you will need an ARM64 cross-compiler on your system. You can install the required tools on your AMD64 system using the following command, depending on your OS: For Debian/Ubuntu: sudo apt-get install gcc-aarch64-linux-gnu For Red Hat/CentOS: sudo yum install gcc-aarch64-linux-gnu Step 2: Setting Up Your Environment Variables When building your application, you'll want to set a couple of environment variables to point to the ARM64 cross-compiler. You can do this in your Jenkins pipeline script or directly in your shell: export CGO_ENABLED=1 export GOARCH=arm64 export CC=aarch64-linux-gnu-gcc Setting CGO_ENABLED=1 allows Go to use CGO, GOARCH=arm64 specifies that we are compiling for the ARM architecture, and CC is set to use the ARM64 cross-compiler we installed previously. Step 3: Building Your Go Application Once your environment is configured, you can build your Go application using the following command: go build -o your-application-name This command will create a binary that is compatible with the ARM64 architecture. Ensure that your application code handles the necessary imports for any C libraries appropriately. Step 4: Testing Your Binary To ensure that your binary works on ARM64, transfer it to an ARM64 device or use a suitable emulator. If you're using AWS Lambda, ensure that you upload your application along with the dependent libraries you manually copied earlier. Frequently Asked Questions What if I encounter "undefined references" during build? Ensure that you have installed all the necessary C libraries your Go application depends on in the environment where the application will run. Can I automate the compilation process in Jenkins? Yes, you can set up a Jenkins pipeline that executes these commands and builds your Go application automatically on each push or trigger. Why is CGO_ENABLED=1 necessary for my application? If your Go application is dependent on C libraries, enabling CGO is crucial to include those dependencies during compilation, ensuring that everything works as intended at runtime. Conclusion Cross-compiling a Go application with CGO_ENABLED=1 for ARM64 architecture can appear daunting. However, by following the steps outlined above—installing the required cross-compiler, setting environment variables, and building your application—you can successfully achieve this from an AMD64 Jenkins agent. Make sure to test your application in the intended environment, and don't forget to package any dependent libraries to avoid runtime issues like the one you experienced earlier. Happy coding!

Introduction
If you're developing Go applications and want to run them on ARM64 architecture, especially within environments like AWS Lambda, cross-compiling can be a bit tricky, particularly when you involve CGO. In this guide, I'll walk you through the process of cross-compiling your Go application with CGO_ENABLED=1
, targeting ARM64 architecture from an AMD64 Jenkins agent.
Understanding the Need for Cross-Compilation
Cross-compiling is essential when you're developing applications on a different architecture than the one they're intended to run on. For instance, you might be developing on an AMD64 system (like most PCs) but want your application to run on an ARM64 architecture, such as AWS Lambda functions. Using CGO_ENABLED=1
specifies that you want to enable CGO, which allows Go to call C libraries. This is particularly useful if your application relies on native libraries, like the libpcsclite.so.1
shared library we mentioned in the context of AWS.
Installing and Setting Up Required Libraries
In your situation, you had previously encountered runtime errors due to missing shared libraries in AWS Lambda. You solved these errors by installing the necessary libraries and copying them into the execution environment. The steps you followed were:
cp /usr/lib64/libpcsclite.so.1 ./lib/
cp /usr/lib64/libpcsclite.so.* ./lib/
These steps are crucial to ensure that the Go application has all the dependencies it needs when executed. However, for cross-compilation with CGO support, you need to ensure that your environment is appropriately set up.
Step-by-Step Guide to Cross-Compile for ARM64
Step 1: Install the ARM64 Cross-Compiler
To cross-compile for ARM64, you will need an ARM64 cross-compiler on your system. You can install the required tools on your AMD64 system using the following command, depending on your OS:
For Debian/Ubuntu:
sudo apt-get install gcc-aarch64-linux-gnu
For Red Hat/CentOS:
sudo yum install gcc-aarch64-linux-gnu
Step 2: Setting Up Your Environment Variables
When building your application, you'll want to set a couple of environment variables to point to the ARM64 cross-compiler. You can do this in your Jenkins pipeline script or directly in your shell:
export CGO_ENABLED=1
export GOARCH=arm64
export CC=aarch64-linux-gnu-gcc
Setting CGO_ENABLED=1
allows Go to use CGO, GOARCH=arm64
specifies that we are compiling for the ARM architecture, and CC
is set to use the ARM64 cross-compiler we installed previously.
Step 3: Building Your Go Application
Once your environment is configured, you can build your Go application using the following command:
go build -o your-application-name
This command will create a binary that is compatible with the ARM64 architecture. Ensure that your application code handles the necessary imports for any C libraries appropriately.
Step 4: Testing Your Binary
To ensure that your binary works on ARM64, transfer it to an ARM64 device or use a suitable emulator. If you're using AWS Lambda, ensure that you upload your application along with the dependent libraries you manually copied earlier.
Frequently Asked Questions
What if I encounter "undefined references" during build?
Ensure that you have installed all the necessary C libraries your Go application depends on in the environment where the application will run.
Can I automate the compilation process in Jenkins?
Yes, you can set up a Jenkins pipeline that executes these commands and builds your Go application automatically on each push or trigger.
Why is CGO_ENABLED=1
necessary for my application?
If your Go application is dependent on C libraries, enabling CGO is crucial to include those dependencies during compilation, ensuring that everything works as intended at runtime.
Conclusion
Cross-compiling a Go application with CGO_ENABLED=1
for ARM64 architecture can appear daunting. However, by following the steps outlined above—installing the required cross-compiler, setting environment variables, and building your application—you can successfully achieve this from an AMD64 Jenkins agent. Make sure to test your application in the intended environment, and don't forget to package any dependent libraries to avoid runtime issues like the one you experienced earlier. Happy coding!