-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Move SSE compiler options to PCL_COMPILE_OPTIONS
. Expose PCL as a CMake imported target.
#2100
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
Move SSE compiler options to PCL_COMPILE_OPTIONS
. Expose PCL as a CMake imported target.
#2100
Conversation
|
@SergioRAgostinho An even more modern cmake approach is
Thanks a lot for attempting to fix #2013 |
Agreed but that's a massive rework into the whole CMake system. One step at the time. Also the SSE flags are compiler options, not exactly preprocessor definitions. I'm not sure those are automatically propagated. |
@SergioRAgostinho My understanding is if you are building a library in the upstream and exporting it as a target for the downstream to target_link, no matter you are doing |
So I have the impression that works pretty great if all your targets are from within the same project, or being built in the same system, but when you want to deploy your library on some external system things are a little different no? In theory you're shipping only your headers, libs, a cmake config with info about which components were built and which external dependencies used/enabled. Do you have an example I can check of a situation where you linked against a third party which implemented this system properly? |
Actually a very basic implementation of this is possible without any rework, just changing a bunch of lines in |
@SergioRAgostinho The smallest 3rd party library I know that does this properly is glog. Only CMake actually allows you export targets differently for internal and external stuff. One classical example is the DLL macros for windows. You can do something like this
So externally the macro is dllimport to them, internally it's dllexport. |
These exports then... install (TARGETS glog
EXPORT glog-targets
RUNTIME DESTINATION ${_glog_CMake_BINDIR}
PUBLIC_HEADER DESTINATION ${_glog_CMake_INCLUDE_DIR}/glog
LIBRARY DESTINATION ${_glog_CMake_LIBDIR}
ARCHIVE DESTINATION ${_glog_CMake_LIBDIR})
export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake)
export (PACKAGE glog)
install (FILES
${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake
DESTINATION ${_glog_CMake_INSTALLDIR})
install (EXPORT glog-targets NAMESPACE glog:: DESTINATION
${_glog_CMake_INSTALLDIR}) |
Yeah, exporting the targets is "the right way", and this will require serious rework. diff --git a/PCLConfig.cmake.in b/PCLConfig.cmake.in
index 7aed0a7..c2d1ed1 100644
--- a/PCLConfig.cmake.in
+++ b/PCLConfig.cmake.in
@@ -531,24 +531,50 @@ foreach(component ${PCL_TO_FIND_COMPONENTS})
list(APPEND PCL_DEFINITIONS ${PCL_${COMPONENT}_DEFINITIONS})
list(APPEND PCL_LIBRARY_DIRS ${component_library_path})
if(PCL_${COMPONENT}_LIBRARY_DEBUG)
- list(APPEND PCL_${COMPONENT}_LIBRARIES optimized ${PCL_${COMPONENT}_LIBRARY} debug ${PCL_${COMPONENT}_LIBRARY_DEBUG})
list(APPEND PCL_LIBRARY_DIRS ${component_library_path_debug})
- else(PCL_${COMPONENT}_LIBRARY_DEBUG)
- list(APPEND PCL_${COMPONENT}_LIBRARIES ${PCL_${COMPONENT}_LIBRARY})
- endif(PCL_${COMPONENT}_LIBRARY_DEBUG)
- list(APPEND PCL_LIBRARIES ${PCL_${COMPONENT}_LIBRARIES})
+ endif()
+ list(APPEND PCL_LIBRARIES ${pcl_component})
mark_as_advanced(PCL_${COMPONENT}_LIBRARY PCL_${COMPONENT}_LIBRARY_DEBUG)
- endif(_is_header_only EQUAL -1)
+ endif()
# Append internal dependencies
foreach(int_dep ${pcl_${component}_int_dep})
string(TOUPPER "${int_dep}" INT_DEP)
if(PCL_${INT_DEP}_FOUND)
list(APPEND PCL_${COMPONENT}_INCLUDE_DIRS ${PCL_${INT_DEP}_INCLUDE_DIRS})
if(PCL_${INT_DEP}_LIBRARIES)
- list(APPEND PCL_${COMPONENT}_LIBRARIES "${PCL_${INT_DEP}_LIBRARIES}")
+ list(APPEND PCL_${COMPONENT}_LINK_LIBRARIES "${PCL_${INT_DEP}_LIBRARIES}")
endif(PCL_${INT_DEP}_LIBRARIES)
endif(PCL_${INT_DEP}_FOUND)
endforeach(int_dep)
+ if(_is_header_only EQUAL -1)
+ add_library(${pcl_component} @PCL_LIB_TYPE@ IMPORTED GLOBAL)
+ if(PCL_${COMPONENT}_LIBRARY_DEBUG)
+ set_target_properties(${pcl_component}
+ PROPERTIES
+ IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
+ IMPORTED_LOCATION_RELEASE "${PCL_${COMPONENT}_LIBRARY}"
+ IMPORTED_LOCATION_DEBUG "${PCL_${COMPONENT}_LIBRARY_DEBUG}"
+ )
+ else()
+ set_target_properties(${pcl_component}
+ PROPERTIES
+ IMPORTED_LOCATION "${PCL_${COMPONENT}_LIBRARY}"
+ )
+ endif()
+ foreach(def ${PCL_DEFINITIONS})
+ string(REPLACE " " ";" def2 ${def})
+ string(REGEX REPLACE "^-D" "" def3 "${def2}")
+ list(APPEND definitions ${def3})
+ endforeach()
+ set_target_properties(${pcl_component}
+ PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "${definitions}"
+ INTERFACE_COMPILE_OPTIONS "${PCL_COMPILE_OPTIONS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${PCL_${COMPONENT}_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES "${PCL_${COMPONENT}_LINK_LIBRARIES}"
+ )
+ set(PCL_${COMPONENT}_LIBRARIES ${pcl_component})
+ endif()
endif(PCL_${COMPONENT}_FOUND)
endforeach(component) Haven't tested it yet, my laptop needs ages to build PCL. |
Applied the patch
Edit: Here's the content of for octree for instance
|
Updated the diff. Should be fixed now; works on my machine. How this will behave on Windows I am not sure though. |
👍 Looking good. The SSE compiler
|
This is how I set definitions/options: + COMPILE_DEFINITIONS "${PCL_${COMPONENT}_DEFINITIONS}"
+ COMPILE_OPTIONS "" I suspect component definitions are actually empty. So just apply |
I tried to set the compiler options in |
You are applying this diff on top of your pull request, right? |
Yup. I'm even printing the contents of |
One more try, prefixed property names with |
We're getting somewhere but we need to extract that -D prefix [ 50%] Building CXX object CMakeFiles/gicp_double_free.dir/gicp_double_free.cpp.o |
Also, somebody suggested that options should be a list, not a string. |
Yep. I confirmed that my sse flags are now passed the correctly but the definitions are messed up because they're being stored with "-D" prefix. |
That's a simple regex, wait a sec |
We'll also need to define the pcl namespace to avoid target name collision with whoever works with our project downstream. Future people can solve that :) |
Right now targets are prefixed, e.g. |
Last try for today. (The filtering code will need to be factored into utility function later.) |
It's working 👍 Gonna append your diff as your commit. Super cool ending for this PR :D |
elseif(HAVE_SSE_EXTENSIONS) | ||
SET(SSE_FLAGS "${SSE_FLAGS} /arch:SSE") |
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.
Is this on purpose that SSE
became SSE3
?
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.
Bad copy paste.
I think it's essential that these changes are tested on Windows before merging. @UnaNancyOwen can you give it a try? Important is to test if after building/installing PCL dependent projects can successfully link against. Further, switching between Debug/Release builds should be possible. |
@taketwo Yes, I'm going to try this tonight. |
9f34ed0
to
b7fce97
Compare
Should be good now. |
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 tried to build/install with and without PCL_ENABLE_SSE
, as well as in "debian" mode (passing compiler flags explicitly). All works fine and fixes segfauls like reported in #2013.
From my side it's ready.
I updated the PR description to make clear that only |
PCL_COMPILE_OPTIONS
. Expose PCL as a CMake imported target.
We just fixed our Windows CI because of this one 🎉 |
Here we are 🤣 I just came through the fact that with the following line Is this still something that need to be addressed under Windows, or am I having an unexpected behaviour 😄? |
Which flags does vcpkg pass? The currently implemented logic is as follows: if This logic existed before this PR. Only thing it changed is fixed a potential nasty bug associated with it. In general, the fact that vcpkg explicitly sets flags warrants a revision of the logic. Perhaps |
By default I have Update: to be precise, those flags are set as soon as |
This would be very interesting to know indeed. Edit: according to this comment these are defaults. So vcpkg is not passing any additional flags. Therefore, we have a flaw in our logic. |
You anticipated me 😁 |
This PR ensures the SSE compiler options are passed properly downstream. After reading the descriptions for
https://cmake.org/cmake/help/v3.0/command/target_compile_definitions.html#command:target_compile_definitions
https://cmake.org/cmake/help/v3.0/command/target_compile_options.html?highlight=target_compile_options
I opted to create the new var PCL_COMPILE_OPTIONS that should be used by downstream projects like this
Fixes #2013, fixes #1725
Edit (IMPORTANT)
This PR also upgrades "PCLConfig.cmake". From now on, only the following two lines are necessary to use PCL in downstream projects:
The
target_include_directories
,target_compile_definitions
, andtarget_compile_options
mentioned above are superfluous (but they don't hurt and may be kept for compatibility with older PCL versions).