[fix] correctly pass environment vars to the RefC compiler

This commit is contained in:
Adam Brouwers-Harries 2023-12-12 21:16:22 +00:00
parent 59e00c5210
commit 170e52b3c1
10 changed files with 103 additions and 4 deletions

View File

@ -44,10 +44,10 @@
#### RefC
* Adds support for `CFLAGS`, `CPPFLAGS`, and `LDFLAGS` to facilitate building on
systems with non-standard installation locations of libraries (e.g. GMP).
Versions of the flags with the `IDRIS2_` prefix can also be used and take
precedence.
* Adds support for `CFLAGS`, `CPPFLAGS`, `LDFLAGS` and `LDLIBS` to facilitate
building on systems with non-standard installation locations of libraries
(e.g. GMP). Versions of the flags with the `IDRIS2_` prefix can also be used
and take precedence.
#### Chez

View File

@ -2,6 +2,7 @@ Thanks to the following for their help and contributions to Idris 2:
Aaron Lebahn
Abdelhakim Qbaich
Adam Brouwers-Harries
Alain Zscheile
Aleksei Volkov
Alex Gryzlov

View File

@ -7,6 +7,8 @@ import Core.Directory
import System
import Data.String
%default total
findCC : IO String
@ -41,6 +43,14 @@ findLDFLAGS
| Just ldflags => pure ldflags
pure ""
findLDLIBS : IO String
findLDLIBS
= do Nothing <- getEnv "IDRIS2_LDLIBS"
| Just ldlibs => pure ldlibs
Nothing <- getEnv "LDLIBS"
| Just ldlibs => pure ldlibs
pure ""
clibdirs : List String -> List String
clibdirs ds = map (\d => "-L" ++ d) ds
@ -68,6 +78,8 @@ compileCObjectFile {asLibrary} sourceFile objectFile =
"-o", objectFile,
"-I" ++ refcDir,
"-I" ++ cDir]
++ (words cppFlags)
++ (words cFlags)
log "compiler.refc.cc" 10 runccobj
0 <- coreLift $ system runccobj
@ -85,6 +97,7 @@ compileCFile {asShared} objectFile outFile =
do cc <- coreLift findCC
cFlags <- coreLift findCFLAGS
ldFlags <- coreLift findLDFLAGS
ldLibs <- coreLift findLDLIBS
dirs <- getDirs
refcDir <- findDataFile "refc"
@ -100,6 +113,9 @@ compileCFile {asShared} objectFile outFile =
"-L" ++ refcDir
] ++ clibdirs (lib_dirs dirs) ++ [
"-lgmp", "-lm"]
++ (words cFlags)
++ (words ldFlags)
++ (words ldLibs)
log "compiler.refc.cc" 10 runcc
0 <- coreLift $ system runcc

View File

@ -38,10 +38,12 @@ envs = [
MkEnvDesc "IDRIS2_CFLAGS" "RefC backend: C compiler flags.",
MkEnvDesc "IDRIS2_CPPFLAGS" "RefC backend: C preprocessor flags.",
MkEnvDesc "IDRIS2_LDFLAGS" "RefC backend: C linker flags.",
MkEnvDesc "IDRIS2_LDLIBS" "RefC backend: C linker library names or flags.",
MkEnvDesc "CC" "RefC backend: C compiler executable (IDRIS2_CC takes precedence).",
MkEnvDesc "CFLAGS" "RefC backend: C compiler flags (IDRIS2_CFLAGS takes precedence).",
MkEnvDesc "CPPFLAGS" "RefC backend: C preprocessor flags (IDRIS2_CPPFLAGS takes precedence).",
MkEnvDesc "LDFLAGS" "RefC backend: C linker flags (IDRIS2_LDFLAGS takes precedence).",
MkEnvDesc "LDLIBS" "RefC backend: C linker library names or flags (IDRIS2_LDLIBS takes precedence).",
MkEnvDesc "NODE" "NodeJS backend: NodeJS executable.",
MkEnvDesc "PATH" "PATH variable is used to search for executables in certain codegens.",
MkEnvDesc "NO_COLOR" "Instruct Idris not to print color to stdout. Passing the --color/--colour option will supersede this env var."]

View File

@ -0,0 +1,15 @@
import System.FFI
libexternal : String -> String
libexternal fn = "C:" ++ fn ++ ",libexternalc,externalc.h"
%foreign (libexternal "add")
add : Int -> Int -> Int
%foreign (libexternal "fastfibsum")
fastfibsum : Int -> Int
main : IO ()
main = do
printLn $ show (add 50 23)
printLn $ show ([fastfibsum x | x <- [0..10]])

View File

@ -0,0 +1,2 @@
"73"
"[0, 1, 2, 4, 7, 12, 20, 33, 54, 88, 143]"

View File

@ -0,0 +1,10 @@
all: libexternalc.so
externalc.o: externalc.c externalc.h
cc -c -fPIC $< -o $@
libexternalc.so: externalc.o
cc $< -shared -o $@
clean:
rm -f externalc.o externalc.so

View File

@ -0,0 +1,20 @@
#include "externalc.h"
int add(int x, int y) {
return x+y;
}
int fastfibsum(int x) {
int acc = 0;
int p = 0;
int c = 1;
int tmp;
for (;0 <=-- x;)
{
acc += c;
tmp = c;
c = c + p;
p = tmp;
}
return acc;
}

View File

@ -0,0 +1,3 @@
int add(int x, int y);
int fastfibsum(int x);

30
tests/refc/ccompilerArgs/run Executable file
View File

@ -0,0 +1,30 @@
. ../../testutils.sh
# This test checks to make sure that Idris2's command line handling for the RefC backend is correct.
# It checks that:
# 1) Idris2 correctly finds `CFLAGS` and `LDFLAGS` in the environment,
# 2) The values in `CFLAGS` and `LDFLAGS` are separated correctly to be passed to the compiler
#
# (1) is achieved by compiling a c library (`externalc`) in a separate folder, and then explicitly
# pointing the compiler to the header files (with `-I./library/`) and shared library (with `-L./library`)
# and requesting that libexternalc.{so,dylib,dll} is linked (with `-lexternalc`). We additionally point the
# dynamic library loader to the correct location with `DYLD_LIBRARY_PATH`.
#
# (2) is achieved by passing multiple options, separated by spaces, in each of `CFLAGS` and `LDFLAGS`.
# These options are `-O3` for the c flags, and `-Wl,-pie` for the linker flags. They do not change the
# semantics of the resulting code (`-O3` simply optimises it more, and `-Wl,-pie` emits position
# independent code in the final executable), but do check that we correctly split up the environment
# variables when we pass them to the C compiler.
cd ./library/
make > /dev/null
cd ..
export CFLAGS="-I./library/ -O3"
export LDFLAGS="-L./library/ -Wl,-pie"
export LDLIBS="-lexternalc"
export DYLD_LIBRARY_PATH="./library/"
idris2 --cg refc -o cffi Main.idr > /dev/null
./build/exec/cffi