A work-around for supporting plugins compiled as *.a.

This is for older CMakes which don't understand object libraries yet.
We auto-generate a file at the top-level that references all the
global plugin objects. Once they are referenced, the linker includes
them into the final executable and their ctors run to register them
with the plugin manager.

By default this is on. Once we can require more recent CMakes, we can
turn it off (and remove) in src/CMakeLists.txt.
This commit is contained in:
Robin Sommer 2013-06-02 19:36:25 -07:00
parent c19779ae88
commit 8e7ef001b3
3 changed files with 40 additions and 3 deletions

View file

@ -8,7 +8,7 @@ set(bro_ALL_GENERATED_OUTPUTS CACHE INTERNAL "automatically generated files" FO
# If TRUE, use CMake's object libraries for sub-directories instead of
# static libraries. This requires CMake >= 2.8.8.
set(bro_HAVE_OBJECT_LIBRARIES TRUE)
set(bro_HAVE_OBJECT_LIBRARIES FALSE)
configure_file(version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c)
configure_file(util-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/util-config.h)
@ -156,6 +156,20 @@ set(bro_SUBDIRS
${bro_PLUGIN_LIBS}
)
if ( NOT bro_HAVE_OBJECT_LIBRARIES )
foreach (_plugin ${bro_PLUGIN_LIBS})
string(REGEX REPLACE "plugin-" "" _plugin "${_plugin}")
string(REGEX REPLACE "-" "_" _plugin "${_plugin}")
set(_decl "namespace plugin { namespace ${_plugin} { class Plugin; extern Plugin __plugin; } };")
set(_use "i += (size_t)(&(plugin::${_plugin}::__plugin));")
set(__BRO_DECL_PLUGINS "${__BRO_DECL_PLUGINS}${_decl}\n")
set(__BRO_USE_PLUGINS "${__BRO_USE_PLUGINS}${_use}\n")
endforeach()
configure_file(plugins.cc.in ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
set(PLUGIN_INIT ${CMAKE_CURRENT_BINARY_DIR}/plugins.cc)
endif()
########################################################################
## bro target
@ -222,6 +236,7 @@ set(bro_SRCS
${FLEX_Scanner_INPUT}
${BISON_Parser_INPUT}
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
${PLUGIN_INIT}
main.cc
net_util.cc
util.cc
@ -367,7 +382,7 @@ if ( bro_HAVE_OBJECT_LIBRARIES )
target_link_libraries(bro ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
else ()
add_executable(bro ${bro_SRCS} ${bro_HEADERS})
target_link_libraries(bro ${brodeps} ${bro_SUBDIRS} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
target_link_libraries(bro ${bro_SUBDIRS} ${brodeps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
endif ()
install(TARGETS bro DESTINATION bin)

View file

@ -50,7 +50,7 @@
} \
}; \
\
static Plugin __plugin; \
Plugin __plugin; \
} }
/**

22
src/plugins.cc.in Normal file
View file

@ -0,0 +1,22 @@
// A work-around the problem that for static libraries unused globals
// aren't linked into the final binary. CMake automatically inserts
// code here to reference the globals that initializes each of the
// statically compiled plugins.
//
// Note: This won't be necessary anymore once we can assume CMake >2.8.8
// as a required depencendy. If so, switch bro_HAVE_OBJECT_LIBRARIES
// in src/CMakeLists.txt to TRUE and remove this.
#include <stdlib.h>
${__BRO_DECL_PLUGINS}
size_t __make_sure_to_use_plugin_globals()
{
// This function is never actually called.
size_t i = 0;
${__BRO_USE_PLUGINS}
return i;
}