blob: bfa980994bebc3aa15cfa90420dc1ae064c589fd [file] [log] [blame]
# -*- Makefile -*-
# This Makefile template is supposed to be included in each plugin's Makefile.
# Plugin Makefiles need to specify the plugin's name and source files.
# The plugin name is how the final shared object will be named.
# This shared object can be imported to Yosys with `plugin -i` command.
#
# Below is an example of a plugin Makefile that uses this template:
# PLUGIN_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
# NAME = plugin_name
# SOURCES = source1.cc source2.cc
# include ../Makefile_plugin.common
#
# For the above example the final plugin shared object will be named plugin_name.so.
# In order to test the plugin it has to be copied to Yosys's shared folder.
# The install target in this Makefile copies the plugins into the shared folder
# of the Yosys installation that is found in the PATH.
# This is needed because the shared folder is where Yosys will look for the
# plugin object when `plugin -i` is called in Yosys's synthesis script.
#
# To add tests for the plugin the Makefile_test.common Makefile should be used.
# Refer to Makefile_test.common to learn more details.
#
# Below is a directory structure which shows how the plugin sources and tests
# should be laid out
#
# |-- Makefile_plugin.common
# |-- Makefile_test.common
# |-- example-plugin
# | |-- Makefile
# | |-- source1.cc
# | |-- source2.cc
# | |-- tests
# | |-- Makefile
# | |-- test_case_1
# | | |-- test_case_1.tcl
# | | |-- test_case_1.v
# | | |-- test_case_1.golden.ext
# | | |-- ...
# |-- example2-plugin
# |-- ...
SHELL := /usr/bin/env bash
# Directory containing this Makefile
TOP_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
_MAKEFILES := $(abspath $(filter-out %.d,$(MAKEFILE_LIST)))
# Either find yosys in system and use its path or use the given path
YOSYS_PATH ?= $(realpath $(dir $(shell command -v yosys))/..)
# Find yosys-config, throw an error if not found
YOSYS_CONFIG = $(YOSYS_PATH)/bin/yosys-config
ifeq (,$(wildcard $(YOSYS_CONFIG)))
$(error "Didn't find 'yosys-config' under '$(YOSYS_PATH)'")
endif
CXX ?= $(shell $(YOSYS_CONFIG) --cxx)
CXXFLAGS := $(shell $(YOSYS_CONFIG) --cxxflags) $(CXXFLAGS) #-DSDC_DEBUG
LDFLAGS := $(shell $(YOSYS_CONFIG) --ldflags) $(LDFLAGS)
LDLIBS := $(shell $(YOSYS_CONFIG) --ldlibs) $(LDLIBS)
EXTRA_FLAGS ?=
YOSYS_DATA_DIR = $(DESTDIR)$(shell $(YOSYS_CONFIG) --datdir)
YOSYS_PLUGINS_DIR = $(YOSYS_DATA_DIR)/plugins
BUILD_DIR := $(PLUGIN_DIR)/build
# Filled below with all object file paths
_ALL_OBJECTS :=
# Filled below with all build directory paths
_ALL_BUILD_SUBDIRS :=
# Default rule
.PHONY: all
all: $(NAME).so
# Object files
define _process-single-source-file
_source_abs := $(abspath $(addprefix $(PLUGIN_DIR)/,$(source)))
_object_abs := $(abspath $(addprefix $(BUILD_DIR)/,$(source).o))
_object_dir := $(abspath $(dir $(_object_abs)))
_ALL_OBJECTS += $(_object_abs)
_ALL_BUILD_SUBDIRS += $(_object_dir)
-include $(abspath $(addprefix $(BUILD_DIR)/,$(source).d))
$(_object_abs): TARGET_SOURCES := $(_source_abs)
$(_object_abs): $(_source_abs) | $(_object_dir)
endef
$(foreach source,$(SOURCES),$(eval $(value _process-single-source-file)))
$(_ALL_OBJECTS): $(_MAKEFILES)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(EXTRA_FLAGS) -MMD -c -o $@ $(TARGET_SOURCES)
# Objects list for the purpose of adding extra dependencies after inclusion.
# Example use: `$(OBJECTS): $(BUILD_DIR)/some-file.h`
OBJECTS := $(_ALL_OBJECTS)
# Shared library
SO_LIB := $(BUILD_DIR)/$(NAME).so
_ALL_BUILD_SUBDIRS += $(abspath $(dir $(SO_LIB)))
$(SO_LIB): $(_ALL_OBJECTS) $(_MAKEFILES) | $(abspath $(dir $(SO_LIB)))
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $@ $(_ALL_OBJECTS) $(LDLIBS)
.PHONY: $(NAME).so
$(NAME).so: $(SO_LIB)
# Tests
.PHONY: test test_clean
ifneq ($(wildcard $(PLUGIN_DIR)/tests/Makefile),)
test:
@$(MAKE) -C tests all
test_clean:
$(MAKE) -C tests clean
else
test:
test_clean:
endif
# Installation
$(YOSYS_PLUGINS_DIR)/$(NAME).so: $(SO_LIB) | $(YOSYS_PLUGINS_DIR)
install -D $(SO_LIB) $@
.PHONY: install_plugin
install_plugin: $(YOSYS_PLUGINS_DIR)/$(NAME).so
.PHONY: install
install: install_plugin
# Cleanup
clean: test_clean
rm -rf $(BUILD_DIR)
# Other
$(sort $(_ALL_BUILD_SUBDIRS)):
mkdir -p $@
$(YOSYS_PLUGINS_DIR):
@mkdir -p $@
PMGEN_PY := $(TOP_DIR)/pmgen.py
$(PMGEN_PY):
@$(MAKE) -C $(TOP_DIR) pmgen.py