The following piece of F# code compile perfectly well with F# 3.0 fsc.exe but fails to execute. In interactive Mode (fsi.exe) everything works correctly.
I get errror message.
"Referenced assembly 'C:_src_\compilation_sql\FSharp.Data.TypeProviders.dll' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found" at execution time.
Why ?
The idea :
The program write in a current.fs
file a piece of code and call Fsharp.compiler.service
to compile the script into a DLL assembly
Problem : the sequence :
let errors1, exitCode1 = scs.Compile([| "fsc";"-r:System.Core.dll";"-r:System.Collections.Immutable.dll";"-r:System.Reflection.Metadata.dll";"-r:FSharp.Compiler.dll";"-r:FSharp.Compiler.CodeDom.dll";"-r:System.Data.Linq.dll";"-r:FSharp.Data.DesignTime.dll";"-r:FSharp.Compiler.Service.dll" ;"-r:FSharp.Data.TypeProviders.dll"; "-o"; fn3; "-a"; fn2 |])
failed when it is executed from a compiled version of the program.
I compiled the code with the command line :
fsc.exe -r:System.Core.dll -r:System.Collections.Immutable.dll -r:System.Reflection.Metadata.dll -r:FSharp.Compiler.dll -r:FSharp.Compiler.CodeDom.dll -r:System.Data.Linq.dll -r:FSharp.Data.TypeProviders.dll -r:FSharp.Compiler.Service.dll compilation_sql.fs
I execute the compiled program very simply :
compilation_sql.exe
Source code :
System.IO.Directory.SetCurrentDirectory (__SOURCE_DIRECTORY__)
printfn "repertoire d execution : %s" __SOURCE_DIRECTORY__
#if INTERACTIVE
#r "System.Data.Linq.dll"
#r "FSharp.Compiler.dll"
#r "FSharp.Compiler.CodeDom.dll"
#r "FSharp.Data.TypeProviders.dll"
#r "FSharp.Compiler.Service.dll"
#r "System.Collections.Immutable.dll"
#r "System.Reflection.Metadata.dll"
#endif
open System
open System.IO
open System.Collections.Immutable
open System.Reflection.Metadata
open Microsoft.FSharp.Compiler.SimpleSourceCodeServices
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
open System.Data.Linq.SqlClient
// let fn = Path.GetTempFileName()
let fn = sprintf "%s\\current.fs" __SOURCE_DIRECTORY__
printfn "Fichier à Compiler %s" fn
let fn2 = Path.ChangeExtension(fn, ".fs")
let fn3 = Path.ChangeExtension(fn, ".dll")
let script = """
#if INTERACTIVE
#r "System.Data.dll"
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.Linq.dll"
#else
namespace ODDO
#endif
open System
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
open System.Data.Linq.SqlClient
module SQL=
[<Literal>]
let sourceConnectionString = @"Data Source=ZDATLMDL6\Z_MUT_3; Initial Catalog=DB_FXO; Integrated Security=True;"
type dbSchema = SqlDataConnection<sourceConnectionString>
let db = dbSchema.GetDataContext()
// Enable the logging of database activity to the console.
db.DataContext.Log <- System.Console.Out
let query1 =
query {
for row in db.COMPTEUR do
select row
}
let display (res : System.Linq.IQueryable<dbSchema.ServiceTypes.COMPTEUR>) =
printfn "Resultat :"
res |> Seq.iter (fun row -> printfn "%d %s %s " row.ID row.CODE row.LIBELLE )
printfn "Fin de table"
()
"""
File.WriteAllText(fn2, script)
let scs = SimpleSourceCodeServices()
//let errors1, exitCode1 = scs.Compile([| "fsc";"-r:System.Core.dll";"-r:FSharp.Compiler.dll";"-r:FSharp.Compiler.CodeDom.dll";"-r:System.Data.Linq.dll";"-r:FSharp.Data.TypeProviders.dll";"-r:FSharp.Compiler.Service.dll"; "-o"; fn3; "-a"; fn2 |])
let errors1, exitCode1 = scs.Compile([| "fsc";"-r:System.Core.dll";"-r:System.Collections.Immutable.dll";"-r:System.Reflection.Metadata.dll";"-r:FSharp.Compiler.dll";"-r:FSharp.Compiler.CodeDom.dll";"-r:System.Data.Linq.dll";"-r:FSharp.Data.DesignTime.dll";"-r:FSharp.Compiler.Service.dll" ;"-r:FSharp.Data.TypeProviders.dll"; "-o"; fn3; "-a"; fn2 |])
printfn "Nombre erreurs compilation : %d" errors1.Length
for i in 0..errors1.Length - 1 do
let mutable werror = Array.get errors1 i
// printfn "%s %d %s %d " werror.get_FileName() werror.get_ErrorNumber() werror.get_Message() werror.get_StartLine()
printfn "Fichier : %s ErrorNumber : %d Message :%s" werror.FileName werror.ErrorNumber werror.Message
I am new to F# and probably don't know enough about assembly but this fools me. can any one give any hint ?