diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml
index 8a901660ce975afde35a22f81485da9bab8e588b..b92e9bc8ae0af67b9d6b10bdca654a262a5db6d5 100644
--- a/substrate/bin/node/runtime/Cargo.toml
+++ b/substrate/bin/node/runtime/Cargo.toml
@@ -35,7 +35,7 @@ sp-version = { version = "2.0.0-alpha.2", default-features = false, path = "../.
 
 # frame dependencies
 frame-executive = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/executive" }
-frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/benchmarking" }
+frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/benchmarking", optional = true }
 frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/support" }
 frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/system" }
 frame-system-rpc-runtime-api = { version = "2.0.0-alpha.2", default-features = false, path = "../../../frame/system/rpc/runtime-api/" }
@@ -132,3 +132,4 @@ std = [
 	"pallet-recovery/std",
 	"pallet-vesting/std",
 ]
+runtime-benchmarks = ["frame-benchmarking"]
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index be5ca25630d4a2f6890dfe5c424eb4f409d3bfff..3a7df27466c5e39853b1061bb6e70c6636e15c39 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
 	spec_version: 227,
-	impl_version: 0,
+	impl_version: 1,
 	apis: RUNTIME_API_VERSIONS,
 };
 
@@ -818,6 +818,7 @@ impl_runtime_apis! {
 		}
 	}
 
+	#[cfg(feature = "runtime-benchmarks")]
 	impl frame_benchmarking::Benchmark<Block> for Runtime {
 		fn dispatch_benchmark(
 			module: Vec<u8>,
diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml
index 9d26c5b957e0cf93029362903e20b72cc1c45723..6bb551c9c6fea03a747e700e5aac6f0d8156f300 100644
--- a/substrate/frame/balances/Cargo.toml
+++ b/substrate/frame/balances/Cargo.toml
@@ -14,7 +14,7 @@ codec = { package = "parity-scale-codec", version = "1.2.0", default-features =
 sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" }
 sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" }
 sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" }
-frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking" }
+frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true }
 frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" }
 frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" }
 
@@ -34,3 +34,4 @@ std = [
 	"frame-support/std",
 	"frame-system/std",
 ]
+runtime-benchmarks = ["frame-benchmarking"]
diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs
index 4dbaf4b8a886d38a38e469f30f68bf5f26f23f58..b4a1b810df325132b00d45a9fee0afa03edd14b2 100644
--- a/substrate/frame/balances/src/lib.rs
+++ b/substrate/frame/balances/src/lib.rs
@@ -155,6 +155,7 @@ mod tests_composite;
 #[cfg(test)]
 #[macro_use]
 mod tests;
+#[cfg(feature = "runtime-benchmarks")]
 mod benchmarking;
 
 use sp_std::prelude::*;
diff --git a/substrate/frame/identity/Cargo.toml b/substrate/frame/identity/Cargo.toml
index 7ea53f776ed1156947c7b1fbc8d4651cea366de6..3dbffedffcdc3ea332807f8542989e04121c92f4 100644
--- a/substrate/frame/identity/Cargo.toml
+++ b/substrate/frame/identity/Cargo.toml
@@ -15,7 +15,7 @@ enumflags2 = { version = "0.6.2" }
 sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" }
 sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" }
 sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" }
-frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking" }
+frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true }
 frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" }
 frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" }
 
@@ -35,3 +35,4 @@ std = [
 	"frame-support/std",
 	"frame-system/std",
 ]
+runtime-benchmarks = ["frame-benchmarking"]
diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs
index 68b7905961da8267b13e86c4fdf51a5606eedaf8..cb2071d5d9ea872876d1a66e8c432341333de0b5 100644
--- a/substrate/frame/identity/src/lib.rs
+++ b/substrate/frame/identity/src/lib.rs
@@ -78,6 +78,7 @@ use frame_support::{
 };
 use frame_system::{self as system, ensure_signed, ensure_root};
 
+#[cfg(feature = "runtime-benchmarks")]
 pub mod benchmarking;
 
 type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
diff --git a/substrate/frame/system/Cargo.toml b/substrate/frame/system/Cargo.toml
index 6a418cab8ec8ede874960afd14ce9ae00428ccfd..4e350be1a90c78b8a18c4da1a77f6d9e4c54f905 100644
--- a/substrate/frame/system/Cargo.toml
+++ b/substrate/frame/system/Cargo.toml
@@ -36,6 +36,7 @@ std = [
 	"sp-runtime/std",
 	"sp-version/std",
 ]
+runtime-benchmarks = []
 
 [[bench]]
 name = "bench"
diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs
index f89c9efbd29621c69c85962f785e1aa757ee3cfe..6cac08117afcf9a07dd0b8cf0f840b713de6fd03 100644
--- a/substrate/frame/system/src/lib.rs
+++ b/substrate/frame/system/src/lib.rs
@@ -885,7 +885,7 @@ impl<T: Trait> Module<T> {
 
 	/// Set the block number to something in particular. Can be used as an alternative to
 	/// `initialize` for tests that don't need to bother with the other environment entries.
-	#[cfg(any(feature = "std", test))]
+	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
 	pub fn set_block_number(n: T::BlockNumber) {
 		<Number<T>>::put(n);
 	}
diff --git a/substrate/frame/timestamp/Cargo.toml b/substrate/frame/timestamp/Cargo.toml
index db1d9aaf37a8a4200a7e4042c407d553336dc73c..ff5b72de670e6cfd364c008e82ff3b0ec168be2d 100644
--- a/substrate/frame/timestamp/Cargo.toml
+++ b/substrate/frame/timestamp/Cargo.toml
@@ -14,10 +14,10 @@ documentation = "https://docs.rs/pallet-timestamp"
 serde = { version = "1.0.101", optional = true }
 codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false, features = ["derive"] }
 sp-std = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/std" }
-sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io" }
+sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/io", optional = true }
 sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" }
 sp-inherents = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/inherents" }
-frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking" }
+frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true }
 frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" }
 frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" }
 sp-timestamp = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/timestamp" }
@@ -40,3 +40,4 @@ std = [
 	"frame-system/std",
 	"sp-timestamp/std"
 ]
+runtime-benchmarks = ["frame-benchmarking", "sp-io"]
diff --git a/substrate/frame/timestamp/src/lib.rs b/substrate/frame/timestamp/src/lib.rs
index 1c3fec2112a084e65bc01f28deb50381368011fb..2a37dfdddb62a89fc7a3aea9f2ce9ef8880421a7 100644
--- a/substrate/frame/timestamp/src/lib.rs
+++ b/substrate/frame/timestamp/src/lib.rs
@@ -90,6 +90,7 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
+#[cfg(feature = "runtime-benchmarks")]
 mod benchmarking;
 
 use sp_std::{result, cmp};
diff --git a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
index 07d7ae40401d52fc8da8b275e9c1207e548ea151..e16cf3b5c46f78f50fbc03f5bff0f699dbedf503 100644
--- a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
+++ b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs
@@ -27,7 +27,7 @@ use proc_macro2::{Span, TokenStream};
 use quote::quote;
 
 use syn::{
-	spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, Path, Signature,
+	spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, Path, Signature, Attribute,
 	ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath,
 	fold::{self, Fold}, parse_quote,
 };
@@ -141,7 +141,7 @@ fn extract_runtime_block_ident(trait_: &Path) -> Result<&TypePath> {
 fn generate_impl_calls(
 	impls: &[ItemImpl],
 	input: &Ident
-) -> Result<Vec<(Ident, Ident, TokenStream)>> {
+) -> Result<Vec<(Ident, Ident, TokenStream, Vec<Attribute>)>> {
 	let mut impl_calls = Vec::new();
 
 	for impl_ in impls {
@@ -162,9 +162,12 @@ fn generate_impl_calls(
 					&impl_trait
 				)?;
 
-				impl_calls.push(
-					(impl_trait_ident.clone(), method.sig.ident.clone(), impl_call)
-				);
+				impl_calls.push((
+					impl_trait_ident.clone(),
+					 method.sig.ident.clone(),
+					 impl_call,
+					 filter_cfg_attrs(&impl_.attrs),
+				));
 			}
 		}
 	}
@@ -178,9 +181,12 @@ fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
 	let c = generate_crate_access(HIDDEN_INCLUDES_ID);
 	let impl_calls = generate_impl_calls(impls, &data)?
 		.into_iter()
-		.map(|(trait_, fn_name, impl_)| {
+		.map(|(trait_, fn_name, impl_, attrs)| {
 			let name = prefix_function_with_trait(&trait_, &fn_name);
-			quote!( #name => Some(#c::Encode::encode(&{ #impl_ })), )
+			quote!(
+				#( #attrs )*
+				#name => Some(#c::Encode::encode(&{ #impl_ })),
+			)
 		});
 
 	Ok(quote!(
@@ -200,13 +206,14 @@ fn generate_wasm_interface(impls: &[ItemImpl]) -> Result<TokenStream> {
 	let c = generate_crate_access(HIDDEN_INCLUDES_ID);
 	let impl_calls = generate_impl_calls(impls, &input)?
 		.into_iter()
-		.map(|(trait_, fn_name, impl_)| {
+		.map(|(trait_, fn_name, impl_, attrs)| {
 			let fn_name = Ident::new(
 				&prefix_function_with_trait(&trait_, &fn_name),
 				Span::call_site()
 			);
 
 			quote!(
+				#( #attrs )*
 				#[cfg(not(feature = "std"))]
 				#[no_mangle]
 				pub fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 {
@@ -447,6 +454,7 @@ fn generate_api_impl_for_runtime(impls: &[ItemImpl]) -> Result<TokenStream> {
 		let trait_ = extend_with_runtime_decl_path(trait_);
 
 		impl_.trait_.as_mut().unwrap().1 = trait_;
+		impl_.attrs = filter_cfg_attrs(&impl_.attrs);
 		impls_prepared.push(impl_);
 	}
 
@@ -622,6 +630,8 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
 			}
 		);
 
+		input.attrs = filter_cfg_attrs(&input.attrs);
+
 		// The implementation for the `RuntimeApiImpl` is only required when compiling with
 		// the feature `std` or `test`.
 		input.attrs.push(parse_quote!( #[cfg(any(feature = "std", test))] ));
@@ -695,8 +705,12 @@ fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result<TokenStream> {
 
 		let id: Path = parse_quote!( #path ID );
 		let version: Path = parse_quote!( #path VERSION );
+		let attrs = filter_cfg_attrs(&impl_.attrs);
 
-		result.push(quote!( (#id, #version) ));
+		result.push(quote!(
+			#( #attrs )*
+			(#id, #version)
+		));
 	}
 
 	let c = generate_crate_access(HIDDEN_INCLUDES_ID);
@@ -745,3 +759,32 @@ fn impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
 		)
 	)
 }
+
+// Filters all attributes except the cfg ones.
+fn filter_cfg_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
+	attrs.into_iter().filter(|a| a.path.is_ident("cfg")).cloned().collect()
+}
+
+#[cfg(test)]
+mod tests {
+	use super::*;
+
+	#[test]
+	fn filter_non_cfg_attributes() {
+		let cfg_std: Attribute = parse_quote!(#[cfg(feature = "std")]);
+		let cfg_benchmarks: Attribute = parse_quote!(#[cfg(feature = "runtime-benchmarks")]);
+
+		let attrs = vec![
+			cfg_std.clone(),
+			parse_quote!(#[derive(Debug)]),
+			parse_quote!(#[test]),
+			cfg_benchmarks.clone(),
+			parse_quote!(#[allow(non_camel_case_types)]),
+		];
+
+		let filtered = filter_cfg_attrs(&attrs);
+		assert_eq!(filtered.len(), 2);
+		assert_eq!(cfg_std, filtered[0]);
+		assert_eq!(cfg_benchmarks, filtered[1]);
+	}
+}