I'm trying to write a Hello World
repository that takes a standard C
function and exposes it as an internal/built-in function to PHP (and other languages written in C).
[ 27%] Building C object CMakeFiles/carbon_php.dir/bindings/php/carbon_php.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -Dcarbon_php_EXPORTS -I/Users/richardmiles/CLionProjects/OmniLang-C-Template/../php-src/main -I/Users/richardmiles/CLionProjects/OmniLang-C-Template/../php-src/Zend -I/Users/richardmiles/CLionProjects/OmniLang-C-Template/../php-src/TSRM -I/Users/richardmiles/CLionProjects/OmniLang-C-Template/../php-src -I/usr/local/Frameworks/Python.framework/Versions/3.12/include/python3.12 -I/Users/richardmiles/CLionProjects/OmniLang-C-Template/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -fPIC -MD -MT CMakeFiles/carbon_php.dir/bindings/php/carbon_php.c.o -MF CMakeFiles/carbon_php.dir/bindings/php/carbon_php.c.o.d -o CMakeFiles/carbon_php.dir/bindings/php/carbon_php.c.o -c /Users/richardmiles/CLionProjects/OmniLang-C-Template/bindings/php/carbon_php.c
/Users/richardmiles/CLionProjects/OmniLang-C-Template/bindings/php/carbon_php.c:14:55: error: expected expression
PHP_FE(carbon_version, arginfo_carbon_version),
^
/Users/richardmiles/CLionProjects/OmniLang-C-Template/bindings/php/carbon_php.c:15:63: error: expected expression
PHP_FE(carbon_hello_world, arginfo_carbon_hello_world),
^
Looking at this post suggests my usage of PHP_FE
is incorrect, but I've replaced the explicit arg definitions with NULL and still no cigar. I know that these generally should work based on how I have added PHP functions to PHP-SRC in the past, but with this being a separate repository, I'm lost. Chat GPT is going in circles. I'm using Clion
, so I generally think nothing syntax is causing the issue.
I've created the repo under RichardTMiles/OmniLang-C-Template
open source to see the full code; here's a sample.
/src/carbon.c
const char* carbon_version() {
return "CarbonC 1.0.0";
}
const char* helloWorld() {
return "Hello World!";
}
/bindings/php/carbon_php.c
#ifndef CARBON_PHP_H
#define CARBON_PHP_H
#include <php.h>
#include "carbon.h"
PHP_FUNCTION(carbon_version);
PHP_FUNCTION(carbon_hello_world);
extern zend_module_entry carbon_module_entry;
#define phpext_carbon_ptr &carbon_module_entry
ZEND_BEGIN_ARG_INFO(arginfo_carbon_version, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_carbon_hello_world, 0)
ZEND_END_ARG_INFO()
#endif // CARBON_PHP_H
#include "carbon_php.h"
PHP_FUNCTION(carbon_version) {
const char* version = carbon_version();
RETURN_STRING(version);
}
PHP_FUNCTION(carbon_hello_world) {
const char* message = helloWorld();
RETURN_STRING(message);
}
const zend_function_entry carbon_functions[] = {
PHP_FE(carbon_version, arginfo_carbon_version),
PHP_FE(carbon_hello_world, arginfo_carbon_hello_world),
PHP_FE_END
};
zend_module_entry carbon_module_entry = {
STANDARD_MODULE_HEADER,
"carbon", // Extension name
carbon_functions, // Functions
NULL, // MINIT
NULL, // MSHUTDOWN
NULL, // RINIT
NULL, // RSHUTDOWN
NULL, // MINFO
"1.0.0", // Version
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_CARBON
ZEND_GET_MODULE(carbon)
#endif
And finally my CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(OmniLangC VERSION 1.0)
# Core C library
add_library(carbon SHARED src/carbon.c)
target_include_directories(carbon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
# Set the path to your PHP source directory
set(PHP_SRC_DIR "../php-src")
# Allow user to specify PHP_SRC_DIR via environment variable or CMake command line
if (DEFINED ENV{PHP_SRC_DIR})
set(PHP_SRC_DIR $ENV{PHP_SRC_DIR})
endif()
# Add PHP include directories
include_directories(
${PHP_SRC_DIR}/main
${PHP_SRC_DIR}/Zend
${PHP_SRC_DIR}/TSRM
)
# Check if PHP headers are found
if (NOT EXISTS "${PHP_SRC_DIR}/main/php.h" OR NOT EXISTS "${PHP_SRC_DIR}/Zend/zend.h" OR NOT EXISTS "${PHP_SRC_DIR}/TSRM/TSRM.h")
message(FATAL_ERROR "Could not find PHP headers. Please ensure PHP_SRC_DIR is set correctly.")
else()
message(STATUS "Found PHP headers in ${PHP_SRC_DIR}")
endif()
# PHP binding
add_library(carbon_php SHARED bindings/php/carbon_php.c)
target_include_directories(carbon_php PUBLIC ${PHP_SRC_DIR}/main ${PHP_SRC_DIR}/Zend ${PHP_SRC_DIR}/TSRM ${PHP_SRC_DIR})
target_link_libraries(carbon_php carbon)
# Python binding
find_package(PythonInterp REQUIRED)
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
set(CYTHON_PYX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/bindings/python/carbon.pyx)
set(CYTHON_C_FILE ${CMAKE_CURRENT_SOURCE_DIR}/bindings/python/carbon.c)
add_custom_command(
OUTPUT ${CYTHON_C_FILE}
COMMAND cython --cplus -3 ${CYTHON_PYX_FILE} -o ${CYTHON_C_FILE}
DEPENDS ${CYTHON_PYX_FILE}
COMMENT "Generating C source from ${CYTHON_PYX_FILE}"
)
add_library(carbon_python MODULE ${CYTHON_C_FILE})
target_link_libraries(carbon_python ${PYTHON_LIBRARIES} carbon)
target_include_directories(carbon_python PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bindings/python)
# Ruby binding
add_library(carbon_ruby SHARED bindings/ruby/carbon_ruby.c)
target_include_directories(carbon_ruby PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby)
target_link_libraries(carbon_ruby carbon)
# Node.js binding
add_library(carbon_node SHARED bindings/node/carbon_node.cpp)
target_include_directories(carbon_node PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bindings/node)
target_link_libraries(carbon_node carbon)
I've created a README.md in the repo. If you're trying to run it locally, please take a look at that as the setup instructions.
The issue is a syntax error because of a comma after the macro. Also, see the documentation for more examples.
Change this section of code:
const zend_function_entry carbon_functions[] = {
PHP_FE(carbon_version, arginfo_carbon_version),
PHP_FE(carbon_hello_world, arginfo_carbon_hello_world),
PHP_FE_END
};
To:
const zend_function_entry carbon_functions[] = {
PHP_FE(carbon_version, arginfo_carbon_version)
PHP_FE(carbon_hello_world, arginfo_carbon_hello_world)
PHP_FE_END
};