困扰2天的Bug终于解决了!因为程序需要,必须使用这个版本。经过探索,原来这个bug可以这样简单的解决!本文记载源码安装fltk-1.1.10的步骤,错误,解决方法以及错误背后隐藏的原理!
安装步骤:
解压从官网下载来的源码包fltk-1.1.10-source.tar.gz,放到/usr/local/src/目录下
sudo tar -xvf fltk-1.1.10-source.tar.gz cd fltk-1.1.10 sudo mkdir bin cd bin sudo ccmake ../
cmake的配置:
BUILD_EXAMPLES *ON
BUILD_SHARED_LIBS *OFF
BUILD_TESTING *ON
CMAKE_BACKWARDS_COMPATIBILITY *2.4
CMAKE_BUILD_TYPE *
CMAKE_INSTALL_PREFIX */usr/local/fltk-1.1.10
CMAKE_USE_PTHREADS *ON
FLTK_USE_SYSTEM_JPEG *OFF
FLTK_USE_SYSTEM_PNG *OFF
FLTK_USE_SYSTEM_ZLIB *OFF
USE_OPENGL *ON
sudo make
[ 53%] Building CXX object src/CMakeFiles/fltk.dir/filename_isdir.o
[ 54%] Building CXX object src/CMakeFiles/fltk.dir/filename_list.o
/usr/local/src/fltk-1.1.10/src/filename_list.cxx: In function ‘int fl_filename_list(const char*, dirent***, int (*)(dirent**, dirent**))’:
/usr/local/src/fltk-1.1.10/src/filename_list.cxx:70:68: error: invalid conversion from ‘int (*)(const void*, const void*)’ to ‘int (*)(const dirent**, const dirent**)’ [-fpermissive]
int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort);
^
In file included from /usr/local/src/fltk-1.1.10/FL/filename.H:91:0,
from /usr/local/src/fltk-1.1.10/src/filename_list.cxx:30:
/usr/include/dirent.h:256:12: error: initializing argument 4 of ‘int scandir(const char*, dirent***, int (*)(const dirent*), int (*)(const dirent**, const dirent**))’ [-fpermissive]
extern int scandir (__const char *__restrict __dir,
^
make[2]: *** [src/CMakeFiles/fltk.dir/filename_list.o] Error 1
make[1]: *** [src/CMakeFiles/fltk.dir/all] Error 2
make: *** [all] Error 2
解决方法:
打开 /usr/local/src/fltk-1.1.10/src/filename_list.cxx文件,将第70行的int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort);
替换为
int n = scandir(d, list, 0, (int(*)(const dirent**, const dirent**))sort);
保存,退出。
sudo make编译通过
sudo make install安装成功。
参考:
http://forums.gentoo.org/viewtopic-p-5855804.html?sid=727c9b485690e762a5c29204c80c363a
https://www.mail-archive.com/[email protected]/msg13896.html
这里把这个错误原理解释的非常好:
The newer compilers don't like it if you try to assign a 64bit pointer /directly/ into an int; it stops the build with a fatal "loss of precision" error.. g++ has no way to disable such errors AFAIK. We did this a lot because we use 'user_data' (which is a void*) to temporarily store all kinds of stuff, including ints. Our use is OK, because if we put a 32bit value into a 64bit pointer, then take it back out as a 32bit value, there's no loss.. but the compiler doesn't know that, and throws an error that can't be disabled.
The first part of the error says:
invalid conversion from ‘int (*)(const void*, const void*)’
..so that's what FLTK is passing the scandir function: a function pointer that returns an int and takes two arguments that are 'const void*'s.
The error goes on to say:
to ‘int (*)(const dirent**, const dirent**)’
..which tells us what the scandir function is actually /expecting/ a function pointer that returns an int and takes two arguments that are const dirent**'s.
Function pointers are syntactically messy, but basically what has to happen here is you need to recast the func pointer from the former to the latter.
The FLTK line in question currently reads:
return scandir(d, list, 0, (int(*)(const void*,const void*))numericsort);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The underlined bit is the problem, and is itself trying to re-cast the function pointer 'numericsort' from whatever it is to be a function that takes two const void*'s, but what the compiler /wants/ to see is two const dirent **'s.
So I think if you just change the two instances of "const void*" in that line to const dirent**'s, that should fix it, I'd think.
我这么做了,确实ok了!