llvm和mingw-w64配合編譯的奇怪問題

lt發表於2016-12-12

晚上和早上都試了很久,不成功。 6.2版這個錯誤

D:\>llg62
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

D:\>clang++ p88c.cpp
In file included from p88c.cpp:1:
In file included from d:\mingw32\lib\gcc\i686-w64-mingw32\6.2.0\include\c++\cstdio:42:
d:\mingw32\i686-w64-mingw32\include\stdio.h:167:63: error: expected ';' after top level declarator
  int __cdecl __mingw_printf(const char * __restrict__ , ... ) __MINGW_NOTHROW;
                                                              ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:170:68: error: expected ';' after top level declarator
  int __cdecl __mingw_vprintf (const char * __restrict__ , va_list) __MINGW_NOTHROW;
                                                                   ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:173:86: error: expected ';' after top level declarator
  int __cdecl __mingw_fprintf (FILE * __restrict__ , const char * __restrict__ , ...) __MINGW_NOTHROW;
                                                                                     ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:176:91: error: expected ';' after top level declarator
  int __cdecl __mingw_vfprintf (FILE * __restrict__ , const char * __restrict__ , va_list) __MINGW_NOTHROW;
                                                                                          ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:179:86: error: expected ';' after top level declarator
  int __cdecl __mingw_sprintf (char * __restrict__ , const char * __restrict__ , ...) __MINGW_NOTHROW;
                                                                                     ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:182:91: error: expected ';' after top level declarator
  int __cdecl __mingw_vsprintf (char * __restrict__ , const char * __restrict__ , va_list) __MINGW_NOTHROW;
                                                                                          ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:185:87: error: expected ';' after top level declarator
  int __cdecl __mingw_asprintf(char ** __restrict__ , const char * __restrict__ , ...) __MINGW_NOTHROW;
                                                                                      ^
d:\mingw32\i686-w64-mingw32\include\stdio.h:188:92: error: expected ';' after top level declarator
  int __cdecl __mingw_vasprintf(char ** __restrict__ , const char * __restrict__ , va_list) __MINGW_NOTHROW;
                                                                                           ^
8 errors generated.

D:\>type llg62.bat
@rem set run llvm+clang with mingw path env
@echo off
set MINGW_HOME=d:\mingw32
set MINGW_VERSION=6.2.0
set SS=i686-w64-mingw32
set "PATH=%MINGW_HOME%\bin;%PATH%"
set "C_INCLUDE_PATH=%MINGW_HOME%\include;%MINGW_HOME%\%SS%\include"
set "CPLUS_INCLUDE_PATH=%C_INCLUDE_PATH%;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++;%MING
W_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++\%SS%;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++\backward"
set  LLVM_HOME=D:\llvm
set "PATH=%LLVM_HOME%\bin;%PATH%"
%comspec%

4.9-5.1版這個錯誤

D:\>llg49
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

D:\>clang++ p88c.cpp
p88c.cpp:51:28: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("%lld %d\n",sum,clock()-t);
                 ~~        ^~~~~~~~~
                 %ld
1 warning generated.
p88c-ede23b.o : error LNK2019: 無法解析的外部符號 __imp__clock,該符號在函式 _main 中被引用
p88c-ede23b.o : error LNK2019: 無法解析的外部符號 __imp__printf,該符號在函式 _main 中被引用
a.exe : fatal error LNK1120: 2 個無法解析的外部命令
clang++.exe: error: linker command failed with exit code 1120 (use -v to see invocation)



D:\>type llg49.bat
@rem set run llvm+clang with mingw path env
@echo off
set MINGW_HOME=D:\cb\MinGW
set MINGW_VERSION=4.9.2
set SS=mingw32
set "PATH=%MINGW_HOME%\bin;%PATH%"
set "C_INCLUDE_PATH=%MINGW_HOME%\include;%MINGW_HOME%\%SS%\include"
set "CPLUS_INCLUDE_PATH=%C_INCLUDE_PATH%;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++;%MING
W_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++\%SS%;%MINGW_HOME%\lib\gcc\%SS%\%MINGW_VERSION%\include\c++\backward"
set  LLVM_HOME=D:\llvm
set "PATH=%LLVM_HOME%\bin;%PATH%"
%comspec%

檢視過去做的.bat檔案,無意就能用了,注意,這裡的c_include,c_plus_include全是錯的。總結的成功經驗就是先把g++的路徑設對了,然後把llvm的include路徑設錯。

D:\>gwin49

D:\>D:\cb\MinGW\mingwvars.bat

Setting up environment for using MinGW with GCC from D:\cb\MinGW\.

D:\>llg
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

D:\>clang++ p88c.cpp
p88c.cpp:51:28: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("%lld %d\n",sum,clock()-t);
                 ~~        ^~~~~~~~~
                 %ld
1 warning generated.


D:\>type gwin49.bat
D:\cb\MinGW\mingwvars.bat
D:\>type D:\cb\MinGW\mingwvars.bat
@echo.
@echo Setting up environment for using MinGW with GCC from %~dp0.
@set PATH=%~dp0bin;%PATH%

D:\>type llg.bat
@rem set run llvm+clang with mingw path env
@echo off
set MINGW_HOME=d:\mingw32
set MINGW_VERSION=6.2.0
set "PATH=%MINGW_HOME%\bin;%PATH%"
set "C_INCLUDE_PATH=%MINGW_HOME%\include;%MINGW_HOME%\x86_64-w64-mingw32\include"
set "CPLUS_INCLUDE_PATH=%C_INCLUDE_PATH%;%MINGW_HOME%\lib\gcc\x86_64-w64-mingw32\%MINGW_VERSION%\include;%MINGW_HOME%\lib\gcc\x86_64-w64-mingw32\%MING
W_VERSION%\include\c++;%MINGW_HOME%\lib\gcc\x86_64-w64-mingw32\%MINGW_VERSION%\include\c++\x86_64-w64-mingw32;%MINGW_HOME%\lib\gcc\x86_64-w64-mingw32\
%MINGW_VERSION%\include\c++\backward"
set  LLVM_HOME=D:\llvm
set "PATH=%LLVM_HOME%\bin;%PATH%"
%comspec%
D:\>cd %MINGW_HOME%\x86_64-w64-mingw32\include
系統找不到指定的路徑。

D:\>g++ --version
g++ (i686-win32-sjlj-rev1, Built by MinGW-W64 project) 6.2.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

D:\>g++ p88c.cpp -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=d:/mingw32/bin/../libexec/gcc/i686-w64-mingw32/6.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
...

最新試驗,其實只要一個llg.bat就夠了,它裡面包含了mingw的一些路徑,內容見上文

D:\>llg
Microsoft Windows [版本 6.1.7601]
版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

D:\>glang++ p88c.cpp
'glang++' 不是內部或外部命令,也不是可執行的程式
或批處理檔案。

D:\>clang++ p88c.cpp
p88c.cpp:51:28: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("%lld %d\n",sum,clock()-t);
                 ~~        ^~~~~~~~~
                 %ld
1 warning generated.

雖然mingw的cplus_include全不對,cpp程式也能正確編譯和連線

D:\>clang++ p88cpp.cpp
p88cpp.cpp:51:28: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("%lld %d\n",sum,clock()-t);cout << sum;
                 ~~        ^~~~~~~~~
                 %ld
p88cpp.cpp:51:39: error: use of undeclared identifier 'cout'; did you mean 'std::cout'?
    printf("%lld %d\n",sum,clock()-t);cout << sum;
                                      ^~~~
                                      std::cout
C:\Program Files\Microsoft Visual Studio 14.0\VC\include\iostream:27:50: note: 'std::cout' declared here
__PURE_APPDOMAIN_GLOBAL extern _CRTDATA2 ostream cout, *_Ptr_cout;
                                                 ^
1 warning and 1 error generated.

D:\>clang++ p88cpp.cpp
p88cpp.cpp:51:28: warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
    printf("%lld %d\n",sum,clock()-t);std::cout << sum;
                 ~~        ^~~~~~~~~
                 %ld
1 warning generated.

這篇文章說到,關於MingW的版本需要注意的是x86版本的要選擇異常處理模式為dwarf的版本而不是sjlj模式,否則編譯出來的clang++是不支援異常處理的。因為clang不支援sjlj模式。至於,x64版本MingW就別搞了,因為clang也不支援seh模式。 今天用了-v引數,才知道在這臺機器上clang呼叫的原來根本就是vc。

D:\>clang++ p582a.cpp -O2 -v
clang version 4.0.0 (trunk)
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: D:\LLVM\bin
 "D:\\llvm\\bin\\clang++.exe" -cc1 -triple i686-pc-windows-msvc19.0.24215 -emit-obj -mincremental-linker-compatible -disable-free -main-file-name p582
a.cpp -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu pentium4 -momit-leaf-frame-pointer -
v -dwarf-column-info -debugger-tuning=gdb -resource-dir "D:\\llvm\\bin\\..\\lib\\clang\\4.0.0" -c-isystem "d:\\mingw32\\include" -c-isystem "d:\\mingw
32\\x86_64-w64-mingw32\\include" -cxx-isystem "d:\\mingw32\\include" -cxx-isystem "d:\\mingw32\\x86_64-w64-mingw32\\include" -cxx-isystem "d:\\mingw32
\\lib\\gcc\\x86_64-w64-mingw32\\6.2.0\\include" -cxx-isystem "d:\\mingw32\\lib\\gcc\\x86_64-w64-mingw32\\6.2.0\\include\\c++" -cxx-isystem "d:\\mingw3
2\\lib\\gcc\\x86_64-w64-mingw32\\6.2.0\\include\\c++\\x86_64-w64-mingw32" -cxx-isystem "d:\\mingw32\\lib\\gcc\\x86_64-w64-mingw32\\6.2.0\\include\\c++
\\backward" -internal-isystem "D:\\llvm\\bin\\..\\lib\\clang\\4.0.0\\include" -internal-isystem "C:\\Program Files\\Microsoft Visual Studio 14.0\\VC\\
include" -internal-isystem "C:\\Program Files\\Windows Kits\\10\\Include\\10.0.10240.0\\ucrt" -internal-isystem "C:\\Program Files\\Windows Kits\\8.1\
\include\\shared" -internal-isystem "C:\\Program Files\\Windows Kits\\8.1\\include\\um" -internal-isystem "C:\\Program Files\\Windows Kits\\8.1\\inclu
de\\winrt" -O2 -fdeprecated-macro -fdebug-compilation-dir "D:\\" -ferror-limit 19 -fmessage-length 150 -fms-extensions -fms-compatibility -fms-compati
bility-version=19.0.24215 -std=c++14 -fdelayed-template-parsing -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-dia
gnostics -vectorize-loops -vectorize-slp -o "C:\\Users\\gjnbs\\AppData\\Local\\Temp\\p582a-215ae6.o" -x c++ p582a.cpp
clang -cc1 version 4.0.0 based upon LLVM 4.0.0-r282394 default target i686-pc-windows-msvc
ignoring nonexistent directory "d:\mingw32\x86_64-w64-mingw32\include"
ignoring nonexistent directory "d:\mingw32\x86_64-w64-mingw32\include"
ignoring nonexistent directory "d:\mingw32\lib\gcc\x86_64-w64-mingw32\6.2.0\include"
ignoring nonexistent directory "d:\mingw32\lib\gcc\x86_64-w64-mingw32\6.2.0\include\c++"
ignoring nonexistent directory "d:\mingw32\lib\gcc\x86_64-w64-mingw32\6.2.0\include\c++\x86_64-w64-mingw32"
ignoring nonexistent directory "d:\mingw32\lib\gcc\x86_64-w64-mingw32\6.2.0\include\c++\backward"
#include "..." search starts here:
#include <...> search starts here:
 d:\mingw32\include
 D:\llvm\bin\..\lib\clang\4.0.0\include
 C:\Program Files\Microsoft Visual Studio 14.0\VC\include
 C:\Program Files\Windows Kits\10\Include\10.0.10240.0\ucrt
 C:\Program Files\Windows Kits\8.1\include\shared
 C:\Program Files\Windows Kits\8.1\include\um
 C:\Program Files\Windows Kits\8.1\include\winrt
End of search list.
p582a.cpp:78:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
 "C:\\Program Files\\Microsoft Visual Studio 14.0\\VC\\bin\\link.exe" -out:a.exe -defaultlib:libcmt "-libpath:C:\\Program Files\\Microsoft Visual Stud
io 14.0\\VC\\lib" "-libpath:C:\\Program Files\\Windows Kits\\10\\Lib\\10.0.10240.0\\ucrt\\x86" "-libpath:C:\\Program Files\\Windows Kits\\8.1\\Lib\\wi
nv6.3\\um\\x86" -nologo "C:\\Users\\gjnbs\\AppData\\Local\\Temp\\p582a-215ae6.o"

相關文章