CC: | tcltk [...] perl.org |
Subject: | Compilation problem applying Makefile.PL --tclconfig |
Hi,
My system is Cygwin 2.10 and I have tcl 8.6 installed. When compile with 'perl Makefile.pl --tclconfig' there is a problem (In fact, Makefile.PL forces --tclconfig option turned on on Cygwin, https://metacpan.org/source/VKON/Tcl-1.05/Makefile.PL#L48 ):
$ perl Makefile.PL --tclconfig /usr/lib/tclConfig.tcl
$ make
:
g++ --shared -Wl,--enable-auto-import -Wl,--export-all-symbols -Wl,--enable-auto-image-base -fstack-protector-strong Tcl.o -o blib/arch/auto/Tcl/Tcl.dll \
/usr/lib/perl5/5.26/x86_64-cygwin-threads/CORE/cygperl5_26.dll -ltclstub8.6 \
Tcl.o: In function `NpInitialize':
/home/user/.cpan/build/Tcl-1.05-SJ/Tcl.xs:475: undefined reference to `Tcl_Init'
/home/user/.cpan/build/Tcl-1.05-SJ/Tcl.xs:475:(.text+0x45d3): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Tcl_Init'
Tcl.o:Tcl.c:(.rdata$.refptr.Tcl_Init[.refptr.Tcl_Init]+0x0): undefined reference to `Tcl_Init'
collect2: error: ld returned 1 exit status
make: *** [Makefile:482: blib/arch/auto/Tcl/Tcl.dll] Error 1
The root cause is that the preprocessor failed to expand the Tcl_Init() macro (https://metacpan.org/source/VKON/Tcl-1.05/Tcl.xs#L374 ), which is defined in tclDecls.h.
When I apply --tclconfig option, the system-provided header file is used. The definition of macro 'Tcl_Init' in newer version of tcl is ( https://github.com/tcltk/tcl/blob/e058389c65a7df317144676413d8d3dcf3c2e252/generic/tclDecls.h#L3735 ):
#define Tcl_Init(interp) (tclStubsPtr->tcl_Init(interp))
The original definition (comes with Tcl module tcl-core/include/tclDecls.h) is:
#define Tcl_Init (tclStubsPtr->tcl_Init)
In a statement like 'func_ptr=Tcl_Init', the macro 'Tcl_Init' can be expanded properly; in new version of declaration, the preprocessor does not recognize 'Tcl_Init' (but Tcl_Init()) and leave it to the compiler. Compiler then fails to find a real Tcl_Init() function for the pointer assignment.
The attachment is a patch to workaround this. It seems not decent. Maybe there is a better solution.
Subject: | Tcl-StubMacro.patch |
--- Tcl-1.05-SJ/Tcl.xs 2018-06-16 08:03:07.415797200 +0800
+++ Tcl-1.05-patched/Tcl.xs 2018-06-16 09:55:16.218662700 +0800
@@ -30,9 +30,13 @@
#undef JOIN
/*
- * Let Tcl_Init() stub could be pointed by a function pointer
+ * Let Tcl_Init() stub could be pointed by a function pointer.
+ * Since tcl 8.5, Tcl_Init() is defined as a macro with an argument and
+ * unable to be assigned to a function pointer. We need to redefine it.
*/
#include <tcl.h>
+#undef Tcl_Init
+#define Tcl_Init (tclStubsPtr->tcl_Init)
#ifdef USE_TCL_STUBS
/*