libsmb2 icon indicating copy to clipboard operation
libsmb2 copied to clipboard

Windows cmake DLL build fails to produce import library - "dlldir" is not being used on windows

Open timmeh87 opened this issue 4 years ago • 6 comments

On Windows, when downloading the latest code and running CMAKE on it, a visual project is produced and the build succeeds. However there is no ".lib" file produced because none of the functions are explicitly exported. This is 'normal' expected behavior on windows and means that libsmb2 can only be used as a static library on windows.

Cmake provides a workaround called "WINDOWS_EXPORT_ALL_SYMBOLS" which could be used to fix this problem, although some people think it is "not the best way to do things"

I only bring this up because I have recently ported libsmb2 into the vcpkg project https://github.com/microsoft/vcpkg/issues/18454

While the port was accepted, it was not accepted to pass "WINDOWS_EXPORT_ALL_SYMBOLS" from the vcpkg side, as this is against their own policy. I was really hoping to have a DLL version of libsmb2 available on vcpkg, which means that libsmb2 itself has to support windows DLL builds somehow.

I would be willing to make a PR to address this but I would like to know the best course of action @sahlberg

timmeh87 avatar Jun 24 '21 21:06 timmeh87

Don't export all symbols. We have a list of the symbols that should be exported and is is used in the autotool bulds : -export-symbols ${srcdir}/libsmb2.syms

I don't know much about building on windows, but it should be possible to tell the cmake windows build to : only export symbols from libsmb2.syms?

As said, I don't know much about windows builds but we do have a list of symbols to be exported that is used everywhere else except windows + cmake build? Patches welcome.

sahlberg avatar Jun 26 '21 08:06 sahlberg

I think you are right, I will look into this

timmeh87 avatar Jun 26 '21 16:06 timmeh87

AFAIK, there are two ways to export symbols from dll in Visual Studio:

  1. using __declspec(dllexport) keyword
  2. using *.def file

Since *.def file in Windows is something just like *.syms file in Linux, we can change libsmb2.syms to libsmb2.def easily. This is my solution:

  1. add a *.def file to the solution in Visual Studio 2017, named libsmb2.def
  2. copy the content form libsmb2.syms to libsmb2.def, do some modifications according to the rules and example
  3. build the solution, then we get smb2.lib and other stuff

I've tested, both my dll and lib work well!

BTW, here's the content of my libsmb2.def

LIBRARY smb2
EXPORTS
    compound_file_id
    dcerpc_allocate_pdu
    dcerpc_call_async
    dcerpc_create_context
    dcerpc_connect_context_async
    dcerpc_destroy_context
    dcerpc_free_data
    dcerpc_free_pdu
    dcerpc_get_error
    dcerpc_context_handle_coder
    nterror_to_str
    nterror_to_errno
    smb2_add_compound_pdu
    smb2_close
    smb2_close_async
    smb2_closedir
    smb2_cmd_close_async
    smb2_cmd_create_async
    smb2_cmd_echo_async
    smb2_cmd_logoff_async
    smb2_cmd_negotiate_async
    smb2_cmd_query_directory_async
    smb2_cmd_query_info_async
    smb2_cmd_session_setup_async
    smb2_cmd_set_info_async
    smb2_cmd_tree_connect_async
    smb2_cmd_tree_disconnect_async
    smb2_connect_async
    smb2_connect_share
    smb2_connect_share_async
    smb2_destroy_context
    smb2_destroy_url
    smb2_disconnect_share
    smb2_disconnect_share_async
    smb2_fd_event_callbacks
    smb2_fh_from_file_id
    smb2_free_data
    smb2_free_pdu
    smb2_fstat
    smb2_fstat_async
    smb2_ftruncate
    smb2_ftruncate_async
    smb2_get_client_guid
    smb2_get_error
    smb2_get_fd
    smb2_get_fds
    smb2_get_file_id
    smb2_get_max_read_size
    smb2_get_max_write_size
    smb2_get_opaque
    smb2_init_context
    smb2_mkdir
    smb2_mkdir_async
    smb2_share_enum_async
    smb2_open
    smb2_open_async
    smb2_opendir
    smb2_opendir_async
    smb2_parse_url
    smb2_pread
    smb2_pread_async
    smb2_pwrite
    smb2_pwrite_async
    smb2_queue_pdu
    smb2_read
    smb2_read_async
    smb2_readdir
    smb2_rewinddir
    smb2_readlink
    smb2_readlink_async
    smb2_rmdir
    smb2_rmdir_async
    smb2_lseek
    smb2_seekdir
    smb2_service
    smb2_service_fd
    smb2_set_authentication
    smb2_set_security_mode
    smb2_set_version
    smb2_set_user
    smb2_set_password
    smb2_set_domain
    smb2_set_workstation
    smb2_set_opaque
    smb2_set_seal
    smb2_set_sign
    smb2_set_timeout
    smb2_stat
    smb2_stat_async
    smb2_statvfs
    smb2_statvfs_async
    smb2_telldir
    smb2_truncate
    smb2_truncate_async
    smb2_rename
    smb2_rename_async
    smb2_unlink
    smb2_unlink_async
    smb2_which_events
    smb2_write
    smb2_write_async
    smb2_echo
    smb2_echo_async
    srvsvc_interface
    srvsvc_NetrShareEnum_rep_coder
    srvsvc_NetrShareEnum_req_coder
    srvsvc_NetrShareGetInfo_rep_coder
    srvsvc_NetrShareGetInfo_req_coder
    NT_SID_AUTHORITY
    lsa_interface
    lsa_Close_rep_coder
    lsa_Close_req_coder
    lsa_LookupSids2_rep_coder
    lsa_LookupSids2_req_coder
    lsa_OpenPolicy2_rep_coder
    lsa_OpenPolicy2_req_coder
    lsa_RPC_SID_coder

shalvenlaw avatar Apr 28 '22 09:04 shalvenlaw

I don't build for windows myself, but can you send me a pull request for this ?

sahlberg avatar Apr 28 '22 09:04 sahlberg

Of course, I can just add my libsmb2.def to the repository.

But I am also finding some way to automate it, like writing some code in CMakeLists.txt to generate libsmb2.def from libsmb2.syms and add it to the solution. So when you change libsmb2.syms, you don't have to change libsmb2.def too!

shalvenlaw avatar Apr 28 '22 09:04 shalvenlaw

I like the idea of using the syms file to get the def file. Ideally he def file should be added to the VS solution automatically through cmake, since then it could be used in vcpkg without further modification. Upstream changes are always preferred. Right now there is a port for libsmb2 on vcpkg that AFAIK has windows disabled due to this issue

(although I created the original vcpkg port, I stopped using it until this could be resolved and just manually edited cmake to include WINDOWS_EXPORT_ALL_SYMBOLS to save myself time)

(Edit: I just went and checked, windows is actually enabled but only for static building, which is a workaround for this issue)

timmeh87 avatar Apr 28 '22 18:04 timmeh87

declaring github issues bancruptcy

sahlberg avatar Mar 29 '24 08:03 sahlberg