MinGW による Windows 95 サポート
@@ -59,6 +59,8 @@ | ||
59 | 59 | elseif(MINGW) |
60 | 60 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}") |
61 | 61 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=${_WIN32_WINNT}") |
62 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__USE_MINGW_ANSI_STDIO=0") | |
63 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=0") | |
62 | 64 | set(CMAKE_C_CXX_WARNING_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare") |
63 | 65 | set(CMAKE_C_WARNING_FLAGS "${CMAKE_C_CXX_WARNING_FLAGS} -Wno-pointer-sign") |
64 | 66 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARNING_FLAGS} -static -ffunction-sections -fdata-sections ${C_ONLY_FLAGS}") |
@@ -172,7 +174,7 @@ | ||
172 | 174 | add_subdirectory(installer) |
173 | 175 | add_subdirectory(doc) |
174 | 176 | add_subdirectory(doc_internal) |
175 | -add_subdirectory(tools) | |
177 | +#add_subdirectory(tools) | |
176 | 178 | |
177 | 179 | ### create buildinfo.txt |
178 | 180 | configure_file( |
@@ -28,6 +28,20 @@ | ||
28 | 28 | ../../teraterm/common/compat_w95_vs2005.c |
29 | 29 | ) |
30 | 30 | endif() |
31 | + if(MINGW) | |
32 | + target_sources( | |
33 | + ${PACKAGE_NAME} | |
34 | + PRIVATE | |
35 | + ../../teraterm/libmingw/tlssup.c | |
36 | + ) | |
37 | + target_link_libraries( | |
38 | + ${PACKAGE_NAME} | |
39 | + PRIVATE | |
40 | + -Wl,--whole-archive | |
41 | + mingw_msvcrt | |
42 | + -Wl,--no-whole-archive | |
43 | + ) | |
44 | + endif() | |
31 | 45 | endif(SUPPORT_OLD_WINDOWS) |
32 | 46 | |
33 | 47 | target_sources( |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -27,7 +27,21 @@ | ||
27 | 27 | ../../teraterm/common/compat_w95_vs2005.c |
28 | 28 | ) |
29 | 29 | endif() |
30 | -endif() | |
30 | + if(MINGW) | |
31 | + target_sources( | |
32 | + ${PACKAGE_NAME} | |
33 | + PRIVATE | |
34 | + ../../teraterm/libmingw/tlssup.c | |
35 | + ) | |
36 | + target_link_libraries( | |
37 | + ${PACKAGE_NAME} | |
38 | + PRIVATE | |
39 | + -Wl,--whole-archive | |
40 | + mingw_msvcrt | |
41 | + -Wl,--no-whole-archive | |
42 | + ) | |
43 | + endif() | |
44 | +endif(SUPPORT_OLD_WINDOWS) | |
31 | 45 | |
32 | 46 | source_group( |
33 | 47 | "common" |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -17,7 +17,14 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | -endif() | |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
27 | +endif(SUPPORT_OLD_WINDOWS) | |
21 | 28 | |
22 | 29 | set_target_properties( |
23 | 30 | ${PACKAGE_NAME} |
@@ -19,7 +19,21 @@ | ||
19 | 19 | ../../teraterm/common/compat_w95_vs2005.c |
20 | 20 | ) |
21 | 21 | endif() |
22 | -endif() | |
22 | + if(MINGW) | |
23 | + target_sources( | |
24 | + ${PACKAGE_NAME} | |
25 | + PRIVATE | |
26 | + ../../teraterm/libmingw/tlssup.c | |
27 | + ) | |
28 | + target_link_libraries( | |
29 | + ${PACKAGE_NAME} | |
30 | + PRIVATE | |
31 | + -Wl,--whole-archive | |
32 | + mingw_msvcrt | |
33 | + -Wl,--no-whole-archive | |
34 | + ) | |
35 | + endif() | |
36 | +endif(SUPPORT_OLD_WINDOWS) | |
23 | 37 | |
24 | 38 | source_group( |
25 | 39 | "common" |
@@ -17,6 +17,20 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + target_link_libraries( | |
27 | + ${PACKAGE_NAME} | |
28 | + PRIVATE | |
29 | + -Wl,--whole-archive | |
30 | + mingw_msvcrt | |
31 | + -Wl,--no-whole-archive | |
32 | + ) | |
33 | + endif() | |
20 | 34 | endif(SUPPORT_OLD_WINDOWS) |
21 | 35 | |
22 | 36 | if (MSVC) |
@@ -17,6 +17,13 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
20 | 27 | endif(SUPPORT_OLD_WINDOWS) |
21 | 28 | |
22 | 29 | set_target_properties( |
@@ -17,6 +17,13 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + endif() | |
20 | 27 | endif(SUPPORT_OLD_WINDOWS) |
21 | 28 | |
22 | 29 | set_target_properties( |
@@ -21,6 +21,20 @@ | ||
21 | 21 | ../../teraterm/common/compat_w95_vs2005.c |
22 | 22 | ) |
23 | 23 | endif() |
24 | + if(MINGW) | |
25 | + target_sources( | |
26 | + ${PACKAGE_NAME} | |
27 | + PRIVATE | |
28 | + ../../teraterm/libmingw/tlssup.c | |
29 | + ) | |
30 | + target_link_libraries( | |
31 | + ${PACKAGE_NAME} | |
32 | + PRIVATE | |
33 | + -Wl,--whole-archive | |
34 | + mingw_msvcrt | |
35 | + -Wl,--no-whole-archive | |
36 | + ) | |
37 | + endif() | |
24 | 38 | endif(SUPPORT_OLD_WINDOWS) |
25 | 39 | |
26 | 40 | source_group( |
@@ -17,6 +17,20 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | + if(MINGW) | |
21 | + target_sources( | |
22 | + TTXttyplay | |
23 | + PRIVATE | |
24 | + ../../teraterm/libmingw/tlssup.c | |
25 | + ) | |
26 | + target_link_libraries( | |
27 | + TTXttyplay | |
28 | + PRIVATE | |
29 | + -Wl,--whole-archive | |
30 | + mingw_msvcrt | |
31 | + -Wl,--no-whole-archive | |
32 | + ) | |
33 | + endif() | |
20 | 34 | endif(SUPPORT_OLD_WINDOWS) |
21 | 35 | |
22 | 36 | target_include_directories( |
@@ -51,6 +65,20 @@ | ||
51 | 65 | ../../teraterm/common/compat_w95_vs2005.c |
52 | 66 | ) |
53 | 67 | endif() |
68 | + if(MINGW) | |
69 | + target_sources( | |
70 | + TTXttyrec | |
71 | + PRIVATE | |
72 | + ../../teraterm/libmingw/tlssup.c | |
73 | + ) | |
74 | + target_link_libraries( | |
75 | + TTXttyrec | |
76 | + PRIVATE | |
77 | + -Wl,--whole-archive | |
78 | + mingw_msvcrt | |
79 | + -Wl,--no-whole-archive | |
80 | + ) | |
81 | + endif() | |
54 | 82 | endif(SUPPORT_OLD_WINDOWS) |
55 | 83 | |
56 | 84 | target_include_directories( |
@@ -15,6 +15,13 @@ | ||
15 | 15 | ../../teraterm/common/compat_w95_vs2005.c |
16 | 16 | ) |
17 | 17 | endif() |
18 | + if(MINGW) | |
19 | + target_sources( | |
20 | + ${PACKAGE_NAME} | |
21 | + PRIVATE | |
22 | + ../../teraterm/libmingw/tlssup.c | |
23 | + ) | |
24 | + endif() | |
18 | 25 | endif(SUPPORT_OLD_WINDOWS) |
19 | 26 | |
20 | 27 | set_target_properties( |
@@ -14,6 +14,13 @@ | ||
14 | 14 | ../../teraterm/common/compat_w95_vs2005.c |
15 | 15 | ) |
16 | 16 | endif() |
17 | + if(MINGW) | |
18 | + target_sources( | |
19 | + ${PACKAGE_NAME} | |
20 | + PRIVATE | |
21 | + ../../teraterm/libmingw/tlssup.c | |
22 | + ) | |
23 | + endif() | |
17 | 24 | endif(SUPPORT_OLD_WINDOWS) |
18 | 25 | |
19 | 26 | target_link_libraries( |
@@ -33,3 +33,10 @@ | ||
33 | 33 | set_target_properties( |
34 | 34 | common_static |
35 | 35 | PROPERTIES FOLDER teraterm) |
36 | + | |
37 | +if(SUPPORT_OLD_WINDOWS AND MINGW) | |
38 | + add_subdirectory(libmingw) | |
39 | + set_target_properties( | |
40 | + mingw_msvcrt | |
41 | + PROPERTIES FOLDER teraterm) | |
42 | +endif() |
@@ -0,0 +1,9 @@ | ||
1 | +set(PACKAGE_NAME "mingw_msvcrt") | |
2 | + | |
3 | +project(${PACKAGE_NAME}) | |
4 | + | |
5 | +add_library( | |
6 | + ${PACKAGE_NAME} | |
7 | + STATIC | |
8 | + msvcrt_wrapper.c | |
9 | + ) |
@@ -0,0 +1,31 @@ | ||
1 | +build with MinGW | |
2 | +================ | |
3 | + | |
4 | +## MinGW | |
5 | + | |
6 | +- [MinGW(Wikipedia)](https://ja.wikipedia.org/wiki/MinGW) | |
7 | +- いくつかの派生プロジェクトが存在する | |
8 | +- プロジェクトによっていくつかの選択がある | |
9 | + - GCC(clang)のバージョン | |
10 | + - ライブラリのバージョン | |
11 | + - ターゲット(i686(32bit)/x86_64(64bit)) | |
12 | + - Thread model (win32/posix) | |
13 | + - 例外 (sjlj/dwarf) | |
14 | +- 比較的新しいOSでTera Termを動作させるならどれでもokと思われる | |
15 | + | |
16 | +## printf()系の動作を Visual Studio と同じにする | |
17 | + | |
18 | +- MinGW は C99,C11 などの仕様に準拠しようとしている | |
19 | +- 古い Visual Studio は仕様策定前の実装 | |
20 | + - "%zd" など新しいフォーマット指定子 | |
21 | + - 古い Visual Studio(msvcrt.dll) の printf()系ではサポートしていない | |
22 | + - L"%s" と "%s" の動作の違い | |
23 | + - msvcrtでは %s は char, L"%s" は wchar_t | |
24 | +- 特に指定していないと MinGW の printf()系(stdio)を使用する | |
25 | +- このため Visual Studio と動作が異なってしまう | |
26 | +- `__USE_MINGW_ANSI_STDIO` マクロので切り替えることができる | |
27 | + - 1 のとき mingw の stdio (デフォルト) | |
28 | + - 0 のとき msvcrt | |
29 | +- 参考URL | |
30 | + - [printf の %lf について](https://ja.stackoverflow.com/questions/34013/printf-%E3%81%AE-lf-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6) | |
31 | + |
@@ -0,0 +1,174 @@ | ||
1 | + | |
2 | + | |
3 | +## MinGW で古いOS(Windows95)をサポートする | |
4 | + | |
5 | +ポイント | |
6 | + | |
7 | +- ランタイム(msvcrt.dll)の違いの吸収 | |
8 | +- dllのロード(loadlibrary()) | |
9 | +- pthreadを使用しない | |
10 | + | |
11 | +## ランタイム(msvcrt.dll)の違いの吸収 | |
12 | + | |
13 | +- MinGW は C runtime として msvcrt.dll (Visual Studioのランタイムdll)を使用する | |
14 | +- WindowsのバージョンによってインストールされているランタイムDLL のバージョンが異なる | |
15 | +- 使用可能な関数が異なっている | |
16 | + - [msvcrt-xref.pdf](https://sourceforge.net/projects/mingw/files/MinGW/Base/mingwrt/msvcrt-xref/) | |
17 | + | |
18 | +- CランタイムDLLのバージョンを吸収するためのwrapperを作成 | |
19 | + - msvcrt_wrapper.c を作成 | |
20 | + | |
21 | +### 未解決シンボルの追加について | |
22 | + | |
23 | +vsnprintf_s() 場合の例 | |
24 | + | |
25 | +- msvcrt-os.a を nm で調べる | |
26 | +- 1つのオブジェクトファイルに次の2つのシンボルがあることがわかる | |
27 | + - __imp__vsnprintf_s | |
28 | + - _vsnprintf_s | |
29 | +- `__declspec(dllimport)` 属性の関数の場合 | |
30 | + - 関数へのポインタが `__imp_<関数名>` に収納される | |
31 | +- 2つのシンボルを解決できるようファイルに追加 | |
32 | + | |
33 | + | |
34 | +``` | |
35 | +libmsvcrt-oss01204.o: | |
36 | +00000000 b .bss | |
37 | +00000000 d .data | |
38 | +00000000 i .idata$4 | |
39 | +00000000 i .idata$5 | |
40 | +00000000 i .idata$6 | |
41 | +00000000 i .idata$7 | |
42 | +00000000 t .text | |
43 | + U __head_lib32_libmsvcrt_os_a | |
44 | +00000000 I __imp__vsnprintf_s | |
45 | +00000000 T _vsnprintf_s | |
46 | +``` | |
47 | + | |
48 | +## dllをロードできるようにする | |
49 | + | |
50 | +- プラグイン(dll)がロードできなくなる | |
51 | +- 原因は TLS(Thread Local Storage,スレッド毎の記憶領域) | |
52 | +- TLSを使用しないようにする | |
53 | +- MinGWのCランタイムスタートアップの一部を置き換える | |
54 | + - tlssup.c | |
55 | + | |
56 | +### TLSについて | |
57 | + | |
58 | +- OSにはTLS(Thread Local Storage,スレッド毎の記憶領域)サポートが有る | |
59 | +- 新しいC,C++の仕様ではスレッドローカル変数が使用できる | |
60 | + - C++11 では thread_local | |
61 | + - C11 では _Thread_local | |
62 | +- Visual Studio では __declspec(thread) で使用できる | |
63 | + - GCC では __thread | |
64 | +- LoadLibrary()で使用するdll(Tera Termの場合、プラグイン)では利用で問題があった | |
65 | + - exe と同時にロードするdllはok | |
66 | + - Windows 7以降からok | |
67 | + - [スレッド固有記憶領域を持つ DLLを LoadLibrary すると異常動作する問題](http://seclan.dll.jp/dtdiary/2011/dt20110818.htm) | |
68 | +- Windowsではexe(PE32)内.tlsセクションを利用して、スレッドローカル変数の処理を行う | |
69 | + - スレッドコールバックテーブル | |
70 | +- Tera Termではスレッドローカル変数を使用していない | |
71 | +- MinGWのCランタイムスタートアップの一部を置き換えてtlsセクションを生成しないようにした | |
72 | + | |
73 | +## Windows 95向けビルドで使える MinGW | |
74 | + | |
75 | +Windows 95で動作させるため、 | |
76 | +Thread model が win32となっていることを確認する。 | |
77 | +posix (pthread)を使用すると95に実装されていない Win32 APIを使用する | |
78 | +バイナリが生成される。 | |
79 | + | |
80 | +NGな例 (msys2) | |
81 | +``` | |
82 | +$ gcc -v | |
83 | +Using built-in specs. | |
84 | +COLLECT_GCC=C:\msys64\mingw32\bin\gcc.exe | |
85 | +COLLECT_LTO_WRAPPER=C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/10.2.0/lto-wrapper.exe | |
86 | +Target: i686-w64-mingw32 | |
87 | +Configured with: ../gcc- .... | |
88 | +: | |
89 | +: | |
90 | +Thread model: posix | |
91 | +Supported LTO compression algorithms: zlib zstd | |
92 | +gcc version 10.2.0 (Rev5, Built by MSYS2 project) | |
93 | +``` | |
94 | +cygwinも同様にNG | |
95 | + | |
96 | +OKな例 (debian gcc-mingw-w64-i686-win32 package) | |
97 | +``` | |
98 | +$ i686-w64-mingw32-gcc-win32 -v | |
99 | +Using built-in specs. | |
100 | +COLLECT_GCC=i686-w64-mingw32-gcc | |
101 | +COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/10-win32/lto-wrapper | |
102 | +Target: i686-w64-mingw32 | |
103 | +Configured with: ../../src/configure --build=x86_64-lin.... | |
104 | +: | |
105 | +: | |
106 | +Thread model: win32 | |
107 | +Supported LTO compression algorithms: zlib | |
108 | +gcc version 10-win32 20200525 (GCC) | |
109 | +``` | |
110 | + | |
111 | +OKな例 (MinGW-W64) | |
112 | +``` | |
113 | +>gcc -v | |
114 | +Using built-in specs. | |
115 | +COLLECT_GCC=gcc | |
116 | +COLLECT_LTO_WRAPPER=C:/Program\ Files\ (x86)/mingw-w64/i686-8.1.0-win32-sjlj-rt_v6-rev0/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/lto-wrapper.exe | |
117 | +Target: i686-w64-mingw32 | |
118 | +Configured with: ../../../src/gcc-8.1.0/configure --host=i68... | |
119 | +: | |
120 | +: | |
121 | +Thread model: win32 | |
122 | +gcc version 8.1.0 (i686-win32-sjlj-rev0, Built by MinGW-W64 project) | |
123 | +``` | |
124 | + | |
125 | +### ビルド例 (debian gcc-mingw-w64-i686-win32 package) | |
126 | + | |
127 | +Tera Term を Windows 95 で動作させるためのビルド | |
128 | + | |
129 | +次のパッケージをインストールしておく | |
130 | +``` | |
131 | +sudo apt-get install gcc-mingw-w64-i686-win32 g++-mingw-w64-i686-win32 | |
132 | +``` | |
133 | + | |
134 | +thread model win32版が動作するか次のコマンドなどでチェックしておく | |
135 | +``` | |
136 | +i686-w64-mingw32-gcc -v | |
137 | +i686-w64-mingw32-g++ -v | |
138 | +update-alternatives --display i686-w64-mingw32-gcc | |
139 | +update-alternatives --display i686-w64-mingw32-g++ | |
140 | +``` | |
141 | + | |
142 | +ビルド例 | |
143 | +``` | |
144 | +cd [Tera Term source dir] | |
145 | +mkdir build | |
146 | +cd build | |
147 | +cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../mingw.toolchain.cmake -DSUPPORT_OLD_WINDOWS=ON -DCMAKE_BUILD_TYPE=Release | |
148 | +make -j | |
149 | +make -j install | |
150 | +make -j zip | |
151 | +``` | |
152 | + | |
153 | +### ビルド例 (MinGW-W64) | |
154 | + | |
155 | +create_locale()がうまく解決できないため今のところ使えない | |
156 | + | |
157 | +- [MinGW-W64](http://mingw-w64.org/doku.php/download/mingw-builds) | |
158 | +- Version 8.1.0 | |
159 | +- Architecture i686 | |
160 | +- Thread win32 | |
161 | +- Exception sjlj | |
162 | +- Build revision 0 | |
163 | + | |
164 | +例 | |
165 | + | |
166 | +``` | |
167 | +cd [Tera Term source dir] | |
168 | +mkdir build_mingw-w64 | |
169 | +cd build_mingw-w64 | |
170 | +cmake .. -G "MinGW Makefiles" | |
171 | +mingw32-make -j | |
172 | +mingw32-make -j install | |
173 | +``` | |
174 | + |
@@ -0,0 +1,410 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2020- TeraTerm Project | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without | |
6 | + * modification, are permitted provided that the following conditions | |
7 | + * are met: | |
8 | + * | |
9 | + * 1. Redistributions of source code must retain the above copyright | |
10 | + * notice, this list of conditions and the following disclaimer. | |
11 | + * 2. Redistributions in binary form must reproduce the above copyright | |
12 | + * notice, this list of conditions and the following disclaimer in the | |
13 | + * documentation and/or other materials provided with the distribution. | |
14 | + * 3. The name of the author may not be used to endorse or promote products | |
15 | + * derived from this software without specific prior written permission. | |
16 | + * | |
17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR | |
18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | + */ | |
28 | + | |
29 | +#include <stdio.h> | |
30 | +#include <string.h> | |
31 | +#include <stdarg.h> | |
32 | +#include <errno.h> | |
33 | +#include <wchar.h> | |
34 | +#include <locale.h> | |
35 | +#include <windows.h> | |
36 | +#include <stdbool.h> | |
37 | +#include <time.h> | |
38 | +#include <sys/types.h> | |
39 | +#include <sys/stat.h> | |
40 | +#include "../common/compat_win.h" | |
41 | + | |
42 | +// 9x系などの古いmsvcrtが使えるようにする | |
43 | +// - _s() 系はセキュリティーの低い関数を呼び出す | |
44 | +// - W() 系関数は ANSI文字版を呼び出す | |
45 | +// - このファイルをリンクすると必ず置き換えられる | |
46 | +// TODO: msvcrtに存在するかチェックして、あればdll内の関数を使用する | |
47 | + | |
48 | +int vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list ap) | |
49 | +{ | |
50 | + int truncate = count == _TRUNCATE ? 1 : 0; | |
51 | + if (truncate) { | |
52 | + count = sizeOfBuffer -1; | |
53 | + } | |
54 | + else if (count < sizeOfBuffer) { | |
55 | + count = sizeOfBuffer; | |
56 | + } | |
57 | + int r = vsnprintf(buffer, count, format, ap); | |
58 | + if (truncate && r == sizeOfBuffer) { | |
59 | + buffer[sizeOfBuffer - 1] = 0; | |
60 | + r = -1; | |
61 | + } | |
62 | + return r; | |
63 | +} | |
64 | + | |
65 | +static int inner_vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list ap) | |
66 | +{ | |
67 | + return vsnprintf_s(buffer, sizeOfBuffer, count, format, ap); | |
68 | +} | |
69 | + | |
70 | +int snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...) | |
71 | +{ | |
72 | + int r; | |
73 | + va_list ap; | |
74 | + va_start(ap, format); | |
75 | + r = vsnprintf_s(buffer, sizeOfBuffer, count, format, ap); | |
76 | + va_end(ap); | |
77 | + return r; | |
78 | +} | |
79 | + | |
80 | +static int inner_snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, ...) | |
81 | +{ | |
82 | + int r; | |
83 | + va_list ap; | |
84 | + va_start(ap, format); | |
85 | + r = vsnprintf_s(buffer, sizeOfBuffer, count, format, ap); | |
86 | + va_end(ap); | |
87 | + return r; | |
88 | +} | |
89 | + | |
90 | +/** | |
91 | + * TODO: locale無視 | |
92 | + */ | |
93 | +static int inner_snprintf_s_l(char *buffer, size_t sizeOfBuffer, size_t count, const char *format, _locale_t locale, ...) | |
94 | +{ | |
95 | + int r; | |
96 | + va_list ap; | |
97 | + va_start(ap, locale); | |
98 | + r = inner_vsnprintf_s(buffer, sizeOfBuffer, count, format, ap); | |
99 | + va_end(ap); | |
100 | + return r; | |
101 | +} | |
102 | + | |
103 | +static int inner_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list ap) | |
104 | +{ | |
105 | + bool truncate = false; | |
106 | + if (count == _TRUNCATE) { | |
107 | + truncate = true; | |
108 | + count = sizeOfBuffer; | |
109 | + } | |
110 | + else if (count < sizeOfBuffer) { | |
111 | + count = sizeOfBuffer; | |
112 | + } | |
113 | + int r = _vsnwprintf(buffer, count, format, ap); | |
114 | + if (r == -1) { | |
115 | + // error or 切り捨て | |
116 | + if (truncate) { | |
117 | + buffer[sizeOfBuffer - 1] = 0; | |
118 | + } | |
119 | + r = -1; | |
120 | + } | |
121 | + else { | |
122 | + // うまく書き込まれた | |
123 | + } | |
124 | + return r; | |
125 | +} | |
126 | + | |
127 | +static int inner_snwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, ...) | |
128 | +{ | |
129 | + int r; | |
130 | + va_list ap; | |
131 | + va_start(ap, format); | |
132 | + r = inner_vsnwprintf_s(buffer, sizeOfBuffer, count, format, ap); | |
133 | + va_end(ap); | |
134 | + return r; | |
135 | +} | |
136 | + | |
137 | +int swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...) | |
138 | +{ | |
139 | + int r; | |
140 | + va_list ap; | |
141 | + va_start(ap, format); | |
142 | + r = inner_vsnwprintf_s(buffer, sizeOfBuffer, 1, format, ap); | |
143 | + va_end(ap); | |
144 | + return r; | |
145 | +} | |
146 | + | |
147 | +static int inner_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...) | |
148 | +{ | |
149 | + int r; | |
150 | + va_list ap; | |
151 | + va_start(ap, format); | |
152 | + r = inner_vsnwprintf_s(buffer, sizeOfBuffer, 1, format, ap); | |
153 | + va_end(ap); | |
154 | + return r; | |
155 | +} | |
156 | + | |
157 | +__declspec(dllimport) int _vscprintf(const char *format, va_list ap) | |
158 | +{ | |
159 | + int r = vsnprintf(NULL, 0, format, ap); | |
160 | + return r; | |
161 | +} | |
162 | + | |
163 | +static int inner_vscprintf(const char *format, va_list ap) | |
164 | +{ | |
165 | + int r = vsnprintf(NULL, 0, format, ap); | |
166 | + return r; | |
167 | +} | |
168 | + | |
169 | +static errno_t inner_sscanf_s(const char *buffer, const char *format, ...) | |
170 | +{ | |
171 | + int r; | |
172 | + va_list ap; | |
173 | + va_start(ap, format); | |
174 | + r = vsscanf(buffer, format, ap); | |
175 | + va_end(ap); | |
176 | + return r; | |
177 | +} | |
178 | + | |
179 | +static errno_t inner_strcat_s(char *strDestination, size_t numberOfElements, const char *strSource) | |
180 | +{ | |
181 | + size_t dest_len = strlen(strDestination); | |
182 | + size_t src_len = strlen(strSource); | |
183 | + | |
184 | + if(dest_len + src_len + 1 > numberOfElements) { | |
185 | + return EINVAL; | |
186 | + } | |
187 | + strcat(strDestination, strSource); | |
188 | + return 0; | |
189 | +} | |
190 | + | |
191 | +static errno_t inner_wcscat_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource) | |
192 | +{ | |
193 | + size_t dest_len = wcslen(strDestination); | |
194 | + size_t src_len = wcslen(strSource); | |
195 | + | |
196 | + if(dest_len + src_len + 1 > numberOfElements) { | |
197 | + return EINVAL; | |
198 | + } | |
199 | + wcscat(strDestination, strSource); | |
200 | + return 0; | |
201 | +} | |
202 | + | |
203 | +static errno_t inner_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource) | |
204 | +{ | |
205 | + size_t src_len = strlen(strSource); | |
206 | + | |
207 | + if(src_len + 1 > numberOfElements) { | |
208 | + return EINVAL; | |
209 | + } | |
210 | + strcpy(strDestination, strSource); | |
211 | + return 0; | |
212 | +} | |
213 | + | |
214 | +static errno_t inner_wcscpy_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource) | |
215 | +{ | |
216 | + size_t src_len = wcslen(strSource); | |
217 | + | |
218 | + if(src_len + 1 > numberOfElements) { | |
219 | + return EINVAL; | |
220 | + } | |
221 | + wcscpy(strDestination, strSource); | |
222 | + return 0; | |
223 | +} | |
224 | + | |
225 | +static errno_t inner_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count) | |
226 | +{ | |
227 | + size_t src_len = strlen(strSource); | |
228 | + | |
229 | + if (count == _TRUNCATE) { | |
230 | + size_t copy_len = numberOfElements - 1 < src_len ? numberOfElements - 1 : src_len; | |
231 | + memcpy(strDestination, strSource, copy_len); | |
232 | + strDestination[copy_len] = '\0'; | |
233 | + } | |
234 | + else { | |
235 | + if (numberOfElements - 1 < src_len) { | |
236 | + size_t copy_len = numberOfElements - 1; | |
237 | + memcpy(strDestination, strSource, copy_len); | |
238 | + strDestination[copy_len] = '\0'; | |
239 | + } | |
240 | + else { | |
241 | + strcpy(strDestination, strSource); | |
242 | + } | |
243 | + } | |
244 | + return 0; | |
245 | +} | |
246 | + | |
247 | +static errno_t inner_wcsncpy_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource, size_t count) | |
248 | +{ | |
249 | + size_t src_len = wcslen(strSource); | |
250 | + | |
251 | + if (count == _TRUNCATE) { | |
252 | + size_t copy_len = numberOfElements - 1 < src_len ? numberOfElements - 1 : src_len; | |
253 | + wmemcpy(strDestination, strSource, copy_len); | |
254 | + strDestination[copy_len] = '\0'; | |
255 | + } | |
256 | + else { | |
257 | + if (numberOfElements - 1 < src_len) { | |
258 | + size_t copy_len = numberOfElements - 1; | |
259 | + wmemcpy(strDestination, strSource, copy_len); | |
260 | + strDestination[copy_len] = '\0'; | |
261 | + } | |
262 | + else { | |
263 | + wcscpy(strDestination, strSource); | |
264 | + } | |
265 | + } | |
266 | + return 0; | |
267 | +} | |
268 | + | |
269 | +static errno_t inner_strncat_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) | |
270 | +{ | |
271 | + size_t dest_len = strlen(strDest); | |
272 | + size_t left_len = numberOfElements - dest_len; | |
273 | + | |
274 | + char *d = strDest + dest_len; | |
275 | + return inner_strncpy_s(d, left_len, strSource, count); | |
276 | +} | |
277 | + | |
278 | +static errno_t inner_wcsncat_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) | |
279 | +{ | |
280 | + size_t dest_len = wcslen(strDest); | |
281 | + size_t left_len = numberOfElements - dest_len; | |
282 | + | |
283 | + wchar_t *d = strDest + dest_len; | |
284 | + return inner_wcsncpy_s(d, left_len, strSource, count); | |
285 | +} | |
286 | + | |
287 | +static size_t inner_strnlen(const char *s, size_t maxlen) | |
288 | +{ | |
289 | + size_t len = 0; | |
290 | + while(*s != 0 && maxlen != 0) { | |
291 | + s++; | |
292 | + maxlen--; | |
293 | + len++; | |
294 | + } | |
295 | + return len; | |
296 | +} | |
297 | + | |
298 | +static size_t inner_wcsnlen(const wchar_t *s, size_t maxlen) | |
299 | +{ | |
300 | + size_t len = 0; | |
301 | + while(*s != 0 && maxlen != 0) { | |
302 | + s++; | |
303 | + maxlen--; | |
304 | + len++; | |
305 | + } | |
306 | + return len; | |
307 | +} | |
308 | + | |
309 | + | |
310 | +static errno_t inner_fopen_s(FILE **f, const char *name, const char *mode) | |
311 | +{ | |
312 | + *f = fopen(name, mode); | |
313 | + return errno; | |
314 | +} | |
315 | + | |
316 | +static errno_t inner_freopen_s(FILE **f, const char *name, const char *mode) | |
317 | +{ | |
318 | + *f = freopen(name, mode, *f); | |
319 | + return errno; | |
320 | +} | |
321 | + | |
322 | +static errno_t inner__wfopen_s(FILE **f, const wchar_t *name, const char *mode) | |
323 | +{ | |
324 | + *f = fopen((char *)name, mode); // TODO | |
325 | + return errno; | |
326 | +} | |
327 | + | |
328 | +static char *inner_strtok_s(char* str, const char* delimiters, char** context) | |
329 | +{ | |
330 | + (void)context; | |
331 | + char *r = strtok(str, delimiters); | |
332 | + return r; | |
333 | +} | |
334 | + | |
335 | +static int inner__wstat64(const wchar_t *pathW, struct __stat64 *st) | |
336 | +{ | |
337 | + struct _stati64 st32; | |
338 | + int r = _wstati64(pathW, &st32); | |
339 | + if (r != 0) { | |
340 | + char pathA[MAX_PATH]; | |
341 | + WideCharToMultiByte(CP_ACP, 0, pathW, -1, pathA, sizeof(pathA)-1, NULL, NULL); | |
342 | + r = _stati64(pathA, &st32); | |
343 | + } | |
344 | + if (r == 0) { | |
345 | + st->st_gid = st32.st_gid; | |
346 | + st->st_atime = st32.st_atime; | |
347 | + st->st_ctime = st32.st_ctime; | |
348 | + st->st_dev = st32.st_dev; | |
349 | + st->st_ino = st32.st_ino; | |
350 | + st->st_mode = st32.st_mode; | |
351 | + st->st_mtime = st32.st_mtime; | |
352 | + st->st_nlink = st32.st_nlink; | |
353 | + st->st_rdev = st32.st_rdev; | |
354 | + st->st_size = st32.st_size; | |
355 | + st->st_uid = st32.st_uid; | |
356 | + } | |
357 | + return r; | |
358 | +} | |
359 | + | |
360 | +static errno_t inner_tmpnam_s(char * str, size_t sizeInChars) | |
361 | +{ | |
362 | + (void)sizeInChars; | |
363 | + tmpnam(str); | |
364 | + return 0; | |
365 | +} | |
366 | + | |
367 | +static errno_t inner_itoa_s(int value, char * buffer, size_t size, int radix ) | |
368 | +{ | |
369 | + (void)size; | |
370 | + itoa(value, buffer, radix); | |
371 | + return 0; | |
372 | +} | |
373 | + | |
374 | +// テスト用関数 | |
375 | +#if 0 | |
376 | +static void not_implemented(void) | |
377 | +{ | |
378 | + MessageBox(NULL, "not_implemented", "tera trem msvcrt_wrapper", MB_OK | MB_ICONEXCLAMATION); | |
379 | +} | |
380 | +void *_imp___itoa_s = (void *)not_implemented; | |
381 | +#endif | |
382 | + | |
383 | +void *_imp___vsnprintf_s = (void *)inner_vsnprintf_s; | |
384 | +void *_imp___snprintf_s = (void *)inner_snprintf_s; | |
385 | +void *_imp___snprintf_s_l = (void *)inner_snprintf_s_l; | |
386 | +void *_imp___vsnwprintf_s = (void *)inner_vsnwprintf_s; | |
387 | +void *_imp___snwprintf_s = (void *)inner_snwprintf_s; | |
388 | +void *_imp__swprintf_s = (void *)inner_swprintf_s; | |
389 | +void *_imp___vscprintf = (void *)inner_vscprintf; | |
390 | +void *_imp__sscanf_s = (void *)inner_sscanf_s; | |
391 | + | |
392 | +void *_imp__strcat_s = (void *)inner_strcat_s; | |
393 | +void *_imp__wcscat_s = (void *)inner_wcscat_s; | |
394 | +void *_imp__strcpy_s = (void *)inner_strcpy_s; | |
395 | +void *_imp__wcscpy_s = (void *)inner_wcscpy_s; | |
396 | +void *_imp__strncat_s = (void *)inner_strncat_s; | |
397 | +void *_imp__wcsncat_s = (void *)inner_wcsncat_s; | |
398 | +void *_imp__strncpy_s = (void *)inner_strncpy_s; | |
399 | +void *_imp__wcsncpy_s = (void *)inner_wcsncpy_s; | |
400 | +void *_imp__strnlen = (void *)inner_strnlen; | |
401 | +void *_imp__wcsnlen = (void *)inner_wcsnlen; | |
402 | +void *_imp__strtok_s = (void *)inner_strtok_s; | |
403 | + | |
404 | +void *_imp__fopen_s = (void *)inner_fopen_s; | |
405 | +void *_imp__freopen_s = (void *)inner_freopen_s; | |
406 | +void *_imp___wfopen_s = (void *)inner__wfopen_s; | |
407 | +void *_imp___wstat64 = (void *)inner__wstat64; | |
408 | +void *_imp__tmpnam_s = (void *)inner_tmpnam_s; | |
409 | + | |
410 | +void *_imp___itoa_s = (void *)inner_itoa_s; |
@@ -0,0 +1,83 @@ | ||
1 | +#cmake_minimum_required(VERSION 3.18) | |
2 | +cmake_minimum_required(VERSION 3.11) | |
3 | + | |
4 | +set(PACKAGE_NAME "msvcrt") | |
5 | + | |
6 | +project(${PACKAGE_NAME}) | |
7 | + | |
8 | +if(MSVC) | |
9 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") | |
10 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") | |
11 | + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /ZI") | |
12 | + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /ZI") | |
13 | + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO") | |
14 | +elseif(MINGW) | |
15 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__USE_MINGW_ANSI_STDIO=0") | |
16 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=0") | |
17 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_WARNING_FLAGS} -g -static -ffunction-sections -fdata-sections ${C_ONLY_FLAGS}") | |
18 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_CXX_WARNING_FLAGS} -g -static -ffunction-sections -fdata-sections") | |
19 | + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") | |
20 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++") | |
21 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") | |
22 | + endif() | |
23 | + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -g") | |
24 | +endif() | |
25 | + | |
26 | +add_executable( | |
27 | + ${PACKAGE_NAME} | |
28 | + main.c | |
29 | + outputdebugprintf.cpp | |
30 | + is.c | |
31 | + ../../common/asprintf.cpp | |
32 | + ../../common/compat_win.cpp | |
33 | + ../../common/layer_for_unicode.cpp | |
34 | + ../../common/codeconv.cpp | |
35 | + ../../common/dllutil.cpp | |
36 | + ) | |
37 | + | |
38 | +if(MINGW) | |
39 | + target_sources( | |
40 | + ${PACKAGE_NAME} | |
41 | + PRIVATE | |
42 | + ../msvcrt_wrapper.c | |
43 | + ) | |
44 | +endif() | |
45 | + | |
46 | +target_include_directories( | |
47 | + ${PACKAGE_NAME} | |
48 | + PRIVATE | |
49 | + . | |
50 | + ../../common | |
51 | + ) | |
52 | + | |
53 | +if(MINGW) | |
54 | + target_compile_options( | |
55 | + ${PACKAGE_NAME} | |
56 | + PUBLIC -Wall | |
57 | + ) | |
58 | +endif() | |
59 | + | |
60 | +target_link_libraries( | |
61 | + ${PACKAGE_NAME} | |
62 | + PRIVATE | |
63 | + gdi32 | |
64 | + ) | |
65 | + | |
66 | + | |
67 | +#target_link_libraries( | |
68 | +# msvcr70 | |
69 | +# PRIVATE | |
70 | +# mingw_msvcrt | |
71 | +# ) | |
72 | + | |
73 | +if(false) | |
74 | +add_executable( | |
75 | + crt_snprintf_s | |
76 | + crt_snprintf_s.cpp | |
77 | + ) | |
78 | + | |
79 | +target_compile_options( | |
80 | + crt_snprintf_s | |
81 | + PUBLIC -Wall | |
82 | + ) | |
83 | +endif() |
@@ -0,0 +1,216 @@ | ||
1 | + | |
2 | +#include <windows.h> | |
3 | +#include "ttlib.h" | |
4 | + | |
5 | +#if (_MSC_VER < 1800) | |
6 | +BOOL vercmp( | |
7 | + DWORD cond_val, | |
8 | + DWORD act_val, | |
9 | + DWORD dwTypeMask) | |
10 | +{ | |
11 | + switch (dwTypeMask) { | |
12 | + case VER_EQUAL: | |
13 | + if (act_val == cond_val) { | |
14 | + return TRUE; | |
15 | + } | |
16 | + break; | |
17 | + case VER_GREATER: | |
18 | + if (act_val > cond_val) { | |
19 | + return TRUE; | |
20 | + } | |
21 | + break; | |
22 | + case VER_GREATER_EQUAL: | |
23 | + if (act_val >= cond_val) { | |
24 | + return TRUE; | |
25 | + } | |
26 | + break; | |
27 | + case VER_LESS: | |
28 | + if (act_val < cond_val) { | |
29 | + return TRUE; | |
30 | + } | |
31 | + break; | |
32 | + case VER_LESS_EQUAL: | |
33 | + if (act_val <= cond_val) { | |
34 | + return TRUE; | |
35 | + } | |
36 | + break; | |
37 | + } | |
38 | + return FALSE; | |
39 | +} | |
40 | + | |
41 | +#endif | |
42 | + | |
43 | +BOOL _myVerifyVersionInfo( | |
44 | + LPOSVERSIONINFOEX lpVersionInformation, | |
45 | + DWORD dwTypeMask, | |
46 | + DWORDLONG dwlConditionMask) | |
47 | +{ | |
48 | + OSVERSIONINFO osvi; | |
49 | + WORD cond; | |
50 | + BOOL ret, check_next; | |
51 | + | |
52 | + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
53 | + GetVersionEx(&osvi); | |
54 | + | |
55 | + if (dwTypeMask & VER_BUILDNUMBER) { | |
56 | + cond = (WORD)((dwlConditionMask >> (2*3)) & 0x07); | |
57 | + if (!vercmp(lpVersionInformation->dwBuildNumber, osvi.dwBuildNumber, cond)) { | |
58 | + return FALSE; | |
59 | + } | |
60 | + } | |
61 | + if (dwTypeMask & VER_PLATFORMID) { | |
62 | + cond = (WORD)((dwlConditionMask >> (3*3)) & 0x07); | |
63 | + if (!vercmp(lpVersionInformation->dwPlatformId, osvi.dwPlatformId, cond)) { | |
64 | + return FALSE; | |
65 | + } | |
66 | + } | |
67 | + ret = TRUE; | |
68 | + if (dwTypeMask & (VER_MAJORVERSION | VER_MINORVERSION)) { | |
69 | + check_next = TRUE; | |
70 | + if (dwTypeMask & VER_MAJORVERSION) { | |
71 | + cond = (WORD)((dwlConditionMask >> (1*3)) & 0x07); | |
72 | + if (cond == VER_EQUAL) { | |
73 | + if (!vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, cond)) { | |
74 | + return FALSE; | |
75 | + } | |
76 | + } | |
77 | + else { | |
78 | + ret = vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, cond); | |
79 | + // ret: result of major version | |
80 | + if (!vercmp(lpVersionInformation->dwMajorVersion, osvi.dwMajorVersion, VER_EQUAL)) { | |
81 | + // !vercmp(...: result of GRATOR/LESS than (not "GRATOR/LESS than or equal to") of major version | |
82 | + // e.g. | |
83 | + // lpvi:5.1 actual:5.0 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor | |
84 | + // lpvi:5.1 actual:5.1 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor | |
85 | + // lpvi:5.1 actual:5.2 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:FALSE must check minor | |
86 | + // lpvi:5.1 actual:6.0 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor | |
87 | + // lpvi:5.1 actual:6.1 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor | |
88 | + // lpvi:5.1 actual:6.2 cond:VER_GREATER_EQUAL ret:TRUE !vercmp(...:TRUE must not check minor | |
89 | + // lpvi:5.1 actual:5.0 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor | |
90 | + // lpvi:5.1 actual:5.1 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor | |
91 | + // lpvi:5.1 actual:5.2 cond:VER_GREATER ret:FALSE !vercmp(...:FALSE must check minor | |
92 | + // lpvi:5.1 actual:6.0 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor | |
93 | + // lpvi:5.1 actual:6.1 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor | |
94 | + // lpvi:5.1 actual:6.2 cond:VER_GREATER ret:TRUE !vercmp(...:TRUE must not check minor | |
95 | + check_next = FALSE; | |
96 | + } | |
97 | + } | |
98 | + } | |
99 | + if (check_next && (dwTypeMask & VER_MINORVERSION)) { | |
100 | + cond = (WORD)((dwlConditionMask >> (0*3)) & 0x07); | |
101 | + if (cond == VER_EQUAL) { | |
102 | + if (!vercmp(lpVersionInformation->dwMinorVersion, osvi.dwMinorVersion, cond)) { | |
103 | + return FALSE; | |
104 | + } | |
105 | + } | |
106 | + else { | |
107 | + ret = vercmp(lpVersionInformation->dwMinorVersion, osvi.dwMinorVersion, cond); | |
108 | + } | |
109 | + } | |
110 | + } | |
111 | + return ret; | |
112 | +} | |
113 | + | |
114 | +ULONGLONG _myVerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask) | |
115 | +{ | |
116 | + ULONGLONG result, mask; | |
117 | + BYTE op = dwConditionMask & 0x07; | |
118 | + | |
119 | + switch (dwTypeBitMask) { | |
120 | + case VER_MINORVERSION: | |
121 | + mask = 0x07 << (0 * 3); | |
122 | + result = dwlConditionMask & ~mask; | |
123 | + result |= op << (0 * 3); | |
124 | + break; | |
125 | + case VER_MAJORVERSION: | |
126 | + mask = 0x07 << (1 * 3); | |
127 | + result = dwlConditionMask & ~mask; | |
128 | + result |= op << (1 * 3); | |
129 | + break; | |
130 | + case VER_BUILDNUMBER: | |
131 | + mask = 0x07 << (2 * 3); | |
132 | + result = dwlConditionMask & ~mask; | |
133 | + result |= op << (2 * 3); | |
134 | + break; | |
135 | + case VER_PLATFORMID: | |
136 | + mask = 0x07 << (3 * 3); | |
137 | + result = dwlConditionMask & ~mask; | |
138 | + result |= op << (3 * 3); | |
139 | + break; | |
140 | + case VER_SERVICEPACKMINOR: | |
141 | + mask = 0x07 << (4 * 3); | |
142 | + result = dwlConditionMask & ~mask; | |
143 | + result |= op << (4 * 3); | |
144 | + break; | |
145 | + case VER_SERVICEPACKMAJOR: | |
146 | + mask = 0x07 << (5 * 3); | |
147 | + result = dwlConditionMask & ~mask; | |
148 | + result |= op << (5 * 3); | |
149 | + break; | |
150 | + case VER_SUITENAME: | |
151 | + mask = 0x07 << (6 * 3); | |
152 | + result = dwlConditionMask & ~mask; | |
153 | + result |= op << (6 * 3); | |
154 | + break; | |
155 | + case VER_PRODUCT_TYPE: | |
156 | + mask = 0x07 << (7 * 3); | |
157 | + result = dwlConditionMask & ~mask; | |
158 | + result |= op << (7 * 3); | |
159 | + break; | |
160 | + default: | |
161 | + result = 0; | |
162 | + break; | |
163 | + } | |
164 | + | |
165 | + return result; | |
166 | +} | |
167 | + | |
168 | +ULONGLONG myVerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask) | |
169 | +{ | |
170 | + typedef ULONGLONG(WINAPI *func)(ULONGLONG, DWORD, BYTE); | |
171 | + static HMODULE hmodKernel32 = NULL; | |
172 | + static func pVerSetConditionMask = NULL; | |
173 | + char kernel32_dll[MAX_PATH]; | |
174 | + | |
175 | + GetSystemDirectory(kernel32_dll, sizeof(kernel32_dll)); | |
176 | + strncat_s(kernel32_dll, sizeof(kernel32_dll), "\\kernel32.dll", _TRUNCATE); | |
177 | + if (hmodKernel32 == NULL) { | |
178 | + hmodKernel32 = LoadLibrary(kernel32_dll); | |
179 | + if (hmodKernel32 != NULL) { | |
180 | + pVerSetConditionMask = (func)GetProcAddress(hmodKernel32, "VerSetConditionMask"); | |
181 | + } | |
182 | + } | |
183 | + | |
184 | + if (pVerSetConditionMask == NULL) { | |
185 | + return _myVerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask); | |
186 | + } | |
187 | + | |
188 | + return pVerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask); | |
189 | +} | |
190 | + | |
191 | +BOOL myVerifyVersionInfo( | |
192 | + LPOSVERSIONINFOEX lpVersionInformation, | |
193 | + DWORD dwTypeMask, | |
194 | + DWORDLONG dwlConditionMask) | |
195 | +{ | |
196 | +#if (_MSC_VER >= 1800) | |
197 | + return VerifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask); | |
198 | +#else | |
199 | + return _myVerifyVersionInfo(lpVersionInformation, dwTypeMask, dwlConditionMask); | |
200 | +#endif | |
201 | +} | |
202 | + | |
203 | +BOOL IsWindowsNTKernel() | |
204 | +{ | |
205 | + OSVERSIONINFOEX osvi; | |
206 | + DWORDLONG dwlConditionMask = 0; | |
207 | + int op = VER_EQUAL; | |
208 | + BOOL ret; | |
209 | + | |
210 | + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); | |
211 | + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | |
212 | + osvi.dwPlatformId = VER_PLATFORM_WIN32_NT; | |
213 | + dwlConditionMask = myVerSetConditionMask(dwlConditionMask, VER_PLATFORMID, op); | |
214 | + ret = myVerifyVersionInfo(&osvi, VER_PLATFORMID, dwlConditionMask); | |
215 | + return (ret); | |
216 | +} |
@@ -0,0 +1,45 @@ | ||
1 | +//gcc -g -o test main.c -Wall -Wl,-wrap=_imp__fopen_s -Wl,-Map=test.map | |
2 | +//gcc -g -o test main.c -Wall -Wl,-Map=test.map,--allow-multiple-definition | |
3 | + | |
4 | +//#define __USE_MINGW_ANSI_STDIO 0 | |
5 | +#include <stdio.h> | |
6 | +#include <string.h> | |
7 | +#include <errno.h> | |
8 | +#include <wchar.h> | |
9 | +#include <windows.h> | |
10 | +#include <locale.h> | |
11 | + | |
12 | +#include "../../common/ttlib.h" | |
13 | +#include "../../common/asprintf.h" | |
14 | + | |
15 | +int vaswprintf_test(const wchar_t *fmt, ...) | |
16 | +{ | |
17 | + wchar_t *message; | |
18 | + va_list ap; | |
19 | + va_start(ap, fmt); | |
20 | + vaswprintf(&message, fmt, ap); | |
21 | + wprintf(L"message='%ls'\n", message); | |
22 | + wprintf(L"message='%s'\n", message); | |
23 | + free(message); | |
24 | + return 0; | |
25 | +} | |
26 | + | |
27 | +int main(int argc, char *argv[]) | |
28 | +{ | |
29 | + FILE *fp; | |
30 | + printf("1\n"); | |
31 | + fopen_s(&fp, "test.txt", "w"); | |
32 | + fclose(fp); | |
33 | + printf("2\n"); | |
34 | + | |
35 | + vaswprintf_test(L"test %s %ls %hs", L"wide", L"wide", "narrow"); | |
36 | + | |
37 | + { | |
38 | + wchar_t buf[128]; | |
39 | + swprintf(buf, _countof(buf), L"test %s %ls %hs", L"wide", L"wide", "narrow"); | |
40 | + wprintf(L"buf='%s'\n", buf); | |
41 | + __ms_wprintf(L"buf='%s'\n", buf); | |
42 | + } | |
43 | + | |
44 | + return 0; | |
45 | +} |
@@ -0,0 +1,27 @@ | ||
1 | + | |
2 | +#include <stdio.h> | |
3 | +#include <windows.h> | |
4 | + | |
5 | +#include "ttlib.h" | |
6 | +#include "layer_for_unicode.h" | |
7 | +#include "compat_win.h" | |
8 | + | |
9 | +void OutputDebugPrintf(const char *fmt, ...) | |
10 | +{ | |
11 | + char tmp[1024]; | |
12 | + va_list arg; | |
13 | + va_start(arg, fmt); | |
14 | + _vsnprintf_s(tmp, sizeof(tmp), _TRUNCATE, fmt, arg); | |
15 | + va_end(arg); | |
16 | + OutputDebugStringA(tmp); | |
17 | +} | |
18 | + | |
19 | +void OutputDebugPrintfW(const wchar_t *fmt, ...) | |
20 | +{ | |
21 | + wchar_t tmp[1024]; | |
22 | + va_list arg; | |
23 | + va_start(arg, fmt); | |
24 | + _vsnwprintf_s(tmp, _countof(tmp), _TRUNCATE, fmt, arg); | |
25 | + va_end(arg); | |
26 | + _OutputDebugStringW(tmp); | |
27 | +} |
@@ -0,0 +1,186 @@ | ||
1 | +/** | |
2 | + * This file has no copyright assigned and is placed in the Public Domain. | |
3 | + * This file is part of the w64 mingw-runtime package. | |
4 | + * No warranty is given; refer to the file DISCLAIMER within this package. | |
5 | + * | |
6 | + * Written by Kai Tietz <kai.tietz@onevision.com> | |
7 | + */ | |
8 | + | |
9 | +#ifdef CRTDLL | |
10 | +#undef CRTDLL | |
11 | +#endif | |
12 | + | |
13 | +#include <windows.h> | |
14 | +#include <stdio.h> | |
15 | +#include <memory.h> | |
16 | +#include <malloc.h> | |
17 | + | |
18 | +#ifndef _CRTALLOC | |
19 | +#define _CRTALLOC(x) __attribute__ ((section (x) )) | |
20 | +#endif | |
21 | + | |
22 | +#ifndef __INTERNAL_FUNC_DEFINED | |
23 | +#define __INTERNAL_FUNC_DEFINED | |
24 | + typedef void (__cdecl *_PVFV)(void); | |
25 | + typedef int (__cdecl *_PIFV)(void); | |
26 | + typedef void (__cdecl *_PVFI)(int); | |
27 | +#endif | |
28 | + | |
29 | +extern WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved); | |
30 | + | |
31 | +#define FUNCS_PER_NODE 30 | |
32 | + | |
33 | +typedef struct TlsDtorNode { | |
34 | + int count; | |
35 | + struct TlsDtorNode *next; | |
36 | + _PVFV funcs[FUNCS_PER_NODE]; | |
37 | +} TlsDtorNode; | |
38 | + | |
39 | +ULONG _tls_index = 0; | |
40 | + | |
41 | +/* TLS raw template data start and end. */ | |
42 | +_CRTALLOC(".tls$AAA") char _tls_start = 0; | |
43 | +_CRTALLOC(".tls$ZZZ") char _tls_end = 0; | |
44 | + | |
45 | +_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0; | |
46 | +_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0; | |
47 | + | |
48 | +#if 0 | |
49 | +#ifdef _WIN64 | |
50 | +_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY64 _tls_used = { | |
51 | + (ULONGLONG) &_tls_start+1, (ULONGLONG) &_tls_end, (ULONGLONG) &_tls_index, | |
52 | + (ULONGLONG) (&__xl_a+1), (ULONG) 0, (ULONG) 0 | |
53 | +}; | |
54 | +#else | |
55 | +_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used = { | |
56 | + (ULONG)(ULONG_PTR) &_tls_start+1, (ULONG)(ULONG_PTR) &_tls_end, | |
57 | + (ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1), | |
58 | + (ULONG) 0, (ULONG) 0 | |
59 | +}; | |
60 | +#endif | |
61 | +#endif | |
62 | + | |
63 | +#ifndef __CRT_THREAD | |
64 | +#ifdef HAVE_ATTRIBUTE_THREAD | |
65 | +#define __CRT_THREAD __declspec(thread) | |
66 | +#else | |
67 | +#define __CRT_THREAD __thread | |
68 | +#endif | |
69 | +#endif | |
70 | + | |
71 | +#define DISABLE_MS_TLS 1 | |
72 | + | |
73 | +static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0; | |
74 | +static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0; | |
75 | + | |
76 | +#if !defined (DISABLE_MS_TLS) | |
77 | +static __CRT_THREAD TlsDtorNode *dtor_list; | |
78 | +static __CRT_THREAD TlsDtorNode dtor_list_head; | |
79 | +#endif | |
80 | + | |
81 | +extern int _CRT_MT; | |
82 | + | |
83 | +BOOL WINAPI __dyn_tls_init (HANDLE, DWORD, LPVOID); | |
84 | + | |
85 | +BOOL WINAPI | |
86 | +__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) | |
87 | +{ | |
88 | + _PVFV *pfunc; | |
89 | + int nfuncs, ifunc; | |
90 | + | |
91 | + /* We don't let us trick here. */ | |
92 | + if (_CRT_MT != 2) | |
93 | + _CRT_MT = 2; | |
94 | + | |
95 | + if (dwReason != DLL_THREAD_ATTACH) | |
96 | + { | |
97 | + if (dwReason == DLL_PROCESS_ATTACH) | |
98 | + __mingw_TLScallback (hDllHandle, dwReason, lpreserved); | |
99 | + return TRUE; | |
100 | + } | |
101 | + | |
102 | + /* Use the nfuncs variable to iterate the TLS functions instead of pfunc to | |
103 | + avoid nasty compiler optimizations when comparing two global pointers. */ | |
104 | + nfuncs = &__xd_z - (&__xd_a + 1); | |
105 | + for (ifunc=0; ifunc < nfuncs; ++ifunc) | |
106 | + { | |
107 | + pfunc = (&__xd_a + 1) + ifunc; | |
108 | + if (*pfunc != NULL) | |
109 | + (*pfunc)(); | |
110 | + } | |
111 | + return TRUE; | |
112 | +} | |
113 | + | |
114 | +const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK) __dyn_tls_init; | |
115 | +_CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init; | |
116 | + | |
117 | +int __cdecl __tlregdtor (_PVFV); | |
118 | + | |
119 | +int __cdecl | |
120 | +__tlregdtor (_PVFV func) | |
121 | +{ | |
122 | + if (!func) | |
123 | + return 0; | |
124 | +#if !defined (DISABLE_MS_TLS) | |
125 | + if (dtor_list == NULL) | |
126 | + { | |
127 | + dtor_list = &dtor_list_head; | |
128 | + dtor_list_head.count = 0; | |
129 | + } | |
130 | + else if (dtor_list->count == FUNCS_PER_NODE) | |
131 | + { | |
132 | + TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode)); | |
133 | + if (pnode == NULL) | |
134 | + return -1; | |
135 | + pnode->count = 0; | |
136 | + pnode->next = dtor_list; | |
137 | + dtor_list = pnode; | |
138 | + | |
139 | + dtor_list->count = 0; | |
140 | + } | |
141 | + dtor_list->funcs[dtor_list->count++] = func; | |
142 | +#endif | |
143 | + return 0; | |
144 | +} | |
145 | + | |
146 | +static BOOL WINAPI | |
147 | +__dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) | |
148 | +{ | |
149 | +#if !defined (DISABLE_MS_TLS) | |
150 | + TlsDtorNode *pnode, *pnext; | |
151 | + int i; | |
152 | +#endif | |
153 | + | |
154 | + if (dwReason != DLL_THREAD_DETACH && dwReason != DLL_PROCESS_DETACH) | |
155 | + return TRUE; | |
156 | + /* As TLS variables are detroyed already by DLL_THREAD_DETACH | |
157 | + call, we have to avoid access on the possible DLL_PROCESS_DETACH | |
158 | + call the already destroyed TLS vars. | |
159 | + TODO: The used local thread based variables have to be handled | |
160 | + manually, so that we can control their lifetime here. */ | |
161 | +#if !defined (DISABLE_MS_TLS) | |
162 | + if (dwReason != DLL_PROCESS_DETACH) | |
163 | + { | |
164 | + for (pnode = dtor_list; pnode != NULL; pnode = pnext) | |
165 | + { | |
166 | + for (i = pnode->count - 1; i >= 0; --i) | |
167 | + { | |
168 | + if (pnode->funcs[i] != NULL) | |
169 | + (*pnode->funcs[i])(); | |
170 | + } | |
171 | + pnext = pnode->next; | |
172 | + if (pnext != NULL) | |
173 | + free ((void *) pnode); | |
174 | + } | |
175 | + } | |
176 | +#endif | |
177 | + __mingw_TLScallback (hDllHandle, dwReason, lpreserved); | |
178 | + return TRUE; | |
179 | +} | |
180 | + | |
181 | +_CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = (PIMAGE_TLS_CALLBACK) __dyn_tls_dtor; | |
182 | + | |
183 | + | |
184 | +int mingw_initltsdrot_force = 0; | |
185 | +int mingw_initltsdyn_force=0; | |
186 | +int mingw_initltssuo_force = 0; |
@@ -212,6 +212,15 @@ | ||
212 | 212 | ../../teraterm/common/compat_w95_vs2005.c |
213 | 213 | ) |
214 | 214 | endif() |
215 | + if(MINGW) | |
216 | + target_link_libraries( | |
217 | + ${PACKAGE_NAME} | |
218 | + PRIVATE | |
219 | + -Wl,--whole-archive | |
220 | + mingw_msvcrt | |
221 | + -Wl,--no-whole-archive | |
222 | + ) | |
223 | + endif() | |
215 | 224 | endif(SUPPORT_OLD_WINDOWS) |
216 | 225 | |
217 | 226 | if (MSVC) |
@@ -26,6 +26,20 @@ | ||
26 | 26 | ../../teraterm/common/compat_w95_vs2005.c |
27 | 27 | ) |
28 | 28 | endif() |
29 | + if(MINGW) | |
30 | + target_sources( | |
31 | + ${PACKAGE_NAME} | |
32 | + PRIVATE | |
33 | + ../../teraterm/libmingw/tlssup.c | |
34 | + ) | |
35 | + target_link_libraries( | |
36 | + ${PACKAGE_NAME} | |
37 | + PRIVATE | |
38 | + -Wl,--whole-archive | |
39 | + mingw_msvcrt | |
40 | + -Wl,--no-whole-archive | |
41 | + ) | |
42 | + endif() | |
29 | 43 | endif(SUPPORT_OLD_WINDOWS) |
30 | 44 | |
31 | 45 | target_sources( |
@@ -17,6 +17,15 @@ | ||
17 | 17 | ../../teraterm/common/compat_w95_vs2005.c |
18 | 18 | ) |
19 | 19 | endif() |
20 | + if(MINGW) | |
21 | + target_link_libraries( | |
22 | + ${PACKAGE_NAME} | |
23 | + PRIVATE | |
24 | + -Wl,--whole-archive | |
25 | + mingw_msvcrt | |
26 | + -Wl,--no-whole-archive | |
27 | + ) | |
28 | + endif() | |
20 | 29 | endif(SUPPORT_OLD_WINDOWS) |
21 | 30 | |
22 | 31 | target_sources( |
@@ -20,6 +20,13 @@ | ||
20 | 20 | ../../teraterm/common/compat_w95_vs2005.c |
21 | 21 | ) |
22 | 22 | endif() |
23 | + if(MINGW) | |
24 | + target_sources( | |
25 | + ${PACKAGE_NAME} | |
26 | + PRIVATE | |
27 | + ../../teraterm/libmingw/tlssup.c | |
28 | + ) | |
29 | + endif() | |
23 | 30 | endif(SUPPORT_OLD_WINDOWS) |
24 | 31 | |
25 | 32 | target_sources( |
@@ -28,6 +28,7 @@ | ||
28 | 28 | target_link_libraries( |
29 | 29 | ttbroadcast |
30 | 30 | PRIVATE |
31 | + ttpcmn | |
31 | 32 | common_static |
32 | 33 | ) |
33 | 34 |
@@ -111,6 +111,20 @@ | ||
111 | 111 | ../../teraterm/common/compat_w95_vs2005.c |
112 | 112 | ) |
113 | 113 | endif() |
114 | + if(MINGW) | |
115 | + target_sources( | |
116 | + ${PACKAGE_NAME} | |
117 | + PRIVATE | |
118 | + ../../teraterm/libmingw/tlssup.c | |
119 | + ) | |
120 | + target_link_libraries( | |
121 | + ${PACKAGE_NAME} | |
122 | + PRIVATE | |
123 | + -Wl,--whole-archive | |
124 | + mingw_msvcrt | |
125 | + -Wl,--no-whole-archive | |
126 | + ) | |
127 | + endif() | |
114 | 128 | endif(SUPPORT_OLD_WINDOWS) |
115 | 129 | |
116 | 130 | target_include_directories( |