From 5fd958a9be7ceb7769b66c3176bb6abdd6022542 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Thu, 30 Jan 2014 18:55:14 -0700 Subject: [PATCH] CMake: Completely re-do the Interrogate macro. --- cmake/macros/Interrogate.cmake | 138 +++++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 42 deletions(-) diff --git a/cmake/macros/Interrogate.cmake b/cmake/macros/Interrogate.cmake index a118b3f945..c0d45aa103 100644 --- a/cmake/macros/Interrogate.cmake +++ b/cmake/macros/Interrogate.cmake @@ -8,7 +8,14 @@ # add_python_module(module [lib1 [lib2 ...]]) # -set(IGATE_FLAGS ${INTERROGATE_OPTIONS} -DCPPPARSER -D__cplusplus -Dvolatile -Dmutable) +set(IGATE_FLAGS ${INTERROGATE_OPTIONS} -DCPPPARSER -D__cplusplus -Dvolatile -Dmutable -python-native) + +# This is a list of regexes that are applied to every filename. If one of the +# regexes matches, that file will not be passed to Interrogate. +set(INTERROGATE_EXCLUDE_REGEXES + ".*\\.I$" + ".*\\.N$" + ".*_src\\..*") if(WIN32) list(APPEND IGATE_FLAGS -longlong __int64 -D_X86_ -D__STDC__=1 -DWIN32_VC -D "_declspec(param)=" -D "__declspec(param)=" -D_near -D_far -D__near -D__far -D_WIN32 -D__stdcall -DWIN32) @@ -17,7 +24,8 @@ if(INTERROGATE_VERBOSE) list(APPEND IGATE_FLAGS "-v") endif() -set(IMOD_FLAGS ${INTERROGATE_MODULE_OPTIONS}) +set(IMOD_FLAGS ${INTERROGATE_MODULE_OPTIONS} -python-native) + # # Function: target_interrogate(target [ALL] [source1 [source2 ...]]) @@ -31,11 +39,6 @@ function(target_interrogate target) if(HAVE_PYTHON AND HAVE_INTERROGATE) set(sources) set(want_all OFF) - - # Find any .N files that would normally be picked up by interrogate. - # We let CMake add these as dependencies too, to allow rebuilding - # the wrappers when the .N files have been modified. - set(deps) foreach(arg ${ARGV}) if(arg STREQUAL "ALL") set(want_all ON) @@ -52,28 +55,95 @@ function(target_interrogate target) list(REMOVE_DUPLICATES sources) - # Go through the sources to determine the full name, - # and also find out if there are any .N files to pick up. + # Now let's get everything's absolute path, so that it can be passed + # through a property while still preserving the reference. + set(absolute_sources) foreach(source ${sources}) - get_source_file_property(exclude "${source}" WRAP_EXCLUDE) + get_source_file_property(location "${source}" LOCATION) + set(absolute_sources ${absolute_sources} ${location}) + endforeach(source) + + set_target_properties("${target}" PROPERTIES IGATE_SOURCES + "${absolute_sources}") + endif() +endfunction(target_interrogate) + +# +# Function: interrogate_sources(target output database module) +# +# This function actually runs a component-level interrogation against 'target'. +# It generates the outfile.cxx (output) and dbfile.in (database) files, which +# can then be used during the interrogate_module step to produce language +# bindings. +# +# The target must first have had sources selected with target_interrogate. +# Failure to do so will result in an error. +# +function(interrogate_sources target output database module) + if(HAVE_PYTHON AND HAVE_INTERROGATE) + get_target_property(sources "${target}" IGATE_SOURCES) + + if(sources STREQUAL "sources-NOTFOUND") + message(FATAL_ERROR + "Cannot interrogate ${target} unless it's run through target_interrogate first!") + endif() + + set(scan_sources) + foreach(source ${sources}) + get_filename_component(source_basename "${source}" NAME) + + # Only certain sources should actually be scanned by Interrogate. The + # rest are merely dependencies. This uses the exclusion regex above in + # order to determine what files are okay: + set(exclude OFF) + foreach(regex ${INTERROGATE_EXCLUDE_REGEXES}) + if("${source_basename}" MATCHES "${regex}") + set(exclude ON) + endif() + endforeach(regex) + + get_source_file_property(source_excluded ${source} WRAP_EXCLUDE) + if(source_excluded) + set(exclude ON) + endif() if(NOT exclude) - get_filename_component(basename "${source}" NAME_WE) - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${basename}.N") - list(APPEND deps "${CMAKE_CURRENT_SOURCE_DIR}/${basename}.N") - endif() - - # Add the full path to the source file itself. - get_source_file_property(location "${source}" LOCATION) - list(APPEND deps "${location}") + # This file is to be scanned by Interrogate. In order to avoid + # cluttering up the command line, we should first make it relative: + file(RELATIVE_PATH rel_source "${CMAKE_CURRENT_BINARY_DIR}" "${source}") + list(APPEND scan_sources "${rel_source}") endif() endforeach(source) - set_target_properties("${target}" PROPERTIES IGATE_SOURCES "${sources}") - set_target_properties("${target}" PROPERTIES IGATE_SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}") - set_target_properties("${target}" PROPERTIES IGATE_DEPS "${deps}") + # Interrogate also needs the include paths, so we'll extract them from the + # target: + set(include_flags) + get_target_property(include_dirs "${target}" INTERFACE_INCLUDE_DIRECTORIES) + foreach(include_dir ${include_dirs}) + # To keep the command-line small, also make this relative: + file(RELATIVE_PATH rel_include_dir "${CMAKE_CURRENT_BINARY_DIR}" "${include_dir}") + list(APPEND include_flags "-I${rel_include_dir}") + endforeach(include_dir) + # The above must also be included when compiling the resulting _igate.cxx file: + include_directories(${include_dirs}) + + + add_custom_command( + OUTPUT "${output}" "${database}" + COMMAND interrogate + -oc "${output}" + -od "${database}" + -module ${module} -library ${target} ${IGATE_FLAGS} + -S "${PROJECT_BINARY_DIR}/include" + -S "${PROJECT_SOURCE_DIR}/dtool/src/parser-inc" + -S "${PROJECT_BINARY_DIR}/include/parser-inc" + ${include_flags} + ${scan_sources} + DEPENDS interrogate ${sources} + COMMENT "Interrogating ${target}" + ) endif() -endfunction(target_interrogate) +endfunction(interrogate_sources) # # Function: add_python_module(module [lib1 [lib2 ...]]) @@ -86,24 +156,7 @@ function(add_python_module module) set(sources) foreach(target ${targets}) - get_target_property(scansrc "${target}" IGATE_SOURCES) - get_target_property(srcdir "${target}" IGATE_SRCDIR) - get_target_property(deps "${target}" IGATE_DEPS) - - add_custom_command( - OUTPUT "${target}_igate.cxx" "${target}.in" - COMMAND interrogate - -od "${target}.in" - -oc "${target}_igate.cxx" - -module ${module} -library ${target} ${IGATE_FLAGS} - -srcdir "${srcdir}" - -I "${PROJECT_BINARY_DIR}/include" - -S "${PROJECT_SOURCE_DIR}/dtool/src/parser-inc" - -S "${PROJECT_BINARY_DIR}/include/parser-inc" - ${scansrc} - DEPENDS interrogate ${deps} - ) - + interrogate_sources(${target} "${target}_igate.cxx" "${target}.in" "${module}") list(APPEND infiles "${target}.in") list(APPEND sources "${target}_igate.cxx") endforeach(target) @@ -115,11 +168,12 @@ function(add_python_module module) -module ${module} -library ${module} ${IMOD_FLAGS} ${infiles} DEPENDS interrogate_module ${infiles} + COMMENT "Generating module ${module}" ) add_library(${module} MODULE "${module}_module.cxx" ${sources}) - target_link_libraries(${module} ${PYTHON_LIBRARIES}) - target_link_libraries(${module} p3interrogatedb) + target_link_libraries(${module} + ${targets} ${PYTHON_LIBRARIES} p3interrogatedb) set_target_properties(${module} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/panda3d"