ソースを参照

CMake: Autogenerate metalib init files

Sam Edwards 7 年 前
コミット
a088e6aba5

+ 81 - 6
cmake/macros/BuildMetalib.cmake

@@ -62,15 +62,23 @@ function(target_link_libraries target)
 endfunction(target_link_libraries)
 
 #
-# Function: add_component_library(target [SYMBOL building_symbol] [SOURCES])
+# Function: add_component_library(target [SYMBOL building_symbol]
+#                                 [SOURCES] [[NOINIT]/[INIT func [header]]])
 #
-# Used very similarly to add_library. You can specify a symbol with SYMBOL,
+# Used very similarly to add_library.  You can specify a symbol with SYMBOL,
 # which works like CMake's own DEFINE_SYMBOL property: it's defined when
 # building the library, but not when building something that links against the
 # library.
 #
+# INIT specifies the init function that should be called from a metalib's init
+# function when this is added to a metalib.  The header parameter can further
+# clarify what header declares this function.  By default, this is
+# init_libTARGET and config_TARGET.h, respectively, where TARGET is the
+# target name (with 'p3' stripped off, if applicable).  The NOINIT keyword
+# suppresses this default.
+#
 # Note that this function gets to decide whether the component library is
-# OBJECT or SHARED, and whether the library is installed or not. Also, as
+# OBJECT or SHARED, and whether the library is installed or not.  Also, as
 # a rule, component libraries may only be linked by other component libraries
 # in the same metalib - outside of the metalib, you must link the metalib
 # itself.
@@ -79,26 +87,50 @@ function(add_component_library target_name)
   set(sources)
   unset(symbol)
 
+  if(target_name MATCHES "^p3.*")
+    string(SUBSTRING "${target_name}" 2 -1 name_without_prefix)
+  else()
+    set(name_without_prefix "${target_name}")
+  endif()
+  set(init_func "init_lib${name_without_prefix}")
+  set(init_header "config_${name_without_prefix}.h")
+
   set(symbol_keyword OFF)
+  set(init_keyword 0)
   foreach(source ${ARGN})
     if(source STREQUAL "SYMBOL")
       set(symbol_keyword ON)
+      set(init_keyword 0)
+    elseif(source STREQUAL "INIT")
+      set(symbol_keyword OFF)
+      set(init_keyword 2)
+    elseif(source STREQUAL "NOINIT")
+      set(init_func)
+      set(init_header)
     elseif(symbol_keyword)
       set(symbol_keyword OFF)
       set(symbol "${source}")
+    elseif(init_keyword EQUAL 2)
+      set(init_func "${source}")
+      set(init_keyword 1)
+    elseif(init_keyword EQUAL 1)
+      set(init_header "${source}")
+      set(init_keyword 0)
     else()
       list(APPEND sources "${source}")
     endif()
   endforeach()
 
-
   if(BUILD_METALIBS)
     add_library("${target_name}" OBJECT ${sources})
   else()
     add_library("${target_name}" ${sources})
   endif()
 
-  set_target_properties("${target_name}" PROPERTIES IS_COMPONENT ON)
+  set_target_properties("${target_name}" PROPERTIES 
+    IS_COMPONENT ON
+    INIT_FUNCTION "${init_func}"
+    INIT_HEADER "${init_header}")
   if(symbol)
     # ... DEFINE_SYMBOL is apparently not respected for object libraries?
     set_property(TARGET "${target_name}" APPEND PROPERTY COMPILE_DEFINITIONS "${symbol}")
@@ -116,19 +148,37 @@ function(add_component_library target_name)
 endfunction(add_component_library)
 
 #
-# Function: add_metalib(target [source1 source2] [COMPONENTS component1 ...])
+# Function: add_metalib(target [source1 source2] [INIT initfunc [initheader.h]]
+#                       [COMPONENTS component1 ...])
 #
 # This is add_library, but for metalibs.
 #
+# The INIT keyword can specify an initialization function/header (which will be
+# autogenerated by this function) that calls the underlying component libs'
+# init functions.
+#
 function(add_metalib target_name)
   set(components_keyword OFF)
+  set(init_keyword 0)
+  set(init_func)
+  set(init_header "${target_name}.h")
   set(components)
   set(sources)
   foreach(arg ${ARGN})
     if(arg STREQUAL "COMPONENTS")
       set(components_keyword ON)
+      set(init_keyword 0)
+    elseif(arg STREQUAL "INIT")
+      set(init_keyword 2)
+      set(components_keyword OFF)
     elseif(components_keyword)
       list(APPEND components "${arg}")
+    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)
     else()
       list(APPEND sources "${arg}")
     endif()
@@ -137,6 +187,8 @@ function(add_metalib target_name)
   set(defines)
   set(includes)
   set(libs)
+  set(component_init_funcs "")
+  set(component_init_headers "")
   foreach(component ${components})
     if(NOT TARGET "${component}")
       message(FATAL_ERROR
@@ -149,6 +201,18 @@ function(add_metalib target_name)
         "Attempted to metalink non-component ${component} into ${target_name}!")
     endif()
 
+    get_target_property(component_init_header "${component}" INIT_HEADER)
+    get_target_property(component_init_func "${component}" INIT_FUNCTION)
+
+    if(component_init_header)
+      set(component_init_headers
+        "${component_init_headers}#include \"${component_init_header}\"\n")
+    endif()
+    if(component_init_func)
+      set(component_init_funcs
+        "${component_init_funcs}  ${component_init_func}();\n")
+    endif()
+
     if(BUILD_METALIBS)
       list(APPEND defines "$<TARGET_PROPERTY:${component},COMPILE_DEFINITIONS>")
       list(APPEND includes "$<TARGET_PROPERTY:${component},INTERFACE_INCLUDE_DIRECTORIES>")
@@ -159,6 +223,17 @@ function(add_metalib target_name)
     endif()
   endforeach()
 
+  if(init_func)
+    set(init_source_path "${CMAKE_CURRENT_BINARY_DIR}/init_${target_name}.cxx")
+    set(init_header_path "${CMAKE_CURRENT_BINARY_DIR}/${init_header}")
+
+    configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.cxx.in" "${init_source_path}")
+    list(APPEND sources "${init_source_path}")
+
+    configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.h.in" "${init_header_path}")
+    install(FILES "${init_header_path}" DESTINATION include/panda3d)
+  endif()
+
   add_library("${target_name}" ${sources})
   target_compile_definitions("${target_name}" PRIVATE ${defines})
   target_link_libraries("${target_name}" ${libs})

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

@@ -0,0 +1,8 @@
+#include "dtoolbase.h"
+
+@component_init_headers@
+
+EXPORT_CLASS void
+@init_func@() {
+@component_init_funcs@
+}

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

@@ -0,0 +1,8 @@
+#ifndef _METALIB_INIT_@target_name@
+#define _METALIB_INIT_@target_name@
+
+#include "dtoolbase.h"
+
+IMPORT_CLASS void @init_func@();
+
+#endif

+ 1 - 2
direct/CMakeLists.txt

@@ -14,14 +14,13 @@ add_subdirectory(src/interval)
 add_subdirectory(src/motiontrail)
 add_subdirectory(src/showbase)
 
-# TODO: p3direct needs a source file!
 set(P3DIRECT_COMPONENTS
   p3dcparser p3deadrec p3directbase
   p3interval p3motiontrail p3showbase)
 if(HAVE_PYTHON)
   list(APPEND P3DIRECT_COMPONENTS p3distributed)
 endif()
-add_metalib(p3direct COMPONENTS ${P3DIRECT_COMPONENTS})
+add_metalib(p3direct INIT init_libdirect direct.h COMPONENTS ${P3DIRECT_COMPONENTS})
 set_property(TARGET p3direct PROPERTY LINKER_LANGUAGE "CXX")
 
 if(HAVE_PYTHON)

+ 1 - 1
direct/src/dcparser/CMakeLists.txt

@@ -46,7 +46,7 @@ set(P3DCPARSER_PARSER_SOURCES
     dcLexer.cxx)
 
 composite_sources(p3dcparser P3DCPARSER_SOURCES)
-add_component_library(p3dcparser ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES}
+add_component_library(p3dcparser NOINIT ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES}
   ${P3DCPARSER_PARSER_SOURCES})
 target_compile_definitions(p3dcparser PUBLIC WITHIN_PANDA)
 target_link_libraries(p3dcparser p3directbase panda)

+ 2 - 1
direct/src/directbase/CMakeLists.txt

@@ -7,7 +7,8 @@ set(P3DIRECTBASE_HEADERS
 )
 
 # Not worth compositing sources, there's really only one.
-add_component_library(p3directbase ${P3DIRECTBASE_HEADERS} ${P3DIRECTBASE_SOURCES})
+add_component_library(p3directbase NOINIT
+  ${P3DIRECTBASE_HEADERS} ${P3DIRECTBASE_SOURCES})
 target_link_libraries(p3directbase panda)
 
 install(TARGETS p3directbase DESTINATION lib)

+ 1 - 1
direct/src/showbase/CMakeLists.txt

@@ -1,4 +1,4 @@
-add_component_library(p3showbase SYMBOL BUILDING_DIRECT_SHOWBASE
+add_component_library(p3showbase NOINIT SYMBOL BUILDING_DIRECT_SHOWBASE
   showBase.cxx showBase.h)
 target_link_libraries(p3showbase p3directbase panda)
 target_interrogate(p3showbase ALL)

+ 1 - 1
dtool/metalibs/dtool/CMakeLists.txt

@@ -1,3 +1,3 @@
-add_metalib(p3dtool dtool.cxx COMPONENTS p3dtoolutil p3dtoolbase)
+add_metalib(p3dtool INIT init_libdtool dtool.h COMPONENTS p3dtoolutil p3dtoolbase)
 
 install(TARGETS p3dtool DESTINATION lib)

+ 1 - 1
dtool/metalibs/dtoolconfig/CMakeLists.txt

@@ -1,3 +1,3 @@
 set(DTOOLCONFIG_LINK_TARGETS p3prc p3dconfig p3interrogatedb)
-add_metalib(p3dtoolconfig dtoolconfig.cxx COMPONENTS ${DTOOLCONFIG_LINK_TARGETS})
+add_metalib(p3dtoolconfig INIT init_libdtoolconfig dtoolconfig.h COMPONENTS ${DTOOLCONFIG_LINK_TARGETS})
 install(TARGETS p3dtoolconfig DESTINATION lib)

+ 1 - 1
dtool/src/dconfig/CMakeLists.txt

@@ -6,7 +6,7 @@ set(P3DCONFIG_SOURCES
 
 composite_sources(p3dconfig P3DCONFIG_SOURCES)
 
-add_component_library(p3dconfig SYMBOL BUILDING_DTOOL_DCONFIG
+add_component_library(p3dconfig NOINIT SYMBOL BUILDING_DTOOL_DCONFIG
   ${P3DCONFIG_HEADERS} ${P3DCONFIG_SOURCES})
 target_link_libraries(p3dconfig p3prc)
 

+ 1 - 1
dtool/src/dtoolbase/CMakeLists.txt

@@ -83,7 +83,7 @@ set(P3DTOOLBASE_IGATEEXT
 
 composite_sources(p3dtoolbase P3DTOOLBASE_SOURCES)
 
-add_component_library(p3dtoolbase SYMBOL BUILDING_DTOOL_DTOOLBASE
+add_component_library(p3dtoolbase NOINIT SYMBOL BUILDING_DTOOL_DTOOLBASE
   ${P3DTOOLBASE_HEADERS} ${P3DTOOLBASE_SOURCES})
 # The extensions need py_panda.h and extension.h from interrogatedb
 target_include_directories(p3dtoolbase PUBLIC

+ 1 - 1
dtool/src/interrogatedb/CMakeLists.txt

@@ -34,7 +34,7 @@ set(P3INTERROGATEDB_IGATE
 
 composite_sources(p3interrogatedb P3INTERROGATEDB_SOURCES)
 
-add_component_library(p3interrogatedb SYMBOL SYMBOL BUILDING_INTERROGATEDB
+add_component_library(p3interrogatedb NOINIT SYMBOL BUILDING_INTERROGATEDB
   ${P3INTERROGATEDB_HEADERS} ${P3INTERROGATEDB_SOURCES})
 target_link_libraries(p3interrogatedb p3dconfig)
 target_use_packages(p3interrogatedb PYTHON)

+ 1 - 1
dtool/src/prc/CMakeLists.txt

@@ -70,7 +70,7 @@ set(P3PRC_IGATEEXT
 
 composite_sources(p3prc P3PRC_SOURCES)
 
-add_component_library(p3prc SYMBOL BUILDING_DTOOL_PRC
+add_component_library(p3prc NOINIT SYMBOL BUILDING_DTOOL_PRC
   ${P3PRC_HEADERS} ${P3PRC_SOURCES})
 target_include_directories(p3prc PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
 # The extensions need py_panda.h and extension.h from interrogatedb

+ 1 - 1
panda/metalibs/panda/CMakeLists.txt

@@ -11,7 +11,7 @@ if(HAVE_FREETYPE)
   list(APPEND PANDA_LINK_TARGETS p3pnmtext)
 endif()
 
-add_metalib(panda panda.cxx COMPONENTS ${PANDA_LINK_TARGETS})
+add_metalib(panda INIT init_libpanda panda.h COMPONENTS ${PANDA_LINK_TARGETS})
 set_target_properties(panda PROPERTIES DEFINE_SYMBOL BUILDING_LIBPANDA)
 
 install(TARGETS panda DESTINATION lib)

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

@@ -21,7 +21,7 @@ set(P3AUDIO_SOURCES
     nullAudioSound.cxx)
 
 composite_sources(p3audio P3AUDIO_SOURCES)
-add_component_library(p3audio SYMBOL BUILDING_PANDA_AUDIO
+add_component_library(p3audio NOINIT SYMBOL BUILDING_PANDA_AUDIO
   ${P3AUDIO_HEADERS} ${P3AUDIO_SOURCES})
 target_link_libraries(p3audio p3putil p3event p3movies p3linmath)
 target_interrogate(p3audio ALL)

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

@@ -53,7 +53,7 @@ set(P3CHAN_SOURCES
 )
 
 composite_sources(p3chan P3CHAN_SOURCES)
-add_component_library(p3chan SYMBOL BUILDING_PANDA_CHAN
+add_component_library(p3chan NOINIT SYMBOL BUILDING_PANDA_CHAN
   ${P3CHAN_HEADERS} ${P3CHAN_SOURCES})
 target_link_libraries(p3chan p3pgraph)
 target_interrogate(p3chan ALL)

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

@@ -12,7 +12,7 @@ set(P3DGRAPH_SOURCES
 )
 
 composite_sources(p3dgraph P3DGRAPH_SOURCES)
-add_component_library(p3dgraph SYMBOL BUILDING_PANDA_DGRAPH
+add_component_library(p3dgraph NOINIT SYMBOL BUILDING_PANDA_DGRAPH
   ${P3DGRAPH_HEADERS} ${P3DGRAPH_SOURCES})
 target_link_libraries(p3dgraph p3pgraph)
 target_interrogate(p3dgraph ALL)

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

@@ -45,7 +45,7 @@ set(P3EVENT_IGATEEXT
 )
 
 composite_sources(p3event P3EVENT_SOURCES)
-add_component_library(p3event SYMBOL BUILDING_PANDA_EVENT
+add_component_library(p3event NOINIT SYMBOL BUILDING_PANDA_EVENT
   ${P3EVENT_HEADERS} ${P3EVENT_SOURCES})
 target_link_libraries(p3event p3linmath p3pstatclient)
 target_interrogate(p3event ALL EXTENSIONS ${P3EVENT_IGATEEXT})

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

@@ -168,7 +168,7 @@ set(P3GOBJ_IGATEEXT
 )
 
 composite_sources(p3gobj P3GOBJ_SOURCES)
-add_component_library(p3gobj SYMBOL BUILDING_PANDA_GOBJ
+add_component_library(p3gobj NOINIT SYMBOL BUILDING_PANDA_GOBJ
   ${P3GOBJ_HEADERS} ${P3GOBJ_SOURCES})
 target_link_libraries(p3gobj p3gsgbase p3pnmimage)
 target_use_packages(p3gobj ZLIB SQUISH CG)

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

@@ -11,7 +11,7 @@ set(P3GSGBASE_SOURCES
 )
 
 composite_sources(p3gsgbase P3GSGBASE_SOURCES)
-add_component_library(p3gsgbase SYMBOL BUILDING_PANDA_GSGBASE
+add_component_library(p3gsgbase NOINIT SYMBOL BUILDING_PANDA_GSGBASE
   ${P3GSGBASE_HEADERS} ${P3GSGBASE_SOURCES})
 target_link_libraries(p3gsgbase p3putil p3linmath)
 target_interrogate(p3gsgbase ALL)

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

@@ -34,7 +34,7 @@ set(P3PARAMETRICS_SOURCES
 )
 
 composite_sources(p3parametrics P3PARAMETRICS_SOURCES)
-add_component_library(p3parametrics SYMBOL BUILDING_PANDA_PARAMETRICS
+add_component_library(p3parametrics NOINIT SYMBOL BUILDING_PANDA_PARAMETRICS
   ${P3PARAMETRICS_HEADERS} ${P3PARAMETRICS_SOURCES})
 target_link_libraries(p3parametrics p3pgraph)
 target_interrogate(p3parametrics ALL)

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

@@ -17,7 +17,7 @@ set(P3RECORDER_SOURCES
 )
 
 composite_sources(p3recorder P3RECORDER_SOURCES)
-add_component_library(p3recorder SYMBOL BUILDING_PANDA_RECORDER
+add_component_library(p3recorder NOINIT SYMBOL BUILDING_PANDA_RECORDER
   ${P3RECORDER_HEADERS} ${P3RECORDER_SOURCES})
 target_link_libraries(p3recorder p3dgraph p3downloader)
 target_interrogate(p3recorder ALL)

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

@@ -27,7 +27,7 @@ set(P3TFORM_SOURCES
 )
 
 composite_sources(p3tform P3TFORM_SOURCES)
-add_component_library(p3tform SYMBOL BUILDING_PANDA_TFORM
+add_component_library(p3tform NOINIT SYMBOL BUILDING_PANDA_TFORM
   ${P3TFORM_HEADERS} ${P3TFORM_SOURCES})
 target_link_libraries(p3tform p3device p3grutil)
 target_interrogate(p3tform ALL)