set(namespace "yosys") # Properties internal to the component system. define_property(TARGET PROPERTY YOSYS_COMPONENT) define_property(TARGET PROPERTY YOSYS_PROVIDES) define_property(TARGET PROPERTY YOSYS_REQUIRES) define_property(TARGET PROPERTY YOSYS_DATA_FILES) define_property(TARGET PROPERTY YOSYS_ENABLE_IF) # Syntax: # # yosys_component( [INTERFACE] # [...] # [DEFINITIONS ...] # [INCLUDE_DIRS ...] # [LIBRARIES ...] # [PROVIDES ...] # [REQUIRES ...] # [DATA_DIR ] # [DATA_FILES ...] # [DATA_EXPLICIT [ ]...] # [ESSENTIAL] # [ENABLE_IF ""] # ) # # Creates a target `yosys_` (if `` is empty) or `yosys__` (if `` is not empty). # This target is an library target with some Yosys-specific behavior that simplifies partitioning the compiler # into small pieces with explicitly defined compile-time and run-time dependency metadata. Circular dependencies # between compilation units in different components are allowed. # # Parameter description: # - `INTERFACE` should be specified for header-only libraries. # - `...` is a shortcut for `target_sources(PRIVATE)`. # - `DEFINITIONS ...` is a shortcut for `target_compile_definitions(PRIVATE)`. # - `INCLUDE_DIRS ...` is a shortcut for `target_include_directories(PRIVATE)`. # - `LIBRARIES ...` is a shortcut for `target_link_libraries(PRIVATE)`. # - `PROVIDES ...` creates aliases to each `` component name. # - `REQUIRES ...` ensures that if this target is linked into the Yosys binary, then every # `` component is also linked in. # - `DATA_DIR ` configures a base directory for installing data files; this directory # is (relative to the root build directory or the installation prefix) `share/` if # `DATA_DIR` is provided, and `share` if not. # - `DATA_FILES ...` installs each of `` as `share///`, # where `` is the directory name of `` and `` is the filename of ``. # - `DATA_EXPLICIT [ ]...` installs each `` as `share//`. # Where possible, `DATA_FILES` should be used instead. # - `ESSENTIAL` ensures that this target is always linked into the Yosys binary. # - `ENABLE_IF ""` marks the component as available only when `if()` would run. # # Avoid using this function directly. Instead, use one of the wrappers below as follows: # - to define a normal pass, use `yosys_pass()` to add a component called ``. # - to define a test pass, use `yosys_test_pass()` to add a component called `test_`. # - to define a frontend, use `yosys_frontend()` to add a component called `read_`. # - to define a backend, use `yosys_backend()` to add a component called `write_`. # - if the component sources define more than one pass, use `PROVIDES` with names of the other passes. # - if the component uses `Pass::call()`, `Frontend::frontend_call()`, `Backend::backend_call()`, or other # similar functions, use `REQUIRES` with names of all possibly needed passes. # - if the component needs an essential pass, add the latter to `REQUIRES` anyway for completeness. # - if the component subclasses a `ScriptPass`, build Yosys, then run `misc/script_pass_depends.py ` # to extract the names of all referenced passes. # - in general, component names should be the same as corresponding pass names (as used in the REPL), # but this is not a hard requirement and any suitable name can be used if desired. # function(yosys_component arg_PREFIX arg_NAME) cmake_parse_arguments(PARSE_ARGV 2 arg "INTERFACE;ESSENTIAL;BOOTSTRAP" "DATA_DIR;ENABLE_IF" "DEFINITIONS;INCLUDE_DIRS;LIBRARIES;DATA_FILES;DATA_EXPLICIT;PROVIDES;REQUIRES" ) set(arg_SOURCES ${arg_UNPARSED_ARGUMENTS}) if ("${arg_ENABLE_IF}" STREQUAL "") set(arg_ENABLE_IF TRUE) endif() if (arg_PREFIX STREQUAL "") set(component "${arg_NAME}") else() set(component "${arg_PREFIX}_${arg_NAME}") endif() set(target "${namespace}_${component}") list(TRANSFORM arg_PROVIDES PREPEND ${namespace}_ OUTPUT_VARIABLE provides_targets) # An OBJECT library is used to allow for circular symbol dependencies between any source files. # Unfortunately, public dependencies between OBJECT libraries aren't handled correctly, so we have # to do it ourselves. if (arg_SOURCES AND NOT arg_INTERFACE) add_library(${target} EXCLUDE_FROM_ALL OBJECT) target_sources(${target} PRIVATE ${arg_SOURCES}) target_include_directories(${target} PRIVATE ${arg_INCLUDE_DIRS}) target_compile_definitions(${target} PRIVATE ${arg_DEFINITIONS}) target_link_libraries(${target} PUBLIC yosys_common ${arg_LIBRARIES}) foreach (alias ${provides_targets}) add_library(${alias} ALIAS ${target}) endforeach() else() add_library(${target} EXCLUDE_FROM_ALL INTERFACE) endif() set_target_properties(${target} PROPERTIES YOSYS_COMPONENT YES YOSYS_PROVIDES "${arg_PROVIDES}" YOSYS_REQUIRES "${arg_REQUIRES}" YOSYS_DATA_FILES "" YOSYS_ENABLE_IF "${arg_ENABLE_IF}" ) set(share_file_pairs) foreach (share_file ${arg_DATA_FILES}) list(APPEND share_file_pairs ${share_file} ${share_file}) endforeach() list(APPEND share_file_pairs ${arg_DATA_EXPLICIT}) if (share_file_pairs) set(data_depends) set(share_root ${CMAKE_BINARY_DIR}/share) while (share_file_pairs) list(LENGTH share_file_pairs share_file_unpaired) if (share_file_unpaired EQUAL 1) message(FATAL_ERROR "Unpaired DATA_EXPLICIT argument: ${share_file_pairs}") endif() list(POP_FRONT share_file_pairs dst_file src_file) cmake_path(ABSOLUTE_PATH src_file BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) set(out_dir ${arg_DATA_DIR}) cmake_path(GET dst_file PARENT_PATH dst_parent) cmake_path(APPEND out_dir ${dst_parent}) cmake_path(GET dst_file FILENAME dst_filename) cmake_path(APPEND out_dir ${dst_filename} OUTPUT_VARIABLE out_file) file(MAKE_DIRECTORY ${share_root}/${out_dir}) add_custom_command( DEPENDS ${src_file} OUTPUT ${share_root}/${out_file} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${share_root}/${out_file} VERBATIM COMMENT "Copying share/${out_file}" ) set_property(TARGET ${target} APPEND PROPERTY YOSYS_DATA_FILES ${out_file}) list(APPEND data_depends ${share_root}/${out_file}) endwhile() add_custom_target(${target}-data DEPENDS ${data_depends}) add_dependencies(${target} ${target}-data) endif() if (NOT arg_BOOTSTRAP) set_property(TARGET yosys_everything APPEND PROPERTY YOSYS_REQUIRES ${component}) if (arg_ESSENTIAL) set_property(TARGET yosys_essentials APPEND PROPERTY YOSYS_REQUIRES ${component}) endif() endif() endfunction() # Syntax: # # yosys_core( [