Windows cmake DLL build fails to produce import library - "dlldir" is not being used on windows
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
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.
I think you are right, I will look into this
AFAIK, there are two ways to export symbols from dll in Visual Studio:
- using __declspec(dllexport) keyword
- 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:
- add a *.def file to the solution in Visual Studio 2017, named libsmb2.def
- copy the content form libsmb2.syms to libsmb2.def, do some modifications according to the rules and example
- 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
I don't build for windows myself, but can you send me a pull request for this ?
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!
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)
declaring github issues bancruptcy