Installing and Compiling Native GCC 13 C Shared Libraries (.so) on CentOS Stream 9 for Custom PHP FFI Integrations
Prerequisites and Environment Setup
This guide assumes a CentOS Stream 9 minimal installation. We’ll need development tools, specifically the GCC compiler and its associated libraries, to build GCC 13 from source. The PHP FFI (Foreign Function Interface) extension requires compiled shared libraries (.so files) to interact with C code. This process involves not just compiling GCC itself but also ensuring the necessary headers and libraries are available for subsequent custom C library development.
First, update your system and install essential development packages:
sudo dnf update -y sudo dnf groupinstall "Development Tools" -y sudo dnf install -y ncurses-devel gmp-devel mpfr-devel libmpc-devel texinfo
The ncurses-devel, gmp-devel, mpfr-devel, and libmpc-devel packages are crucial build dependencies for GCC. texinfo is needed for documentation generation, which is often a part of the GCC build process.
Downloading and Extracting GCC 13 Source
We will download the GCC 13.2.0 release. It’s good practice to create a dedicated directory for source code compilation.
mkdir ~/gcc-build cd ~/gcc-build wget https://ftp.gnu.org/gnu/gcc/gcc-13.2.0/gcc-13.2.0.tar.gz tar -xf gcc-13.2.0.tar.gz
Next, we need to download the prerequisites for GCC. This includes libraries like GMP, MPFR, and MPC, which GCC itself depends on.
cd gcc-13.2.0 ./contrib/download_prerequisites
This script will download and place the necessary library sources into the gcc-13.2.0/ directory, ensuring they are available for the build process.
Configuring and Compiling GCC 13
It’s highly recommended to build GCC in a separate directory from the source tree to keep the source clean and facilitate easier management. We’ll configure GCC to build as a C compiler and install it to a custom location to avoid conflicts with the system’s default GCC.
cd .. mkdir gcc-13.2.0-build cd gcc-13.2.0-build ../gcc-13.2.0/configure --prefix=/opt/gcc-13.2.0 --enable-languages=c --disable-multilib --program-suffix=-13.2.0
Let’s break down the configure options:
--prefix=/opt/gcc-13.2.0: Specifies the installation directory. This keeps our custom GCC isolated.--enable-languages=c: Instructs GCC to build only the C compiler. This is sufficient for our FFI needs and speeds up the build.--disable-multilib: Simplifies the build by not generating libraries for multiple architectures (e.g., 32-bit and 64-bit on the same system). For most modern server environments targeting 64-bit, this is appropriate.--program-suffix=-13.2.0: Appends a suffix to the compiler executables (e.g.,gcc-13.2.0,g++-13.2.0). This is crucial for distinguishing it from the system’s default GCC.
Now, compile GCC. This step can take a significant amount of time, depending on your server’s CPU and RAM. We’ll use make -j$(nproc) to leverage all available CPU cores for faster compilation.
make -j$(nproc) sudo make install
The make install command will place the GCC executables, libraries, and headers into the /opt/gcc-13.2.0 directory.
Setting up the Environment for Custom C Libraries
To compile custom C shared libraries that can be used with PHP FFI, we need to ensure our system knows where to find the newly installed GCC 13 headers and libraries. We also need to tell the linker where to find shared libraries at runtime.
First, let’s add the GCC 13 binaries to our PATH. This is useful for direct compilation of C files using the new GCC.
echo 'export PATH="/opt/gcc-13.2.0/bin:$PATH"' | sudo tee /etc/profile.d/gcc-13.2.0.sh
To make this change effective immediately in your current session, source the file:
source /etc/profile.d/gcc-13.2.0.sh
Verify the GCC version:
gcc-13.2.0 --version
Next, we need to configure the dynamic linker to find the shared libraries installed by our custom GCC. This is done by adding the GCC’s library path to /etc/ld.so.conf.d/.
echo "/opt/gcc-13.2.0/lib64" | sudo tee /etc/ld.so.conf.d/gcc-13.2.0.conf sudo ldconfig
The ldconfig command updates the linker cache, making the newly installed shared libraries discoverable.
Compiling a Sample C Shared Library
Let’s create a simple C function and compile it into a shared library. This will serve as a test case for our FFI integration.
Create a file named libmymath.c with the following content:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
void greet(const char* name) {
printf("Hello, %s!\n", name);
}
Now, compile this C code into a shared library using our custom GCC 13. We need to specify the output format as a shared object (-shared) and use the position-independent code flag (-fPIC).
gcc-13.2.0 -shared -fPIC libmymath.c -o libmymath.so
This command will produce libmymath.so in the current directory. For PHP FFI to load this library, it needs to be in a location discoverable by the system’s dynamic linker, or its path must be explicitly provided.
PHP FFI Integration and Testing
Ensure the PHP FFI extension is enabled. On CentOS Stream 9, you might need to install it:
sudo dnf install -y php-ffi
Now, create a PHP script (e.g., test_ffi.php) to load and use our compiled C library. For simplicity, we’ll place libmymath.so in the same directory as the PHP script and use the FFI::load() method with an explicit path.
<?php
// Define the C library structure and function signatures
// This is crucial for FFI to know how to call the C functions.
$ffi = FFI::load(__DIR__ . '/libmymath.so');
// Define the C types that will be used in the function signatures
$ffi->cdef("
int add(int a, int b);
void greet(const char* name);
");
// Call the C functions
$result = $ffi->add(10, 20);
echo "Result of add(10, 20): " . $result . "\n";
$ffi->greet("World");
?>
Execute the PHP script:
php test_ffi.php
The expected output should be:
Result of add(10, 20): 30 Hello, World!
This successful execution confirms that GCC 13 has been correctly compiled and installed, and that a custom C shared library can be built and integrated with PHP using the FFI extension on CentOS Stream 9.
Leave a Reply
You must be logged in to post a comment.