diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41d677d4d24827b88ce5635096ba1c4b1fa93b9c..d59cd634cb6882e01c732ea4fe9af2e86a0eb723 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,6 +87,8 @@ if(WIN32)
   set(_gRPC_PLATFORM_WINDOWS ON)
 endif()
 
+set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+
 if (MSVC)
   add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
   # needed to compile boringssl
@@ -3321,7 +3323,7 @@ target_link_libraries(qps
 
 endif (gRPC_BUILD_TESTS)
 
-add_library(grpc_csharp_ext
+add_library(grpc_csharp_ext SHARED
   src/csharp/ext/grpc_csharp_ext.c
 )
 
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index b034763fb0633970f75abae3e7c8d2e1c5244b77..837f0d058f2d0e847677b4ca27c9fe3313b1f827 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -129,6 +129,9 @@
   if(WIN32)
     set(_gRPC_PLATFORM_WINDOWS ON)
   endif()
+  
+  ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF
+  set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
 
   if (MSVC)
     add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS)
@@ -428,7 +431,7 @@
   % endfor
 
   <%def name="cc_library(lib)">
-  add_library(${lib.name}
+  add_library(${lib.name}${' SHARED' if lib.get('dll', None) == 'only' else ''}
   % for src in lib.src:
   % if not proto_re.match(src):
     ${src}