我想仅使用CLI在Windows上编译一个OpenCV C/C++(MSYS2)程序。实现这一点的GNU Bash方法是(在MSYS2 MINGW64 Shell上运行良好):
g++ main.cc -o main `pkg-config --cflags --libs opencv4`
Bash完美地将反号识别为子表达式,而PowerShell则不能:
> g++ main.cc -o main `pkg-config --cflags --libs opencv4`
g++.exe: error: unrecognized command-line option '--cflags'
g++.exe: error: unrecognized command-line option '--libs'
我做了一些研究,PowerShell上的等价物是
g++ main.cc -o main $(pkg-config --cflags --libs opencv4)
尽管$(pkg-config --cflags --libs opencv4)
是在PowerShell中写入子表达式的正确方式,因为ECHO命令显示它会产生正确的输出(在本例中,编译器INCLUDE和链接器标志是我需要的):
> echo $(pkg-config --cflags --libs opencv4)
-IC:/msys64/mingw64/bin/../include/opencv4 -LC:/msys64/mingw64/bin/../lib -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_ccalib -lopencv_cvv -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm (...)
这根本行不通:
> g++ main.cc -o main $(pkg-config --cflags --libs opencv4)
main.cc:1:10: fatal error: opencv2/imgcodecs.hpp: No such file or directory
1 | #include <opencv2/imgcodecs.hpp>
| ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
因此,我需要使用详细的解决方法来编译我的文件:
> g++ main.cc -o main -IC:/msys64/mingw64/bin/../include/opencv4 -LC:/msys64/mingw64/bin/../lib -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_ccalib -lopencv_cvv -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash (...)
我的PowerShell版本:
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.22621.608
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.608
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
我的问题是:我如何才能使这个特定的子表达式在PowerShell中工作,这样我就不必求助于在g++ main.cc -o main
之后复制和粘贴pkg-config --cflags --libs opencv4
的输出的冗长后备?
1条答案
按热度按时间rjee0c151#
相当于您的
bash
命令是:即:
(pkg-config --cflags --libs opencv4)
执行pkg-config
调用,通过将其包含在分组运算符(...)
中,其输出可以参与更大的表达式。-split
的一元形式string splitting operator,然后将pkg-config
调用的输出拆分成一个由空格分隔的数组,这相当于bash
*隐含地通过其名为word splitting的shell expansion执行的操作。注:
$(...)
,PowerShell的子表达式运算符在这种情况下不工作,因为它的输出将作为一个整体*,作为单个参数传递给目标可执行文件(或者,在输出多个行的外部程序调用的情况下,每行完整将作为一个参数传递)。bash
需要$(...)
(或其遗留形式...
)时,PowerShell中的(...)
通常就足够了**(在作业中甚至不需要,例如$var = Get-Date
);PowerShell中$(...)
的主要用例是在"..."
中,即在可扩展(双引号)的字符串中bash
的shell expansions:${var//foo/bar}
)不受支持,而需要使用表达式*(例如($var -replace 'foo', 'bar')
)-*转义*(
,所谓的反号,是PowerShell的escape character),或者要求将整个参数括在引号中。~
)解释为引用主目录,或将参数(如*.txt
)解释为通配符模式*-无论此类参数是否用引号传递。$var
)和基于变量引用的简单表达式(例如$var.Property
)、(分组)表达式(例如((1 + 2)
),以及子表达式($(...)
)和数组子表达式(@(...)
)可以按原样用作参数,即使它们评估为包含空格-在Windows上调用外部程序的情况下,PowerShell会在后台按需对结果进行双引号;如上所述,多个输出每个都*作为参数传递。