-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support BLOCKFACTORY_PLUGIN_PATH environment variable #32
Support BLOCKFACTORY_PLUGIN_PATH environment variable #32
Conversation
The path can be extended in two ways: - Defining a SHLIBPP_PLUGIN_PATH env variables - Calling the new extendSearchPath method
The paths contained in this environment variable will have the priority over the system paths of the linker
On xenial the Catch2 CMake functions fail if there is more than one test. This commit disables temporary ctest on xenial.
What's still puzzling me that in Windows everything works only if |
What is strange about that? |
You are exporting all symbols in https://github.com/robotology/blockfactory/pull/32/files#diff-af3b638bc2a3e6c650974192a53c7291L92 , so that should work fine with shared libraries unless you have some static variables to export. |
For all the file path stuff did you considered to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only important comment is the order with which plugins are found in Windows when both Release and Debug plugins are available.
Furthermore, it is probably necessary to document the search PATH of the plugins, but this is probably something that can be discussed at the shlibpp PR level.
{ | ||
|
||
#if defined(_WIN32) | ||
return {library + ".dll", library + "d.dll", "lib" + library + ".dll"}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused by this. Why is "lib" + library + ".dll"
is included and "lib" + library + "d.dll"
not?
Furthermore, if the order of the vector indicates the order in which the candidates are searched for, I think that depending on whether BlockFactory
is compiled in release or in debug, the order needs to be changed to make sure that in Debug builds the library + "d.dll"
is searched first. It could make sense to still have the normal one as a fallback, but if both are found and BlockFactory is compiled in debug, for sure library + "d.dll"
is the one to load.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused by this. Why is
"lib" + library + ".dll"
is included and"lib" + library + "d.dll"
not?
Because this case happens only if you don't use the VS generator. This is for instance the case with Ninja, and since it is not a multi-config generator the debug suffix is not used.
For what concern the order, yes, on windows it actually makes sense to define it wrt to the CMAKE_BUILD_TYPE
. There's always the caveat of linking Release code to Release code, and I think this applies also to plugin libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this case happens only if you don't use the VS generator. This is for instance the case with Ninja, and since it is not a multi-config generator the debug suffix is not used.
Cool. So if you use Ninja and compile BlockFactory in Debug, the libraries are compiled with the lib
prefix and without the d
suffix, even if CMAKE_DEBUG_POSTFIX
is set to d
in
Line 95 in 5a0b977
set(CMAKE_DEBUG_POSTFIX "d") |
Ack then, even if it really seems to be a CMake+Ninja+MSVC bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what concern the order, yes, on windows it actually makes sense to define it wrt to the
CMAKE_BUILD_TYPE
. There's always the caveat of linking Release code to Release code, and I think this applies also to plugin libraries.
Nitpick: CMAKE_BUILD_TYPE
is ignored for multiple config generator. Do you have any idea of where this logic in YARP? As far as I know, in YARP that logic is is working fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack then, even if it really seems to be a CMake+Ninja+MSVC bug.
In my tests I was using g++ with Ninja (check travis). I am not 100% sure of the outcome of the combo of MSVC compiler + Ninja generator. I guess it generates the same things of using just MSVC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, sorry I did not understand we wanted to support Mingw.
In that case, in that case it make sense, the CMAKE_DEBUG_POSTFIX
is only set for MSVC
, not for WIN32
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: CMAKE_BUILD_TYPE is ignored for multiple config generator. Do you have any idea of where this logic in YARP? As far as I know, in YARP that logic is is working fine.
You mean in shlibpp
? I didn't find it, I think that this portion of code already handles it:
blockfactory/deps/sharedlibpp/src/SharedLibrary.cpp
Lines 56 to 69 in 7b9033c
#if defined(_WIN32) | |
mPriv->implementation = (void*)LoadLibrary(filename); | |
LPTSTR msg = nullptr; | |
FormatMessage( | |
FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, | |
nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPTSTR)&msg, 0, nullptr); | |
if(msg != nullptr) { | |
mPriv->err_message = std::string(msg); | |
// release memory allocated by FormatMessage() | |
LocalFree(msg); msg = nullptr; | |
} | |
return (mPriv->implementation != nullptr); |
In the example of shlibpp
you must pass the OS-specific name (see test). I added the support of doing it automatically in this PR.
Actually, I just realized that if the library is not in the extended search path, I pass only the libname. This case would cover the case where the library is in the linker search path, and I'm not sure dlopen
can be called without specifying the prefix (lib) and suffix (.so) of the library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean in shlibpp? I didn't find it, I think that this portion of code already handles it:
No, I meant in YARP. I found it, it is in https://github.com/robotology/yarp/blob/master/src/libYARP_OS/src/YarpPlugin.cpp#L69 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding mingw, in theory the mingw would be searched first if BlockFactory is compiled with mingw, as Mingw's and MSVC's C++ ABI are not compatible. However, the trick of <name>d.dll
, name.dll
to distinguish the various ABI is just a dirty trick (there are a few other differences that should be considered to fully determine the ABI compatibility), so I guess it is not tragic if we search it later, as in most cases Mingw-libraries and MSVC-libraries are not installed in the same prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I meant in YARP. I found it, it is in https://github.com/robotology/yarp/blob/master/src/libYARP_OS/src/YarpPlugin.cpp#L69 .
👍
Btw I think that YARP code does not work well with icc
^^ I'm not sure tho if we support it.
Regarding mingw, in theory the mingw would be searched first if BlockFactory is compiled with mingw, as Mingw's and MSVC's C++ ABI are not compatible. However, the trick of d.dll, name.dll to distinguish the various ABI is just a dirty trick (there are a few other differences that should be considered to fully determine the ABI compatibility), so I guess it is not tragic if we search it later, as in most cases Mingw-libraries and MSVC-libraries are not installed in the same prefix.
These are edge cases at this stage. We never stated the we support Mingw and the installation instructions on Windows only mention MSVC. I think we can postpone safely these cases.
Yes but I was not 100% sure that it would work on all compilers. Do you have any experience? |
Yes, but just in Ubuntu, see https://github.com/robotology/gazebo-fmi/blob/master/.travis.yml . It works fine (with the proper flags, see https://github.com/robotology/gazebo-fmi/blob/733ef7c66cdf8241ab8c91c83fb34148f4716ed7/libraries/private-utils/CMakeLists.txt#L24). Apparently there could be problems on macOS, see https://stackoverflow.com/questions/49577343/filesystem-with-c17-doesnt-work-on-my-mac-os-x-high-sierra/49600206 . It is probably indeed better to avoid it for now. |
I didn't get it entirely. The factory test fails on Windows if blockfactory/cmake/BlockFactoryPlugin.cmake Lines 54 to 57 in 7b9033c
I still have to figure out what can be the problem. |
Sorry, I was confused and thought you were surprised that it worked with BUILD_SHARED_LIBS to ON, not that it was not working with BUILD_SHARED_LIBS set to OFF. |
Do you think if would be safe setting by default |
Not sure, I would probably just print a clear error if BUILD_SHARED_LIBS set to OFF is used with Windows, setting |
74a7a0e
to
954d04a
Compare
954d04a
to
04b9bed
Compare
@traversaro Addressed all the requested changes |
shlibpp
to extend plugin search pathSHLIBPP_PLUGIN_PATH
environment variable insideshlibpp
BLOCKFACTORY_PLUGIN_PATH
environment variable for finding pluginsFactoryUnitTest.cpp
P.s. for the time being I will keep the
shlibpp
changes local to this project. I will open a PR upstream in the future.