timerNew
is implemented in terms of Fl_Timer_New
:
{# fun Fl_Timer_New as timerNewWithLabel' { `Int',`Int',`Int',`Int', unsafeToCString `T.Text'} -> `Ptr ()' id #}
timerNew :: Rectangle -> T.Text -> IO (Ref Timer)
timerNew rectangle l'=
let (x_pos, y_pos, width, height) = fromRectangle rectangle
in timerNewWithLabel' x_pos y_pos width height l' >>= toRef
But while Fl_Timer_New
is declared in Fl_TimerC.h
:
FL_EXPORT_C(fl_Timer, Fl_Timer_New)(int x, int y, int w, int h, const char* l);
The corresponding implementation in Fl_TimerC.cpp
uses the name Fl_Timer_New_WithLabel
, not Fl_Timer_New
:
FL_EXPORT_C(fl_Timer, Fl_Timer_New_WithLabel)(int X, int Y, int W, int H, const char* label){
fl_Widget_Virtual_Funcs* fs = Fl_Widget_default_virtual_funcs();
Fl_DerivedTimer* w = new Fl_DerivedTimer(FL_NORMAL_TIMER,X,Y,W,H,label,fs);
return (fl_Timer)w;
}
So if I try to compile a program containing timerNew
, I get a linking error.
-- Undefined symbols for architecture x86_64:
-- "_Fl_OverriddenTimer_New", referenced from:
-- _fltkhszm0zi5zi2zi4zmJ8HFBnbOGX86OTsRCvwWFo_GraphicsziUIziFLTKziLowLevelziTimer_zdwoverriddenWidgetNewzq_info in libHSfltkhs-0.5.2.4-J8HFBnbOGX86OTsRCvwWFo.a(Timer.o)
-- (maybe you meant: _Fl_OverriddenTimer_New_WithLabel)
-- "_Fl_Timer_New", referenced from:
-- _cblHE_info in libHSfltkhs-0.5.2.4-J8HFBnbOGX86OTsRCvwWFo.a(Timer.o)
-- (maybe you meant: _Fl_Timer_New_WithLabel)
-- ld: symbol(s) not found for architecture x86_64
-- clang: error: linker command failed with exit code 1 (use -v to see invocation)
-- `gcc' failed in phase `Linker'. (Exit code: 1)
{-# LANGUAGE OverloadedStrings #-}
import Graphics.UI.FLTK.LowLevel.Fl_Types
import Graphics.UI.FLTK.LowLevel.Timer
main :: IO ()
main = do
_ <- timerNew (Rectangle (Position (X 10) (Y 30))
(Size (Width 95) (Height 30)))
"timer"
return ()
It's easy to fix the problem by changing timerNew
to use Fl_Timer_New_WithLabel
instead of Fl_Timer_New
, but I think there's more to this bug than a simple name change.
Since the FLTK documentation for Fl_Timer recommends not to use that widget, the fact that it doesn't work isn't a big loss. But while googling for my error message, I noticed issue #53 in which you're getting linking errors for that symbol on Nix as well. Maybe clang links lazily, so the error only occurs when a symbol is actually used, whereas Nix is strict in that regard? If so, I should also be able to produce linking errors for each of the other symbols in that issue. And indeed:
{-# LANGUAGE OverloadedStrings #-}
import Graphics.UI.FLTK.LowLevel.Fl_Types
import Graphics.UI.FLTK.LowLevel.Timer
import Graphics.UI.FLTK.LowLevel.FileBrowser
main :: IO ()
main = do
-- linking error for _Fl_Timer_New and _Fl_OverriddenTimer_New
_ <- timerNew (Rectangle (Position (X 10) (Y 30))
(Size (Width 95) (Height 30)))
"timer"
-- linking error for _Fl_OverriddenFile_Browser_New
_ <- fileBrowserCustom (Rectangle (Position (X 10) (Y 30))
(Size (Width 95) (Height 30)))
Nothing
Nothing
Nothing
-- linking error for _Fl_File_Browser_New
_ <- fileBrowserNew (Rectangle (Position (X 10) (Y 30))
(Size (Width 95) (Height 30)))
Nothing
-- linking error for _Fl_File_Browser_New_WithLabel
-- and _Fl_OverriddenFile_Browser_New_WithLabel
_ <- fileBrowserNew (Rectangle (Position (X 10) (Y 30))
(Size (Width 95) (Height 30)))
(Just "file browser")
return ()
Looking at the history, I see that Fl_Timer_New
and Fl_File_Browser_New_WithLabel
were both removed in commit d97b613, "Custom Widgets". By adding support for custom widgets, maybe you accidentally introduced a regression in the script which generates your bindings?