From 71c81c927b6832a8cf7d429b05c4a90183a27af2 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 6 Aug 2021 08:15:20 +0200 Subject: [PATCH 01/10] Added Conan support - Added a conanfile.py for Conan dependency managing - Use StandardProjectSettings (also used in libArcus) - Set all compiler warnings known to mankind. - Prefer BUILD_SHARED_LIBS over BUILD_STATIC but no change in interface so no change needed on the build servers. - Set build_type to Release if not specified - export compile commands to a json for easier debugging - Use position independent code if applicable (-fPIC) - Switch between MT/MTd of MD/MDd for Visual Studio using text generators - Set C++17 standard - Set stdlib=libc++ for clang-apple - Add option ENABLE_BUILD_WITH_TIME_TRACE for generating time tracing json on Clang compilers - Created an uniform method of Using Python. Setting an exact Python version (standard 3.8). By providing Python_VERSION you can find user specified python version - Created an uniform method of using threading which prefer pthread if the platform supports it and has multiple threading libraries installed. - Updated FindSIP with target alias SIP::SIP - Define USE_SHIPPED_PUGIXML option. Allowing the user to choose between the shipped pugixml library or provide his/her own external library. - Changed pugixml includes and removed it from the public Savitar header. - Removed target libraries from the SIPMacros, this is now a responsibility of the main script. - updated .gitignore with cmake-build-* and tmp --- .gitignore | 3 + CMakeLists.txt | 140 ++++++++----------- cmake/FindSIP.cmake | 67 ++++----- cmake/SIPMacros.cmake | 206 ++++++++++++++-------------- cmake/StandardProjectSettings.cmake | 166 ++++++++++++++++++++++ conanfile.py | 132 ++++++++++++++++++ pugixml/CMakeLists.txt | 53 ++++--- src/MeshData.cpp | 3 +- src/Namespace.cpp | 2 +- src/Scene.cpp | 2 +- src/SceneNode.cpp | 2 +- src/ThreeMFParser.cpp | 1 + src/ThreeMFParser.h | 1 - tests/MeshDataTest.cpp | 2 +- tests/NamespaceTest.cpp | 2 +- 15 files changed, 530 insertions(+), 252 deletions(-) create mode 100644 cmake/StandardProjectSettings.cmake create mode 100644 conanfile.py diff --git a/.gitignore b/.gitignore index 40071d1..fd199af 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ build # Generated headers /src/SavitarExport.h + +cmake-build-*/ +tmp/* diff --git a/CMakeLists.txt b/CMakeLists.txt index ac2afff..098ca80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,51 +1,16 @@ +cmake_minimum_required(VERSION 3.13) project(savitar) -cmake_minimum_required(VERSION 3.8) - -include(GNUInstallDirs) -include(CMakePackageConfigHelpers) -include(GenerateExportHeader) option(BUILD_PYTHON "Build " ON) option(BUILD_STATIC "Build as a static library" OFF) option(BUILD_TESTS "Building the test-suite" OFF) -if(BUILD_TESTS) - message(STATUS "Building with tests...") - find_package(GTest REQUIRED) - find_package(Threads QUIET) -endif() - -add_subdirectory(pugixml) - -if(BUILD_PYTHON) - list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - - # FIXME: Remove the code for CMake <3.12 once we have switched over completely. - # FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. - if(${CMAKE_VERSION} VERSION_LESS 3.12) - # FIXME: Use FindPython3 to find Python, new in CMake 3.12. - # However currently on our CI server it finds the wrong Python version and then doesn't find the headers. - find_package(PythonInterp 3.4 REQUIRED) - find_package(PythonLibs 3.4 REQUIRED) - - else() - # Use FindPython3 for CMake >=3.12 - find_package(Python3 3.4 REQUIRED COMPONENTS Interpreter Development) - endif() - - find_package(SIP REQUIRED) - if(NOT DEFINED LIB_SUFFIX) - set(LIB_SUFFIX "") - endif() - - include_directories(python/ src/ ${SIP_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS}) -endif() - -set(CMAKE_CXX_STANDARD 17) +include(cmake/StandardProjectSettings.cmake) +include(CMakePackageConfigHelpers) +include(GenerateExportHeader) -if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") -endif() +set(SAVITAR_VERSION 0.1.2) +set(SAVITAR_SOVERSION 0) set(savitar_SRCS src/Namespace.cpp @@ -69,38 +34,57 @@ set(savitar_HDRS ${CMAKE_CURRENT_BINARY_DIR}/src/SavitarExport.h ) -set(SAVITAR_VERSION 0.1.2) -set(SAVITAR_SOVERSION 0) +if(BUILD_SHARED_LIBS) + add_library(Savitar SHARED ${savitar_SRCS}) +else() + add_library(Savitar STATIC ${savitar_SRCS}) +endif() -set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) +use_threads(Savitar) -if(BUILD_STATIC) - add_library(Savitar STATIC ${savitar_SRCS}) +set_project_standards(Savitar) +set_project_warnings(Savitar) + +set(USE_SHIPPED_PUGIXML ON CACHE BOOL "Use the shipped pugixml library") +if(USE_SHIPPED_PUGIXML) + message(STATUS "Using shipped pugixml library") + add_subdirectory(pugixml) else() - add_library(Savitar SHARED ${savitar_SRCS}) + find_package(pugixml 1.8 REQUIRED) endif() -set(Savitar_LINK_LIBRARIES pugixml) -if(CMAKE_USE_PTHREADS_INIT) - list(APPEND Savitar_LINK_LIBRARIES pthread) -endif() -target_link_libraries(Savitar PUBLIC ${Savitar_LINK_LIBRARIES}) +target_link_libraries(Savitar PRIVATE pugixml::pugixml) -if(NOT WIN32 OR CMAKE_COMPILER_IS_GNUCXX) - set_target_properties(Savitar PROPERTIES COMPILE_FLAGS -fPIC) -endif() +generate_export_header(Savitar EXPORT_FILE_NAME src/SavitarExport.h) +target_include_directories(Savitar + PUBLIC + $ + $ + $ # Include SavitarExport.h + ) if(BUILD_PYTHON) + list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + + find_package(SIP REQUIRED) + set(SIP_EXTRA_FILES_DEPEND python/Types.sip python/MeshData.sip python/SceneNode.sip python/Scene.sip) - #set(SIP_EXTRA_SOURCE_FILES python/Types.cpp) - set(SIP_EXTRA_OPTIONS -g -n PyQt5.sip) # -g means always release the GIL before calling C++ methods. -n PyQt5.sip is required to not get the PyCapsule error + set(SIP_EXTRA_OPTIONS -y Savitar.pyi -o -g -n PyQt5.sip) + add_sip_python_module(Savitar python/ThreeMFParser.sip Savitar) -endif() -target_include_directories(Savitar PUBLIC - $ - $ -) + set_project_standards(python_module_Savitar) + set_project_warnings(python_module_Savitar) + use_python(python_module_Savitar Interpreter Development) + + target_link_libraries(python_module_Savitar PRIVATE SIP::SIP) + target_include_directories(python_module_Savitar + PRIVATE + $ + $ + $ # Include SavitarExport.h + ) +endif() if(${CMAKE_BUILD_TYPE}) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") @@ -118,13 +102,6 @@ set_target_properties(Savitar PROPERTIES VISIBILITY_INLINES_HIDDEN 1 ) -generate_export_header(Savitar - EXPORT_FILE_NAME src/SavitarExport.h -) -# This is required when building out-of-tree. -# The compiler won't find the generated header otherwise. -include_directories(${CMAKE_BINARY_DIR}/src) - install(TARGETS Savitar EXPORT Savitar-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -133,23 +110,22 @@ install(TARGETS Savitar PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/Savitar ) -install(EXPORT Savitar-targets - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Savitar -) +install(EXPORT Savitar-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Savitar) configure_package_config_file(SavitarConfig.cmake.in ${CMAKE_BINARY_DIR}/SavitarConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Savitar) write_basic_package_version_file(${CMAKE_BINARY_DIR}/SavitarConfigVersion.cmake VERSION ${SAVITAR_VERSION} COMPATIBILITY SameMajorVersion) -# List of tests. For each test there must be a file tests/${NAME}.cpp. -set(savitar_TEST - ThreeMFParserTest - MeshDataTest - NamespaceTest -) - # Compiling the test environment. if (BUILD_TESTS) - include_directories(${GTEST_INCLUDE_DIR}) + message(STATUS "Building with tests...") + find_package(GTest CONFIG REQUIRED) + + # List of tests. For each test there must be a file tests/${NAME}.cpp. + set(savitar_TEST + ThreeMFParserTest + MeshDataTest + NamespaceTest + ) enable_testing() @@ -159,7 +135,9 @@ if (BUILD_TESTS) foreach (test ${savitar_TEST}) add_executable(${test} tests/main.cpp tests/${test}.cpp) - target_link_libraries(${test} Savitar ${GTEST_BOTH_LIBRARIES}) + set_project_standards(${test}) + set_project_warnings(${test}) + target_link_libraries(${test} PRIVATE Savitar GTest::gtest GTest::gmock pugixml::pugixml) add_test(${test} ${test}) add_dependencies(build_all_tests ${test}) #Make sure that this gets built as part of the build_all_tests target. endforeach() diff --git a/cmake/FindSIP.cmake b/cmake/FindSIP.cmake index 3774b12..8e2c1e9 100644 --- a/cmake/FindSIP.cmake +++ b/cmake/FindSIP.cmake @@ -24,57 +24,55 @@ if(APPLE) set(CMAKE_FIND_FRAMEWORK LAST) endif() -# FIXME: Use the new FindPython3 module rather than these. New in CMake 3.12. -# However currently that breaks on our CI server, since the CI server finds the built-in Python3.6 and then doesn't find the headers. -find_package(PythonInterp 3.5 REQUIRED) -find_package(PythonLibs 3.5 REQUIRED) - -# Define variables that are available in FindPython3, so there's no need to branch off in the later part. -set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) -set(Python3_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) -set(Python3_LIBRARIES ${PYTHON_LIBRARIES}) +if(NOT Python_VERSION) + set(Python_VERSION + 3.8 + CACHE STRING "Python Version" FORCE) + message(STATUS "Setting Python version to ${Python_VERSION}. Set Python_VERSION if you want to compile against an other version.") +endif() +find_package(Python3 ${Python_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development) execute_process( - COMMAND ${Python3_EXECUTABLE} -c - "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False))" - RESULT_VARIABLE _process_status - OUTPUT_VARIABLE _process_output - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${Python3_EXECUTABLE} -c + "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False))" + RESULT_VARIABLE _process_status + OUTPUT_VARIABLE _process_output + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${_process_status} EQUAL 0) - string(STRIP ${_process_output} Python3_SITELIB) + string(STRIP ${_process_output} Python3_SITELIB) else() - message(FATAL_ERROR "Failed to get Python3_SITELIB. Error: ${_process_output}") + message(FATAL_ERROR "Failed to get Python3_SITELIB. Error: ${_process_output}") endif() execute_process( - COMMAND ${Python3_EXECUTABLE} -c - "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False))" - RESULT_VARIABLE _process_status - OUTPUT_VARIABLE _process_output - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${Python3_EXECUTABLE} -c + "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False))" + RESULT_VARIABLE _process_status + OUTPUT_VARIABLE _process_output + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${_process_status} EQUAL 0) - string(STRIP ${_process_output} Python3_SITEARCH) + string(STRIP ${_process_output} Python3_SITEARCH) else() - message(FATAL_ERROR "Failed to get Python3_SITEARCH. Error: ${_process_output}") + message(FATAL_ERROR "Failed to get Python3_SITEARCH. Error: ${_process_output}") endif() get_filename_component(_python_binary_path ${Python3_EXECUTABLE} DIRECTORY) find_program(SIP_EXECUTABLE sip - HINTS ${CMAKE_PREFIX_PATH}/bin ${CMAKE_INSTALL_PATH}/bin ${_python_binary_path} ${Python3_SITELIB}/PyQt5 -) + HINTS ${CMAKE_PREFIX_PATH}/bin ${CMAKE_INSTALL_PATH}/bin ${_python_binary_path} ${Python3_SITELIB}/PyQt5 + ) find_path(SIP_INCLUDE_DIRS sip.h - HINTS ${CMAKE_PREFIX_PATH}/include ${CMAKE_INSTALL_PATH}/include ${Python3_INCLUDE_DIRS} ${Python3_SITELIB}/PyQt5 -) + HINTS ${CMAKE_PREFIX_PATH}/include ${CMAKE_INSTALL_PATH}/include ${Python3_INCLUDE_DIRS} ${Python3_SITELIB}/PyQt5 + ) execute_process( - COMMAND ${Python3_EXECUTABLE} -c "import sip; print(sip.SIP_VERSION_STR)" - RESULT_VARIABLE _process_status - OUTPUT_VARIABLE _process_output - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${Python3_EXECUTABLE} -c "import sip; print(sip.SIP_VERSION_STR)" + RESULT_VARIABLE _process_status + OUTPUT_VARIABLE _process_output + OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${_process_status} EQUAL 0) @@ -88,4 +86,9 @@ if(SIP_FOUND) include(${CMAKE_CURRENT_LIST_DIR}/SIPMacros.cmake) endif() -mark_as_advanced(SIP_EXECUTABLE SIP_INCLUDE_DIRS SIP_VERSION) +add_library(SIP::SIP INTERFACE IMPORTED) +set_property(TARGET SIP::SIP + PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${SIP_INCLUDE_DIRS} APPEND) + +mark_as_advanced(SIP_EXECUTABLE SIP_INCLUDE_DIRS SIP_VERSION SIP::SIP) \ No newline at end of file diff --git a/cmake/SIPMacros.cmake b/cmake/SIPMacros.cmake index 14544d2..c46fd2b 100644 --- a/cmake/SIPMacros.cmake +++ b/cmake/SIPMacros.cmake @@ -16,114 +16,110 @@ # which is typically a shared library, should be linked to. The built # module will also be install into Python's site-packages directory. # -# The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a -# number of variables: +#The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a number +#of variables: # -# SIP_INCLUDE_DIRS - List of directories which SIP will scan through when looking -# for included .sip files. (Corresponds to the -I option for SIP.) +#SIP_INCLUDE_DIRS - List of directories which SIP will scan through when looking +# for included .sip files. (Corresponds to the -I option for SIP.) # -# SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t -# option for SIP.) +#SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t +# option for SIP.) # -# SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code -# of each module should be split into. Defaults to 8. (Corresponds to the -# -j option for SIP.) +#SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code of +# each module should be split into. Defaults to 8. (Corresponds to the -j +# option for SIP.) # -# SIP_DISABLE_FEATURES - List of feature names which should be disabled -# running SIP. (Corresponds to the -x option for SIP.) +#SIP_DISABLE_FEATURES - List of feature names which should be disabled running +# SIP. (Corresponds to the -x option for SIP.) # -# SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to -# SIP. - -SET(SIP_INCLUDE_DIRS) -SET(SIP_TAGS) -SET(SIP_CONCAT_PARTS 8) -SET(SIP_DISABLE_FEATURES) -SET(SIP_EXTRA_OPTIONS) - -MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP) - - SET(EXTRA_LINK_LIBRARIES ${ARGN}) - - STRING(REPLACE "." "/" _x ${MODULE_NAME}) - GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH) - GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME) - - GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH) - GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE) - - # We give this target a long logical target name. - # (This is to avoid having the library name clash with any already - # install library names. If that happens then cmake dependency - # tracking get confused.) - STRING(REPLACE "." "_" _logical_name ${MODULE_NAME}) - SET(_logical_name "python_module_${_logical_name}") - - FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}) # Output goes in this dir. - - SET(_sip_includes) - FOREACH (_inc ${SIP_INCLUDES}) - GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE) - LIST(APPEND _sip_includes -I ${_abs_inc}) - ENDFOREACH (_inc ) - - SET(_sip_tags) - FOREACH (_tag ${SIP_TAGS}) - LIST(APPEND _sip_tags -t ${_tag}) - ENDFOREACH (_tag) - - SET(_sip_x) - FOREACH (_x ${SIP_DISABLE_FEATURES}) - LIST(APPEND _sip_x -x ${_x}) - ENDFOREACH (_x ${SIP_DISABLE_FEATURES}) - - SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}") - SET(_sip_output_files) - FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) - IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) - SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/sip${_child_module_name}part${CONCAT_NUM}.cpp ) - ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} ) - ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} ) - - # Suppress warnings - IF(PEDANTIC) - IF(MSVC) - # 4996 deprecation warnings (bindings re-export deprecated methods) - # 4701 potentially uninitialized variable used (sip generated code) - # 4702 unreachable code (sip generated code) - ADD_DEFINITIONS( /wd4996 /wd4701 /wd4702 ) - ELSE(MSVC) - # disable all warnings - ADD_DEFINITIONS( -w ) - ENDIF(MSVC) - ENDIF(PEDANTIC) - - ADD_CUSTOM_COMMAND( - OUTPUT ${_sip_output_files} - COMMAND ${CMAKE_COMMAND} -E echo ${message} - COMMAND ${CMAKE_COMMAND} -E touch ${_sip_output_files} - COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_BINARY_DIR}/${_module_path} ${_sip_includes} ${_abs_module_sip} - DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND} +#SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to +# SIP. + +set(SIP_INCLUDE_DIRS) +set(SIP_TAGS) +set(SIP_CONCAT_PARTS 8) +set(SIP_DISABLE_FEATURES) +set(SIP_EXTRA_OPTIONS) + +macro(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP) + + set(EXTRA_LINK_LIBRARIES ${ARGN}) + + string(REPLACE "." "/" _x ${MODULE_NAME}) + get_filename_component(_parent_module_path ${_x} PATH) + get_filename_component(_child_module_name ${_x} NAME) + + get_filename_component(_module_path ${MODULE_SIP} PATH) + get_filename_component(_abs_module_sip ${MODULE_SIP} ABSOLUTE) + + #We give this target a long logical target name. + #(This is to avoid having the library name clash with any already install + #library names. If that happens then CMake dependency tracking gets + #confused.) + string(REPLACE "." "_" _logical_name ${MODULE_NAME}) + set(_logical_name "python_module_${_logical_name}") + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}) #Output goes in this dir. + + set(_sip_includes) + foreach(_inc ${SIP_INCLUDES}) + get_filename_component(_abs_inc ${_inc} ABSOLUTE) + list(APPEND _sip_includes -I ${_abs_inc}) + endforeach(_inc) + + set(_sip_tags) + foreach(_tag ${SIP_TAGS}) + list(APPEND _sip_tags -t ${_tag}) + endforeach(_tag) + + set(_sip_x) + foreach(_x ${SIP_DISABLE_FEATURES}) + list(APPEND _sip_x -x ${_x}) + endforeach(_x ${SIP_DISABLE_FEATURES}) + + set(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}") + set(_sip_output_files) + foreach(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS}) + if(${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS}) + set(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_BINARY_DIR}/${_module_path}/sip${_child_module_name}part${CONCAT_NUM}.cpp) + endif( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS}) + endforeach(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS}) + + #Suppress warnings. + if(PEDANTIC) + if(MSVC) + #4996 deprecation warnings (bindings re-export deprecated methods). + #4701 potentially uninitialized variable used (sip generated code). + #4702 unreachable code (sip generated code). + add_definitions(/wd4996 /wd4701 /wd4702) + else(MSVC) + #Disable all warnings. + add_definitions(-w) + endif(MSVC) + endif(PEDANTIC) + + add_custom_command( + OUTPUT ${_sip_output_files} + COMMAND ${CMAKE_COMMAND} -E echo ${message} + COMMAND ${CMAKE_COMMAND} -E touch ${_sip_output_files} + COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_BINARY_DIR}/${_module_path} ${_sip_includes} ${_abs_module_sip} + DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND} ) - # not sure if type MODULE could be uses anywhere, limit to cygwin for now - IF (CYGWIN OR APPLE) - ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} ${SIP_EXTRA_SOURCE_FILES}) - ELSE (CYGWIN OR APPLE) - ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} ${SIP_EXTRA_SOURCE_FILES}) - ENDIF (CYGWIN OR APPLE) - IF (NOT APPLE) - TARGET_LINK_LIBRARIES(${_logical_name} ${Python3_LIBRARIES}) - ENDIF (NOT APPLE) - TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES}) - IF (APPLE) - SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") - ENDIF (APPLE) - SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name}) - - IF (WIN32) - SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES SUFFIX ".pyd" IMPORT_PREFIX "_") - ENDIF (WIN32) - - INSTALL(TARGETS ${_logical_name} DESTINATION "${Python3_SITEARCH}/${_parent_module_path}") - -ENDMACRO(ADD_SIP_PYTHON_MODULE) + #Not sure if type MODULE could be uses anywhere, limit to Cygwin for now. + if(CYGWIN OR APPLE) + add_library(${_logical_name} MODULE ${_sip_output_files} ${SIP_EXTRA_SOURCE_FILES}) + else(CYGWIN OR APPLE) + add_library(${_logical_name} SHARED ${_sip_output_files} ${SIP_EXTRA_SOURCE_FILES}) + endif(CYGWIN OR APPLE) + if(APPLE) + set_target_properties(${_logical_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") + endif(APPLE) + set_target_properties(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name}) + + if(WIN32) + set_target_properties(${_logical_name} PROPERTIES SUFFIX ".pyd" IMPORT_PREFIX "_") + endif(WIN32) + + install(TARGETS ${_logical_name} DESTINATION "${Python3_SITEARCH}/${_parent_module_path}") + +endmacro(ADD_SIP_PYTHON_MODULE) \ No newline at end of file diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake new file mode 100644 index 0000000..b63ad7a --- /dev/null +++ b/cmake/StandardProjectSettings.cmake @@ -0,0 +1,166 @@ +include(GNUInstallDirs) # Standard install dirs +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") # TODO: Check if this is still needed + +# Uniform how we define BUILD_STATIC or BUILD_SHARED_LIBS (common practice) +if(DEFINED BUILD_STATIC) + if(DEFINED BUILD_SHARED_LIBS) + if(${BUILD_SHARED_LIBS} AND ${BUILD_STATIC}) + message(FATAL_ERROR "Conflicting arguments for BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} and BUILD_STATIC=${BUILD_STATIC}") + endif() + else() + set(BUILD_SHARED_LIBS NOT ${BUILD_STATIC}) + endif() +else() + if(NOT DEFINED BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ON) + endif() +endif() +message(STATUS "Setting BUILD_SHARED_LIBS to ${BUILD_SHARED_LIBS}") + +# Set a default build type if none was specified +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui, ccmake + set_property( + CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS + "Debug" + "Release" + "MinSizeRel" + "RelWithDebInfo") +endif() + +# Generate compile_commands.json to make it easier to work with clang based tools +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if (NOT MSVC) + # Compile with the -fPIC options if supported + if(DEFINED POSITION_INDEPENDENT_CODE) # Use the user/Conan set value + message(STATUS "Using POSITION_INDEPENDENT_CODE: ${POSITION_INDEPENDENT_CODE}") + else() + set(POSITION_INDEPENDENT_CODE ON) # Defaults to on + message(STATUS "Setting POSITION_INDEPENDENT_CODE: ${POSITION_INDEPENDENT_CODE}") + + # Set Visual Studio flags MD/MDd or MT/MTd + if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + endif() + endif() +endif() + +# Use C++17 Standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Set common project options for the target +function(set_project_standards project_name) + if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF) + if(ENABLE_BUILD_WITH_TIME_TRACE) + add_compile_definitions(${project_name} PRIVATE -ftime-trace) + endif() + if (APPLE) # Linux already compiles against libstdc++ + target_compile_options(${project_name} PRIVATE "-stdlib=libc++") + endif() + endif() +endfunction() + +# Ultimaker uniform Python linking method +function(use_python project_name) + SET(COMPONENTS ${ARGN}) + if(NOT DEFINED Python_VERSION) + set(Python_VERSION + 3.8 + CACHE STRING "Python Version" FORCE) + message(STATUS "Setting Python version to ${Python_VERSION}. Set Python_VERSION if you want to compile against an other version.") + endif() + find_package(Python3 ${Python_VERSION} EXACT REQUIRED COMPONENTS ${COMPONENTS}) + target_link_libraries(${project_name} PRIVATE ${Python3_LIBRARIES}) + target_include_directories(${project_name} PUBLIC ${Python3_INCLUDE_DIRS}) + message(STATUS "Linking and building ${project_name} against Python ${Python3_VERSION}") +endfunction() + +# Ultimaker uniform Thread linking method +function(use_threads project_name) + message(STATUS "Enabling threading support for ${project_name}") + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + set(THREADS_PREFER_PTHREAD_FLAG TRUE) + find_package(Threads) + target_link_libraries(${project_name} PRIVATE Threads::Threads) +endfunction() + +# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md +function(set_project_warnings project_name) + + set(MSVC_WARNINGS + /W4 # Baseline reasonable warnings + /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data + /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data + /w14263 # 'function': member function does not override any base class virtual member function + /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not + # be destructed correctly + /w14287 # 'operator': unsigned/negative constant mismatch + /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside + # the for-loop scope + /w14296 # 'operator': expression is always 'boolean_value' + /w14311 # 'variable': pointer truncation from 'type1' to 'type2' + /w14545 # expression before comma evaluates to a function which is missing an argument list + /w14546 # function call before comma missing argument list + /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect + /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? + /w14555 # expression has no effect; expected expression with side- effect + /w14619 # pragma warning: there is no warning number 'number' + /w14640 # Enable warning on thread un-safe static member initialization + /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. + /w14905 # wide string literal cast to 'LPSTR' + /w14906 # string literal cast to 'LPWSTR' + /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied + /permissive- # standards conformance mode for MSVC compiler. + ) + + set(CLANG_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wshadow # warn the user if a variable declaration shadows one from a parent context + -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps + # catch hard to track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual function + -Wpedantic # warn if non-standard C++ is used + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output (ie printf) + ) + + set(GCC_WARNINGS + ${CLANG_WARNINGS} + -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise were probably wanted + -Wuseless-cast # warn if you perform a cast to the same type + ) + + if(MSVC) + set(PROJECT_WARNINGS ${MSVC_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(PROJECT_WARNINGS ${CLANG_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(PROJECT_WARNINGS ${GCC_WARNINGS}) + else() + message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") + endif() + + target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) + +endfunction() \ No newline at end of file diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..a0d6daa --- /dev/null +++ b/conanfile.py @@ -0,0 +1,132 @@ +import os +import pathlib + +from conans import ConanFile, tools +from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake + +class SavitarConan(ConanFile): + name = "Savitar" + version = "4.10.0" + license = "LGPL-3.0" + author = "Ultimaker B.V." + url = "https://github.com/Ultimaker/libSavitar" + description = "libSavitar is a c++ implementation of 3mf loading with SIP python bindings" + topics = ("conan", "python", "binding", "sip", "cura", "3mf", "c++") + settings = "os", "compiler", "build_type", "arch" + exports = "LICENSE" + options = { + "shared": [True, False], + "fPIC": [True, False], + "tests": [True, False], + "python_version": "ANY" + } + default_options = { + "shared": True, + "fPIC": True, + "tests": False, + "python_version": "3.8" + } + scm = { + "type": "git", + "subfolder": ".", + "url": "auto", + "revision": "auto" + } + + # TODO: Move lib naming logic to python_requires project + _ext = None + + @property + def ext(self): + if self._ext: + return self._ext + self._ext = "lib" if self.settings.os == "Windows" else "a" + if self.options.shared: + if self.settings.os == "Windows": + self._ext = "dll" + elif self.settings.os == "Macos": + self._ext = "dylib" + else: + self._ext = "so" + return self._ext + + @property + def lib_name(self): + return self.name + + def configure(self): + self.options["SIP"].shared = self.options.shared + self.options["SIP"].python_version = self.options.python_version + self.options["pugixml"].shared = self.options.shared + if self.options.shared or self.settings.compiler == "Visual Studio": + del self.options.fPIC + + def build_requirements(self): + self.build_requires("cmake/[>=3.16.2]") + if self.options.tests: + self.build_requires("gtest/[>=1.10.0]", force_host_context=True) + + def requirements(self): + self.requires("SIP/[>=4.19.24]@riverbankcomputing/testing") + self.requires("pugixml/1.8.1@bincrafters/stable") + + def validate(self): + if self.settings.compiler.get_safe("cppstd"): + tools.check_min_cppstd(self, 17) + + def generate(self): + cmake = CMakeDeps(self) + cmake.generate() + + tc = CMakeToolchain(self) + + # FIXME: This shouldn't be necessary (maybe a bug in Conan????) + if self.settings.compiler == "Visual Studio": + tc.blocks["generic_system"].values["generator_platform"] = None + tc.blocks["generic_system"].values["toolset"] = None + + tc.variables["SIP_MODULE_SITE_PATH"] = "site-packages" + tc.variables["USE_SHIPPED_PUGIXML"] = False + tc.variables["Python_VERSION"] = self.options.python_version + tc.variables["BUILD_TESTS"] = self.options.tests + tc.generate() + + _cmake = None + + def configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + + def build(self): + cmake = self.configure_cmake() + cmake.build() + + def package(self): + cmake = self.configure_cmake() + cmake.install() + self.copy("*", src = os.path.join("package", "include"), dst = "include") + self.copy("*", src = os.path.join("package", "lib"), dst = "lib", excludes = "*.cmake") + self.copy("*", src = os.path.join("package", "site-packages"), dst = "site-packages") + self.copy("*.pyi", src = ".", dst = "site-packages") + + def package_info(self): + self.cpp_info.libs = [self.lib_name] + if self.in_local_cache: + self.runenv_info.prepend_path("PYTHONPATH", os.path.join(self.package_folder, "site-packages")) + self.cpp_info.includedirs = ["include"] + self.cpp_info.libdirs = ["lib"] + else: + local_build_path = os.path.join(str(pathlib.Path(__file__).parent.absolute())),\ + f"cmake-build{self.settings.build_type}".lower() + self.runenv_info.prepend_path("PYTHONPATH", local_build_path) + self.cpp_info.includedirs = ["src"] + self.cpp_info.libdirs = [local_build_path] + self.cpp_info.names["cmake_find_package"] = self.name + self.cpp_info.names["cmake_find_package_multi"] = self.name + if self.settings.build_type == "Debug": + self.cpp_info.defines.append("SAVITAR_DEBUG") + if self.settings.os in ["Linux", "FreeBSD", "Macos"]: + self.cpp_info.system_libs.append("pthread") \ No newline at end of file diff --git a/pugixml/CMakeLists.txt b/pugixml/CMakeLists.txt index 593ce60..5ead4ec 100644 --- a/pugixml/CMakeLists.txt +++ b/pugixml/CMakeLists.txt @@ -1,6 +1,6 @@ +cmake_minimum_required(VERSION 3.13) project(pugixml) - -cmake_minimum_required(VERSION 2.6) +include(${CMAKE_SOURCE_DIR}/cmake/StandardProjectSettings.cmake) option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF) option(BUILD_TESTS "Build tests" OFF) @@ -8,53 +8,50 @@ option(BUILD_PKGCONFIG "Build in PKGCONFIG mode" OFF) set(BUILD_DEFINES "" CACHE STRING "Build defines") -if(MSVC) - option(STATIC_CRT "Use static CRT libraries" OFF) - - # Rewrite command line flags to use /MT if necessary - if(STATIC_CRT) - foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - endif() +if (MSVC) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ${BUILD_SHARED_LIBS}) endif() # Pre-defines standard install locations on *nix systems. include(GNUInstallDirs) mark_as_advanced(CLEAR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR) -set(HEADERS src/pugixml.hpp src/pugiconfig.hpp) set(SOURCES ${HEADERS} src/pugixml.cpp) if(DEFINED BUILD_DEFINES) - foreach(DEFINE ${BUILD_DEFINES}) - add_definitions("-D" ${DEFINE}) - endforeach() + foreach(DEFINE ${BUILD_DEFINES}) + add_definitions("-D" ${DEFINE}) + endforeach() endif() if(BUILD_SHARED_LIBS) - add_library(pugixml SHARED ${SOURCES}) + add_library(pugixml SHARED ${SOURCES}) else() - add_library(pugixml STATIC ${SOURCES}) + add_library(pugixml STATIC ${SOURCES}) endif() -set_target_properties(pugixml PROPERTIES COMPILE_FLAGS -fPIC) +use_threads(pugixml) + +target_include_directories(pugixml + PUBLIC + $ + $ + ) + +set_project_standards(pugixml) +set_project_warnings(pugixml) # Enable C++11 long long for compilers that are capable of it if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} STRLESS 3.1 AND ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_long_long_type;") - target_compile_features(pugixml PUBLIC cxx_long_long_type) + target_compile_features(pugixml PUBLIC cxx_long_long_type) endif() set_target_properties(pugixml PROPERTIES VERSION 1.8 SOVERSION 1) get_target_property(PUGIXML_VERSION_STRING pugixml VERSION) if(BUILD_PKGCONFIG) - # Install library into its own directory under LIBDIR - set(INSTALL_SUFFIX /pugixml-${PUGIXML_VERSION_STRING}) + # Install library into its own directory under LIBDIR + set(INSTALL_SUFFIX /pugixml-${PUGIXML_VERSION_STRING}) endif() install(TARGETS pugixml EXPORT pugixml-config @@ -65,6 +62,8 @@ install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${INSTALL_SUFFIX install(EXPORT pugixml-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml) if(BUILD_PKGCONFIG) - configure_file(scripts/pugixml.pc.in ${PROJECT_BINARY_DIR}/pugixml.pc @ONLY) - install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) + configure_file(scripts/pugixml.pc.in ${PROJECT_BINARY_DIR}/pugixml.pc @ONLY) + install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) endif() + +add_library(pugixml::pugixml ALIAS pugixml) diff --git a/src/MeshData.cpp b/src/MeshData.cpp index 97c089a..6640062 100644 --- a/src/MeshData.cpp +++ b/src/MeshData.cpp @@ -16,8 +16,9 @@ * along with this program. If not, see . */ +#include + #include "MeshData.h" -#include "../pugixml/src/pugixml.hpp" #include #include #include //For std::runtime_error. diff --git a/src/Namespace.cpp b/src/Namespace.cpp index 2cfff76..23c3349 100644 --- a/src/Namespace.cpp +++ b/src/Namespace.cpp @@ -3,7 +3,7 @@ #include "Namespace.h" -#include "../pugixml/src/pugixml.hpp" +#include namespace xml_namespace { diff --git a/src/Scene.cpp b/src/Scene.cpp index 7a40570..86e9295 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -17,7 +17,7 @@ */ #include "Scene.h" -#include "../pugixml/src/pugixml.hpp" +#include #include #include using namespace Savitar; diff --git a/src/SceneNode.cpp b/src/SceneNode.cpp index db686e9..8c9dd8c 100644 --- a/src/SceneNode.cpp +++ b/src/SceneNode.cpp @@ -18,7 +18,7 @@ #include "SceneNode.h" #include "Namespace.h" -#include "../pugixml/src/pugixml.hpp" +#include #include using namespace Savitar; diff --git a/src/ThreeMFParser.cpp b/src/ThreeMFParser.cpp index 7bd61bd..f56ac15 100644 --- a/src/ThreeMFParser.cpp +++ b/src/ThreeMFParser.cpp @@ -19,6 +19,7 @@ #include "ThreeMFParser.h" #include "Namespace.h" #include "Scene.h" +#include #include #include #include diff --git a/src/ThreeMFParser.h b/src/ThreeMFParser.h index 3394683..1d5fdd1 100644 --- a/src/ThreeMFParser.h +++ b/src/ThreeMFParser.h @@ -21,7 +21,6 @@ #include "SavitarExport.h" #include "SceneNode.h" -#include "../pugixml/src/pugixml.hpp" #include namespace Savitar diff --git a/tests/MeshDataTest.cpp b/tests/MeshDataTest.cpp index 583b946..76d3187 100644 --- a/tests/MeshDataTest.cpp +++ b/tests/MeshDataTest.cpp @@ -10,7 +10,7 @@ #include #include -#include "../pugixml/src/pugixml.hpp" +#include namespace Savitar { diff --git a/tests/NamespaceTest.cpp b/tests/NamespaceTest.cpp index 1a2c2a2..4ac77fa 100644 --- a/tests/NamespaceTest.cpp +++ b/tests/NamespaceTest.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "../pugixml/src/pugixml.hpp" +#include namespace xml_namespace { From d115a2fbbeefa01912ec7fccff1a579e9148ab8d Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 7 Aug 2021 15:37:37 +0200 Subject: [PATCH 02/10] Add Sanitizers and best practices You can now set the following extra options (default is OFF) - ENABLE_CPPCHECK "Enable static analysis with cppcheck" - ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" - ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" - ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" - ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" - ENABLE_SANITIZER_LEAK "Enable leak sanitizer" - ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" - ENABLE_SANITIZER_THREAD "Enable thread sanitizer" - ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" Disallow in-souce builds and added messages --- CMakeLists.txt | 1 + cmake/StandardProjectSettings.cmake | 171 ++++++++++++++++++++++++++-- 2 files changed, 160 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 098ca80..25a1821 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ use_threads(Savitar) set_project_standards(Savitar) set_project_warnings(Savitar) +enable_sanitizers(Savitar) set(USE_SHIPPED_PUGIXML ON CACHE BOOL "Use the shipped pugixml library") if(USE_SHIPPED_PUGIXML) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index b63ad7a..54aaeea 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -34,8 +34,24 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() # Generate compile_commands.json to make it easier to work with clang based tools +message(STATUS "Generating compile commands to ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" ON) +if(ENABLE_IPO) + include(CheckIPOSupported) + check_ipo_supported( + RESULT + result + OUTPUT + output) + if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(SEND_ERROR "IPO is not supported: ${output}") + endif() +endif() + if (NOT MSVC) # Compile with the -fPIC options if supported if(DEFINED POSITION_INDEPENDENT_CODE) # Use the user/Conan set value @@ -43,17 +59,20 @@ if (NOT MSVC) else() set(POSITION_INDEPENDENT_CODE ON) # Defaults to on message(STATUS "Setting POSITION_INDEPENDENT_CODE: ${POSITION_INDEPENDENT_CODE}") - - # Set Visual Studio flags MD/MDd or MT/MTd - if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - else() - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") - endif() + endif() +else() + # Set Visual Studio flags MD/MDd or MT/MTd + if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) + message(STATUS "Setting MD/MDd flags") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + else() + message(STATUS "Setting MT/MTd flags") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") endif() endif() # Use C++17 Standard +message(STATUS "Setting C++17 support with extensions off and standard required") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -63,9 +82,11 @@ function(set_project_standards project_name) if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF) if(ENABLE_BUILD_WITH_TIME_TRACE) + message(STATUS "Enabling time tracing for ${project_name}") add_compile_definitions(${project_name} PRIVATE -ftime-trace) endif() - if (APPLE) # Linux already compiles against libstdc++ + if (APPLE) + message(STATUS "Compiling ${project_name} against libc++") target_compile_options(${project_name} PRIVATE "-stdlib=libc++") endif() endif() @@ -73,7 +94,7 @@ endfunction() # Ultimaker uniform Python linking method function(use_python project_name) - SET(COMPONENTS ${ARGN}) + set(COMPONENTS ${ARGN}) if(NOT DEFINED Python_VERSION) set(Python_VERSION 3.8 @@ -97,7 +118,7 @@ endfunction() # https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md function(set_project_warnings project_name) - + message(STATUS "Setting warnings for ${project_name}") set(MSVC_WARNINGS /W4 # Baseline reasonable warnings /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data @@ -161,6 +182,132 @@ function(set_project_warnings project_name) message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") endif() - target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) + target_compile_options(${project_name} PRIVATE ${PROJECT_WARNINGS}) + +endfunction() + +# This function will prevent in-source builds +function(AssureOutOfSourceBuilds) + # make sure the user doesn't play dirty with symlinks + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + + # disallow in-source builds + if("${srcdir}" STREQUAL "${bindir}") + message("######################################################") + message("Warning: in-source builds are disabled") + message("Please create a separate build directory and run cmake from there") + message("######################################################") + message(FATAL_ERROR "Quitting configuration") + endif() +endfunction() + +assureoutofsourcebuilds() + +function(enable_sanitizers project_name) + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) + + if(ENABLE_COVERAGE) + target_compile_options(${project_name} INTERFACE --coverage -O0 -g) + target_link_libraries(${project_name} INTERFACE --coverage) + endif() + + set(SANITIZERS "") + + option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE) + if(ENABLE_SANITIZER_ADDRESS) + list(APPEND SANITIZERS "address") + endif() + + option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE) + if(ENABLE_SANITIZER_LEAK) + list(APPEND SANITIZERS "leak") + endif() -endfunction() \ No newline at end of file + option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE) + if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) + list(APPEND SANITIZERS "undefined") + endif() + + option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE) + if(ENABLE_SANITIZER_THREAD) + if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) + message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") + else() + list(APPEND SANITIZERS "thread") + endif() + endif() + + option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE) + if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + if("address" IN_LIST SANITIZERS + OR "thread" IN_LIST SANITIZERS + OR "leak" IN_LIST SANITIZERS) + message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") + else() + list(APPEND SANITIZERS "memory") + endif() + endif() + + list( + JOIN + SANITIZERS + "," + LIST_OF_SANITIZERS) + + endif() + + if(LIST_OF_SANITIZERS) + if(NOT + "${LIST_OF_SANITIZERS}" + STREQUAL + "") + target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) + target_link_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) + endif() + endif() + +endfunction() + +option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) +option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) +option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) + +if(ENABLE_CPPCHECK) + find_program(CPPCHECK cppcheck) + if(CPPCHECK) + message(STATUS "Using cppcheck") + set(CMAKE_CXX_CPPCHECK + ${CPPCHECK} + --suppress=missingInclude + --enable=all + --inline-suppr + --inconclusive + -i + ${CMAKE_SOURCE_DIR}/imgui/lib) + else() + message(WARNING "cppcheck requested but executable not found") + endif() +endif() + +if(ENABLE_CLANG_TIDY) + find_program(CLANGTIDY clang-tidy) + if(CLANGTIDY) + message(STATUS "Using clang-tidy") + set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) + else() + message(WARNING "clang-tidy requested but executable not found") + endif() +endif() + +if(ENABLE_INCLUDE_WHAT_YOU_USE) + find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) + if(INCLUDE_WHAT_YOU_USE) + message(STATUS "Using include-what-you-use") + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) + else() + message(WARNING "include-what-you-use requested but executable not found") + endif() +endif() \ No newline at end of file From 3bd06e7c7e9a7e3f6719005ff9fe54ee77f351d5 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 7 Aug 2021 17:24:35 +0200 Subject: [PATCH 03/10] Allow for building in-source Strongly discouraged but some automated systems use this method. This can be enabled by setting ALLOW_IN_SOURCE_BUILD ON --- cmake/StandardProjectSettings.cmake | 5 ++++- conanfile.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index 54aaeea..00c9f58 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -202,7 +202,10 @@ function(AssureOutOfSourceBuilds) endif() endfunction() -assureoutofsourcebuilds() +option(ALLOW_IN_SOURCE_BUILD "Allow building in your source folder. Strongly discouraged" OFF) +if(NOT ALLOW_IN_SOURCE_BUILD) + assureoutofsourcebuilds() +endif() function(enable_sanitizers project_name) diff --git a/conanfile.py b/conanfile.py index a0d6daa..19d96a5 100644 --- a/conanfile.py +++ b/conanfile.py @@ -85,6 +85,7 @@ def generate(self): tc.blocks["generic_system"].values["generator_platform"] = None tc.blocks["generic_system"].values["toolset"] = None + tc.variables["ALLOW_IN_SOURCE_BUILD"] = True tc.variables["SIP_MODULE_SITE_PATH"] = "site-packages" tc.variables["USE_SHIPPED_PUGIXML"] = False tc.variables["Python_VERSION"] = self.options.python_version From 1a0aab5bf38580649d72226466ffac72798f04e3 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Sun, 8 Aug 2021 14:23:39 +0200 Subject: [PATCH 04/10] Workaround for the __declspec(dllimport) When building libSavitar as a shared DLL library on Windows it throws a lot of: unresolved external symbol __declspec(dllimport) as a workaround I now build it statically on that platform. --- CMakeLists.txt | 8 +++----- cmake/StandardProjectSettings.cmake | 14 ++++++++------ conanfile.py | 7 ++++++- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25a1821..a09fcd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,14 +54,13 @@ else() find_package(pugixml 1.8 REQUIRED) endif() -target_link_libraries(Savitar PRIVATE pugixml::pugixml) +target_link_libraries(Savitar PUBLIC pugixml::pugixml) -generate_export_header(Savitar EXPORT_FILE_NAME src/SavitarExport.h) +generate_export_header(Savitar EXPORT_FILE_NAME ${CMAKE_SOURCE_DIR}/src/SavitarExport.h) target_include_directories(Savitar PUBLIC $ $ - $ # Include SavitarExport.h ) if(BUILD_PYTHON) @@ -78,12 +77,11 @@ if(BUILD_PYTHON) set_project_warnings(python_module_Savitar) use_python(python_module_Savitar Interpreter Development) - target_link_libraries(python_module_Savitar PRIVATE SIP::SIP) + target_link_libraries(python_module_Savitar PRIVATE SIP::SIP Savitar) target_include_directories(python_module_Savitar PRIVATE $ $ - $ # Include SavitarExport.h ) endif() diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index 00c9f58..1a3f96f 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -62,12 +62,14 @@ if (NOT MSVC) endif() else() # Set Visual Studio flags MD/MDd or MT/MTd - if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) - message(STATUS "Setting MD/MDd flags") - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - else() - message(STATUS "Setting MT/MTd flags") - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) + if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) + message(STATUS "Setting MD/MDd flags") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + else() + message(STATUS "Setting MT/MTd flags") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + endif() endif() endif() diff --git a/conanfile.py b/conanfile.py index 19d96a5..b7be22d 100644 --- a/conanfile.py +++ b/conanfile.py @@ -57,7 +57,7 @@ def lib_name(self): def configure(self): self.options["SIP"].shared = self.options.shared self.options["SIP"].python_version = self.options.python_version - self.options["pugixml"].shared = self.options.shared + self.options["pugixml"].header_only = True if self.options.shared or self.settings.compiler == "Visual Studio": del self.options.fPIC @@ -90,6 +90,11 @@ def generate(self): tc.variables["USE_SHIPPED_PUGIXML"] = False tc.variables["Python_VERSION"] = self.options.python_version tc.variables["BUILD_TESTS"] = self.options.tests + + # FIXME: Otherwise it throws: error LNK2001: unresolved external symbol "__declspec(dllimport) + tc.variables["BUILD_STATIC"] = not self.options.shared if self.settings.os != "Windows" else True + tc.variables["BUILD_SHARED_LIBS"] = self.options.shared if self.settings.os != "Windows" else False + tc.generate() _cmake = None From 25a4f8b05e6f2f666c90e7fdca3a4e03cbb107a3 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Sun, 8 Aug 2021 14:30:22 +0200 Subject: [PATCH 05/10] Fixed mixed message MD and MT --- cmake/StandardProjectSettings.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index 1a3f96f..e7a825c 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -64,10 +64,10 @@ else() # Set Visual Studio flags MD/MDd or MT/MTd if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) if(BUILD_STATIC OR NOT BUILD_SHARED_LIBS) - message(STATUS "Setting MD/MDd flags") + message(STATUS "Setting MT/MTd flags") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") else() - message(STATUS "Setting MT/MTd flags") + message(STATUS "Setting MD/MDd flags") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") endif() endif() From 5d397e050324c7ef25942fca3f0a6e5e84d32d05 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Sun, 8 Aug 2021 14:49:52 +0200 Subject: [PATCH 06/10] Set BUILD_SHARED_LIBS in the shared block Otherwise the conan_toolchain.cmake has 2 entries. --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index b7be22d..0d70689 100644 --- a/conanfile.py +++ b/conanfile.py @@ -84,6 +84,7 @@ def generate(self): if self.settings.compiler == "Visual Studio": tc.blocks["generic_system"].values["generator_platform"] = None tc.blocks["generic_system"].values["toolset"] = None + tc.blocks["shared"].values["shared_libs"] = False # FIXME: Otherwise it throws: error LNK2001: unresolved external symbol "__declspec(dllimport) tc.variables["ALLOW_IN_SOURCE_BUILD"] = True tc.variables["SIP_MODULE_SITE_PATH"] = "site-packages" @@ -93,7 +94,6 @@ def generate(self): # FIXME: Otherwise it throws: error LNK2001: unresolved external symbol "__declspec(dllimport) tc.variables["BUILD_STATIC"] = not self.options.shared if self.settings.os != "Windows" else True - tc.variables["BUILD_SHARED_LIBS"] = self.options.shared if self.settings.os != "Windows" else False tc.generate() From d5513121500cbdda5146b9d5498c2bff3b8e92d5 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Sun, 8 Aug 2021 15:42:18 +0200 Subject: [PATCH 07/10] SavitarExport.h moved to source I really dislike including out-of-source stuff --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a09fcd1..bcffc5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ set(savitar_HDRS src/MeshData.h src/Vertex.h src/Face.h - ${CMAKE_CURRENT_BINARY_DIR}/src/SavitarExport.h + src/SavitarExport.h ) if(BUILD_SHARED_LIBS) From 2132ef067cf34af25f35f7a024b51a8edc3c1466 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 10 Aug 2021 23:28:28 +0200 Subject: [PATCH 08/10] Never link against Frameworks on Apple --- cmake/StandardProjectSettings.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index e7a825c..cf20b1b 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -103,6 +103,9 @@ function(use_python project_name) CACHE STRING "Python Version" FORCE) message(STATUS "Setting Python version to ${Python_VERSION}. Set Python_VERSION if you want to compile against an other version.") endif() + if(APPLE) + set(Python3_FIND_FRAMEWORK NEVER) + endif() find_package(Python3 ${Python_VERSION} EXACT REQUIRED COMPONENTS ${COMPONENTS}) target_link_libraries(${project_name} PRIVATE ${Python3_LIBRARIES}) target_include_directories(${project_name} PUBLIC ${Python3_INCLUDE_DIRS}) From aa7ce5bf888cb04d4dec057b13cdaa9711ad36a9 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 8 Sep 2021 10:39:40 +0200 Subject: [PATCH 09/10] Use Conan build Python --- cmake/StandardProjectSettings.cmake | 10 ++--- conanfile.py | 57 +++++++++++------------------ 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index cf20b1b..0d5dede 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -104,12 +104,12 @@ function(use_python project_name) message(STATUS "Setting Python version to ${Python_VERSION}. Set Python_VERSION if you want to compile against an other version.") endif() if(APPLE) - set(Python3_FIND_FRAMEWORK NEVER) + set(Python_FIND_FRAMEWORK NEVER) endif() - find_package(Python3 ${Python_VERSION} EXACT REQUIRED COMPONENTS ${COMPONENTS}) - target_link_libraries(${project_name} PRIVATE ${Python3_LIBRARIES}) - target_include_directories(${project_name} PUBLIC ${Python3_INCLUDE_DIRS}) - message(STATUS "Linking and building ${project_name} against Python ${Python3_VERSION}") + find_package(Python ${Python_VERSION} EXACT REQUIRED COMPONENTS ${COMPONENTS}) + target_link_libraries(${project_name} PRIVATE Python::Python) + target_include_directories(${project_name} PUBLIC ${Python_INCLUDE_DIRS}) + message(STATUS "Linking and building ${project_name} against Python ${Python_VERSION}") endfunction() # Ultimaker uniform Thread linking method diff --git a/conanfile.py b/conanfile.py index 0d70689..dba175b 100644 --- a/conanfile.py +++ b/conanfile.py @@ -4,27 +4,30 @@ from conans import ConanFile, tools from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake + class SavitarConan(ConanFile): name = "Savitar" - version = "4.10.0" + version = "4.11.0" license = "LGPL-3.0" author = "Ultimaker B.V." url = "https://github.com/Ultimaker/libSavitar" description = "libSavitar is a c++ implementation of 3mf loading with SIP python bindings" topics = ("conan", "python", "binding", "sip", "cura", "3mf", "c++") settings = "os", "compiler", "build_type", "arch" + revision_mode = "scm" + build_policy = "missing" exports = "LICENSE" options = { + "build_python": [True, False], "shared": [True, False], "fPIC": [True, False], "tests": [True, False], - "python_version": "ANY" } default_options = { + "build_python": True, "shared": True, "fPIC": True, - "tests": False, - "python_version": "3.8" + "tests": False } scm = { "type": "git", @@ -33,30 +36,15 @@ class SavitarConan(ConanFile): "revision": "auto" } - # TODO: Move lib naming logic to python_requires project - _ext = None - - @property - def ext(self): - if self._ext: - return self._ext - self._ext = "lib" if self.settings.os == "Windows" else "a" - if self.options.shared: - if self.settings.os == "Windows": - self._ext = "dll" - elif self.settings.os == "Macos": - self._ext = "dylib" - else: - self._ext = "so" - return self._ext - - @property - def lib_name(self): - return self.name + def config_options(self): + if self.settings.os == "Windows": + self.options.shared = False + if self.settings.compiler == "gcc": + self.options.build_python = False def configure(self): - self.options["SIP"].shared = self.options.shared - self.options["SIP"].python_version = self.options.python_version + if self.options.build_python: + self.options["SIP"].shared = self.options.shared self.options["pugixml"].header_only = True if self.options.shared or self.settings.compiler == "Visual Studio": del self.options.fPIC @@ -67,7 +55,9 @@ def build_requirements(self): self.build_requires("gtest/[>=1.10.0]", force_host_context=True) def requirements(self): - self.requires("SIP/[>=4.19.24]@riverbankcomputing/testing") + if self.options.build_python: + self.requires("SIP/[>=4.19.24]@riverbankcomputing/testing") + self.requires("Python/3.8.10@python/testing") self.requires("pugixml/1.8.1@bincrafters/stable") def validate(self): @@ -84,16 +74,15 @@ def generate(self): if self.settings.compiler == "Visual Studio": tc.blocks["generic_system"].values["generator_platform"] = None tc.blocks["generic_system"].values["toolset"] = None - tc.blocks["shared"].values["shared_libs"] = False # FIXME: Otherwise it throws: error LNK2001: unresolved external symbol "__declspec(dllimport) tc.variables["ALLOW_IN_SOURCE_BUILD"] = True - tc.variables["SIP_MODULE_SITE_PATH"] = "site-packages" tc.variables["USE_SHIPPED_PUGIXML"] = False - tc.variables["Python_VERSION"] = self.options.python_version + if self.options.build_python: + tc.variables["Python_VERSION"] = self.deps_cpp_info["Python"].version + tc.variables["SIP_MODULE_SITE_PATH"] = "site-packages" tc.variables["BUILD_TESTS"] = self.options.tests - # FIXME: Otherwise it throws: error LNK2001: unresolved external symbol "__declspec(dllimport) - tc.variables["BUILD_STATIC"] = not self.options.shared if self.settings.os != "Windows" else True + tc.variables["BUILD_STATIC"] = not self.options.shared tc.generate() @@ -119,7 +108,7 @@ def package(self): self.copy("*.pyi", src = ".", dst = "site-packages") def package_info(self): - self.cpp_info.libs = [self.lib_name] + self.cpp_info.libs = tools.collect_libs(self) if self.in_local_cache: self.runenv_info.prepend_path("PYTHONPATH", os.path.join(self.package_folder, "site-packages")) self.cpp_info.includedirs = ["include"] @@ -130,8 +119,6 @@ def package_info(self): self.runenv_info.prepend_path("PYTHONPATH", local_build_path) self.cpp_info.includedirs = ["src"] self.cpp_info.libdirs = [local_build_path] - self.cpp_info.names["cmake_find_package"] = self.name - self.cpp_info.names["cmake_find_package_multi"] = self.name if self.settings.build_type == "Debug": self.cpp_info.defines.append("SAVITAR_DEBUG") if self.settings.os in ["Linux", "FreeBSD", "Macos"]: From 4a08ca474e61e0885c0b514b5af744b655ba15ef Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Oct 2021 13:42:18 +0200 Subject: [PATCH 10/10] Use pugixml 1.1 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index dba175b..30b2683 100644 --- a/conanfile.py +++ b/conanfile.py @@ -58,7 +58,7 @@ def requirements(self): if self.options.build_python: self.requires("SIP/[>=4.19.24]@riverbankcomputing/testing") self.requires("Python/3.8.10@python/testing") - self.requires("pugixml/1.8.1@bincrafters/stable") + self.requires("pugixml/1.11") def validate(self): if self.settings.compiler.get_safe("cppstd"):