CMake: Autogenerate metalib init files

This commit is contained in:
Sam Edwards 2018-06-10 01:43:42 -06:00
parent c4126942f6
commit a088e6aba5
23 changed files with 118 additions and 27 deletions

View File

@ -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})

View File

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

View File

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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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})

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)