diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 6ccfc42e2ef..11ade3231f1 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -480,8 +480,11 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif() -message("== Generate version files (DONE) ==\n") +if(CGAL_TEST_SUITE) + include(display-third-party-libs-versions) +endif() +message("== Generate version files (DONE) ==\n") #-------------------------------------------------------------------------------------------------- # # -= External libraries =- diff --git a/Installation/cmake/modules/display-third-party-libs-versions.cmake b/Installation/cmake/modules/display-third-party-libs-versions.cmake new file mode 100644 index 00000000000..fa344cc04d6 --- /dev/null +++ b/Installation/cmake/modules/display-third-party-libs-versions.cmake @@ -0,0 +1,104 @@ +set(LIBRARIES_TO_CHECK + Eigen3 Qt6 TBB OpenMesh Boost + GMP Threads SuiteSparse MPFI METIS + VTK SCIP OSQP LASLIB GLPK + ITT Ceres MPFR libpointmatcher ITK + OpenGR OpenCV ZLIB +) + +function(get_library_version header_path major_macro minor_macro patchlevel_macro version_var) + if(EXISTS ${header_path}) + file(READ ${header_path} HEADER_CONTENT) + if("${HEADER_CONTENT}" MATCHES "#define[ \t]+${major_macro}[ \t]+([0-9]+)") + set(VERSION_MAJOR ${CMAKE_MATCH_1}) + endif() + if("${HEADER_CONTENT}" MATCHES "#define[ \t]+${minor_macro}[ \t]+([0-9]+)") + set(VERSION_MINOR ${CMAKE_MATCH_1}) + endif() + if("${HEADER_CONTENT}" MATCHES "#define[ \t]+${patchlevel_macro}[ \t]+([0-9]+)") + set(VERSION_PATCHLEVEL ${CMAKE_MATCH_1}) + else() + set(VERSION_PATCHLEVEL "") + endif() + if(VERSION_PATCHLEVEL) + set(${version_var} "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCHLEVEL}" PARENT_SCOPE) + elseif(VERSION_MAJOR GREATER_EQUAL 0 OR VERSION_MINOR GREATER_EQUAL 0) + set(${version_var} "${VERSION_MAJOR}.${VERSION_MINOR}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function(check_library cgal_3rdparty_lib) + set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) + set(CMAKE_FIND_PACKAGE_QUIET TRUE) + string(TOUPPER ${cgal_3rdparty_lib} cgal_3rdparty_lib_upper) + find_package(${cgal_3rdparty_lib} QUIET) + set(CMAKE_FIND_PACKAGE_QUIET FALSE) + if(${cgal_3rdparty_lib}_FOUND) + set(version_var "") + if(DEFINED ${cgal_3rdparty_lib}_VERSION) + set(version_var ${${cgal_3rdparty_lib}_VERSION}) + elseif(DEFINED ${cgal_3rdparty_lib}_VERSION_STRING) + set(version_var ${${cgal_3rdparty_lib}_VERSION_STRING}) + elseif(DEFINED ${cgal_3rdparty_lib_upper}_VERSION) + set(version_var ${${cgal_3rdparty_lib_upper}_VERSION}) + elseif(DEFINED ${cgal_3rdparty_lib_upper}_VERSION_STRING) + set(version_var ${${cgal_3rdparty_lib_upper}_VERSION_STRING}) + elseif(${cgal_3rdparty_lib} STREQUAL "GMP") + set(version_var "") + get_library_version("${GMP_INCLUDE_DIR}/gmp.h" "__GNU_MP_VERSION" "__GNU_MP_VERSION_MINOR" "__GNU_MP_VERSION_PATCHLEVEL" version_var) + if(NOT version_var) + file(READ "${GMP_INCLUDE_DIR}/gmp.h" GMP_HEADER_CONTENT) + string(REGEX MATCHALL "#include[ \t]+\"([^\"]+)\"" INCLUDED_HEADERS "${GMP_HEADER_CONTENT}") + foreach(INCLUDED_HEADER ${INCLUDED_HEADERS}) + string(REGEX REPLACE "#include[ \t]+\"([^\"]+)\"" "\\1" GMP_ARCH_HEADER "${INCLUDED_HEADER}") + set(GMP_ARCH_HEADER_PATH "${GMP_INCLUDE_DIR}/${GMP_ARCH_HEADER}") + if(EXISTS ${GMP_ARCH_HEADER_PATH}) + get_library_version("${GMP_ARCH_HEADER_PATH}" "__GNU_MP_VERSION" "__GNU_MP_VERSION_MINOR" "__GNU_MP_VERSION_PATCHLEVEL" version_var) + if(version_var) + break() + endif() + endif() + endforeach() + endif() + elseif(${cgal_3rdparty_lib} STREQUAL "GLPK") + get_library_version("${GLPK_INCLUDE_DIR}/glpk.h" "GLP_MAJOR_VERSION" "GLP_MINOR_VERSION" "" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "MPFR") + get_library_version("${MPFR_INCLUDE_DIR}/mpfr.h" "MPFR_VERSION_MAJOR" "MPFR_VERSION_MINOR" "MPFR_VERSION_PATCHLEVEL" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "METIS") + get_library_version("${METIS_INCLUDE_DIR}/metis.h" "METIS_VER_MAJOR" "METIS_VER_MINOR" "METIS_VER_SUBMINOR" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "SuiteSparse") + get_library_version("${SuiteSparse_Config_INCLUDE_DIR}/SuiteSparse_config.h" "SUITESPARSE_MAIN_VERSION" "SUITESPARSE_SUB_VERSION" "SUITESPARSE_SUBSUB_VERSION" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "LASLIB") + get_library_version("${LASLIB_INCLUDE_DIR}/lasdefinitions.hpp" "LAS_TOOLS_VERSION" "" "" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "ITT") + get_library_version("${ITT_INCLUDE_DIR}/ittnotify.h" "ITT_MAJOR" "ITT_MINOR" "" version_var) + elseif(${cgal_3rdparty_lib} STREQUAL "OpenMesh") + if (TARGET OpenMeshCore) + get_target_property(OpenMesh_INCLUDE_DIRS OpenMeshCore INTERFACE_INCLUDE_DIRECTORIES) + set(CONFIG_FILE_PATH "${OpenMesh_INCLUDE_DIRS}/OpenMesh/Core/System/config.h") + if(EXISTS ${CONFIG_FILE_PATH}) + file(READ ${CONFIG_FILE_PATH} CONFIG_CONTENT) + if("${CONFIG_CONTENT}" MATCHES "#define[ \t]+OM_VERSION[ \t]+(0x[0-9A-F]+)") + set(VERSION_HEX ${CMAKE_MATCH_1}) + math(EXPR VERSION_MAJOR "(${VERSION_HEX} & 0xF0000) >> 16") + math(EXPR VERSION_MINOR "(${VERSION_HEX} & 0x0FF00) >> 8") + math(EXPR VERSION_PATCH "(${VERSION_HEX} & 0x000FF)") + set(version_var "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") + endif() + endif() + endif() + endif() + if(version_var) + message(STATUS "Third-party library ${cgal_3rdparty_lib} ${version_var}") + else() + message(STATUS "Third-party library ${cgal_3rdparty_lib} found") + endif() + else() + message(STATUS "Third-party library ${cgal_3rdparty_lib} not found") + endif() +endfunction() + +foreach(cgal_3rdparty_lib IN LISTS LIBRARIES_TO_CHECK) + check_library(${cgal_3rdparty_lib}) +endforeach() diff --git a/Maintenance/test_handling/Summary_Script.js b/Maintenance/test_handling/Summary_Script.js new file mode 100644 index 00000000000..90a87da08e5 --- /dev/null +++ b/Maintenance/test_handling/Summary_Script.js @@ -0,0 +1,322 @@ +const $mainContainer = $('#main_container'); +const $platformContainer = $('#platform_container'); +const $packageContainer = $('#package_container'); +let release = ""; +let packages = []; + +function getAllTestDirectories(data) { + return data.platforms.flatMap(platform => platform.test_directories.map(directory => directory.test_directory)); +} + +function clearPackagesOptions() { + $('#packagesSelector option').each(function() { + if ($(this).val() !== 'all' && !packages.includes($(this).val())) { + $(this).remove(); + } + }); +} + +function filterByPlatform(platform) { + const $packageSelector = $('#packagesSelector'); + $packageSelector.prop('disabled', platform !== 'all'); + $platformContainer.find('.platform').each(function() { + const $this = $(this); + if (platform === 'all' || $this.hasClass(platform)) { + $this.show(); + } else { + $this.hide(); + } + }); +} + +function filterByPackage(package) { + const $platformSelector = $('#platformSelector'); + const $packageContainers = $packageContainer.find('.package'); + if (package === 'all') { + $platformSelector.prop('disabled', false); + $platformContainer.show(); + $packageContainer.hide(); + } else { + $platformSelector.prop('disabled', true); + $platformContainer.hide(); + $packageContainer.show(); + } + $packageContainers.each(function() { + const $this = $(this); + if (package === 'all' || $this.hasClass(package)) { + $this.show(); + } else { + $this.hide(); + } + }); +} + +function filterByLetter(letter) { + const $letterContainers = $mainContainer.find('.letter_container'); + $letterContainers.each(function() { + const $this = $(this); + if (letter === 'all' || $this.hasClass(letter)) { + $this.show(); + } else { + $this.hide(); + } + if ($this.children().length <= 2) { + $this.hide(); + } + }); +} + +function search() { + const searchTerm = $('#searchInput').val().toLowerCase(); + const releaseType = $('#releaseSelector').val(); + const $resultsContainer = $('#searchResults'); + $resultsContainer.empty(); + + if (!searchTerm) { + $resultsContainer.append('

Please enter a search term.

'); + return; + } + + const matchingDirectories = []; + + window.data.platforms.forEach(platform => { + platform.test_directories.forEach(directory => { + if (directory.content.toLowerCase().includes(searchTerm)) { + matchingDirectories.push({ + test_directory: directory.test_directory, + platform_name: platform.name + }); + } + }); + }); + + if (matchingDirectories.length === 0) { + $resultsContainer.append('

No matching directories found.

'); + } else { + matchingDirectories.forEach(match => { + const link = `${window.data.release}/${match.test_directory}/TestReport_${match.platform_name}.gz`; + $resultsContainer.append(`

${match.platform_name} - ${match.test_directory} - ${window.data.release}

`); + }); + } +} + +function packageContainer(platforms) { + const testDirectories = {}; + + platforms.forEach(platform => { + platform.test_directories.forEach(testDir => { + if (!testDirectories[testDir.test_directory]) { + testDirectories[testDir.test_directory] = {}; + } + if (!testDirectories[testDir.test_directory][testDir.letters]) { + testDirectories[testDir.test_directory][testDir.letters] = []; + } + testDirectories[testDir.test_directory][testDir.letters].push({ + platformName: platform.name, + content: testDir.content + }); + }); + }); + + for (const [testDirectory, letters] of Object.entries(testDirectories)) { + const $container = $('
', { class: 'package ' + testDirectory }).appendTo($packageContainer); + $('

').text(testDirectory).appendTo($container); + + for (const [letter, platformDetails] of Object.entries(letters)) { + const $letterContainer = $('
', { + class: 'letter_container ' + letter, + }).appendTo($container); + $('

').text(letter).appendTo($letterContainer); + + platformDetails.forEach(detail => { + const { platformName, content } = detail; + + const $platformContainer = $('
', { class: 'platform-container' }).appendTo($letterContainer); + + const $platformLink = $('', { + href: `${release}/${testDirectory}/TestReport_${platformName}.gz`, + text: platformName, + class: 'platform-link' + }).appendTo($platformContainer); + + const $contentSpan = $('
', {
+                    text: content,
+                    class: 'summary-content',
+                    css: { display: 'none' }
+                }).appendTo($letterContainer);
+
+                if (content.length > 0) {
+                    const $toggleButton = $('
+

+ + + +
+

Summary Results of ${release_name}

+ + + +
+
+ + +
+
+
+
+
+ + EOF - - my $summary_page_path = "$testresult_dir/summary".substr($release_name,4).".html"; + if (-e $summary_script_src) { + copy($summary_script_src, $summary_script_dest) or die "Copy failed: $!"; + } else { + die "Source file $summary_script_src does not exist."; + } open(my $out, '>', $summary_page_path) or die "Could not open file '$summary_page_path' $!"; print $out $Summary_output; diff --git a/Maintenance/test_handling/testresult.css b/Maintenance/test_handling/testresult.css index f95a62452f9..0345403739e 100644 --- a/Maintenance/test_handling/testresult.css +++ b/Maintenance/test_handling/testresult.css @@ -89,4 +89,179 @@ TABLE.result TD > a.package_name { grid-template-columns: repeat(4, 1fr); gap: 20px; padding: 20px; - } \ No newline at end of file +} + +.toggle-button { + text-decoration: underline; +} + +.summary-content{ + overflow: auto; + max-height: 600px; +} + +.directory_container{ + display: flex; + align-items: center; +} + +.platform-container { + display: flex; + align-items: center; +} + +.platform-link { + margin-right: 10px; +} + +/* TPL table */ + +.tpl-table { + width: auto; + border-collapse: collapse; + margin-top: 10px; + table-layout: fixed; + border: 1px solid #ccc; +} + +.tpl-table th, .tpl-table td { + border: 1px solid #ddd; + padding: 6px 12px; + text-align: left; + white-space: nowrap; +} + +.tpl-table tr:nth-child(even) { + background-color: #a6a6a6; +} + +.tpl-table th { + padding-top: 8px; + padding-bottom: 8px; + background-color: #a6a6a6; + color: #333; + font-weight: normal; +} + +.tpl-toggle-button { + display: inline-block; + margin-bottom: 10px; + padding: 6px 12px; + font-size: 14px; + color: #333; + background-color: #f0f0f0; + border: 1px solid #ccc; + cursor: pointer; + text-align: center; + text-decoration: underline; +} + +.tpl-toggle-button:hover { + background-color: #e0e0e0; +} + +.tpl-link { + color: #0000EE; + text-decoration: underline; + cursor: pointer; +} + +.tpl-link:hover { + color: #1A0DAB; +} + +/* TPL Modal */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); +} + +.modal-content { + background-color: white; + margin: 10% auto; + padding: 20px; + border: 1px solid #888; + width: 60%; + max-width: 600px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); +} + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + cursor: pointer; +} + +.close:hover, .close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +.modal h2 { + margin-top: 0; + color: #333; +} + +.modal p { + margin: 10px 0; + font-size: 14px; + color: #555; +} + +table.tablesorter { + width: 100%; + margin: 20px 0; + border-collapse: collapse; + background-color: #f0f0f0; + color: #333; + font-family: Arial, sans-serif; +} + +table.tablesorter thead th { + background-color: #d9d9d9; + color: #333; + font-weight: bold; + padding: 10px; + border: 1px solid #ccc; + text-align: left; + cursor: pointer; +} + +table.tablesorter thead th.tablesorter-headerAsc { + background-repeat: no-repeat; + background-position: right center; + padding-right: 20px; +} + +table.tablesorter thead th.tablesorter-headerDesc { + background-repeat: no-repeat; + background-position: right center; + padding-right: 20px; +} + +table.tablesorter tbody tr:nth-child(odd) { + background-color: #e6e6e6; +} + +table.tablesorter tbody tr:nth-child(even) { + background-color: #f0f0f0; +} + +table.tablesorter tbody td { + padding: 8px; + border: 1px solid #ccc; + text-align: left; +} + +table.tablesorter tbody tr:hover { + background-color: #d1d1d1 +} diff --git a/Maintenance/test_handling/to_zipped_format b/Maintenance/test_handling/to_zipped_format index 9131d100065..60c98ce2432 100755 --- a/Maintenance/test_handling/to_zipped_format +++ b/Maintenance/test_handling/to_zipped_format @@ -51,7 +51,7 @@ sub reformat_results($) $_ = $line; open (PLATFORM_INFO,">${platform}.info") or return; open (PLATFORM_NEW_RESULTS,">${platform}.new_results") or return; - my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","no"); + my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$CMAKE,$TPL) = ("-","-","-","-","-","-","-","-","-","-","-","no","TPL:"); my ($LDFLAGS,$CXXFLAGS) = ("", ""); while (! /^------/) { if(/^\s*$/) { @@ -132,6 +132,9 @@ sub reformat_results($) # print PLATFORM_NEW_RESULTS $_; # last; # } + if (/^-- Third-party library (.+)$/) { + $TPL = "$TPL $1,"; + } NEXT: if(! ($_= )) { # should never happen!! last; @@ -154,6 +157,7 @@ $QT $LEDA_VERSION $CXXFLAGS $LDFLAGS +$TPL EOF close(PLATFORM_INFO); close(PLATFORM_RESULTS); diff --git a/Scripts/developer_scripts/create_new_release b/Scripts/developer_scripts/create_new_release index 2b0e0f2ff2b..bb88cc894ed 100755 --- a/Scripts/developer_scripts/create_new_release +++ b/Scripts/developer_scripts/create_new_release @@ -136,7 +136,7 @@ HTML_DIR="/u/agrion/geometrica/CGAL/Members/Releases" URL="http://cgal.inria.fr/CGAL/Members/Releases" -PATH=$PATH:/usr/local/bin:/usr/bin/gnu +PATH=$PATH:/usr/local/bin:/usr/sbin # Working dir TMPDIR="`pwd`" diff --git a/Scripts/developer_scripts/run_testsuite_with_ctest b/Scripts/developer_scripts/run_testsuite_with_ctest index 1785c96e63b..2ed82f53335 100644 --- a/Scripts/developer_scripts/run_testsuite_with_ctest +++ b/Scripts/developer_scripts/run_testsuite_with_ctest @@ -372,6 +372,7 @@ run_test_on_platform() grep -e "^-- USING " "${CGAL_BINARY_DIR}/installation.log"|sort -u >> $RESULT_FILE #Use sed to get the content of DEBUG or RELEASE CXX FLAGS so that Multiconfiguration platforms do provide their CXXXFLAGS to the testsuite page (that greps USING CXXFLAGS to get info) sed -i -E 's/(^-- USING )(DEBUG|RELEASE) (CXXFLAGS)/\1\3/' $RESULT_FILE + sed -n '/^-- Third-party library /p' "${CGAL_BINARY_DIR}/installation.log" >> $RESULT_FILE echo "------------" >> "$RESULT_FILE" #if git branch, create empty scm file for python script if [ -n "${SCRIPTS_DIR}" ]; then