Переглянути джерело

CMake: Update add_metalib() to support exports

This allows exporting (a stub function that forwards to) a
function that returns a value - it's particularly useful in
the graphics plugins for the "get_pipe_type_foo()" functions.

This also frees up CMake from needing to use any of the source
files in the metalibs/*/ directories.
Sam Edwards 7 роки тому
батько
коміт
3050203e24

+ 47 - 2
cmake/macros/BuildMetalib.cmake

@@ -182,7 +182,9 @@ function(add_component_library target_name)
 endfunction(add_component_library)
 
 #
-# Function: add_metalib(target [source1 source2] [INIT initfunc [initheader.h]]
+# Function: add_metalib(target [source1 source2]
+#                       [INCLUDE header1.h ...]
+#                       [INIT initfunc [initheader.h] [EXPORT type name expr]]
 #                       [COMPONENTS component1 ...])
 #
 # This is add_library, but for metalibs.
@@ -191,28 +193,72 @@ endfunction(add_component_library)
 # autogenerated by this function) that calls the underlying component libs'
 # init functions.
 #
+# The EXPORT keyword exports the expression `expr`, which yields a value of
+# type `type`, as the undecorated (extern "C") symbol `name`
+#
+# The INCLUDE keyword allows the init file to pull in additional headers, which
+# may be useful for EXPORT.
+#
 function(add_metalib target_name)
   set(components_keyword OFF)
   set(init_keyword 0)
   set(init_func)
   set(init_header "${target_name}.h")
+  set(export_keyword 0)
+  set(export_declarations)
+  set(export_definitions)
+  set(component_init_headers)
   set(components)
   set(sources)
   foreach(arg ${ARGN})
     if(arg STREQUAL "COMPONENTS")
       set(components_keyword ON)
+      set(include_keyword OFF)
+      set(init_keyword 0)
+      set(export_keyword 0)
+    elseif(arg STREQUAL "INCLUDE")
+      set(include_keyword ON)
+      set(components_keyword OFF)
       set(init_keyword 0)
+      set(export_keyword 0)
     elseif(arg STREQUAL "INIT")
       set(init_keyword 2)
       set(components_keyword OFF)
+      set(include_keyword OFF)
+      set(export_keyword 0)
+    elseif(arg STREQUAL "EXPORT")
+      if(NOT init_func)
+        message(FATAL_ERROR "EXPORT cannot be used before INIT")
+      endif()
+      set(export_keyword 3)
+      set(components_keyword OFF)
+      set(include_keyword OFF)
+      set(init_keyword 0)
     elseif(components_keyword)
       list(APPEND components "${arg}")
+    elseif(include_keyword)
+      set(component_init_headers
+        "${component_init_headers}#include \"${arg}\"\n")
     elseif(init_keyword EQUAL 2)
       set(init_func "${arg}")
       set(init_keyword 1)
     elseif(init_keyword EQUAL 1)
       set(init_header "${arg}")
       set(init_keyword 0)
+    elseif(export_keyword EQUAL 3)
+      set(_export_type "${arg}")
+      set(export_keyword 2)
+    elseif(export_keyword EQUAL 2)
+      set(_export_name "${arg}")
+      set(export_keyword 1)
+    elseif(export_keyword EQUAL 1)
+      set(export_declarations
+        "${export_declarations}\nextern \"C\" IMPORT_CLASS ${_export_type} ${_export_name}();")
+      set(export_definitions
+        "${export_definitions}\nextern \"C\" EXPORT_CLASS ${_export_type} ${_export_name}() { return ${arg}; }")
+      unset(_export_type)
+      unset(_export_name)
+      set(export_keyword 0)
     else()
       list(APPEND sources "${arg}")
     endif()
@@ -226,7 +272,6 @@ function(add_metalib target_name)
   set(includes)
   set(libs)
   set(component_init_funcs "")
-  set(component_init_headers "")
   foreach(component ${components})
     if(NOT TARGET "${component}")
       message(FATAL_ERROR

+ 1 - 0
cmake/templates/metalib_init.cxx.in

@@ -6,3 +6,4 @@ EXPORT_CLASS void
 @init_func@() {
 @component_init_funcs@
 }
+@export_definitions@

+ 1 - 0
cmake/templates/metalib_init.h.in

@@ -4,5 +4,6 @@
 #include "dtoolbase.h"
 
 IMPORT_CLASS void @init_func@();
+@export_declarations@
 
 #endif

+ 4 - 2
panda/metalibs/pandadx9/CMakeLists.txt

@@ -2,8 +2,10 @@ if(NOT HAVE_DX9)
   return()
 endif()
 
-add_metalib(pandadx9 ${MODULE_TYPE} pandadx9.cxx
+add_metalib(pandadx9 ${MODULE_TYPE}
+  INCLUDE wdxGraphicsPipe9.h
+  INIT init_libpandadx9 pandadx9.h
+  EXPORT int get_pipe_type_pandadx9 "wdxGraphicsPipe9::get_class_type().get_index()"
   COMPONENTS p3dxgsg9 p3windisplay)
-set_target_properties(pandadx9 PROPERTIES DEFINE_SYMBOL BUILDING_PANDADX)
 
 install(TARGETS pandadx9 DESTINATION ${MODULE_DESTINATION})

+ 32 - 27
panda/metalibs/pandagl/CMakeLists.txt

@@ -1,32 +1,37 @@
-if(HAVE_GL)
-  # Check that we actually have a display subsystem.
-  if(NOT HAVE_WGL AND NOT HAVE_COCOA AND NOT HAVE_CARBON AND NOT HAVE_GLX)
-    message("") # Add extra line before error
-    message(SEND_ERROR
-      "When compiling with OpenGL (HAVE_GL), at least one of:
-    HAVE_WGL, HAVE_COCOA, HAVE_CARBON, or HAVE_GLX must be defined.")
-  endif()
-
-  set(PANDAGL_LINK_TARGETS p3glgsg p3glstuff)
-
-  if(HAVE_GLX)
-    list(APPEND PANDAGL_LINK_TARGETS p3glxdisplay p3x11display)
-  endif()
+if(NOT HAVE_GL)
+  return()
+endif()
 
-  if(HAVE_WGL)
-    list(APPEND PANDAGL_LINK_TARGETS p3wgldisplay p3windisplay)
-  endif()
+set(PANDAGL_LINK_TARGETS p3glgsg p3glstuff)
 
-  if(HAVE_COCOA)
-    list(APPEND PANDAGL_LINK_TARGETS p3cocoadisplay)
-  endif()
+if(HAVE_GLX)
+  list(APPEND PANDAGL_LINK_TARGETS p3glxdisplay p3x11display)
+  set(PANDAGL_PIPE_TYPE "glxGraphicsPipe")
+elseif(HAVE_WGL)
+  list(APPEND PANDAGL_LINK_TARGETS p3wgldisplay p3windisplay)
+  set(PANDAGL_PIPE_TYPE "wglGraphicsPipe")
+elseif(HAVE_COCOA)
+  list(APPEND PANDAGL_LINK_TARGETS p3cocoadisplay)
+  set(PANDAGL_PIPE_TYPE "CocoaGraphicsPipe")
+  set(PANDAGL_PIPE_INCLUDE "cocoaGraphicsPipe.h")
+elseif(HAVE_CARBON)
+  list(APPEND PANDAGL_LINK_TARGETS p3osxdisplay)
+  set(PANDAGL_PIPE_TYPE "osxGraphicsPipe")
+else()
+  message("") # Add extra line before error
+  message(SEND_ERROR
+    "When compiling with OpenGL (HAVE_GL), at least one of:
+  HAVE_WGL, HAVE_COCOA, HAVE_CARBON, or HAVE_GLX must be defined.")
+endif()
 
-  if(HAVE_CARBON)
-    list(APPEND PANDAGL_LINK_TARGETS p3osxdisplay)
-  endif()
+if(NOT PANDAGL_PIPE_INCLUDE)
+  set(PANDAGL_PIPE_INCLUDE "${PANDAGL_PIPE_TYPE}.h")
+endif()
 
-  add_metalib(pandagl ${MODULE_TYPE} pandagl.cxx COMPONENTS ${PANDAGL_LINK_TARGETS})
-  set_target_properties(pandagl PROPERTIES DEFINE_SYMBOL BUILDING_PANDAGL)
+add_metalib(pandagl ${MODULE_TYPE}
+  INCLUDE "${PANDAGL_PIPE_INCLUDE}"
+  INIT init_libpandagl pandagl.h
+  EXPORT int get_pipe_type_pandagl "${PANDAGL_PIPE_TYPE}::get_class_type().get_index()"
+  COMPONENTS ${PANDAGL_LINK_TARGETS})
 
-  install(TARGETS pandagl DESTINATION ${MODULE_DESTINATION})
-endif()
+install(TARGETS pandagl DESTINATION ${MODULE_DESTINATION})

+ 12 - 2
panda/metalibs/pandagles/CMakeLists.txt

@@ -2,8 +2,18 @@ if(NOT HAVE_GLES1 OR NOT HAVE_EGL)
   return()
 endif()
 
-add_metalib(pandagles ${MODULE_TYPE} pandagles.cxx
+if(ANDROID)
+  set(GLES1_PIPE_TYPE "AndroidGraphicsPipe")
+  set(GLES1_PIPE_INCLUDE "androidGraphicsPipe.h")
+else()
+  set(GLES1_PIPE_TYPE "eglGraphicsPipe")
+  set(GLES1_PIPE_INCLUDE "eglGraphicsPipe.h")
+endif()
+
+add_metalib(pandagles ${MODULE_TYPE}
+  INCLUDE "${GLES1_PIPE_INCLUDE}"
+  INIT init_libpandagles pandagles.h
+  EXPORT int get_pipe_type_pandagles "${GLES1_PIPE_TYPE}::get_class_type().get_index()"
   COMPONENTS p3egldisplay_gles1 p3glesgsg)
-set_target_properties(pandagles PROPERTIES DEFINE_SYMBOL BUILDING_PANDAGLES)
 
 install(TARGETS pandagles DESTINATION ${MODULE_DESTINATION})

+ 4 - 2
panda/metalibs/pandagles2/CMakeLists.txt

@@ -2,8 +2,10 @@ if(NOT HAVE_GLES2 OR NOT HAVE_EGL)
   return()
 endif()
 
-add_metalib(pandagles2 ${MODULE_TYPE} pandagles2.cxx
+add_metalib(pandagles2 ${MODULE_TYPE}
+  INCLUDE eglGraphicsPipe.h
+  INIT init_libpandagles2 pandagles2.h
+  EXPORT int get_pipe_type_pandagles2 "eglGraphicsPipe::get_class_type().get_index()"
   COMPONENTS p3egldisplay_gles2 p3gles2gsg)
-set_target_properties(pandagles2 PROPERTIES DEFINE_SYMBOL BUILDING_PANDAGLES2)
 
 install(TARGETS pandagles2 DESTINATION ${MODULE_DESTINATION})

+ 2 - 0
panda/src/egldisplay/CMakeLists.txt

@@ -29,6 +29,7 @@ composite_sources(p3egldisplay P3EGLDISPLAY_SOURCES)
 # We actually build this twice!  Once for GLES1, once for GLES2.
 if(HAVE_GLES1)
   add_component_library(p3egldisplay_gles1 SYMBOL BUILDING_PANDAGLES
+    INIT init_libegldisplay config_egldisplay.h
     ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES})
   target_compile_definitions(p3egldisplay_gles1 PUBLIC OPENGLES_1)
   target_link_libraries(p3egldisplay_gles1 p3glesgsg p3x11display
@@ -41,6 +42,7 @@ endif()
 
 if(HAVE_GLES2)
   add_component_library(p3egldisplay_gles2 SYMBOL BUILDING_PANDAGLES2
+    INIT init_libegldisplay config_egldisplay.h
     ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES})
   target_compile_definitions(p3egldisplay_gles2 PUBLIC OPENGLES_2)
   target_link_libraries(p3egldisplay_gles2 p3gles2gsg p3x11display

+ 1 - 1
panda/src/glstuff/CMakeLists.txt

@@ -34,7 +34,7 @@ set(P3GLSTUFF_SOURCES
 )
 
 composite_sources(p3glstuff P3GLSTUFF_SOURCES)
-add_component_library(p3glstuff ${P3GLSTUFF_HEADERS} ${P3GLSTUFF_SOURCES})
+add_component_library(p3glstuff NOINIT ${P3GLSTUFF_HEADERS} ${P3GLSTUFF_SOURCES})
 target_link_libraries(p3glstuff panda)
 
 if(NOT BUILD_METALIBS)