ZTS Support: Error while building protobuf.c: tsrm_ls undeclared
avengerx opened this issue · 2 comments
I'm using gentoo linux on a fresh updated version of PHP (didn't have PDO support which I needed for something else).
$ php --version
PHP 5.6.24-pl0-gentoo (cli) (built: Aug 9 2016 01:50:45)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
During make
, I am getting:
libtool: compile: cc -I. -I/home/avenger/whatsapi/php-protobuf -DPHP_ATOM_INC -I/home/avenger/whatsapi/php-protobuf/include -I/home/avenger/whatsapi/php-protobuf/main -I/home/avenger/whatsapi/php-protobuf -I/usr/lib64/php5.6/include/php -I/usr/lib64/php5.6/include/php/main -I/usr/lib64/php5.6/include/php/TSRM -I/usr/lib64/php5.6/include/php/Zend -I/usr/lib64/php5.6/include/php/ext -I/usr/lib64/php5.6/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /home/avenger/whatsapi/php-protobuf/protobuf.c -fPIC -DPIC -o .libs/protobuf.o
In file included from /usr/lib64/php5.6/include/php/Zend/zend_alloc.h:27:0,
from /usr/lib64/php5.6/include/php/Zend/zend.h:252,
from /usr/lib64/php5.6/include/php/main/php.h:35,
from /home/avenger/whatsapi/php-protobuf/protobuf.c:1:
/home/avenger/whatsapi/php-protobuf/protobuf.c: In function ‘pb_assign_value’:
/usr/lib64/php5.6/include/php/Zend/../TSRM/TSRM.h:167:18: error: ‘tsrm_ls’ undeclared (first use in this function)
#define TSRMLS_C tsrm_ls
^
/usr/lib64/php5.6/include/php/Zend/../TSRM/TSRM.h:168:21: note: in expansion of macro ‘TSRMLS_C’
#define TSRMLS_CC , TSRMLS_C
^
/home/avenger/whatsapi/php-protobuf/protobuf.c:24:34: note: in expansion of macro ‘TSRMLS_CC’
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s: compile error - " #message, Z_OBJCE_P(this)->name, __VA_ARGS__)
^
What I could find about this missing tsrm_ls
is related to PHP with ZTS (zend threads security) enabled and seems that a different approach must be taken while building extensions to PHP using it. To enable ZTS on php, the --enable-maintainer-zts
flag should be used.
PHP manual page for this setting: http://php.net/manual/en/internals2.buildsys.environment.php
I'm not sure which gentoo USE
flag enabled this in my PHP set up, but I could successfully build and install other extension (https://github.com/mgp25/curve25519-php) with no problem.
I could find some projects that required slight changes in the source files in order to be able to. To name some: phpredis/phpredis#193 and libgeos/geos#9.
I'll try to investigate more on this (for a solution) when I have more time but, if the investigation above helps someone willing to jump in, please don't hesitate!
This seems to be the best documentation (linked from libgeos/geos#9) on how to handle this issue. But as I am not really experienced in building and developing PHP extensions, and I also not familiar to the php-protobuf source code, it might take a lot to me to figure out & fix where it hurts, but may be just easy for someone acquainted with the project. :)
Hello! I'm too lazy to create a pull request so I release my fix in open domain here:
diff --git a/protobuf.c b/protobuf.c
index 0bf18b5..21a8deb 100644
--- a/protobuf.c
+++ b/protobuf.c
@@ -58,7 +58,7 @@ enum
zend_class_entry *pb_entry;
-static int pb_assign_value(zval *this, zval *dst, zval *src, uint32_t field_number);
+static int pb_assign_value(zval *this, zval *dst, zval *src, uint32_t field_number TSRMLS_DC);
static int pb_print_field_value(zval **value, long level, zend_bool only_set);
static int pb_dump_field_value(zval **value, long level, zend_bool only_set);
static int pb_print_debug_field_value(zval **value, long level);
@@ -70,9 +70,9 @@ static int pb_get_wire_type(int field_type);
static const char *pb_get_wire_type_name(int wire_type);
static zval **pb_get_value(zval *this, zval **values, uint32_t field_number);
static zval **pb_get_values(zval *this);
-static int pb_parse_field_value(zval *this, reader_t *reader, long field_number, long field_type, zval *value);
+static int pb_parse_field_value(zval *this, reader_t *reader, long field_number, long field_type, zval *value TSRMLS_DC);
static int pb_serialize_field_value(zval *this, writer_t *writer, uint32_t field_number, zval **type, zval **value);
-static int pb_serialize_packed_field(zval *this, writer_t *writer, long field_number, long field_type, zval *values);
+static int pb_serialize_packed_field(zval *this, writer_t *writer, long field_number, long field_type, zval *values TSRMLS_DC);
static ulong PB_FIELD_TYPE_HASH;
static ulong PB_VALUES_PROPERTY_HASH;
@@ -106,7 +106,7 @@ PHP_METHOD(ProtobufMessage, append)
RETURN_THIS();
MAKE_STD_ZVAL(val);
- if (pb_assign_value(getThis(), val, value, field_number) != 0) {
+ if (pb_assign_value(getThis(), val, value, field_number TSRMLS_CC) != 0) {
zval_ptr_dtor(&val);
RETURN_THIS();
}
@@ -462,7 +462,7 @@ PHP_METHOD(ProtobufMessage, parseFromString)
ALLOC_INIT_ZVAL(value);
add_next_index_zval(*old_value, value);
}
- if (pb_parse_field_value(getThis(), &packed_reader, field_number, Z_LVAL_PP(field_type), value) != 0) {
+ if (pb_parse_field_value(getThis(), &packed_reader, field_number, Z_LVAL_PP(field_type), value TSRMLS_CC) != 0) {
return;
}
value = NULL;
@@ -473,7 +473,7 @@ PHP_METHOD(ProtobufMessage, parseFromString)
return;
}
- if (pb_parse_field_value(getThis(), &reader, field_number, Z_LVAL_PP(field_type), value) != 0) {
+ if (pb_parse_field_value(getThis(), &reader, field_number, Z_LVAL_PP(field_type), value TSRMLS_CC) != 0) {
return;
}
}
@@ -532,7 +532,7 @@ PHP_METHOD(ProtobufMessage, serializeToString)
array = value;
if (zend_hash_find(Z_ARRVAL_PP(field_descriptor), PB_FIELD_PACKED, sizeof(PB_FIELD_PACKED), (void **) &packed) != FAILURE && Z_BVAL_PP(packed)) {
- if (pb_serialize_packed_field(getThis(), &writer, field_number, Z_LVAL_PP(type), *array) != 0)
+ if (pb_serialize_packed_field(getThis(), &writer, field_number, Z_LVAL_PP(type), *array TSRMLS_CC) != 0)
goto fail;
} else {
PB_FOREACH(&j, Z_ARRVAL_PP(array)) {
@@ -577,7 +577,7 @@ PHP_METHOD(ProtobufMessage, set)
}
} else {
zval_dtor(*old_value);
- pb_assign_value(getThis(), *old_value, value, field_number);
+ pb_assign_value(getThis(), *old_value, value, field_number TSRMLS_CC);
}
RETURN_THIS();
@@ -685,10 +685,9 @@ zend_module_entry protobuf_module_entry = {
ZEND_GET_MODULE(protobuf)
#endif
-static int pb_assign_value(zval *this, zval *dst, zval *src, uint32_t field_number)
+static int pb_assign_value(zval *this, zval *dst, zval *src, uint32_t field_number TSRMLS_DC)
{
zval **field_descriptor, *field_descriptors, tmp, **type;
- TSRMLS_FETCH();
if ((field_descriptors = pb_get_field_descriptors(this)) == NULL)
goto fail0;
@@ -988,7 +987,7 @@ static zval **pb_get_values(zval *this)
return values;
}
-static int pb_parse_field_value(zval *this, reader_t *reader, long field_number, long field_type, zval *value)
+static int pb_parse_field_value(zval *this, reader_t *reader, long field_number, long field_type, zval *value TSRMLS_DC)
{
int ret, str_size;
char *str;
@@ -1115,7 +1114,7 @@ static int pb_serialize_field_value(zval *this, writer_t *writer, uint32_t field
return 0;
}
-static int pb_serialize_packed_field(zval *this, writer_t *writer, long field_number, long field_type, zval *values)
+static int pb_serialize_packed_field(zval *this, writer_t *writer, long field_number, long field_type, zval *values TSRMLS_DC)
{
int ret = 0;
@@ -1152,4 +1151,4 @@ static int pb_serialize_packed_field(zval *this, writer_t *writer, long field_nu
}
return ret;
-}
\ No newline at end of file
+}
Point is: to support ZTS you have to add to related functions:
- to function prototypes:
TSRMLS_DC
(orTSRMLS_D
if you don't want it to pretend a comma to the function's argument - to function calls:
TSRMLS_CC
(orTSRMLS_C
likewise)
There's also a #ifdef ZTS
thing that I didn't really try to fiddle with. The changes above were enough to build the package pragmatically and I'll see what happens when running the lib. :B
This blog post helped me understand an actual application of the ZTS rules to an extension: STILL TRYING TO GET IT ALL OUT - What the heck is TSRMLS_CC, anyway? from -- what? -- 2006. :)
I'd better leave this open until someone merges the changes to the code, right? :)