英文:
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 >=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
Then, I ran 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
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论