diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..262a6cbc --- /dev/null +++ b/.clang-format @@ -0,0 +1,21 @@ +BasedOnStyle: GNU + +ColumnLimit: 80 +SortIncludes: false + +TabWidth: 4 +UseTab: Always +IndentWidth: 4 +ContinuationIndentWidth: 4 + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +SpaceBeforeParens: ControlStatements +BreakBeforeBraces: Custom +BraceWrapping: { AfterFunction: true } +AlignAfterOpenBracket: DontAlign +SpaceAfterCStyleCast: true +AllowShortFunctionsOnASingleLine: false + +BinPackParameters: true +AllowAllParametersOfDeclarationOnNextLine: false diff --git a/.gitignore b/.gitignore index 0326282d..081192dd 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,32 @@ test-driver isl_srcdir.c bound_test.sh pip_test.sh + +# CMake generated files +/CMakeCache.txt +/CMakeFiles/ +/CTestTestfile.cmake +/cmake_install.cmake +/build.ninja +/rules.ninja +/.ninja_deps +/.ninja_log + +# Configure-written files +*.tmp +/codegen_test.sh +/interface/cmake_install.cmake +/interface/include/isl-interface/config.h +/islConfig.cmake +/islConfigVersion.cmake + +# Build artifacts +/isl_test_imath +/isl_test_int +/isl_codegen +/isl_test2 +/interface/extract_interface + +# Generated bindings +# This is the only one not checked into the repository -- forgotten? +/include/isl/python.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..06d7e687 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,533 @@ +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +cmake_minimum_required(VERSION 3.20) + +project("isl" C CXX) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/isl/isl_ctx.c") + set(ISL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/isl") +elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/isl_ctx.c") + set(ISL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +else () + message(FATAL_ERROR "Cannot find ISL source dir") +endif () +set(ISL_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + +# TODO: Extract from configure.ac +#set(ISL_VERSION_MAJOR 0) +#set(ISL_VERSION_MINOR 24) +#set(ISL_VERSION_PATCH 0) + +file(STRINGS "${ISL_SOURCE_DIR}/configure.ac" configure_ac_init REGEX "AC\_INIT") +string(REGEX MATCH "\\\[([0-9.]+)\\\]" configure_ac_init_ver "${configure_ac_init}") +set(ISL_VERSION "${CMAKE_MATCH_1}") + +find_package(Clang QUIET) +find_package(Python QUIET) + +# See https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html +include(GNUInstallDirs) + +set(IMATH_SOURCE_DIR "${ISL_SOURCE_DIR}/imath") +set(IMATH_BINARY_DIR "${ISL_BINARY_DIR}/imath") + +## Configure options +set(ISL_INT "gmp" CACHE STRING "Which package to use to represent multi-precision integers (gmp|imath)") +option(ISL_SMALL_INT_OPT "Use small integer optimization" ON) + + +# Process configure options +set(USE_GMP_FOR_MP OFF) +set(USE_IMATH_FOR_MP OFF) +set(USE_SMALL_INT_OPT OFF) +if (ISL_INT STREQUAL "gmp") + set(USE_GMP_FOR_MP ON) +elseif (ISL_INT STREQUAL "imath") + set(USE_IMATH_FOR_MP ON) + if (ISL_SMALL_INT_OPT) + set(USE_SMALL_INT_OPT ON) + endif () +else () + message(FATAL_ERROR "Unsupported option for ISL_INT: ${ISL_INT}") +endif () + + +## Search for libraries +if (USE_GMP_FOR_MP) + find_package(Gmp REQUIRED) +endif () +find_package(PipLib QUIET) + + +## Platform introspection +# Determine version of isl +if (EXISTS "${ISL_SOURCE_DIR}/GIT_HEAD_ID") + # The source comes from a 'make dist' archive + file(READ "${ISL_SOURCE_DIR}/GIT_HEAD_ID" ISL_GIT_HEAD_ID) + string(STRIP "${ISL_GIT_HEAD_ID}" ISL_GIT_HEAD_ID) +elseif (EXISTS "${ISL_SOURCE_DIR}/gitversion.h") + # The source directory is preconfigured + file(READ "${ISL_SOURCE_DIR}/gitversion.h" GITVERSION_H) + string(REGEX REPLACE ".*\\\"([^\\\"]*)\\\".*" "\\1" ISL_GIT_HEAD_ID "${GITVERSION_H}") +elseif (EXISTS "${ISL_SOURCE_DIR}/.git" AND "${ISL_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + # This is the GIT repository itself + # GetGitRevisionDescription uses CMAKE_CURRENT_SOURCE_DIR to look for the .git directory, so it must refer to ISL's source directory + include(GetGitRevisionDescription) + git_describe(ISL_GIT_HEAD_ID) +elseif () + # Unknown revision + # TODO: We could look for a .git and get the revision from HEAD + set(ISL_GIT_HEAD_ID "UNKNOWN") +endif () + + + +# Determine compiler characteristics +if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_COMPILER_IS_CLANGCC ON) # TODO: rename, not a cmake var +endif() + +include(CheckCSourceCompiles) + +# Like check_c_source_compiles, but sets the result to either +# 0 (error while compiling) or 1 (compiled successfully) +# Required for compatibility with autotool's AC_CHECK_DECLS +function (check_c_source_compiles_numeric _prog _var) + check_c_source_compiles("${_prog}" "${_var}") + if ("${${_var}}") + set("${_var}" 1 PARENT_SCOPE) + else () + set("${_var}" 0 PARENT_SCOPE) + endif () +endfunction () + +# Check for the existance of a type +function (check_c_type_exists _type _files _variable) + set(_includes "") + foreach (file_name ${_files}) + set(_includes "${_includes}#include<${file_name}>\n") + endforeach() + check_c_source_compiles(" + ${_includes} + ${_type} typeVar; + int main() { + return 0; + } + " ${_variable}) +endfunction () + + +check_c_source_compiles(" + int func(void) __attribute__((__warn_unused_result__)); + int main() { return 0; } + " HAS_ATTRIBUTE_WARN_UNUSED_RESULT) +set(GCC_WARN_UNUSED_RESULT) +if (HAS_ATTRIBUTE_WARN_UNUSED_RESULT) + set(GCC_WARN_UNUSED_RESULT "__attribute__((__warn_unused_result__))") +endif () + +check_c_source_compiles(" + static void foo(void) __attribute__ ((unused)); + int main() { return 0; } + " HAVE___ATTRIBUTE__) + + +check_c_source_compiles_numeric(" + #include + int main() { (void)ffs(0); return 0; } + " HAVE_DECL_FFS) + +check_c_source_compiles_numeric(" + int main() { __builtin_ffs(0); return 0; } + " HAVE_DECL___BUILTIN_FFS) + +check_c_source_compiles_numeric(" + #include + int main() { _BitScanForward(NULL, 0); return 0; } + " HAVE_DECL__BITSCANFORWARD) + +if (NOT HAVE_DECL_FFS AND + NOT HAVE_DECL___BUILTIN_FFS AND + NOT HAVE_DECL__BITSCANFORWARD) + message(FATAL_ERROR "No ffs implementation found") +endif () + + +check_c_source_compiles_numeric(" + #include + int main() { (void)strcasecmp(\"\", \"\"); return 0; } + " HAVE_DECL_STRCASECMP) + +check_c_source_compiles_numeric(" + #include + int main() { _stricmp(\"\", \"\"); return 0; } + " HAVE_DECL__STRICMP) + +if (NOT HAVE_DECL_STRCASECMP AND NOT HAVE_DECL__STRICMP) + message(FATAL_ERROR "No strcasecmp implementation found") +endif () + + +check_c_source_compiles_numeric(" + #include + int main() { (void)strncasecmp(\"\", \"\", 0); return 0; } + " HAVE_DECL_STRNCASECMP) + +check_c_source_compiles_numeric(" + #include + int main() { _strnicmp(\"\", \"\", 0); return 0; } + " HAVE_DECL__STRNICMP) + +if (NOT HAVE_DECL_STRNCASECMP AND NOT HAVE_DECL__STRNICMP) + message(FATAL_ERROR "No strncasecmp implementation found") +endif () + + +check_c_source_compiles_numeric(" + #include + int main() { snprintf((void*)0, 0, \"\"); return 0; } + " HAVE_DECL_SNPRINTF) + +check_c_source_compiles_numeric(" + #include + int main() { _snprintf((void*)0, 0, \"\"); return 0; } + " HAVE_DECL__SNPRINTF) + +if (NOT HAVE_DECL_SNPRINTF AND NOT HAVE_DECL__SNPRINTF) + message(FATAL_ERROR "No snprintf implementation found") +endif () + + +check_c_type_exists(uint8_t "" HAVE_UINT8T) +check_c_type_exists(uint8_t "stdint.h" HAVE_STDINT_H) +check_c_type_exists(uint8_t "inttypes.h" HAVE_INTTYPES_H) +check_c_type_exists(uint8_t "sys/types.h" HAVE_SYS_INTTYPES_H) +if (HAVE_UINT8T) + set(INCLUDE_STDINT_H "") +elseif (HAVE_STDINT_H) + set(INCLUDE_STDINT_H "#include ") +elseif (HAVE_INTTYPES_H) + set(INCLUDE_STDINT_H "#include ") +elseif (HAVE_SYS_INTTYPES_H) + set(INCLUDE_STDINT_H "#include ") +else () + message(FATAL_ERROR "No stdint.h or compatible found") +endif () + +# Write configure result +# configure_file(... COPYONLY) avoids that the time stamp changes if the file is identical +file(WRITE "${ISL_BINARY_DIR}/gitversion.h.tmp" + "#define GIT_HEAD_ID \"${ISL_GIT_HEAD_ID}\"") +configure_file("${ISL_BINARY_DIR}/gitversion.h.tmp" + "${ISL_BINARY_DIR}/gitversion.h" COPYONLY) + +file(WRITE "${ISL_BINARY_DIR}/include/isl/stdint.h.tmp" + "${INCLUDE_STDINT_H}\n") +configure_file("${ISL_BINARY_DIR}/include/isl/stdint.h.tmp" + "${ISL_BINARY_DIR}/include/isl/stdint.h" COPYONLY) + +configure_file("isl_config.h.cmake" "${ISL_BINARY_DIR}/isl_config.h") +configure_file("isl_srcdir.c.cmake" "${ISL_BINARY_DIR}/isl_srcdir.c") + +# FIXME: codegen_test.sh passes -w option that cmake's compare_files rejects +#set(DIFF "${CMAKE_COMMAND}") +#set(DIFF_OPTIONS "-E compare_files --ignore-eol") +set(DIFF "diff") +set(DIFF_OPTIONS "-u") +set(EXEEXT "${CMAKE_EXECUTABLE_SUFFIX}") +set(srcdir "${ISL_SOURCE_DIR}") +configure_file("codegen_test.sh.in" "${ISL_BINARY_DIR}/codegen_test.sh" @ONLY) + +# ISL files to compile +set(libisl_common_sources + isl_aff.c + isl_aff_map.c + isl_affine_hull.c + isl_arg.c + isl_ast.c + isl_ast_build.c + isl_ast_build_expr.c + isl_ast_codegen.c + isl_ast_graft.c + basis_reduction_tab.c + isl_bernstein.c + isl_blk.c + isl_bound.c + isl_box.c + isl_coalesce.c + isl_constraint.c + isl_convex_hull.c + isl_ctx.c + isl_deprecated.c + isl_dim_map.c + isl_equalities.c + isl_factorization.c + isl_farkas.c + isl_ffs.c + isl_flow.c + isl_fold.c + isl_hash.c + isl_id_to_ast_expr.c + isl_id_to_id.c + isl_id_to_pw_aff.c + isl_ilp.c + isl_input.c + isl_local.c + isl_local_space.c + isl_lp.c + isl_map.c + isl_map_list.c + isl_map_simplify.c + isl_map_subtract.c + isl_map_to_basic_set.c + isl_mat.c + isl_morph.c + isl_id.c + isl_obj.c + isl_options.c + isl_output.c + isl_point.c + isl_polynomial.c + isl_printer.c + print.c + isl_range.c + isl_reordering.c + isl_sample.c + isl_scan.c + isl_schedule.c + isl_schedule_band.c + isl_schedule_node.c + isl_schedule_read.c + isl_schedule_tree.c + isl_schedule_constraints.c + isl_scheduler.c + isl_scheduler_clustering.c + isl_scheduler_scc.c + isl_set_list.c + isl_sort.c + isl_space.c + isl_stream.c + isl_seq.c + isl_set_to_ast_graft_list.c + isl_stride.c + isl_tab.c + isl_tab_pip.c + isl_tarjan.c + isl_transitive_closure.c + isl_union_map.c + isl_val.c + isl_vec.c + isl_version.c + isl_vertices.c + isl_scheduler_clustering.c + isl_scheduler_scc.c +) + +set(libisl_gmp_sources + ${ISL_SOURCE_DIR}/isl_gmp.c + ${ISL_SOURCE_DIR}/isl_val_gmp.c +) + +set(libisl_imath_sources + ${ISL_SOURCE_DIR}/imath/gmp_compat.c + ${ISL_SOURCE_DIR}/imath/imath.c + ${ISL_SOURCE_DIR}/imath/imrat.c + ${ISL_SOURCE_DIR}/isl_imath.c +) + +set(libisl_imath32_sources + ${ISL_SOURCE_DIR}/imath/gmp_compat.c + ${ISL_SOURCE_DIR}/imath/imath.c + ${ISL_SOURCE_DIR}/imath/imrat.c + ${ISL_SOURCE_DIR}/isl_imath.c + ${ISL_SOURCE_DIR}/isl_int_sioimath.c + ${ISL_SOURCE_DIR}/isl_val_sioimath.c +) + +set(libisl_sources ${libisl_common_sources}) +if (USE_GMP_FOR_MP) + list(APPEND libisl_sources ${libisl_gmp_sources}) +elseif (USE_IMATH_FOR_MP) + if (USE_SMALL_INT_OPT) + list(APPEND libisl_sources ${libisl_imath32_sources}) + else () + list(APPEND libisl_sources ${libisl_imath_sources}) + endif () +endif () + + +add_library(isl ${libisl_sources}) +set_target_properties(isl PROPERTIES FOLDER "Integer Set Library") + +target_include_directories(isl PRIVATE "${ISL_BINARY_DIR}" "${ISL_SOURCE_DIR}" ${PIPLIB_INCLUDE_DIRS}) +target_include_directories(isl PUBLIC "$" "$") +if (USE_GMP_FOR_MP) + target_include_directories(isl PUBLIC ${GMP_INCLUDE_DIRS}) + target_link_libraries(isl PRIVATE ${GMP_LIBRARIES}) +endif () +if (USE_IMATH_FOR_MP) + target_include_directories(isl PUBLIC "$") +endif () + +# General compiler options +if (CMAKE_COMPILER_IS_CLANGCC OR CMAKE_COMPILER_IS_GNUCC) + target_compile_options(isl PRIVATE -Wall) +endif () + + +# Auxiliary executables +macro (add_isl_executable _name) + set(_sources ${ARGN}) + add_executable("${_name}" ${_sources}) + set_target_properties("${_name}" PROPERTIES FOLDER "Integer Set Library") + target_include_directories("${_name}" PRIVATE "${ISL_SOURCE_DIR}" "${ISL_BINARY_DIR}" ${GMP_INCLUDE_DIRS} ${PIPLIB_INCLUDE_DIRS}) + target_link_libraries("${_name}" isl) +endmacro () + + + +add_isl_executable(isl_test "${ISL_SOURCE_DIR}/isl_test.c") +if (Clang_FOUND AND Python_FOUND) + add_isl_executable(isl_test2 "${ISL_SOURCE_DIR}/isl_test2.cc") + add_dependencies(isl_test2 interface-cpp) +endif () +add_isl_executable(isl_test_int "${ISL_SOURCE_DIR}/isl_test_int.c") +if (USE_IMATH_FOR_MP) + add_isl_executable(isl_test_imath "${ISL_SOURCE_DIR}/isl_test_imath.c") +endif () +add_isl_executable(isl_polyhedron_sample "${ISL_SOURCE_DIR}/polyhedron_sample.c") +add_isl_executable(isl_pip "${ISL_SOURCE_DIR}/pip.c") +add_isl_executable(isl_polyhedron_minimize "${ISL_SOURCE_DIR}/polyhedron_minimize.c") +add_isl_executable(isl_polytope_scan "${ISL_SOURCE_DIR}/polytope_scan.c") +add_isl_executable(isl_polyhedron_detect_equalities "${ISL_SOURCE_DIR}/polyhedron_detect_equalities.c") +add_isl_executable(isl_cat "${ISL_SOURCE_DIR}/cat.c") +add_isl_executable(isl_closure "${ISL_SOURCE_DIR}/closure.c") +add_isl_executable(isl_bound "${ISL_SOURCE_DIR}/bound.c") +add_isl_executable(isl_codegen "${ISL_SOURCE_DIR}/codegen.c") + + +if (NOT Clang_FOUND) + message(STATUS "Not generating non-C bindings: No Clang") +elseif (NOT Python_FOUND) + message(STATUS "Not generating non-C bindings: No Python") +else () + add_subdirectory(interface) +endif () + + +# Testing +enable_testing() + +set(check_depends isl_test isl_test_int isl_codegen) +add_test(NAME isl_test_int + COMMAND "$" +) +if (USE_IMATH_FOR_MP) + add_test(NAME isl_test_imath + COMMAND "$" + ) + list(APPEND check_depends isl_test_imath) +endif () +add_test(NAME isl_test + COMMAND "$" +) +if (Clang_FOUND AND Python_FOUND) + add_test(NAME isl_test2 + COMMAND "$" + ) + list(APPEND check_depends isl_test2) +endif () +add_test(NAME codegen_test + COMMAND "${ISL_BINARY_DIR}/codegen_test.sh" +) + + +set(ctest_test_args --output-on-failure) + +include(ProcessorCount) +ProcessorCount(JOBS) +if(NOT JOBS EQUAL 0) + list(APPEND ctest_test_args --jobs ${JOBS}) +endif() + +if(CMAKE_CONFIGURATION_TYPES) + list(APPEND check_command --build-config "$") +endif() + +# CMake also has a "test" target, but it does not build dependencies/ +add_custom_target(check + COMMAND "${CMAKE_CTEST_COMMAND}" ${ctest_test_args} + VERBATIM + USES_TERMINAL +) +add_dependencies(check ${check_depends}) + + + + +# Installing + +# https://www.studyplan.dev/cmake/cmake-file-sets +# Don't do the FILE_SET stuff + +install(TARGETS isl + EXPORT islTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +install( + FILES + include/isl/ctx.h + include/isl/aff.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +# COMPONENT Devel +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/islConfigVersion.cmake" + VERSION "${ISL_VERSION}" + COMPATIBILITY AnyNewerVersion +) + + +set(ConfigPackageLocation lib/cmake/isl) +set(targets_export_name "islTargets") +configure_package_config_file( + "cmake/islConfig.cmake.in" + "islConfig.cmake" + INSTALL_DESTINATION "${ConfigPackageLocation}" + PATH_VARS CMAKE_INSTALL_LIBDIR +) + + +install(EXPORT islTargets + FILE + islTargets.cmake + DESTINATION + ${ConfigPackageLocation} +) + + + +message("################################################################################") +message("# Configuration summary:") +message("# ISL version: ${ISL_VERSION} (${ISL_GIT_HEAD_ID})") +if (USE_GMP_FOR_MP) + message("# Integer implementation: GNU MP") +elseif (USE_IMATH_FOR_MP AND USE_SMALL_INT_OPT) + message("# Integer implementation: imath with sio32") +elseif (USE_IMATH_FOR_MP) + message("# Integer implementation: imath") +endif () +if (TARGET interface) + get_property(_interfaces GLOBAL PROPERTY ISL_INTERFACES) + string(JOIN " " _interfaces ${_interfaces}) + message("# Language bindings: ${_interfaces}") +else () + message("# Language bindings generation: no") +endif () +message("################################################################################") diff --git a/README b/README index e7a5f7d2..e5e856e8 100644 --- a/README +++ b/README @@ -1,3 +1,23 @@ +Integer Set Library (ISL) branch with CMake build system +-------------------------------------------------------- + +The orignal project's website can be found at https://libisl.sourceforge.io/ and +its discussion takes place on the mailing list isl-development@googlegroups.com. +Web frontend: https://groups.google.com/g/isl-development + +For discussions about this branch please use the GitHub tools +(https://github.com/Meinersbur/isl), and the pull request tied to this branch: +https://github.com/Meinersbur/isl/pull/11 + + +This branch adds the files necessary to compile ISL using CMake. It is not a +feature-complete replacement of the autotools build system, but has been created +for convenience in order to use builders such as Ninja or Visual Studio. The +autotools-based build system remains in place. + + +Original README +--------------- isl is a thread-safe C library for manipulating sets and relations of integer points bounded by affine constraints. The descriptions of the sets and relations may involve both parameters and existentially diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake new file mode 100644 index 00000000..72fa09e5 --- /dev/null +++ b/cmake/FindGmp.cmake @@ -0,0 +1,21 @@ + +set(GMP_DEFINITIONS) + +find_path(GMP_INCLUDE_DIR gmp.h + PATHS ENV GMP_INCLUDE ENV GMP_DIR + NO_DEFAULT_PATH +) +find_path(GMP_INCLUDE_DIR gmp.h) +mark_as_advanced(GMP_INCLUDE_DIR) +set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) + +find_library(GMP_LIBRARY NAMES gmp mpir + HINTS ENV GMP_LIB ENV GMP_DIR + NO_DEFAULT_PATH +) +find_library(GMP_LIBRARY NAMES gmp mpir) +mark_as_advanced(GMP_LIBRARY) +set(GMP_LIBRARIES ${GMP_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Gmp DEFAULT_MSG GMP_LIBRARY GMP_INCLUDE_DIR) diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake new file mode 100644 index 00000000..310b47eb --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake @@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in new file mode 100644 index 00000000..6d8b708e --- /dev/null +++ b/cmake/GetGitRevisionDescription.cmake.in @@ -0,0 +1,41 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/cmake/islConfig.cmake.in b/cmake/islConfig.cmake.in new file mode 100644 index 00000000..8d66f250 --- /dev/null +++ b/cmake/islConfig.cmake.in @@ -0,0 +1,2 @@ +@PACKAGE_INIT@ +include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") diff --git a/codegen_test.sh.in b/codegen_test.sh.in old mode 100644 new mode 100755 diff --git a/configure.ac b/configure.ac index 1881c0e3..228111d7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([isl], [0.27], [isl-development@googlegroups.com]) +AC_INIT([isl], [0.27], [isl@meinersbur.de]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign]) diff --git a/gitversion.h.cmake b/gitversion.h.cmake new file mode 100644 index 00000000..8a6f36ec --- /dev/null +++ b/gitversion.h.cmake @@ -0,0 +1 @@ +#define GIT_HEAD_ID "@GIT_HEAD_ID@" diff --git a/imath b/imath index 48932bf2..e8052bd1 160000 --- a/imath +++ b/imath @@ -1 +1 @@ -Subproject commit 48932bf246a758929e00bee4ef2c0e0dd91a81c2 +Subproject commit e8052bd179c455cb07b6f256b8613f6cf56a500e diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt new file mode 100644 index 00000000..b9c7f242 --- /dev/null +++ b/interface/CMakeLists.txt @@ -0,0 +1,110 @@ +add_executable(extract_interface + extract_interface.cc + generator.cc + python.cc + cpp.cc + cpp_conversion.cc + plain_cpp.cc + template_cpp.cc +) + +# I think extract_interface is supposed to have its own header config.h separate from ${ISL_BINARY_DIR}/isl_config.h, but that seems to have been applied inconsistently +# These include paths are such as mess +configure_file("${ISL_SOURCE_DIR}/isl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/include/isl-interface/config.h") +target_include_directories(extract_interface PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/include" #include "isl-interface/clang_wrap.h" + "${CMAKE_CURRENT_BINARY_DIR}/include" #include + "${ISL_BINARY_DIR}" #include "isl_config.h" + "${ISL_SOURCE_DIR}" #include + ${CLANG_INCLUDE_DIRS} +) + + +if (MSVC) +else () + target_compile_options(extract_interface PUBLIC -fno-rtti) +endif () +target_compile_definitions(extract_interface PRIVATE + ADDPATH_TAKES_4_ARGUMENTS + "ISL_CLANG_PREFIX=\"${CLANG_INSTALL_PREFIX}\"" + CREATEPREPROCESSOR_TAKES_TUKIND + CREATETARGETINFO_TAKES_SHARED_PTR + CREATE_FROM_ARGS_TAKES_ARRAYREF + HAVE_BASIC_DIAGNOSTICOPTIONS_H + HAVE_DLFCN_H=1 + HAVE_INTTYPES_H=1 + HAVE_LEX_PREPROCESSOROPTIONS_H + HAVE_LLVM_OPTION_ARG_H + HAVE_MEMORY_H=1 + HAVE_SETMAINFILEID + HAVE_STDINT_H=1 + HAVE_STDLIB_H=1 + HAVE_STRINGS_H=1 + HAVE_STRING_H=1 + HAVE_SYS_STAT_H=1 + HAVE_SYS_TYPES_H=1 + HAVE_UNISTD_H=1 + HAVE_TARGETPARSER_HOST_H=1 + SETLANGDEFAULTS=LangOptions + HandleTopLevelDeclContinue=true + HandleTopLevelDeclReturn=bool + "IK_C=Language::C" + SETINVOCATION_TAKES_SHARED_PTR + SETLANGDEFAULTS_TAKES_5_ARGUMENTS + STDC_HEADERS=1 + USE_ARRAYREF + getArgType=getParamType + getNumArgs=getNumParams +) +target_link_libraries(extract_interface PRIVATE clangBasic clangAnalysis clangAST clangLex clangEdit clangParse clangSema clangFrontend clangSerialization) + + +set_property(GLOBAL + PROPERTY ISL_INTERFACES "" +) + +# Note that some header files have the same name: +# +# * ${CMAKE_CURRENT_SOURCE_DIR}/python.h used by extract_interface and the generated ${ISL_BINARY_DIR}/include/isl/python.h +# * ${CMAKE_CURRENT_SOURCE_DIR}/cpp.h used by extract_interface and the generated ${ISL_BINARY_DIR}/include/isl/cpp.h +# +# Totally not confusing! +function(gen_interface TARGET GENERATOR OUTFILE) + cmake_parse_arguments(ARG "" "" "PREPEND;APPEND" ${ARGN}) + + cmake_path(SET _outpath "${ISL_BINARY_DIR}/include/isl/") + cmake_path(APPEND _outpath "${OUTFILE}") + + set(_more) + foreach (_prepend IN LISTS ARG_PREPEND) + list(APPEND _more --prepend ${_prepend}) + endforeach () + foreach (_append IN LISTS ARG_APPEND) + list(APPEND _more --append ${_append}) + endforeach () + add_custom_command( + OUTPUT "${_outpath}" + COMMAND "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/redirect_to_file.py" "${_outpath}" ${_more} "$" --language=${GENERATOR} "-I${ISL_BINARY_DIR}/include" "-I${ISL_SOURCE_DIR}/include" "${ISL_SOURCE_DIR}/all.h" + DEPENDS redirect_to_file.py + IMPLICIT_DEPENDS "${ISL_SOURCE_DIR}/all.h" + ) + + add_custom_target(${TARGET} + DEPENDS "${_outpath}" + ) + add_dependencies(${TARGET} extract_interface) + add_dependencies(interface ${TARGET}) + + set_property(GLOBAL + APPEND PROPERTY ISL_INTERFACES "${GENERATOR}" + ) +endfunction() + + +add_custom_target(interface ALL) +gen_interface(interface-python python "python.h") +gen_interface(interface-cpp cpp "cpp.h" PREPEND "${ISL_SOURCE_DIR}/cpp/cpp.h.top" "${ISL_SOURCE_DIR}/all.h" APPEND "${ISL_SOURCE_DIR}/cpp/cpp.h.bot") +gen_interface(interface-cpp-checked cpp-checked "cpp-checked.h" PREPEND "${ISL_SOURCE_DIR}/cpp/cpp-checked.h.top" "${ISL_SOURCE_DIR}/all.h" APPEND "${ISL_SOURCE_DIR}/cpp/cpp-checked.h.bot") +gen_interface(interface-cpp-checked-conversion cpp-checked-conversion "cpp-checked-conversion.h" PREPEND "${ISL_SOURCE_DIR}/cpp/cpp-checked-conversion.h.top" APPEND "${ISL_SOURCE_DIR}/cpp/cpp-checked-conversion.h.bot") +gen_interface(interface-template-cpp template-cpp "typed_cpp.h" PREPEND "${ISL_SOURCE_DIR}/cpp/typed_cpp.h.top" APPEND "${ISL_SOURCE_DIR}/cpp/typed_cpp.h.bot") + diff --git a/interface/redirect_to_file.py b/interface/redirect_to_file.py new file mode 100644 index 00000000..c1bdf680 --- /dev/null +++ b/interface/redirect_to_file.py @@ -0,0 +1,25 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import subprocess +import sys +import argparse + +parser = argparse.ArgumentParser(allow_abbrev=False) +parser.add_argument('output') +parser.add_argument('--prepend',action='append',default=[]) +parser.add_argument('--append',action='append',default=[]) + +args,cmdline = parser.parse_known_intermixed_args() + +with open(args.output,'w+') as fd: + for pre in args.prepend: + with open(pre,'r') as pfd: + fd.write(pfd.read()) + + p = subprocess.run(cmdline,check=True,stdout=subprocess.PIPE,text=True) + fd.write(p.stdout) + + for app in args.append: + with open(app,'r') as pfd: + fd.write(pfd.read()) diff --git a/isl_config.h.cmake b/isl_config.h.cmake new file mode 100644 index 00000000..d93e8469 --- /dev/null +++ b/isl_config.h.cmake @@ -0,0 +1,56 @@ +/* define if your compiler has __attribute__ */ +#cmakedefine HAVE___ATTRIBUTE__ /**/ + +/* most gcc compilers know a function __attribute__((__warn_unused_result__)) */ +#define GCC_WARN_UNUSED_RESULT @GCC_WARN_UNUSED_RESULT@ + + +/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */ +#define HAVE_DECL_FFS @HAVE_DECL_FFS@ + +/* Define to 1 if you have the declaration of `__builtin_ffs', and to 0 if you + don't. */ +#define HAVE_DECL___BUILTIN_FFS @HAVE_DECL___BUILTIN_FFS@ + +/* Define to 1 if you have the declaration of `_BitScanForward', and to 0 if + you don't. */ +#define HAVE_DECL__BITSCANFORWARD @HAVE_DECL__BITSCANFORWARD@ + + +/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRCASECMP @HAVE_DECL_STRCASECMP@ + +/* Define to 1 if you have the declaration of `_stricmp', and to 0 if you + don't. */ +#define HAVE_DECL__STRICMP @HAVE_DECL__STRICMP@ + + +/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRNCASECMP @HAVE_DECL_STRNCASECMP@ + +/* Define to 1 if you have the declaration of `_strnicmp', and to 0 if you + don't. */ +#define HAVE_DECL__STRNICMP @HAVE_DECL__STRNICMP@ + + +/* Define to 1 if you have the declaration of `snprintf', and to 0 if you + don't. */ +#define HAVE_DECL_SNPRINTF @HAVE_DECL_SNPRINTF@ + +/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you + don't. */ +#define HAVE_DECL__SNPRINTF @HAVE_DECL__SNPRINTF@ + + +/* use gmp to implement isl_int */ +#cmakedefine USE_GMP_FOR_MP + +/* use imath to implement isl_int */ +#cmakedefine USE_IMATH_FOR_MP + +/* Use small integer optimization */ +#cmakedefine USE_SMALL_INT_OPT + +#include diff --git a/isl_srcdir.c.cmake b/isl_srcdir.c.cmake new file mode 100644 index 00000000..34ef890f --- /dev/null +++ b/isl_srcdir.c.cmake @@ -0,0 +1 @@ +static const char *srcdir = "@ISL_SOURCE_DIR@"; diff --git a/isl_version.c b/isl_version.c index 114323d6..8cd9e669 100644 --- a/isl_version.c +++ b/isl_version.c @@ -13,5 +13,5 @@ const char *isl_version(void) "-32" #endif #endif - "\n"; + "-cmake\n"; }