find_orb 的编译—msys2交叉编译
一、前言
该工具用于人工卫星识别、识别短小行星弧和已知小行星等等
链接
find_orb 官方文档
find_orb github 仓库
jpl_eph
sat_code
lunar
前置工作
find_orb
依赖于一些 第三方库,并且需要使用 交叉编译工具 来构建,我们使用 msys2
- 下载包含 依赖库 源代码的压缩包
jpl_eph
sat_code
lunar
- 安装
msys2
交叉编译工具 - 将 依赖库、项目压缩包放到
msys2
根目录下的opt
目录中- 我的
msys2
安装在 D 盘根目录,即根目录为D:/msys64
,那么opt
在D:/msys64/opt
中 - 接下来我都以
D:/msys64
来表示msys2
的根目录
- 我的
二、编译
前置工作
msys2
安装后还不能直接使用,还需要安装一些工具
- 打开
msys2
的mingw64
,其他的应该也可以,这是一个命令行窗口,路径为家目录,我的用户名为azh
,故为/home/azh
-
使用
pacman
命令,使用-S
选项,后面跟着需要安装的 软件包,即可安装对应软件# 这是注释 # 安装 gcc、make 工具 pacman -S gcc pacman -S make # 安装一些依赖 pacman -S ncurses-devel # 这个可能不需要 # pacman -S libcurl-devel
以
gcc
为例,安装过程中需要输入y
确定
依赖库的编译
使用 cd /opt
命令,切换到刚刚解压源代码的目录,使用 ls
命令能显示当前目录下的文件,该目录下显示了4个目录文件
-
lunar
(1)
sat_code
依赖于jpl_eph
,由于jpl_eph
依赖于lunar
,故应当优先编译lunar
,执行cd lunar-master
命令,切换到该目录,列出文件
(2) 执行
make
命令即可编译,但是ades2mpc.cpp
文件报错了,这是因为name
字符数组未初始化,将 487 行的char name[40]
; 修改为char name[40]={0};
,然后接着执行make
# 错误 1 ades2mpc.cpp: In function 'int process_ades_tag(char*, ades2mpc_t*, int, const char*, size_t)': ades2mpc.cpp:745:33: error: 'name' may be used uninitialized [-Werror=maybe-uninitialized] 745 | cptr->line[13] = name[0]; | ~~~~~~^ ades2mpc.cpp:487:9: note: 'name' declared here 487 | char name[40]; # 解决方法 # char name[40]; # 改为 # char name[40]={0}; # 错误 2 # 还有可能出现以下错误 D:/local/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: add_off.o: in function `set_offsets': D:/local/msys64/opt/lunar-master/add_off.c:219:(.text+0x286): undefined reference to `URLDownloadToFileA' collect2.exe: error: ld returned 1 exit status g++ -Wextra -Wall -O3 -pedantic -g -Werror -o cgicheck -DCGI_VERSION cgicheck.o astcheck.cpp liblunar.a -lm make: *** [makefile:223: add_off] Error 1 make: *** Waiting for unfinished jobs.... # make加上参数 W64=Y 即可 # make W64=Y
(3) 编译完成后执行
make install
,便会安装到家目录,我的是/home/azh
-
jpl_eph
如同
lunar
,直接进入到源代码所在目录,执行make
# 错误 1 sat_eph.c: In function ‘desig_match’: sat_eph.c:87:25: error: array subscript has type ‘char’ [-Werror=char-subscripts] 87 | while( isdigit( desig[i])) | ~~~~~^~~ gcc -Wextra -Wall -O3 -pedantic -Werror -g -o test_des test_des.o libsatell.a -lm sat_eph.c: In function ‘generate_artsat_ephems’: sat_eph.c:364:31: error: array subscript has type ‘char’ [-Werror=char-subscripts] 364 | if( !isdigit( buff[i]) || !isdigit( buff[i + 7])) | ~~~~^~~ sat_eph.c:364:53: error: array subscript has type ‘char’ [-Werror=char-subscripts] 364 | if( !isdigit( buff[i]) || !isdigit( buff[i + 7])) | ~~~~^~~~~~~ sat_eph.c: In function ‘fix_desig’: sat_eph.c:472:25: error: array subscript has type ‘char’ [-Werror=char-subscripts] 472 | if( isdigit( desig[i])) | ~~~~~^~~ In file included from sat_eph.c:2: sat_eph.c: In function ‘desig_match’: sat_eph.c:87:25: error: array subscript has type ‘char’ [-Werror=char-subscripts] 87 | while( isdigit( desig[i])) | ~~~~~^~~ gcc -Wextra -Wall -O3 -pedantic -Werror -g -o test_out test_out.o tle_out.o get_el.o sgp4.o common.o -lm sat_eph.c: In function ‘generate_artsat_ephems’: sat_eph.c:364:31: error: array subscript has type ‘char’ [-Werror=char-subscripts] 364 | if( !isdigit( buff[i]) || !isdigit( buff[i + 7])) | ~~~~^~~ sat_eph.c:364:53: error: array subscript has type ‘char’ [-Werror=char-subscripts] 364 | if( !isdigit( buff[i]) || !isdigit( buff[i + 7])) | ~~~~^~~~~~~ sat_eph.c: In function ‘fix_desig’: sat_eph.c:472:25: error: array subscript has type ‘char’ [-Werror=char-subscripts] 472 | if( isdigit( desig[i])) # 将所有 isdigit(参数) 改为 isdigit((int)(参数)) # 例如 isdigit( buff[i]) 改为 isdigit( (int)(buff[i])) # 分别为 87 364 472 行 # 错误 2 # 可能会报这个错误 ephem0.cpp: In function ‘int put_ephemeris_posn_angle_sigma(char*, double, double, bool)’: ephem0.cpp:542:29: error: ‘%3d’ directive output may be truncated writing between 3 and 11 bytes into a region of size between 5 and 12 [-Werror=format-truncation=] 542 | snprintf( obuff, 13, "%s %3d", resid_buff + 1, integer_posn_ang); | ^~~ ephem0.cpp:542:25: note: directive argument in the range [-2147483468, 179] 542 | snprintf( obuff, 13, "%s %3d", resid_buff + 1, integer_posn_ang); | ^~~~~~~~ ephem0.cpp:542:12: note: ‘snprintf’ output between 5 and 20 bytes into a destination of size 13 542 | snprintf( obuff, 13, "%s %3d", resid_buff + 1, integer_posn_ang); # 将 makefile 的第 135 行的 CXXFLAGS 里的 -Wall 去掉
编译完无误后执行
make install
,即可 -
sat_code
如同
lunar
,直接进入到源代码所在目录,执行make
,编译完无误后执行make install
,即可
find_orb 的编译
可能会有报错,解决这些错误后,编译完无误后执行 make install
,即可
-
如果过以下文件报错找不到
curses.h
头文件,则修改以下文件中的curses.h
改为ncurses/curses.h
findorb.cpp
(39行)getstrex.cpp
(7行)
# 错误 1 getstrex.cpp:7:13: fatal error: curses.h: No such file or directory 7 | #include <curses.h> findorb.cpp:39:13: fatal error: curses.h: No such file or directory 39 | #include "curses.h" | ^~~~~~~~~~ # 将 curses.h 改为 ncurses/curses.h # 错误 2 # 可能会出现以下错误 D:/local/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -llunar: No such file or directory D:/local/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -ljpl: No such file or directory D:/local/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lsatell: No such file or directory collect2.exe: error: ld returned 1 exit status make: *** [makefile:210: fo] Error 1 # 修改第 159 行的 LIBS+=$(LIBSADDED) -llunar -ljpl -lsatell # 改为 LIBS+=$(LIBSADDED) -L ~/lib -llunar -ljpl -lsatell
-
如果报错
isdigit
的错误,则将传入的参数强转成int
,如变量isdigit(array[i])
,改为isdigit((int)(array[i]))
最后
我的是家目录是 /home/azh
,故最后可以在 /home/azh/bin
找到可执行文件,还有就是在离开 msys2
后直接运行可能会报错找不到 dll
,需要把 D:/msys64/usr/bin
(以我的路径为例)添加到系统环境变量 Path
中
添加 环境变量 步骤如下
-
右键 开始菜单,选择 系统
-
点击 高级系统设置
-
点击 环境变量
-
找到 系统变量 中的 Path 变量,点击 编辑
-
点击 新建
-
输入动态库路径,我这里就不输入了,我的是
D:/msys64/usr/bin
,然后点击 确认
三、调试
前置工作
- 前面的编译中的
make
应当加上debug
参数,即make DEBUG=Y
,才可以调试 - 下载
VSCode
- 在
VSCode
的扩展商店安装C/C++
扩展(可能不需要)
具体步骤
-
使用
VSCode
来调试,打开源代码目录(例如D:/msys2/home/azh/opt/find_orb-master
)为VSCode
的工作区,点击侧边栏第四个选项,运行与调试,随后点击创建launch.json
文件
-
然后点击右下角的添加配置,便会弹出一些默认的配置文件,我们对此进行修改
# 默认 { "name": "(gdb) Windows 上的 Bash 启动", "type": "cppdbg", "request": "launch", "program": "输入程序名称,例如 ${workspaceFolder}/a.exe", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "pipeTransport": { "debuggerPath": "/usr/bin/gdb", "pipeProgram": "${env:windir}\\system32\\bash.exe", "pipeArgs": ["-c"], "pipeCwd": "" }, "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "将反汇编风格设置为 Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] } # 修改为 { "name": "find_orb 调试",//配置名称;在启动配置下拉菜单中显示 "type": "cppdbg",//配置类型。 "request": "launch",//请求配置类型。可以是“启动”或“附加”。 "program": "${workspaceFolder}/find_orb.exe",//需要调试的可执行文件 "args": ["debug.txt"],//传递给程序的命令行参数。 "stopAtEntry": false,//可选参数。如果为true,则调试器应在目标的入口点停止。如果传递了进程ID,则无效。 "cwd": "${workspaceFolder}",//目标的工作目录 "environment": [],//要添加到程序环境中的环境变量。示例:[“name”:“squid”,“value”:“clam”]。 "externalConsole": true, "linux": {//特定于 Linux 的启动配置属性。 "MIMode": "gdb",//指示midebugengine将连接到的控制台调试器。允许值为“gdb”“lldb”。 "miDebuggerPath": "/usr/bin/gdb",//调试器的路径。 }, "setupCommands": [//要执行的一个或多个gdb/lldb命令,以便设置底层调试器。 { "description": "Enable pretty-printing for gdb",//命令的可选说明。 "text": "-enable-pretty-printing",//要执行的调试器命令。 "ignoreFailures": true,//如果为true,则应忽略来自命令的失败。默认值为假。 } ] }
-
在
mpc_obs.cpp
文件中,有个debug_printf
函数,读取的是debug.txt
,故我们可以把mpc
数据文件命名为debug.txt
,然后在该函数中打断点来直观的进行调试
补充
记得在 msys2
中安装 gdb
,由于刚刚已经将 D:/msys64/usr/bin
添加到系统环境变量中,gdb
也会安装在其中
pacman -S gdb