开发工具
遇到的问题
下载下来的CLion是不包括编译器的, 需要自己另外下载, 正是因为这样, 才产生了一系列的问题.
1.CLion默认是使用cmake工具, 之前从来没有接触过这个工具, 所以就束手无策了. 搜索出来的文章都看不懂… 直到找到了《CMake中构建静态库与动态库及其使用》这篇文章。
摘录一下用到的内容:
SET (LIBHELLO_SRC hello.cpp)
set()
表示设置变量LIBHELLO
表示名称hello.cpp
表示值- 值可以有多个,有多个时,需要用双引号括起来
ADD_LIBRARY (hello SHARED ${LIBHELLO_SRC})
add_libray()
表示编译为库文件hello
表示输出的文件名,会自动加上lib
前缀和.so
后缀,例如libhello.so
shared
表示编译出动态链接库
,如果是static
则表示编译为静态链接库
,后缀为.a
。${LIBHELLO_SRC}
是表示要编译的源文件,其中使用${}
来引用变量。
2.在弄好了CLion编译动态链接库的问题后, 又有新的问题产生了. 将编译好的dll文件copy到java.library.path的路径下, 编译java工程, 没报错, 一运行, 就出现了异常
Exception in thread "main" java.lang.UnsatisfiedLinkError:
D:\JniOut\Debug\libCppDemo.dll: Can't find dependent libraries
找不到依赖库??? 程序是我自己写的, 也没用过什么第三方的库呀, 怎么会找不到依赖库呢???
随后搜索了一下, 找到了一个可以分析dll依赖库的工具depends.exe, 分析一看, 是缺少一个LIBSTDC++-6.DLL的dll, 搜索了好久都找不到解决方法, 最后在一篇博客《MinGW编译的EXE需要DLL的问题》中找到了解救方法。
原来,只要在编译时加入一个参数-static
就可以了。
MinGW升级到4.5.2生成的exe需要libgcc_s_dw2-1.dll和libstdc++-6.dll
-static-libgcc 在gcc/g++或ld中加上这个参数, 就可以不用libgcc_s_dw2-1.dll
-static-libstdc++ 在g++或ld中加上这个参数, 就可以不用libstdc++-6.dll
-static 在gcc/g++或ld中加上这个参数, 對所有的库都会采用静态链接的方式GCC4.5预设所有的标准程式库都是动态连结,包含C和C++,如果未加上连结选项 -static-libgcc 和 -static-libstdc++,那麼编译出来的程序就需要依赖这两个DLL,无法在缺乏此DLL的电脑上执行。即使确定采用预设的动态连结,也需要额外补上-Wl,–enable-auto-import ,否则链接出来的EXE不正确。无论如何,旧有的 makefile 都要重新调整。若不喜欢这些,记得我之前用的版本,忘掉是4.2还4.3,没有这方面的问题。
如果你使用Qt进行开发,那么有可能加了-static参数还是需要libgcc_s_dw2-1.dll和libstdc++-6.dll ,这是因为Qt的DLL需要。。。。
3.查看java.library.path的方法,通常是跟系统的Path环境变量是一样的:
String[] paths = properties.getProperty("java.library.path").split(";");
for (String path : paths)
System.out.println(path);
4.最好修改一下库文件的输出路径. 在CLion的File->Settings->Build,Execution,Deployment->CMake
中,设置一下Build output path就可以了,CLion会根据编译方案(Debug/Release/RelWithDebInfo/MinSizeRel)在所设置的目录中生成对于的子目录,只要将这个目录添加到系统的Path环境变量中(我用的是Debug目录),然后重启一下IDE,就会重新读取最新的java.library.path。
5.最后的CMakeLists.txt
文件的内容如下(太复杂的我还不会写,学习时简简单单的就可以了):
cmake_minimum_required(VERSION 3.2)
project(CppDemo)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static")
set(SOURCE_FILES main.cpp)
#add_executable(CppDemo ${SOURCE_FILES})
add_library(CppDemo SHARED ${SOURCE_FILES})
默认的add_executable()
要注释掉,这个是用于编译exe文件的,如果不写main函数,会编译出错。