PackageCompiler.jl icon indicating copy to clipboard operation
PackageCompiler.jl copied to clipboard

Building libraries on Windows generates DLLs, but not the corresponding import libraries

Open acarta opened this issue 2 years ago • 3 comments

On Windows, building a shared library from a Julia package using PackageCompiler produces a shared library, but not an associated import library. As such, shared libraries generated by PackageCompiler cannot be linked to other C/C++ code in a straightforward manner.

When using PackageCompiler to compile a package to a shared library on Windows, the output consists of DLLs corresponding to the package itself as well as the Julia-related dependencies (libjulia.dll, libamd.dll, etc.).

As a MWE, I tried compiling the Julia portion of the libcg proof-of-concept (https://github.com/simonbyrne/libcg) using the following code (run from within libcg/CG):

build_dir = "build"
target_dir = joinpath("..", "..", "target")
project_toml = realpath("Project.toml")

PackageCompiler.create_library(".", target_dir;
                            lib_name="cg",
                            precompile_execution_file=[joinpath(build_dir, "generate_precompile.jl")],
                            precompile_statements_file=[joinpath(build_dir, "additional_precompile.jl")],
                            incremental=false,
                            filter_stdlibs=true,
                            header_files = [joinpath(build_dir, "cg.h")],
                            force=true,
)

The output directory looks like this:

───bin
│       julia.exe
│       libamd.dll
│       libatomic-1.dll
│       libblastrampoline.dll
│       libbtf.dll
│       libcamd.dll
│       libccalltest.dll
│       libccolamd.dll
│       libcholmod.dll
│       libcolamd.dll
│       libcurl-4.dll
│       libdSFMT.dll
│       libgcc_s_seh-1.dll
│       libgfortran-5.dll
│       libgit2.dll
│       libgmp-10.dll
│       libgmp.dll
│       libgmpxx-4.dll
│       libgmpxx.dll
│       libgomp-1.dll
│       libjulia-internal.dll
│       libjulia.dll
│       libklu.dll
│       libldl.dll
│       libLLVM.dll
│       libllvmcalltest.dll
│       libLTO.dll
│       libmbedcrypto.dll
│       libmbedtls.dll
│       libmbedx509.dll
│       libmlir_async_runtime.dll
│       libmlir_c_runner_utils.dll
│       libmlir_runner_utils.dll
│       libmlir_test_cblas.dll
│       libmlir_test_cblas_interface.dll
│       libmpfr-6.dll
│       libmpfr.dll
│       libnghttp2-14.dll
│       libopenblas64_.dll
│       libopenlibm.dll
│       libpcre2-16-0.dll
│       libpcre2-16.dll
│       libpcre2-32-0.dll
│       libpcre2-32.dll
│       libpcre2-8-0.dll
│       libpcre2-8.dll
│       libpcre2-posix-2.dll
│       libquadmath-0.dll
│       librbio.dll
│       libRemarks.dll
│       libspqr.dll
│       libssh2.dll
│       libssp-0.dll
│       libstdc++-6.dll
│       libsuitesparseconfig.dll
│       libumfpack.dll
│       libuv-2.dll
│       libwinpthread-1.dll
│       libz.dll
│
└───include
        cg.h
        julia_init.h

However, in order for these DLLs to be implicitly linked to another library/executable (i.e. not using LoadLibrary), there should be corresponding import libraries (.lib or .dll.a); these are not generated by the compilation process initiated by PackageCompiler.

I noticed that PR #614 added tests for create_library, but examining the current state of those tests here, it looks like the test consists mainly of running create_library without checking the output.

Not sure if this is related, but I opened an issue on libcg itself related to the failing build of the C library/executable.

Version Info

julia> versioninfo()
Julia Version 1.7.2
Commit bf53498635 (2022-02-06 15:21 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, skylake-avx512)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS =

acarta avatar May 05 '22 15:05 acarta

As an addendum, there are tools to generate import libraries from DLLs (e.g. lib.exe from MSVC, but there still seem to be problems there, as well. It seemed to me that is a separate issue, and this is the best place to start. However, I can provide more info on that here, if desired, or open a separate issue.

acarta avatar May 05 '22 15:05 acarta

I have the same problem when trying to embed julia in a VS C++ project. Without .lib files I got LNK2019 and LNK1120 errors related to unresolved external symbols. I also tried lib.exe and failed. Does anyone have a solution?

islent avatar Aug 01 '22 06:08 islent

~~I havethe same / similar issue, the compiled project can not be started each MS Window computers.~~ ~~On the machine where I have compiled the project, I am able to run the compiled MyApp.exe,~~ ~~but on another PC, where no Julia is installed, I see:~~

ERROR: Unable to load dependent library C:\Users\joshuaeder\Desktop\Test\../bin/libopenlibm.dll
ERROR: Unable to load dependent library C:\Users\joshuaeder\Desktop\Test\../bin/libgcc_s_seh-1.dll

~~It does not make a difference, if I compile with Julia v1.8.5 or v1.9.0~~ ~~Unfortunately, both missing DLL are already in the "bin" folder ...~~ It was my fault, I had just copied the folder bin. Maybe it can be written more specifically that all three folder must be copied (yes it is written implicitly).

StefanPofahl avatar Feb 14 '23 21:02 StefanPofahl