In the CMake build, make sure that the DLL import library is generated.

* CMakeLists.txt: Define the export blacklist as in SConstruct.
   Generate a Windows DEF file and add it to the shared-lib sources.
* build/SerfWindowsToolkit.cmake (SerfWindowsGenDef): New function.
   Generates the DEF file, apparently just like build/gen_def.py.

git-svn-id: https://svn.apache.org/repos/asf/serf/trunk@1834948 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5f50e53..d54f15d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -115,7 +115,14 @@
 )
 
 if(SERF_WINDOWS)
-  set(SHARED_SOURCES "serf.rc")
+  list(APPEND EXPORTS_BLACKLIST
+       "serf_connection_switch_protocol"
+       "serf_http_protocol_create"
+       "serf_https_protocol_create"
+       "serf_http_request_queue"
+  )
+  SerfWindowsGenDef("${EXPORTS_BLACKLIST}" "${CMAKE_BINARY_DIR}/serf.def" ${HEADERS})
+  set(SHARED_SOURCES "serf.rc" "${CMAKE_BINARY_DIR}/serf.def")
 
   # Static OpenSSL, APR and APR-Util need additional libraries that are not
   # linked by default by CMake. These will be ignored by the linker if they're
diff --git a/build/SerfWindowsToolkit.cmake b/build/SerfWindowsToolkit.cmake
index feaa7a1..7968024 100644
--- a/build/SerfWindowsToolkit.cmake
+++ b/build/SerfWindowsToolkit.cmake
@@ -33,3 +33,37 @@
   if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
   endif()
 endfunction(SerfWindowsProcessZLIB)
+
+# Generate a Windows DLL .def file from a list of headers.
+function(SerfWindowsGenDef blacklist_ target_)
+  if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+    set(func_search_rx_ "^(([a-zA-Z_0-9]+|\\*) )+\\*?(serf_[a-z][a-zA-Z_0-9]*)\\(")
+    set(type_search_rx_ "^extern const serf_bucket_type_t (serf_[a-z_]*);")
+    set(func_rx_ "^(([a-zA-Z_0-9]+|\\*) )+\\*?(serf_[a-z][a-zA-Z_0-9]*).*$")
+    set(type_rx_ "^extern const serf_bucket_type_t (serf_[a-z_]*).*$")
+
+    foreach(file_ ${ARGN})
+      message(STATUS "Looking for exports in ${file_}")
+      file(STRINGS ${file_} funcs_ REGEX "${func_search_rx_}")
+      file(STRINGS ${file_} types_ REGEX "${type_search_rx_}")
+      foreach(sym_ ${funcs_})
+        string(REGEX REPLACE "${func_rx_}" "\\3" def_ ${sym_})
+        list(APPEND defs_ ${def_})
+      endforeach()
+      foreach(sym_ ${types_})
+        string(REGEX REPLACE "${type_rx_}" "\\1" def_ ${sym_})
+        list(APPEND defs_ ${def_})
+      endforeach()
+    endforeach()
+
+    list(SORT defs_)
+    list(REMOVE_DUPLICATES defs_)
+    file(WRITE ${target_} "EXPORTS\n")
+    foreach(def_ ${defs_})
+      list(FIND blacklist_ "${def_}" skip_)
+      if(skip_ LESS 0)
+        file(APPEND ${target_} "${def_}\n")
+      endif()
+    endforeach()
+  endif()
+endfunction(SerfWindowsGenDef)