gcc 9.3.0 preprocessor under Cygwin: cmdline -Dname but name seems to be undefined

362 views Asked by At

I'm trying to build OCRmyPDF under Cygwin and have run into a brick wall. While I've been a developer my entire career, I've worked mostly in Java and have little knowledge of Python internals and C++. The problem might be obvious to an expert in these areas but I'm stumped.

OCRmyPDF on Linux installs as a set of "wheel" packages. I gather a wheel is a pre-built bundle of dependencies. For some reason, under Cygwin the pip installer believes it cannot use the wheel bundles and wants to rebuild from source. The problem occurs when trying to rebuild the pikepdf package.

Here's the error:

  building 'pikepdf._qpdf' extension
  creating build/temp.cygwin-3.1.4-x86_64-3.7
  creating build/temp.cygwin-3.1.4-x86_64-3.7/src
  creating build/temp.cygwin-3.1.4-x86_64-3.7/src/qpdf
  gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -ggdb -O2 -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong --param=ssp-buffer-size=4 -fdebug-prefix-map=/cygdrive/d/cyg_pub/devel/python/python37/python37-3.7.7-1.x86_64/build=/usr/src/debug/python37-3.7.7-1 -fdebug-prefix-map=/cygdrive/d/cyg_pub/devel/python/python37/python37-3.7.7-1.x86_64/src/Python-3.7.7=/usr/src/debug/python37-3.7.7-1 -ggdb -O2 -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong --param=ssp-buffer-size=4 -fdebug-prefix-map=/cygdrive/d/cyg_pub/devel/python/python37/python37-3.7.7-1.x86_64/build=/usr/src/debug/python37-3.7.7-1 -fdebug-prefix-map=/cygdrive/d/cyg_pub/devel/python/python37/python37-3.7.7-1.x86_64/src/Python-3.7.7=/usr/src/debug/python37-3.7.7-1 -D__MISC_VISIBLE=1 -I/tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include -I/tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include -I/usr/include/python3.7m -c src/qpdf/annotation.cpp -o build/temp.cygwin-3.1.4-x86_64-3.7/src/qpdf/annotation.o -DVERSION_INFO="1.11.2" -std=c++14 -fvisibility=hidden
  In file included from src/qpdf/annotation.cpp:18:
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h: In member function ‘void pybind11::cpp_function::initialize_generic(pybind11::detail::function_record*, const char*, const std::type_info* const*, pybind11::size_t)’:
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:197:21: error: ‘strdup’ was not declared in this scope; did you mean ‘strcmp’?
    197 |         rec->name = strdup(rec->name ? rec->name : "");
        |                     ^~~~~~
        |                     strcmp
  In file included from src/qpdf/annotation.cpp:18:
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h: In member function ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_static(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...)’:
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1284:31: error: there are no arguments to ‘strdup’ that depend on a template parameter, so a declaration of ‘strdup’ must be available [-fpermissive]
   1284 |               rec_fget->doc = strdup(rec_fget->doc);
        |                               ^~~~~~
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1284:31: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1292:33: error: there are no arguments to ‘strdup’ that depend on a template parameter, so a declaration of ‘strdup’ must be available [-fpermissive]
   1292 |                 rec_fset->doc = strdup(rec_fset->doc);
        |                                 ^~~~~~
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_static(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::is_method, pybind11::return_value_policy}; type_ = QPDFAnnotationObjectHelper; options = {}]’:
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1263:80:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::return_value_policy}; type_ = QPDFAnnotationObjectHelper; options = {}]’
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1252:91:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property(const char*, const Getter&, const Setter&, const Extra& ...) [with Getter = pybind11::cpp_function; Setter = std::nullptr_t; Extra = {pybind11::return_value_policy}; type_ = QPDFAnnotationObjectHelper; options = {}]’
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1234:58:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_readonly(const char*, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::return_value_policy}; type_ = QPDFAnnotationObjectHelper; options = {}]’
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1228:87:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_readonly(const char*, const Getter&, const Extra& ...) [with Getter = std::basic_string<char> (QPDFAnnotationObjectHelper::*)(); Extra = {}; type_ = QPDFAnnotationObjectHelper; options = {}]’
  src/qpdf/annotation.cpp:28:82:   required from here
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1284:37: error: ‘strdup’ was not declared in this scope; did you mean ‘strcmp’?
   1284 |               rec_fget->doc = strdup(rec_fget->doc);
        |                               ~~~~~~^~~~~~~~~~~~~~~
        |                               strcmp
  /tmp/pip-build-env-fdjj5aaz/overlay/lib/python3.7/site-packages/pybind11/include/pybind11/pybind11.h:1292:39: error: ‘strdup’ was not declared in this scope; did you mean ‘strcmp’?
   1292 |                 rec_fset->doc = strdup(rec_fset->doc);
        |                                 ~~~~~~^~~~~~~~~~~~~~~
        |                                 strcmp
  error: command 'gcc' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for pikepdf
Failed to build pikepdf
ERROR: Could not build wheels for pikepdf which use PEP 517 and cannot be installed directly

So it appears pybind11.h needs strdup() but it is not available. strdup() is declared in /usr/include/string.h, which contains this:

#if __MISC_VISIBLE || __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 4
char    *strdup (const char *) __malloc_like __result_use_check;
#endif
char    *_strdup_r (struct _reent *, const char *);
#if __POSIX_VISIBLE >= 200809
char    *strndup (const char *, size_t) __malloc_like __result_use_check;
#endif

So I tried adding an explicit -D__MISC_VISIBLE in the command line to see if that would fix the problem, but it didn't work (as shown above). I captured the preprocessor output with -E and find that even with -D__MISC_VISIBLE it's behaving as if that macro is NOT defined. Only _strdup_r appears:

Preprocessor output snippet

# 86 "/usr/include/string.h" 3 4
char *_strdup_r (struct _reent *, const char *);

And this is where I'm stuck. I cannot seem to make the compiler include strdup(). I'm not sure how to proceed next and would welcome any suggestions.

1

There are 1 answers

0
matzeri On BEST ANSWER

strdup is an extension to standard C.

The Cygwin headers are more strict than other systems and the scope are reported on

/usr/include/sys/features.h 

Usual solutions:

  1. replace the -std=c++11 with -std=gnu++11
  2. remove the -std=xxx altogether
  3. use -D_GNU_SOURCE

the last two are more or less equivalent as the default scope is the largest and -std=xxx reduces it.