Skip to content

Commit b0ff4e2

Browse files
committed
Set code page to UTF-8 (65001) on Windows #738
1 parent 542f027 commit b0ff4e2

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

src/Stack/Build/Execute.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,13 @@ withSingleContext ActionContext {..} ExecuteEnv {..} task@Task {..} msuffix inne
602602
cp = cp0
603603
{ cwd = Just $ toFilePath pkgDir
604604
, Process.env = envHelper menv
605-
, std_in = CreatePipe
605+
-- Ideally we'd create a new pipe here and then close it
606+
-- below to avoid the child process from taking from our
607+
-- stdin. However, if we do this, the child process won't
608+
-- be able to get the codepage on Windows that we want.
609+
-- See:
610+
-- https://github.com/commercialhaskell/stack/issues/738
611+
-- , std_in = CreatePipe
606612
, std_out =
607613
case mlogFile of
608614
Nothing -> CreatePipe
@@ -615,8 +621,7 @@ withSingleContext ActionContext {..} ExecuteEnv {..} task@Task {..} msuffix inne
615621
$logProcessRun (toFilePath exeName) fullArgs
616622

617623
-- Use createProcess_ to avoid the log file being closed afterwards
618-
(Just inH, moutH, merrH, ph) <- liftIO $ createProcess_ "singleBuild" cp
619-
liftIO $ hClose inH
624+
(Nothing, moutH, merrH, ph) <- liftIO $ createProcess_ "singleBuild" cp
620625

621626
let makeAbsolute = stripTHLoading -- If users want control, we should add a config option for this
622627

src/main/Main.hs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE CPP #-}
12
{-# LANGUAGE OverloadedStrings #-}
23
{-# LANGUAGE ScopedTypeVariables #-}
34
{-# LANGUAGE FlexibleContexts #-}
@@ -73,10 +74,31 @@ import System.FilePath (dropTrailingPathSeparator)
7374
import System.IO (hIsTerminalDevice, stderr, stdin, stdout, hSetBuffering, BufferMode(..))
7475
import System.Process.Read
7576

77+
#if WINDOWS
78+
import System.Win32.Console (setConsoleCP, setConsoleOutputCP, getConsoleCP, getConsoleOutputCP)
79+
import System.IO (hSetEncoding, utf8, hPutStrLn)
80+
#endif
81+
7682
-- | Commandline dispatcher.
7783
main :: IO ()
78-
main = withInterpreterArgs stackProgName $ \args isInterpreter ->
79-
do -- Line buffer the output by default, particularly for non-terminal runs.
84+
main = withInterpreterArgs stackProgName $ \args isInterpreter -> do
85+
#if WINDOWS
86+
-- Set the code page for this process to 65001 (UTF-8). See:
87+
-- https://github.com/commercialhaskell/stack/issues/738
88+
origCPI <- getConsoleCP
89+
origCPO <- getConsoleOutputCP
90+
91+
when (origCPI /= 65001 || origCPO /= 65001) $ do
92+
hPutStrLn stderr
93+
"Setting codepage to UTF-8 (65001) to ensure correct output from GHC"
94+
setConsoleCP 65001
95+
setConsoleOutputCP 65001
96+
hSetEncoding stdin utf8
97+
hSetEncoding stdout utf8
98+
hSetEncoding stderr utf8
99+
#endif
100+
101+
-- Line buffer the output by default, particularly for non-terminal runs.
80102
-- See https://github.com/commercialhaskell/stack/pull/360
81103
hSetBuffering stdout LineBuffering
82104
hSetBuffering stdin LineBuffering

stack.cabal

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ executable stack
207207
, transformers
208208
, http-client
209209
default-language: Haskell2010
210+
if os(windows)
211+
build-depends: Win32
212+
cpp-options: -DWINDOWS
210213

211214
test-suite stack-test
212215
type: exitcode-stdio-1.0

0 commit comments

Comments
 (0)