Unicode-enabling Microsoft C/C++ Source Code(转载)

 Cheat Sheet:
Unicode-enabling Microsoft C/C++ Source Code

Here is a cheat sheet for converting Microsoft C or C++ source code to support Unicode. It does not attempt to explain much and presumes you are generally familiar with Microsoft's approach to Unicode. The goal is just to have a single place to look for names, correct spellings, etc. of relevant data types, functions, etc.

Initial Steps for Unicode-enabling Microsoft C/C++ Source

  • Define _UNICODE, undefine _MBCS if defined.
  • Convert literal strings to use L or _T
  • Convert string functions to use Wide or TCHAR versions.
  • Clarify string lengths in API as byte or character counts. For character-based display or printing (as opposed to GUI which is pixel-based) use column counts, not byte or character.
  • Replace character pointer arithmetic with GetNext style, as characters may consist of more than one Unicode code unit.
  • Watch buffer size and buffer overflows- changing encodings may require either larger buffers or limiting string lengths. If character size changes from 1 byte to as many as 4 bytes, and string length was formerly 20 characters and 20 bytes, either expand the string buffer(s) from 20 to 80 bytes or limit the string to 5 characters (and therefore 20 bytes). Note maximum buffer expansion may be constrained (for example to 65 KB). Reducing string length to a fixed number of characters may break existing applications. Limiting strings to a fixed byte length is dangerous. For example, allowing any string that fits into 20 bytes. Simple operations such as uppercasing a string may cause it to grow and exceed the byte length.
  • Replace functions that accept or return arguments of a single character, with functions that use strings instead. (International) Operations on a single character may result in more than one code point being returned. For example, upper('ß') returns "SS".
  • Use wmain instead of main. The environment variable is then _wenviron instead of _environ.
    wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] ).
  • MFC Unicode applications use wWinMain as the entry point.
    In the Output page of the Linker folder in the project's Property Pages dialog box, set the Entry Point symbol to wWinMainCRTStartup.
  • Consider fonts. Identify the fonts that will render each language or script used.

File I/O, Database, Transfer Protocol Considerations

  • Consider whether to read/write UTF-8 or UTF-16 in files, databases, and for data exchange.
  • Consider Endian-ness in UTF-16 files.
    Read/Write Big-Endian on networks. Use Big-Endian if you don't produce a BOM.
    Endian-ness of files will depend on the file format and/or the architecture of the source or target machine.
    When reading files encoded in UTF-16 or UTF-32, be prepared to swap-bytes to convert endian-ness.
    Also consider streams and transfer protocols and the encoding used in each.
  • Label files or protocols for data exchange with the correct character encoding. E.g. set HTTP, HTML, XML to UTF-8 or UTF-16.
  • Consider Unicode BOM (Byte Order Marker) and whether it should be written with data. Remove it when reading data.
  • Consider encoding conversion of legacy data and files, import and export, transfer protocols. (MultiByteToWideChar, WideCharToMultiByte, mbtowc, wctomb, wctombs, mbstowcs )
  • Consider writing to the Clipboard-
    use CF_TEXT format and write native character encoding (ANSI) text, and
    use CF_UNICODETEXT format and write Unicode text.
  • Database applications should consider Data Type (NCHAR, NVARCHAR) and Schema Changes, Triggers, Stored Procedures, and Queries. Data Storage growth, Indexes and Performance.
    Note that the Unicode schema changes will have different impacts and concerns on different vendors' databases. If database portability is a requirement, the features and behaviors of each database need to be taken into account.
    (I know this item is seriously understated. To be expanded sometime in the future.)

Stream I/O

Streams are difficult in Microsoft C++. You may run into 3 types of problems:

  1. Unicode filenames are not supported. The workaround is to use FILE * _wfopen and if needed, use the FILE handle in subsequent stream I/O.
    std::ifstream stm(_wfopen(pFilename, L"r"));
  2. Stream I/O will convert Unicode data from/to native (ANSI) code page on read/write, not UTF-8 or UTF-16. However the stream class can be modified to read/write UTF-8. You can implement a facet to convert between Unicode and UTF-8.
    codecvt <wchar_t, char_traits <wchar_t> >
  3. To read/write UTF-16 with stream I/O, use binary opens and binary I/O. To set binary I/O:
    _setmode( _fileno( stdin ), _O_BINARY );

    Also see the Microsoft run-time library reference: "Unicode Stream I/O in Text and Binary Modes".

Note: There aren't TCHAR equivalents for cout/wcout, cin/wcin, etc. You may want to make your own preprocessor definition for "tout", if you are compiling code both ways.

Internationalization, Advanced Unicode, Platform and Other Considerations

Unicode BOM Encoding Values

Encoding FormBOM Encoding
UTF-8EF BB BF
UTF-16
(big-endian)
FE FF
UTF-16
(little-endian)
FF FE
UTF-16BE, UTF-32BE
(big-endian)
No BOM!
UTF-16LE, UTF-32LE
(little-endian)
No BOM!
UTF-32
(big-endian)
00 00 FE FF
UTF-32
(little-endian)
FF FE 00 00
SCSU
(compression)
0E FE FF

The Byte Order Marker (BOM) is Unicode character U+FEFF. (It can also represent a Zero Width No-break Space.) The code point U+FFFE is illegal in Unicode, and should never appear in a Unicode character stream. Therefore the BOM can be used in the first character of a file (or more generally a string), as an indicator of endian-ness. With UTF-16, if the first character is read as bytes FE FF then the text has the same endian-ness as the machine reading it. If the character is read as bytes FF FE, then the endian-ness is reversed and all 16-bit words should be byte-swapped as they are read-in. In the same way, the BOM indicates the endian-ness of text encoded with UTF-32.

Note that not all files start with a BOM however. In fact, the Unicode Standard says that text that does not begin with a BOM MUST be interpreted in big-endian form.

The character U+FEFF also serves as an encoding signature for the Unicode Encoding Forms. The table shows the encoding of U+FEFF in each of the Unicode encoding forms. Note that by definition, text labeled as UTF-16BE, UTF-32BE, UTF-32LE or UTF-16LE should not have a BOM. The endian-ness is indicated in the label.

For text that is compressed with the SCSU (Standard Compression Scheme for Unicode) algorithm, there is also a recommended signature.

Constant and Global Variables

ANSIWideTCHAR
EOFWEOF_TEOF
_environ_wenviron_tenviron
_pgmptr_wpgmptr_tpgmptr

Data Types

ANSIWideTCHAR
charwchar_t_TCHAR
_finddata_t_wfinddata_t_tfinddata_t
__finddata64_t__wfinddata64_t_tfinddata64_t
_finddatai64_t_wfinddatai64_t_tfinddatai64_t
intwint_t_TINT
signed charwchar_t_TSCHAR
unsigned charwchar_t_TUCHAR
charwchar_t_TXCHAR
 L_T or _TEXT
LPSTR
(char *)
LPWSTR
(wchar_t *)
LPTSTR
(_TCHAR *)
LPCSTR
(const char *)
LPCWSTR
(const wchar_t *)
LPCTSTR
(const _TCHAR *)
LPOLESTR
(For OLE)
LPWSTRLPTSTR

Platform SDK String Functions

There are many Windows API that compile into ANSI or Wide forms, depending on whether the symbol UNICODE is defined. Modules that operate on both ANSI and Wide characters, need to be aware of this. Otherwise, using the Character Data Type-independent name requires no changes, just compile with the symbol UNICODE defined.

The following list is by no means all of the Character Data Type-dependent API, just some character and string related ones. Look in WinNLS.h for some code page and locale related API.

ANSIWideCharacter Data Type-
Independent Name
CharLowerACharLowerWCharLower
CharLowerBuffACharLowerBuffWCharLowerBuff
CharNextACharNextWCharNext
CharNextExACharNextExWCharNextEx
CharPrevACharPrevWCharPrev
CharPrevExACharPrevExWCharPrevEx
CharToOemACharToOemWCharToOem
CharToOemBuffACharToOemBuffWCharToOemBuff
CharUpperACharUpperWCharUpper
CharUpperBuffACharUpperBuffWCharUpperBuff
CompareStringACompareStringWCompareString
FoldStringAFoldStringWFoldString
GetStringTypeAGetStringTypeWGetStringType
GetStringTypeExAGetStringTypeExWGetStringTypeEx
IsCharAlphaAIsCharAlphaWIsCharAlpha
IsCharAlphaNumericAIsCharAlphaNumericWIsCharAlphaNumeric
IsCharLowerAIsCharLowerWIsCharLower
IsCharUpperAIsCharUpperWIsCharUpper
LoadStringALoadStringWLoadString
lstrcatAlstrcatWlstrcat
lstrcmpAlstrcmpWlstrcmp
lstrcmpiAlstrcmpiWlstrcmpi
lstrcpyAlstrcpyWlstrcpy
lstrcpynAlstrcpynWlstrcpyn
lstrlenAlstrlenWlstrlen
OemToCharAOemToCharWOemToChar
OemToCharBuffAOemToCharBuffWOemToCharBuff
wsprintfAwsprintfWwsprintf
wvsprintfAwvsprintfWwvsprintf

TCHAR String Functions

Functions sorted by ANSI name, for ease of converting to Unicode.

ANSIWideTCHAR
_access_waccess_taccess
_atoi64_wtoi64_tstoi64
_atoi64_wtoi64_ttoi64
_cgets_cgetwscgetts
_chdir_wchdir_tchdir
_chmod_wchmod_tchmod
_cprintf_cwprintf_tcprintf
_cputs_cputws_cputts
_creat_wcreat_tcreat
_cscanf_cwscanf_tcscanf
_ctime64_wctime64_tctime64
_execl_wexecl_texecl
_execle_wexecle_texecle
_execlp_wexeclp_texeclp
_execlpe_wexeclpe_texeclpe
_execv_wexecv_texecv
_execve_wexecve_texecve
_execvp_wexecvp_texecvp
_execvpe_wexecvpe_texecvpe
_fdopen_wfdopen_tfdopen
_fgetchar_fgetwchar_fgettchar
_findfirst_wfindfirst_tfindfirst
_findnext64_wfindnext64_tfindnext64
_findnext_wfindnext_tfindnext
_findnexti64_wfindnexti64_tfindnexti64
_fputchar_fputwchar_fputtchar
_fsopen_wfsopen_tfsopen
_fullpath_wfullpath_tfullpath
_getch_getwch_gettch
_getche_getwche_gettche
_getcwd_wgetcwd_tgetcwd
_getdcwd_wgetdcwd_tgetdcwd
_ltoa_ltow_ltot
_makepath_wmakepath_tmakepath
_mkdir_wmkdir_tmkdir
_mktemp_wmktemp_tmktemp
_open_wopen_topen
_popen_wpopen_tpopen
_putch_putwch_puttch
_putenv_wputenv_tputenv
_rmdir_wrmdir_trmdir
_scprintf_scwprintf_sctprintf
_searchenv_wsearchenv_tsearchenv
_snprintf_snwprintf_sntprintf
_snscanf_snwscanf_sntscanf
_sopen_wsopen_tsopen
_spawnl_wspawnl_tspawnl
_spawnle_wspawnle_tspawnle
_spawnlp_wspawnlp_tspawnlp
_spawnlpe_wspawnlpe_tspawnlpe
_spawnv_wspawnv_tspawnv
_spawnve_wspawnve_tspawnve
_spawnvp_wspawnvp_tspawnvp
_spawnvpe_wspawnvpe_tspawnvpe
_splitpath_wsplitpath_tsplitpath
_stat64_wstat64_tstat64
_stat_wstat_tstat
_stati64_wstati64_tstati64
_strdate_wstrdate_tstrdate
_strdec_wcsdec_tcsdec
_strdup_wcsdup_tcsdup
_stricmp_wcsicmp_tcsicmp
_stricoll_wcsicoll_tcsicoll
_strinc_wcsinc_tcsinc
_strlwr_wcslwr_tcslwr
_strncnt_wcsncnt_tcsnbcnt
_strncnt_wcsncnt_tcsnccnt
_strncnt_wcsncnt_tcsnccnt
_strncoll_wcsncoll_tcsnccoll
_strnextc_wcsnextc_tcsnextc
_strnicmp_wcsnicmp_tcsncicmp
_strnicmp_wcsnicmp_tcsnicmp
_strnicoll_wcsnicoll_tcsncicoll
_strnicoll_wcsnicoll_tcsnicoll
_strninc_wcsninc_tcsninc
_strnset_wcsnset_tcsncset
_strnset_wcsnset_tcsnset
_strrev_wcsrev_tcsrev
_strset_wcsset_tcsset
_strspnp_wcsspnp_tcsspnp
_strtime_wstrtime_tstrtime
_strtoi64_wcstoi64_tcstoi64
_strtoui64_wcstoui64_tcstoui64
_strupr_wcsupr_tcsupr
_tempnam_wtempnam_ttempnam
_ui64toa_ui64tow_ui64tot
_ultoa_ultow_ultot
_ungetch_ungetwch_ungettch
_unlink_wunlink_tunlink
_utime64_wutime64_tutime64
_utime_wutime_tutime
_vscprintf_vscwprintf_vsctprintf
_vsnprintf_vsnwprintf_vsntprintf
asctime_wasctime_tasctime
atof_wtof_tstof
atoi_wtoi_tstoi
atoi_wtoi_ttoi
atol_wtol_tstol
atol_wtol_ttol
character compareMaps to macro or inline function_tccmp
character copyMaps to macro or inline function_tccpy
character lengthMaps to macro or inline function_tclen
ctime_wctime_tctime
fgetcfgetwc_fgettc
fgetsfgetws_fgetts
fopen_wfopen_tfopen
fprintffwprintf_ftprintf
fputcfputwc_fputtc
fputsfputws_fputts
freopen_wfreopen_tfreopen
fscanffwscanf_ftscanf
getcgetwc_gettc
getchargetwchar_gettchar
getenv_wgetenv_tgetenv
getsgetws_getts
isalnumiswalnum_istalnum
isalphaiswalpha_istalpha
isasciiiswascii_istascii
iscntrliswcntrl_istcntrl
isdigitiswdigit_istdigit
isgraphiswgraph_istgraph
islead (Always FALSE)(Always FALSE)_istlead
isleadbyte (Always FALSE)isleadbyte (Always FALSE)_istleadbyte
islegal (Always TRUE)(Always TRUE)_istlegal
isloweriswlower_istlower
isprintiswprint_istprint
ispunctiswpunct_istpunct
isspaceiswspace_istspace
isupperiswupper_istupper
isxdigitiswxdigit_istxdigit
mainwmain_tmain
perror_wperror_tperror
printfwprintf_tprintf
putcputwc_puttc
putcharputwchar_puttchar
puts_putws_putts
remove_wremove_tremove
rename_wrename_trename
scanfwscanf_tscanf
setlocale_wsetlocale_tsetlocale
sprintfswprintf_stprintf
sscanfswscanf_stscanf
strcatwcscat_tcscat
strchrwcschr_tcschr
strcmpwcscmp_tcscmp
strcollwcscoll_tcscoll
strcpywcscpy_tcscpy
strcspnwcscspn_tcscspn
strerror_wcserror_tcserror
strftimewcsftime_tcsftime
strlenwcslen_tcsclen
strlenwcslen_tcslen
strncatwcsncat_tcsncat
strncatwcsncat_tcsnccat
strncmpwcsncmp_tcsnccmp
strncmpwcsncmp_tcsncmp
strncpywcsncpy_tcsnccpy
strncpywcsncpy_tcsncpy
strpbrkwcspbrk_tcspbrk
strrchrwcsrchr_tcsrchr
strspnwcsspn_tcsspn
strstrwcsstr_tcsstr
strtodwcstod_tcstod
strtokwcstok_tcstok
strtolwcstol_tcstol
strtoulwcstoul_tcstoul
strxfrmwcsxfrm_tcsxfrm
system_wsystem_tsystem
tmpnam_wtmpnam_ttmpnam
tolowertowlower_totlower
touppertowupper_totupper
ungetcungetwc_ungettc
vfprintfvfwprintf_vftprintf
vprintfvwprintf_vtprintf
vsprintfvswprintf_vstprintf
WinMainwWinMain_tWinMain

References

me@me-Yilong15Pro-Series-GM5HG0A:~/下载/px4-autopilot-1.15.4$ make px4_fmu-v5_default -- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.10", minimum required is "3") -- PX4 config file: /home/me/下载/px4-autopilot-1.15.4/boards/px4/fmu-v5/default.px4board -- PLATFORM nuttx -- TOOLCHAIN arm-none-eabi -- ARCHITECTURE cortex-m7 -- ROMFSROOT px4fmu_common -- IO px4_io-v2_default -- SERIAL_GPS1 /dev/ttyS0 -- SERIAL_TEL1 /dev/ttyS1 -- SERIAL_TEL2 /dev/ttyS2 -- SERIAL_TEL4 /dev/ttyS3 -- UAVCAN_INTERFACES 2 -- UAVCAN_TIMER_OVERRIDE 6 -- PX4 config: px4_fmu-v5_default -- PX4 platform: nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 -- The CXX compiler identification is GNU 9.2.1 -- The C compiler identification is GNU 9.2.1 -- The ASM compiler identification is GNU -- Found assembler: /usr/bin/arm-none-eabi-gcc -- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ -- Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Enabling double FP precision hardware instructions -- cmake build type: MinSizeRel -- ccache enabled (export CCACHE_DISABLE=1 to disable) -- drivers/px4io: ROMFS including px4_io-v2_default -- Found PythonInterp: /usr/bin/python3 (found version "3.8.10") -- Using C++11 -- Release build type: MinSizeRel /usr/bin/python3: Error while finding module specification for 'symforce.symbolic' (ModuleNotFoundError: No module named 'symforce') -- ROMFS: ROMFS/px4fmu_common -- ROMFS: Adding platforms/nuttx/init/stm32f7/rc.board_arch_defaults -> /etc/init.d/rc.board_arch_defaults -- ROMFS: Adding boards/px4/fmu-v5/init/rc.board_defaults -> /etc/init.d/rc.board_defaults -- ROMFS: Adding boards/px4/fmu-v5/init/rc.board_sensors -> /etc/init.d/rc.board_sensors -- ROMFS: Adding boards/px4/fmu-v5/extras/px4_fmu-v5_bootloader.bin -> /etc/extras/px4_fmu-v5_bootloader.bin -- ROMFS: Adding boards/px4/fmu-v5/extras/px4_io-v2_default.bin -> /etc/extras/px4_io-v2_default.bin -- Configuring done -- Generating done -- Build files have been written to: /home/me/下载/px4-autopilot-1.15.4/build/px4_fmu-v5_default [0/1324] git submodule src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client [8/1324] git submodule platforms/nuttx/NuttX/nuttx [10/1324] Generating git version header FAILED: src/lib/version/build_git_version.h cd /home/me/下载/px4-autopilot-1.15.4 && /usr/bin/python3 /home/me/下载/px4-autopilot-1.15.4/src/lib/version/px_update_git_header.py /home/me/下载/px4-autopilot-1.15.4/build/px4_fmu-v5_default/src/lib/version/build_git_version.h --validate Error: the git tag 'ba685c85fc' does not match the expected format. The expected format is 'v<PX4 version>[-<custom version>]' <PX4 version>: v<major>.<minor>.<patch>[-rc<rc>|-beta<beta>|-alpha<alpha>|-dev] <custom version>: <major>.<minor>.<patch>[-rc<rc>|-beta<beta>|-alpha<alpha>|-dev] Examples: v1.9.0-rc3 (preferred) v1.9.0-beta1 v1.9.0-1.0.0 v1.9.0-1.0.0-alpha2 See also https://docs.px4.io/main/en/dev_setup/building_px4.html#building-for-nuttx [19/1324] Generating ../../../platforms/nuttx/NuttX/nuttx/.config fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx fatal: 不是 git 仓库:/home/me/下载/px4-autopilot-1.15.4/platforms/nuttx/NuttX/nuttx/../../../../.git/modules/platforms/nuttx/NuttX/nuttx mv: 无法获取'.version.tmp' 的文件状态(stat): 没有那个文件或目录 [20/1324] Generating uORB topic ucdr headers ninja: build stopped: subcommand failed. make: *** [Makefile:227:px4_fmu-v5_default] 错误 1 me@me-Yilong15Pro-Series-GM5HG0A:~/下载/px4-autopilot-1.15.4$
最新发布
08-15
<think>我们正在处理PX4编译过程中出现的两个主要问题: 1. CMakeLists.txt中的list index out of range错误(129行、131行、132行) 2. 多个git子模块路径未匹配的错误(如NuttX、heatshrink、libuavcan等) 根据错误信息,我们可以推断: - 在CMakeLists.txt的第129、131、132行,对列表的操作可能因为列表为空而越界。 - 多个子模块(如NuttX、heatshrink等)没有被正确初始化,导致git无法找到路径。 解决方案分为两个部分: 第一部分:解决子模块未初始化的问题 第二部分:修复CMakeLists.txt中的错误 详细步骤: ### 第一部分:确保所有子模块正确初始化 1. **更新子模块**: 在PX4源码根目录下执行以下命令,确保所有子模块被拉取和初始化: ```bash git submodule update --init --recursive ``` 如果遇到某些子模块更新失败(可能由于网络问题),可以尝试单独初始化: ```bash # 例如,单独初始化NuttX子模块 git submodule update --init platforms/nuttx/NuttX ``` 2. **检查子模块状态**: 使用以下命令检查子模块状态: ```bash git submodule status ``` 如果状态为`-`开头,表示该子模块尚未初始化,需要手动初始化。 3. **如果子模块初始化失败(例如网络问题),可以尝试以下替代方案**: - 修改`.gitmodules`文件中相关子模块的URL为国内镜像(如gitee) - 或者手动下载子模块代码并放入对应目录 4. **注意权限问题**: 如果之前使用了`sudo`执行部分命令,可能导致一些目录的权限问题。建议在用户权限下操作,避免混合使用sudo和普通用户权限。 ### 第二部分:修复CMakeLists.txt中的错误 根据错误信息,CMakeLists.txt中第129、131、132行出现了问题。我们分析可能的原因: - 错误1和2:`list index: 1 out of range (-1, 0)` 和 `list index: 2 out of range (-1, 0)` 这通常是因为对一个空列表或者长度不足的列表进行索引操作。我们需要查看相关代码。 - 错误3:`string sub-command REPLACE requires at least four arguments.` 说明`string(REPLACE ...)`命令缺少参数,需要至少四个参数(旧字符串、新字符串、输出变量和输入字符串)。 由于我们没有具体的CMakeLists.txt内容,只能根据常见情况给出建议: 1. **检查相关代码行**: 打开CMakeLists.txt,定位到第129行、131行、132行(可能因版本不同而略有差异,但错误信息中指出了行号)。 例如,假设129行附近代码可能是这样的: ```cmake # 假设原始代码(可能因为split结果为空列表导致索引失败) string(REPLACE ":" ";" BOARD_MEMORY_LIST ${BOARD_MEMORY}) list(GET BOARD_MEMORY_LIST 1 MEMORY_TYPE) ``` 如果`BOARD_MEMORY`不包含冒号,那么`BOARD_MEMORY_LIST`就会是一个只有一个元素的列表,索引1就会越界。 2. **修复方法**: 在索引列表之前,先检查列表长度: ```cmake # 修改后的代码 string(REPLACE ":" ";" BOARD_MEMORY_LIST ${BOARD_MEMORY}) list(LENGTH BOARD_MEMORY_LIST MEMORY_LIST_LEN) if(MEMORY_LIST_LEN GREATER 1) list(GET BOARD_MEMORY_LIST 1 MEMORY_TYPE) else() # 处理错误情况,比如设置默认值或报错 message(FATAL_ERROR "BOARD_MEMORY format error: ${BOARD_MEMORY}") endif() ``` 3. **对于string命令参数不足的错误**: 确保`string(REPLACE ...)`命令有四个参数: ```cmake # 正确格式 string(REPLACE <old_string> <new_string> <output_variable> <input>) ``` 检查第132行,确保格式正确。 4. **如果上述方法无效,考虑升级CMake**: 错误信息中提到了`CMP0097`策略未知(引用[1]),说明当前CMake版本过低。PX4需要较新版本的CMake(至少3.16以上,推荐3.18+)。 升级CMake的方法: - **Ubuntu**: ```bash sudo apt remove cmake sudo apt install cmake # 如果官方源版本低,考虑使用Kitware的仓库 sudo apt update && sudo apt install apt-transport-https ca-certificates gnupg software-properties-common wget wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" sudo apt update sudo apt install cmake ``` 5. **清理构建目录**: 在修复代码后,务必清理之前的构建缓存: ```bash rm -rf build/ ``` 6. **重新构建**: ```bash make px4_fmu-v5_default ``` ### 其他可能的问题 1. **Python模块缺失**: 错误信息中出现了`No module named 'symforce'`,需要安装symforce: ```bash pip3 install symforce ``` 2. **权限问题**(引用[5]): 确保整个编译过程使用相同的用户权限(不要混合使用sudo和普通用户)。 3. **构建目标选择**: 根据错误信息,您正在构建`px4_fmu-v5_default`,请确保目标名称正确。 4. **使用Qt Creator**(引用[3][4]): 如果使用Qt Creator,请确保导入项目时选择了正确的CMakeLists.txt(根目录下的),并且Kit配置正确。 5. **路径问题**(引用[2]): 如果CMake找不到某些文件,可能需要调整路径设置。例如,将相对路径改为绝对路径,或者使用`${CMAKE_SOURCE_DIR}`。 ### 总结步骤 1. 确保子模块全部初始化:`git submodule update --init --recursive` 2. 升级CMake到最新版本(至少3.16+) 3. 修复CMakeLists.txt中的列表索引和字符串替换命令(添加长度检查) 4. 安装缺失的Python包:`pip3 install symforce` 5. 清理构建目录:`rm -rf build/` 6. 重新构建:`make px4_fmu-v5_default` 如果问题仍然存在,请提供CMakeLists.txt中相关行(129-132行)的代码,以便进一步分析。 引用说明: [^1]: 提到了CMake策略未知,需要升级CMake。 [^5]: 提到了权限问题和编译目标的选择。</think>以下是针对 PX4 编译过程中出现的 CMake 列表索引错误和 Git 子模块路径问题的完整解决方案: ### 问题根源分析 1. **CMake 列表索引越界错误**: - 在 `CMakeLists.txt` 第 129/131/132 行操作空列表导致索引越界 - 通常由子模块未初始化或路径变量错误引起 2. **Git 子模块路径未匹配**: - `error: 路径规格 'platforms/nuttx/NuttX/nuttx' 未匹配任何 git 已知文件` - 子模块未正确初始化或克隆失败 --- ### 解决方案 #### 第一步:修复 Git 子模块问题 ```bash # 清理无效的子模块缓存 rm -rf .git/modules/* # 强制重新初始化所有子模块 git submodule deinit --all -f git submodule update --init --recursive --force # 单独初始化关键子模块(针对报错路径) git submodule update --init platforms/nuttx/NuttX git submodule update --init src/drivers/uavcan/libuavcan git submodule update --init src/modules/mavlink/mavlink ``` #### 第二步:修复 CMake 列表操作错误 在 `CMakeLists.txt` 中添加列表长度检查(修改第 129-132 行附近): ```cmake # 原始问题代码(示例) list(GET MY_LIST 1 ITEM) # 当列表为空时报错 # 修复后代码(添加长度检查) list(LENGTH MY_LIST LIST_LEN) if(LIST_LEN GREATER 1) list(GET MY_LIST 1 ITEM) else() message(WARNING "列表为空,跳过索引操作") endif() ``` #### 第三步:解决依赖问题 ```bash # 安装缺失的 Python 模块 sudo pip3 install symforce pyros-genmsg # 修复工具链路径(根据引用[5]的权限问题) sudo chown -R $USER:$USER /opt/arm-gcc-toolchain export PATH=$PATH:/opt/arm-gcc-toolchain/bin ``` #### 第四步:完整构建流程 ```bash # 清理构建缓存 make clean rm -rf build/ # 重新生成构建系统(指定工具链) cmake -Bbuild -S. \ -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/Toolchain-arm-none-eabi.cmake \ -DCMAKE_BUILD_TYPE=MinSizeRel # 开始编译 make px4_fmu-v5_default -j$(nproc) ``` #### 第五步:验证关键配置 1. 在 `src/drivers/uavcan/CMakeLists.txt` 中修复路径引用: ```cmake # 修改前(绝对路径错误) add_subdirectory("/home/me/下载/.../libuavcan") # 修改后(使用相对路径) add_subdirectory(${CMAKE_SOURCE_DIR}/src/drivers/uavcan/libuavcan) ``` 2. 在 `src/modules/uxrce_dds_client/CMakeLists.txt` 中指定下载源: ```cmake # 添加 URL 源(引用[4]的解决方案) ExternalProject_Add(libmicroxrceddsclient_project URL https://github.com/eProsima/Micro-XRCE-DDS-Client/archive/v2.4.1.tar.gz SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client ) ``` --- ### 预防措施 1. **子模块管理**: ```bash # 每次更新代码后执行 git pull --recurse-submodules git submodule update --init --recursive ``` 2. **环境配置检查**: ```bash # 验证关键工具版本 cmake --version # 需要 ≥3.16 arm-none-eabi-gcc --version # 需要 ≥9.2.1 python3 -c "import symforce; print(symforce.__version__)" # 需要 ≥0.8.0 ``` 3. **权限管理(引用[5])**: - 避免混合使用 `sudo` 和普通用户权限 - 统一使用普通用户操作:`sudo chown -R $USER:$USER ~/px4-autopilot` --- ### 常见错误处理参考 | 错误类型 | 解决方案 | 引用来源 | |---------|---------|---------| | `Policy “CMP0097” unknown` | 升级 CMake ≥3.15 | [^1] | | 路径未匹配 | 修复子模块初始化 | [^2] | | Python 模块缺失 | `pip install symforce pyros-genmsg` | [^4] | | 权限导致路径问题 | 统一操作权限 | [^5] | 通过以上步骤应能解决列出的构建错误。如果问题仍然存在,请提供 `build/CMakeError.log` 的具体内容以便进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值