Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ TOOL=gcc
ARC=ar
DBG_OPTS=--di\ --opt_level=0
DBG_GCC=-g
CPP_FLAGS=-std=c++17
# every function and global in a section of its own, so a program's link (--gc-sections) keeps only
# the wrappers it calls - as tslang does for lib.ts
CPP_FLAGS=-std=c++17\ -ffunction-sections\ -fdata-sections
TOOL_NAME=tslang

if [ "$1" == "release" ] ; then
Expand Down
3 changes: 2 additions & 1 deletion scripts/build_android.bat
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ if not exist %TSLANG% (
)

set NDK_BIN=%ANDROID_NDK_HOME%\toolchains\llvm\prebuilt\windows-x86_64\bin
set CXX="%NDK_BIN%\clang++.exe" --target=%TRIPLE% -fPIC -std=c++17 %DBG_CXX%
rem sections per function and global: a program's link (--gc-sections) keeps only the wrappers it calls
set CXX="%NDK_BIN%\clang++.exe" --target=%TRIPLE% -fPIC -std=c++17 -ffunction-sections -fdata-sections %DBG_CXX%
set AR="%NDK_BIN%\llvm-ar.exe"
set TSC=%TSLANG% -mtriple=%TRIPLE% -relocation-model=pic %DBG% -mm=%MM% --emit=obj --export=none --nowarn --no-default-lib

Expand Down
34 changes: 21 additions & 13 deletions scripts/build_core.bat
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,20 @@ rem (--di, no --opt) picks this debug archive and links the static debug CRT (li
rem _ITERATOR_DEBUG_LEVEL=2); an --opt program picks the release archive and the static release CRT
rem (see tslang/tslang/exe.cpp). Without a flag cl defaults to /MT, so the debug archive carried
rem release-CRT wrappers and a debug `tslang --emit=exe` against it failed with LNK2038 mismatches.
set DBG_CL=/MTd /Z7 /std:c++latest
rem /Gy /Gw: every function and global in a COMDAT of its own, so a program's link keeps only
rem the wrappers it calls (tslang does the same for lib.ts). Release builds add /O2 - without it
rem cl does not optimize at all.
set DBG_CL=/MTd /Z7 /Gy /Gw /std:c++latest
rem TSLANG_DEBUG_CRT=/MT builds the debug archive against the release CRT instead. /MTd is right
rem next to a debug tslang build, whose runtime and collector are /MTd too. A
rem release package ships only /MT builds of those (TypeScriptAsyncRuntime.lib and
rem gc.lib), so there a /MTd debug archive cannot be linked with them at all: every
rem `tslang --di --emit=exe` failed with LNK2038. The compiler's release workflow sets it. It
rem changes only the CRT; the archive still carries debug info (/Z7, --di).
if /I "%TSLANG_DEBUG_CRT%"=="/MT" (
set DBG_CL=/MT /Z7 /std:c++latest
set DBG_CL=/MT /Z7 /Gy /Gw /std:c++latest
) else if /I "%TSLANG_DEBUG_CRT%"=="/MTd" (
set DBG_CL=/MTd /Z7 /std:c++latest
set DBG_CL=/MTd /Z7 /Gy /Gw /std:c++latest
) else if not "%TSLANG_DEBUG_CRT%"=="" (
echo TSLANG_DEBUG_CRT must be /MT or /MTd, not "%TSLANG_DEBUG_CRT%"
exit /b 1
Expand All @@ -75,7 +78,8 @@ if "%1"=="release" (
set BUILD1=release
set LLVM_BUILD=Release
set DBG=--opt --opt_level=3
set DBG_CL=/MT /std:c++latest
rem /wd4710 /wd4711: /Wall reports every inlining decision /O2 makes, thousands of lines
set DBG_CL=/MT /O2 /Gy /Gw /wd4710 /wd4711 /std:c++latest
)

rem Memory model (%2). The default library is not model-neutral: under gc it allocates through
Expand Down Expand Up @@ -218,22 +222,25 @@ md %LIB_OUT%

rem echo on

rem Build native wrappers for C++ code
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\io.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\datetime.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\regex.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall %WRAPPER_MM_DEF% /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\thread.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\http.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\memory.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\os.cpp
rem Build native wrappers for C++ code, twice. The static archive's copies export nothing: a
rem program links them, and an exported function is one the linker has to keep, so every program
rem carried all of the RegExp, HTTP and stdio wrappers (and wrote a .lib/.exp beside itself). The
rem DLL's copies (TSLANG_WRAPPERS_DLL, see src\wrappers\tslang_export.h) export each entry point,
rem since the JIT binds them through the DLL's export table.
set DLL_WRAPPERS_OUT=%LIB_OUT%\dll_wrappers
md %DLL_WRAPPERS_OUT%
for %%w in (io datetime regex thread http memory os) do (
%TSLANG_CC% %DBG_CL% /EHsc /Wall %WRAPPER_MM_DEF% /c /Fo%OUTPUT%\%LIB_OUT%\ %SRC%\src\wrappers\%%w.cpp
%TSLANG_CC% %DBG_CL% /EHsc /Wall %WRAPPER_MM_DEF% /DTSLANG_WRAPPERS_DLL /c /Fo%OUTPUT%\%DLL_WRAPPERS_OUT%\ %SRC%\src\wrappers\%%w.cpp
)

rem Build OS-specific Lib
echo Build OS-specific Lib
%TOOL_PATH%\%TOOL_NAME%.exe %TRIPLE_OPT% %DBG% %MM_OPT% --emit=obj --export=none --nowarn --no-default-lib %SRC%\src\lib.win32.ts -o %OUTPUT%\%LIB_OUT%\lib.win32.obj

rem Build DLL
echo Build DLL
%TOOL_PATH%\%TOOL_NAME%.exe %TRIPLE_OPT% %DBG% %MM_OPT% --emit=dll --gc-lib-path=%GC_SHARED_LIB_PATH% %TSLANG_RUNTIME_OPT% --embed-declarations=false --nowarn --no-default-lib %SRC%\src\lib.ts --obj=%OUTPUT%\%LIB_OUT%\lib.win32.obj --obj=%OUTPUT%\%LIB_OUT%\io.obj --obj=%OUTPUT%\%LIB_OUT%\datetime.obj --obj=%OUTPUT%\%LIB_OUT%\regex.obj --obj=%OUTPUT%\%LIB_OUT%\thread.obj --obj=%OUTPUT%\%LIB_OUT%\http.obj --obj=%OUTPUT%\%LIB_OUT%\memory.obj --obj=%OUTPUT%\%LIB_OUT%\os.obj -o %OUTPUT%\%DLL_OUT%\TypeScriptDefaultLib.dll
%TOOL_PATH%\%TOOL_NAME%.exe %TRIPLE_OPT% %DBG% %MM_OPT% --emit=dll --gc-lib-path=%GC_SHARED_LIB_PATH% %TSLANG_RUNTIME_OPT% --embed-declarations=false --nowarn --no-default-lib %SRC%\src\lib.ts --obj=%OUTPUT%\%LIB_OUT%\lib.win32.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\io.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\datetime.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\regex.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\thread.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\http.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\memory.obj --obj=%OUTPUT%\%DLL_WRAPPERS_OUT%\os.obj -o %OUTPUT%\%DLL_OUT%\TypeScriptDefaultLib.dll

rem Build Lib
echo Build Lib
Expand All @@ -252,6 +259,7 @@ del %OUTPUT%\%LIB_OUT%\thread.obj
del %OUTPUT%\%LIB_OUT%\http.obj
del %OUTPUT%\%LIB_OUT%\memory.obj
del %OUTPUT%\%LIB_OUT%\os.obj
rd /S /Q %OUTPUT%\%DLL_WRAPPERS_OUT%

rem Stage into a single shared defaultlib tree with per-target, per-build, per-model subfolders
rem under dll\ and lib\. Only the current build's subfolders are refreshed so the other
Expand Down
8 changes: 6 additions & 2 deletions src/wrappers/tslang_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@

// Native wrappers must be exported from the shared default-lib DLL so JIT-mode
// programs (which bind imports via the DLL export table) can resolve them.
// In AOT mode the static .lib provides them, so the macro is a no-op there.
//
// Every extern "C" entry point that lib.ts declares in src/native/lib.native.d.ts
// needs this - without it the symbol is absent from the DLL export table and the
// call only resolves in AOT builds.
#ifdef _WIN32
//
// Only the DLL's copies export: scripts/build_core.bat compiles the wrappers a second
// time for it, with TSLANG_WRAPPERS_DLL. The static archive's copies must not, since a
// program keeps every function it exports - every program carried all the RegExp,
// HTTP and stdio wrappers, called or not, and wrote an import library beside itself.
#if defined(_WIN32) && defined(TSLANG_WRAPPERS_DLL)
#define TSLANG_EXPORT __declspec(dllexport)
#else
#define TSLANG_EXPORT
Expand Down
Loading