xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
9.86k stars 775 forks source link

Can't use openmp on windows #1884

Closed xq114 closed 2 years ago

xq114 commented 2 years ago

描述问题

windows上无法使用openmp

期待的结果

正常使用openmp

错误信息

如果是xmake相关编译问题,请加上-vD参数运行,并给出完整编译输出信息以及执行的完整命令,例如:

$ xmake f -vD -c
checking for platform ... windows
checking for architecture ... x64
checking for vswhere.exe ... C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for Microsoft Visual Studio (x64) version ... 2019
checkinfo: cannot runv(dmd.exe --version), No such file or directory
checking for dmd ... no
checkinfo: cannot runv(ldc2.exe --version), No such file or directory
checking for ldc2 ... no
checkinfo: cannot runv(gdc.exe --version), No such file or directory
checking for gdc ... no
checkinfo: cannot runv(zig.exe version), No such file or directorychecking for zig ... no
checkinfo: cannot runv(zig.exe version), No such file or directorychecking for zig ... no
checkinfo: cannot runv(unzip.exe -v), No such file or directory   
checking for unzip ... no
checking for 7z ... C:\Users\xq114\xmake\winenv\bin\7z
checking for git ... ok
checkinfo: cannot runv(gzip.exe --version), No such file or directory
checking for gzip ... no
git rev-parse HEAD
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for the c++ compiler (cxx) ... cl.exe
finding runenvs from xmake ..
checking for xmake::runenvs ... runenvs latest
checking for xmake-repo::openmp ... openmp 
checking for link.exe ... C:\Program Files (x86)\Microsoft Visual 
Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\link.exe
checking for the linker (ld) ... link.exe
configure
{
    ndk_stdcxx = true
    host = windows
    network = public
    ccache = true
    proxy_pac = pac.lua
    kind = static
    pkg_searchdirs = C:/Users/xq114/Downloads
    buildir = build
    clean = true
    mode = release
    theme = default
    plat = windows
    arch = x64
    vs = 2019
}
PS C:\Users\xq114\OneDrive - pku.edu.cn\WorksOnCloud\Output\Lectures\202112 C.Cpp Build System\HelloOpenMP> xmake f -cvD
checking for platform ... windows
checking for architecture ... x64
checking for vswhere.exe ... C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for Microsoft Visual Studio (x64) version ... 2019
checkinfo: cannot runv(dmd.exe --version), No such file or directory
checking for dmd ... no
checkinfo: cannot runv(ldc2.exe --version), No such file or directory
checking for ldc2 ... no
checkinfo: cannot runv(gdc.exe --version), No such file or directory
checking for gdc ... no
checkinfo: cannot runv(zig.exe version), No such file or directorychecking for zig ... no
checkinfo: cannot runv(zig.exe version), No such file or directorychecking for zig ... no
checkinfo: cannot runv(unzip.exe -v), No such file or directory   
checking for unzip ... no
checking for 7z ... C:\Users\xq114\xmake\winenv\bin\7z
checking for git ... ok
checkinfo: cannot runv(gzip.exe --version), No such file or directory
checking for gzip ... no
git rev-parse HEAD
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
checking for cl.exe ... C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe
checking for the c++ compiler (cxx) ... cl.exe
checking for xmake-repo::openmp ... openmp 
checking for link.exe ... C:\Program Files (x86)\Microsoft Visual 
Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\link.exe
checking for the linker (ld) ... link.exe
configure
{
    mode = release
    network = public
    arch = x64
    host = windows
    pkg_searchdirs = C:/Users/xq114/Downloads
    proxy_pac = pac.lua
    ccache = true
    clean = true
    kind = static
    plat = windows
    buildir = build
    vs = 2019
    ndk_stdcxx = true
    theme = default
}
$ xmake -vD
checking for the c compiler (cc) ... cl.exe
checking for C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe ... ok  
checking for flags (-Ox -fp:fast) ... ok
> cl.exe "-Ox" "-fp:fast"
checking for flags (-DNDEBUG) ... ok
> cl.exe "-DNDEBUG" "-nologo"
checkinfo: cannot runv(ccache.exe --version), No such file or directory
checking for ccache ... no
[ 25%]: compiling.release main.c
"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX64\\x64\\cl.exe" -c -nologo -Ox -fp:fast -DNDEBUG -Fobuild\.objs\main\windows\x64\release\main.c.obj main.c
checking for flags (cl_sourceDependencies) ... ok
> cl.exe "/sourceDependencies" "C:\Users\xq114\AppData\Local\Temp\.xmake\211204\_B2A8E382C4F14C108BB2172AE132DD40.json" "-nologo"   
[ 50%]: linking.release main.exe
"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX64\\x64\\link.exe" -nologo -dynamicbase -nxcompat -machine:x64 /opt:ref /opt:icf -out:build\windows\x64\release\main.exe build\.objs\main\windows\x64\release\main.c.obj
[100%]: build ok!

没有任何一步加了openmp的flag

相关环境

请提供编译和运行环境信息,下面是一些必须填写的基础信息,便于我们针对性排查问题:

其他信息

--xmake.lua
add_rules("mode.debug", "mode.release")
add_requires("openmp")
target("main")
    add_files("main.c")
    add_packages("openmp")

把openmp package的on_fetch返回{}删掉之后,运行xmake f -c会提示安装,安装完毕后可以正常使用openmp

xq114 commented 2 years ago

并且现在还无法支持探测openmp 的存在性,一直是返回true的

waruqi commented 2 years ago

我记得之前可以的么

waruqi commented 2 years ago

确实有点问题,我得调下

waruqi commented 2 years ago

修复了,再试下。。xrepo update-repo; xmake f -c; xmake

xq114 commented 2 years ago

修复了,再试下。。xrepo update-repo; xmake f -c; xmake

现在会提示安装,安装后可用,但还有几个问题:

  1. 无法检测是否存在openmp,on_test那个只要存在omp.h就可以过编译,不需要-fopenmp的flag也能运行。
  2. openmp是针对编译器和toolchain的,而xmake的安装不区分toolchain,导致换toolchain之后也还是用的原来的flag,出现问题。
waruqi commented 2 years ago

改了下 再试试

xq114 commented 2 years ago

改了下 再试试

问题2解决了,1还是没有解决

1可以先这样测试:把/openmp、-fopenmp这些都换成/openmpp、-fopenmpp,这样编译器不包含这个flag,应该提示fetch失败,toolchain不支持openmp。现在不会有任何提示

waruqi commented 2 years ago

这个是 on_test 里面的 test code 问题, #pragma omp parallel 不支持,没flags,编译器顶多忽略,不会触发编译失败。。

对 openmp 不熟,你可以找下有没有 macros 啥来做检测,触发 #error 来个 pr 改进下 on_test

xq114 commented 2 years ago

这个是 on_test 里面的 test code 问题, #pragma omp parallel 不支持,没flags,编译器顶多忽略,不会触发编译失败。。

对 openmp 不熟,你可以找下有没有 macros 啥来做检测,触发 #error 来个 pr 改进下 on_test

我这on_fetch直接返回了,没走到on_test

xq114 commented 2 years ago

可以用#ifndef _OPENMP这个 macro来检测

waruqi commented 2 years ago

可以用#ifndef _OPENMP这个 macro来检测

跨编译器?

xq114 commented 2 years ago

可以用#ifndef _OPENMP这个 macro来检测

跨编译器?

对,这个macro表示openmp的版本,201611这种,类似__cplusplus

waruqi commented 2 years ago

加上了

xq114 commented 2 years ago

加上了

没有,我这边实测on_fetch直接返回不会走到on_test,在没有openmp的地方也不会报错

waruqi commented 2 years ago

这个目前没办法,如果首次 fetch 返回非 nil,就是当做这个包已经被安装,被找到了,就不会走 on_test 逻辑

之后首次找不到,然后走了 on_install 后,才会走到 on_test 逻辑,目前就带有 libomp 的情况,如果 libomp 还没装,那么首次就会整体安装后走测试

如果纯编译器 flags 的 openmp 情况,首次 fetch 就直接返回结果了,目前没办法走测试。。

目前只能做到这个程度,除非不走 on_fetch ,走 on_load 那就又会有编译器不实时切换生效的问题。。所以先这么凑活着用吧。暂时无解,但也问题不大

xq114 commented 2 years ago

这个目前没办法,如果首次 fetch 返回非 nil,就是当做这个包已经被安装,被找到了,就不会走 on_test 逻辑

不用走on_test,也可以在on_fetch里面检测,同时顺便把版本也确定了。

local ok, stdout = package:check_csnippets({test = [[
#include <omp.h>
int main() {
#ifndef _OPENMP
#error openmp not found
#else
  printf("%d", _OPENMP)
#endif
}
]]}, {cflags = result.cflags, ldflags = result.ldflags, output = true, tryrun = true})
if ok then
  result.version = map[stdout]
  return result
end
waruqi commented 2 years ago

理论上可以,但是感觉也没啥必要,总共就那么几个 flags ,写错的概率本来就低,没必要搞这么复杂,只要做包阶段基本搞定。这些 flags 基本都能过掉。。

而且带 libomp 走实际安装的,还得跑 on_test,测试两边。。

另外 fetch 可能会在包的各种地方被多次执行,相当于多次检测。。

xq114 commented 2 years ago

理论上可以,但是感觉也没啥必要,总共就那么几个 flags ,写错的概率本来就低,没必要搞这么复杂,只要做包阶段基本搞定。这些 flags 基本都能过掉。。

不是flag写错的问题,是有的编译器(老版本编译器,或者自定义toolchain)压根不支持openmp,做成package的原意也就是探测到底有没有openmp。cmake是用的FindOpenMP.cmake来检测,支持检测存在性和openmp版本,xmake应该也能做到才对

而且带 libomp 走实际安装的,还得跑 on_test,测试两边。。

应该不会吧?带libomp的在on_fetch前已经安装/查找完成,on_fetch会直接返回,走不到on_install更走不到on_test,这个空的on_install应该可以去掉

另外 fetch 可能会在包的各种地方被多次执行,相当于多次检测。。

这个可以加个缓存,对于包fetch的结果加缓存也挺合理。如果说每次执行on_fetch就打印一行check for openmp...的话,从log里看只执行了一次,应该没啥影响

waruqi commented 2 years ago

应该不会吧?带libomp的在on_fetch前已经安装/查找完成,on_fetch会直接返回,走不到on_install更走不到on_test,这个空的on_install应该可以去掉

如果 libomp 没装,on_fetch 开头的 return 会返回 nil 然后走安装 libomp 和 on_install 再走 on_test

如果 libomp 装好了,才不会走