使用Haskell stack构建时,使用Clang而不是gcc编译C源文件?

huangapple go评论51阅读模式
英文:

Compiling C source files with Clang instead of gcc when building with Haskell stack?

问题

目前,如果我构建一个同时包含C源文件的Haskell项目,Stack会使用gcc编译C源文件。然而,我想用Clang编译这些C源文件。是否可以更改package.yaml或stack.yaml来实现这一点?

英文:

Currently if I build a haskell project that also has c source files, stack compiles the c source files using gcc. However, i would like to compile these C source files with Clang instead. Is it possible to change the package.yaml or stack.yaml to achieve this?

答案1

得分: 2

看起来在你的 stack.yaml 文件中指定类似以下内容可能会有所帮助:

with-gcc: /usr/bin/clang-15

如果你遇到了关于 .addrsig 操作码的错误,可能需要在你的 .cabal 文件中添加一个 C 标志,例如:

library ...
  ...
  cc-options: -fno-addrsig
  ...

至少,我成功地使用 clang-15 让以下示例工作。

我创建了一个 Stack 项目,包含以下文件:

# stack.yaml
resolver: lts-21.0
packages:
- .
with-gcc: /usr/bin/clang-15
# clangtest.cabal
cabal-version: 1.12
name:           clangtest
version:        0.1.0.0
build-type:     Simple

executable clangtest-exe
  main-is: Main.hs
  c-sources: test.c
  cc-options: -fno-addrsig
  build-depends: base >=4.7 && <5
  default-language: Haskell2010
/* test.h */
char* world(int key);
/* test.c */
#include "test.h"

char* world(int key)
{
        switch(key) {
        case 1: return "world";
        case 2: return "Bob";
        default: return "<unknown>";
        }
}
-- Main.hs
module Main (main) where

import Foreign.C

foreign import ccall "world" world :: Int -> CString

main :: IO ()
main = do
  thing <- peekCString (world 1)
  putStrLn $ "Hello, " ++ thing

然后,我运行了 stack build

$ stack build
Building all executables for `clangtest' once. After a successful build of all of them, only specified executables will be rebuilt.
clangtest> configure (exe)
Configuring clangtest-0.1.0.0...
clangtest> build (exe)
Preprocessing executable 'clangtest-exe' for clangtest-0.1.0.0...
Building executable 'clangtest-exe' for clangtest-0.1.0.0...
[1 of 1] Compiling Main
[2 of 2] Linking .stack-work/dist/x86_64-linux/Cabal-3.8.1.0/build/clangtest-exe/clangtest-exe
clangtest> copy/register
Installing executable clangtest-exe in /u/buhr/src/overflow/clangtest/.stack-work/install/x86_64-linux/af84b282df7268d5dbef65c10bee4a1a2517fa1d96db69f048f962dabf7b870f/9.4.5/bin

我验证了 C 文件确实使用 clang 编译:

$ strings .stack-work/dist/x86_64-linux/Cabal-3.8.1.0/build/clangtest-exe/clangtest-exe-tmp/test.o | egrep clang
Debian clang version 15.0.6

我还验证了程序确实运行:

buhr@delores:~/src/overflow/clangtest$ stack exec clangtest-exe
Hello, world

希望这些信息对你有所帮助。

英文:

It looks like specifying something like the following in your stack.yaml file:

with-gcc: /usr/bin/clang-15

and -- if you get an error about an .addrsig opcode -- possibly adding a C flag to your .cabal file:

library ...
  ...
  cc-options: -fno-addrsig
  ...

might be sufficient. At least, I was able to get the following toy example working with clang-15.

I created a Stack project with the following files:

# stack.yaml
resolver: lts-21.0
packages:
- .
with-gcc: /usr/bin/clang-15
# clangtest.cabal
cabal-version: 1.12
name:           clangtest
version:        0.1.0.0
build-type:     Simple

executable clangtest-exe
  main-is: Main.hs
  c-sources: test.c
  cc-options: -fno-addrsig
  build-depends: base &gt;=4.7 &amp;&amp; &lt;5
  default-language: Haskell2010
/* test.h */
char* world(int key);
/* test.c */
#include &quot;test.h&quot;

char* world(int key)
{
        switch(key) {
        case 1: return &quot;world&quot;;
        case 2: return &quot;Bob&quot;;
        default: return &quot;&lt;unknown&gt;&quot;;
        }
}
-- Main.hs
module Main (main) where

import Foreign.C

foreign import ccall &quot;world&quot; world :: Int -&gt; CString

main :: IO ()
main = do
  thing &lt;- peekCString (world 1)
  putStrLn $ &quot;Hello, &quot; ++ thing

Then, I ran stack build:

$ stack build
Building all executables for `clangtest&#39; once. After a successful build of all of them, only specified executables will be rebuilt.
clangtest&gt; configure (exe)
Configuring clangtest-0.1.0.0...
clangtest&gt; build (exe)
Preprocessing executable &#39;clangtest-exe&#39; for clangtest-0.1.0.0..
Building executable &#39;clangtest-exe&#39; for clangtest-0.1.0.0..
[1 of 1] Compiling Main
[2 of 2] Linking .stack-work/dist/x86_64-linux/Cabal-3.8.1.0/build/clangtest-exe/clangtest-exe
clangtest&gt; copy/register
Installing executable clangtest-exe in /u/buhr/src/overflow/clangtest/.stack-work/install/x86_64-linux/af84b282df7268d5dbef65c10bee4a1a2517fa1d96db69f048f962dabf7b870f/9.4.5/bin

I verified that the C file had actually been compiled with clang:

$ strings .stack-work/dist/x86_64-linux/Cabal-3.8.1.0/build/clangtest-exe/clangtest-exe-tmp/test.o | egrep clang
Debian clang version 15.0.6

and I verified that the program actually ran:

buhr@delores:~/src/overflow/clangtest$ stack exec clangtest-exe
Hello, world

huangapple
  • 本文由 发表于 2023年6月26日 05:08:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552414.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定