# This is adapt based on the OpenROAD cmake module: # https://github.com/The-OpenROAD-Project/OpenROAD/tree/master/src/cmake # # Sets up swig for a .i file and encode .tcl files # Arguments # NAME : the generated library name # I_FILE : the .i file input to swig # NAMESPACE : the namespace prefix in TCL # SWIG_INCLUDES * : optional list of include dirs for swig # SCRIPTS * : tcl files to encode # # The intention is that this will create a library target with the # generated code in it. Additional c++ source will be added to the # target with target_sources() afterwards. function(SwigLib) # Parse args set(options "") set(oneValueArgs I_FILE NAME NAMESPACE LANGUAGE RUNTIME_HEADER) set(multiValueArgs SWIG_INCLUDES SCRIPTS) cmake_parse_arguments( ARG # prefix on the parsed args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) # Validate args if (DEFINED ARG_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown argument(s) to SwigLib: ${ARG_UNPARSED_ARGUMENTS}") endif() if (DEFINED ARG_KEYWORDS_MISSING_VALUES) message(FATAL_ERROR "Missing value for argument(s) to SwigLib: ${ARG_KEYWORDS_MISSING_VALUES}") endif() foreach(arg I_FILE NAME NAMESPACE) if (NOT DEFINED ARG_${arg}) message(FATAL_ERROR "${arg} argument must be provided to SwigLib") endif() endforeach() # Default to tcl if unspecified if (NOT DEFINED ARG_LANGUAGE) set(ARG_LANGUAGE tcl) endif() set_source_files_properties(${ARG_I_FILE} PROPERTIES CPLUSPLUS ON) if (DEFINED ARG_SWIG_INCLUDES) set_property(SOURCE ${ARG_I_FILE} PROPERTY INCLUDE_DIRECTORIES ${ARG_SWIG_INCLUDES}) endif() if (${ARG_LANGUAGE} STREQUAL "tcl") set(LANGUAGE_OPTIONS -namespace -prefix ${ARG_NAMESPACE}) endif() # Setup swig of I_FILE. set_property(SOURCE ${ARG_I_FILE} PROPERTY COMPILE_OPTIONS ${LANGUAGE_OPTIONS} -Werror -w317,325,378,401,402,467,472,503,509) set_property(SOURCE ${ARG_I_FILE} PROPERTY SWIG_MODULE_NAME ${ARG_NAME}) set_property(SOURCE ${ARG_I_FILE} PROPERTY USE_SWIG_DEPENDENCIES TRUE) set_property(SOURCE ${ARG_I_FILE} PROPERTY USE_TARGET_INCLUDE_DIRECTORIES true) swig_add_library(${ARG_NAME} LANGUAGE ${ARG_LANGUAGE} TYPE STATIC SOURCES ${ARG_I_FILE} ) # Disable problematic compiler warnings on generated files. # At this point only the swig generated sources are present. get_target_property(GEN_SRCS ${ARG_NAME} SOURCES) foreach(GEN_SRC ${GEN_SRCS}) set_source_files_properties(${GEN_SRC} PROPERTIES COMPILE_OPTIONS "-Wno-cast-qual;-Wno-missing-braces" ) endforeach() # These includes are always needed. target_include_directories(${ARG_NAME} PRIVATE ${OPENROAD_HOME}/include ) if (${ARG_LANGUAGE} STREQUAL tcl) target_include_directories(${ARG_NAME} PRIVATE ${TCL_INCLUDE_PATH} ) elseif (${ARG_LANGUAGE} STREQUAL python) target_include_directories(${ARG_NAME} PRIVATE ${Python3_INCLUDE_DIRS} ) if (SWIG_VERSION VERSION_GREATER_EQUAL "4.1.0") set_property(TARGET ${ARG_NAME} PROPERTY SWIG_COMPILE_OPTIONS -flatstaticmethod) endif() swig_link_libraries(${ARG_NAME} PUBLIC Python3::Python ) endif() if (DEFINED ARG_RUNTIME_HEADER) add_custom_command( OUTPUT ${ARG_RUNTIME_HEADER} COMMAND ${SWIG_EXECUTABLE} -${ARG_LANGUAGE} -external-runtime ${ARG_RUNTIME_HEADER} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) add_custom_target(${ARG_NAME}_RUNTIME_HEADER DEPENDS ${ARG_RUNTIME_HEADER} ) add_dependencies(${ARG_NAME} ${ARG_NAME}_RUNTIME_HEADER ) target_include_directories(${ARG_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ) endif() # Generate the encoded of the script files. if (DEFINED ARG_SCRIPTS) set(LANG_INIT ${CMAKE_CURRENT_BINARY_DIR}/${ARG_NAME}-${ARG_LANGUAGE}InitVar.cc) add_custom_command(OUTPUT ${LANG_INIT} COMMAND ${OPENSTA_HOME}/etc/TclEncode.tcl ${LANG_INIT} ${ARG_NAME}_${ARG_LANGUAGE}_inits ${ARG_SCRIPTS} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${ARG_SCRIPTS} ) target_sources(${ARG_NAME} PRIVATE ${LANG_INIT} ) endif() endfunction()