之前的笔记《联盛德W801系列4-MQTT使用》出现过编译《cjson.c》出错,找不到标准数学函数pow(幂函数,在转换科学记数法表示的字符串用到),floor(浮点取整函数),当时因为没有用到这些功能,就直接注释相关报错行,但求能通过编译,没有去解决根本问题。
昨天在移植GUI源码,用到三角函数,又出现这个错误,就到联盛德问答社区提问。
我的问题页面:http://ask.winnermicro.com/question/325.html,
5分钟内立刻有专家帮我解答。因为有其他网友之前提过类似的问题:http://ask.winnermicro.com/question/291.html
这次有点空闲时间,我就找一下相关知识看看,补补欠缺,并做笔记。
先来看看问题的表象。
尽管已经包含了
解决方法:
1.通过下面的方法进入工程设置:
2.在 linker页面的 Library Name增加m,用分号隔开。再次编译就可以正常使用数学 函数。
CDK默认库目录下面有这些库:
这里的-l是L的小写。
-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是 libm.a,很容易看出,把库文件名的头lib和尾.a去掉就是库名了。cdk默认库的目录是 《$(CDKPath)/CSKY/MinGW/csky-abiv2-elf-toolchain/csky-elfabiv2/lib》。
看到这里,就知道怎么为何增加m就可以解决问题。下面再扩展一下。
当我们自已要用到一个第三方提供的库名字libtest.a,那么我们只要把libtest.a拷贝到默认库的目录里,编译时加上-ltest参数,我们就能用上libtest.a库了(当然要用libtest.a库里的函数,我们还需要与libtest.a配套的头文件);但如果库文件没放在这个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/bin/ld: cannot find -lxxx”,也就是链接程序ld在这个目录里找不到libxxx.a,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.a放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。
错误现象:
《UIcode.cpp》是c++文件,函数内部的静态局部变量的初始化是在函数第一次调用时执行,编译器会用函数__cxa_guard_acquire; 用来保证在之后的调用中不会对其重复初始化。这个函数存在于libstdc++库里面,这个库还是编译器自带的,只要在我们的工程中增加-lstdc++就可以了。那我们依照增加数学函数库的方法来解决问题。
保存,重新编译。编译成功。功能正常。