Browse Source

Add composite_sources, add bison macro, emulate CMAKE_CURRENT_DIR_IN_INTERFACE in pre-2.8.11

rdb 12 years ago
parent
commit
57c9b1ae64

+ 8 - 5
CMakeLists.txt

@@ -1,17 +1,20 @@
-cmake_minimum_required(VERSION 2.8)
+# We require 2.8.4 because earlier releases had a bug
+# with invalid HEADER_FILE_ONLY behavior in MSVC 2010.
+cmake_minimum_required(VERSION 2.8.4)
 project(Panda3D)
 
-## Set Panda's CMake Module path ##
+# Set Panda's CMake module path
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
 
-## This is where dtool_config.h gets generated ##
+# This is where dtool_config.h gets generated.
 include_directories("${CMAKE_BINARY_DIR}")
 
-## Configure Panda3D ##(
+# Configure Panda3D
+include(dtool/PandaMacros.cmake)
 include(dtool/PandaVersion.cmake)
 include(dtool/Packages.cmake)
 include(dtool/Config.cmake)
 
-## Include Panda3D Packages ##
+# Include Panda3D packages
 add_subdirectory(dtool)
 add_subdirectory(panda)

+ 0 - 7
dtool/Config.cmake

@@ -353,10 +353,3 @@ if(BUILD_PREFER_STDFLOAT)
   set(STDFLOAT_DOUBLE TRUE)
 endif()
 
-#XXX note from rdb: I've moved the automatically-configured
-# compiler settings to LocalSetup.cmake, which is also where
-# dtool_config.h.cmake is now being invoked.
-# LocalSetup.cmake is included in dtool/CMakeLists.txt, which
-# is OK since the variables in there don't have to be used
-# outside of dtool_config.h.cmake.
-

+ 2 - 1
dtool/LocalSetup.cmake

@@ -175,6 +175,7 @@ check_include_file_cxx(typeinfo HAVE_RTTI)
 #/* Define if needed to have 64-bit file i/o */
 #$[cdefine __USE_LARGEFILE64]
 
-configure_file(dtool_config.h.cmake "${PROJECT_BINARY_DIR}/dtool_config.h")
+# Generate dtool_config.h
+configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/dtool_config.h")
 include_directories("${PROJECT_BINARY_DIR}")
 #install(FILES "${PROJECT_BINARY_DIR}/dtool_config.h" DESTINATION include/panda3d)

+ 22 - 0
dtool/MakeComposite.cmake

@@ -0,0 +1,22 @@
+# This script is invoked via add_custom_target, like this:
+# cmake -P MakeComposite.cmake -D COMPOSITE_FILE="x_composite1.cxx" -D COMPOSITE_SOURCES="a.cxx b.cxx"
+
+if(CMAKE_SCRIPT_MODE_FILE)
+  #cmake_minimum_required(VERSION 2.8.4)
+
+  if(NOT DEFINED COMPOSITE_FILE)
+    message(FATAL_ERROR "COMPOSITE_FILE should be defined when running MakeComposite.cmake!")
+    return()
+  endif()
+
+  file(WRITE "${COMPOSITE_FILE}" "/* Generated by CMake.  DO NOT EDIT. */\n")
+
+  separate_arguments(COMPOSITE_SOURCES)
+  foreach(source ${COMPOSITE_SOURCES})
+    file(APPEND "${COMPOSITE_FILE}" "#include \"${source}\"\n")
+  endforeach()
+
+else()
+  message(SEND_ERROR "MakeComposite.cmake should not be included but run in script mode.")
+
+endif()

+ 215 - 0
dtool/PandaMacros.cmake

@@ -0,0 +1,215 @@
+# Settings for composite builds.
+set(COMPOSITE_SOURCE_LIMIT "10" CACHE STRING
+  "Setting this to a value higher than 1 will enable unity builds.
+A high value will speed up the build dramatically but use more RAM.")
+
+set(COMPOSITE_SOURCE_EXTENSIONS "cxx;c;mm" CACHE STRING
+  "Only files of these extensions will be added to composite files.")
+
+set(COMPOSITE_GENERATOR "${CMAKE_CURRENT_LIST_DIR}/MakeComposite.cmake")
+
+# Settings for interrogate.
+#set(INTERROGATE_OPTIONS
+
+#
+# Function: write_composite_file(file [source1 [source2 ...])
+# Writes out a single composite file.  Used by composite_sources, below.
+#
+#function(write_composite_file file)
+#  set(COMPOSITE_INCLUDES "")
+#  foreach(source ${ARGN})
+#    set(COMPOSITE_INCLUDES "${COMPOSITE_INCLUDES}#include \"${source}\"\n")
+#  endforeach()
+#
+#  configure_file("${COMPOSITE_TEMPLATE}" "${file}")
+#endfunction(write_composite_file)
+
+#
+# Macro: composite_sources(target sources_var)
+# Looks at all the sources, generates _composite#.cxx and modifies the list.
+# Usage:
+#   set(MY_SOURCES a.cxx b.cxx c.cxx)
+#   composite_sources(MY_SOURCES)
+#   add_library(my ${MY_SOURCES})
+#
+#TODO: only supports .cxx files so far, not yet .mm files
+# it should probably sort the files by extension (.c, .cxx, .mm) first.
+#
+function(composite_sources target sources_var)
+  # How many sources were specified?
+  set(orig_sources ${${sources_var}})
+  set(sources ${orig_sources})
+  list(LENGTH sources num_sources)
+
+  if(num_sources LESS 2 OR ${COMPOSITE_SOURCE_LIMIT} LESS 2)
+    # It's silly to do this for a single source.
+    return()
+  endif()
+
+  set(composite_files "")
+  set(composite_sources "")
+
+  while(num_sources GREATER 0)
+    # Pop the first element
+    list(GET sources 0 source)
+    list(REMOVE_AT sources 0)
+    list(LENGTH sources num_sources)
+
+    # Check if we can safely add this to a composite file.
+    get_source_file_property(generated "${source}" GENERATED)
+    get_source_file_property(is_header "${source}" HEADER_FILE_ONLY)
+
+    if(NOT generated AND NOT is_header)
+      # Add it to composite_sources.
+      list(APPEND composite_sources ${source})
+      list(LENGTH composite_sources num_composite_sources)
+
+      if(num_sources EQUAL 0 OR NOT num_composite_sources LESS ${COMPOSITE_SOURCE_LIMIT})
+
+        # It's pointless to make a composite source from just one file.
+        if(num_composite_sources GREATER 1)
+
+          # Figure out the name of our composite file.
+          list(LENGTH composite_files index)
+          math(EXPR index "1+${index}")
+          set(composite_file "${CMAKE_CURRENT_BINARY_DIR}/${target}_composite${index}.cxx")
+          list(APPEND composite_files "${composite_file}")
+
+          # Set HEADER_FILE_ONLY to prevent it from showing up in the
+          # compiler command, but still show up in the IDE environment.
+          set_source_files_properties(${composite_sources} PROPERTIES HEADER_FILE_ONLY ON)
+
+          # We'll interrogate the composite files, so exclude the original sources.
+          set_source_files_properties(${composite_sources} PROPERTIES WRAP_EXCLUDE YES)
+
+          # Finally, add the target that generates the composite file.
+          add_custom_command(
+            OUTPUT "${composite_file}"
+            COMMAND ${CMAKE_COMMAND}
+              -DCOMPOSITE_FILE="${composite_file}"
+              -DCOMPOSITE_SOURCES="${composite_sources}"
+              -P "${COMPOSITE_GENERATOR}"
+            DEPENDS ${composite_sources})          
+
+          # Reset for the next composite file.
+          set(composite_sources "")
+        endif()
+      endif()
+    endif()
+  endwhile()
+
+  #set_source_files_properties(${composite_files} PROPERTIES GENERATED YES)
+
+  # The new files are added to the existing files, which means the old files
+  # are still there, but they won't be compiled due to the HEADER_FILE_ONLY setting.
+  set(${sources_var} ${orig_sources} ${composite_files} PARENT_SCOPE)
+endfunction(composite_sources)
+
+#
+# Function: add_bison_target(output_cxx input_yxx [DEFINES output_h] [PREFIX prefix])
+# Takes .prebuilt files into account if BISON_FOUND is not true.
+#
+function(add_bison_target output_cxx input_yxx)
+  set(arguments "")
+  set(outputs "${output_cxx}")
+  set(keyword "")
+
+  # Parse the extra arguments to the function.
+  foreach(arg ${ARGN})
+    if(arg STREQUAL "DEFINES")
+      set(keyword "DEFINES")
+    elseif(arg STREQUAL "PREFIX")
+      set(keyword "PREFIX")
+
+    elseif(keyword STREQUAL "PREFIX")
+      set(arguments ${arguments} -p "${arg}")
+    elseif(keyword STREQUAL "DEFINES")
+      set(arguments ${arguments} --defines="${arg}")
+      list(APPEND outputs "${arg}")
+
+    else()
+      message(SEND_ERROR "Unexpected argument ${arg} to add_bison_target")
+    endif()
+  endforeach()
+
+  if(keyword STREQUAL arg AND NOT keyword STREQUAL "")
+    message(SEND_ERROR "Expected argument after ${keyword}")
+  endif()
+
+  if(HAVE_BISON)
+    # If we have bison, we can of course just run it.
+    add_custom_command(
+      OUTPUT ${outputs}
+      COMMAND ${BISON_EXECUTABLE}
+        -o "${output_cxx}" ${arguments}
+        "${input_yxx}"
+      MAIN_DEPENDENCY "${input_yxx}"
+    )
+
+  else()
+    # Look for prebuilt versions of the outputs.
+    set(commands "")
+    set(depends "")
+
+    foreach(output ${outputs})
+      set(prebuilt_file "${output}.prebuilt")
+      get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE)
+
+      if(NOT EXISTS "${prebuilt_file}")
+        message(SEND_ERROR "Bison was not found and ${prebuilt_file} does not exist!")
+      endif()
+
+      list(APPEND depends "${prebuilt_file}")
+      set(commands ${commands} COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output})
+    endforeach()
+
+    add_custom_command(
+      OUTPUT ${outputs}
+      ${commands}
+      DEPENDS ${depends}
+    )
+  endif()
+endfunction(add_bison_target)
+
+
+# Emulate CMake 2.8.11's CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE behavior.
+if(CMAKE_VERSION VERSION_LESS 2.8.11)
+  # Replace some built-in functions in order to extend their functionality.
+  function(add_library target)
+    _add_library(${target} ${ARGN})
+    set_target_properties("${target}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}")
+  endfunction()
+
+  function(add_executable target)
+    _add_executable(${target} ${ARGN})
+    set_target_properties("${target}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}")
+  endfunction()
+
+  function(target_link_libraries target)
+    set(interface_dirs "")
+    get_target_property(target_interface_dirs "${target}" INTERFACE_INCLUDE_DIRECTORIES)
+
+    foreach(lib ${ARGN})
+      get_target_property(lib_interface_dirs "${lib}" INTERFACE_INCLUDE_DIRECTORIES)
+
+      set(interface_dirs ${interface_dirs} ${lib_interface_dirs})
+    endforeach()
+
+    #NB. target_include_directories is new in 2.8.8.
+    #target_include_directories("${target}" ${interace_dirs})
+    include_directories(${interface_dirs})
+    message(STATUS "adding extra ${interface_dirs}")
+
+    # Update this target's interface inc dirs.
+    set_target_properties("${target}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${target_interface_dirs};${interface_dirs}")
+
+    # Call to the built-in function we are overriding.
+    _target_link_libraries(${name} ${ARGN})
+  endfunction()
+
+else()
+  # 2.8.11 supports this natively.
+  set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+endif()
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)

+ 0 - 0
dtool/dtool_config.h.cmake → dtool/dtool_config.h.in


+ 6 - 32
dtool/src/cppparser/CMakeLists.txt

@@ -1,6 +1,3 @@
-include_directories(../dtoolutil)
-include_directories(../dtoolbase)
-
 set(P3CPPPARSER_HEADERS
 	cppArrayType.h cppBison.yxx cppBisonDefs.h
 	cppClassTemplateParameter.h cppCommentBlock.h cppConstType.h
@@ -37,39 +34,16 @@ set(P3CPPPARSER_SOURCES
 	cppUsing.cxx cppVisibility.cxx
 )
 
+composite_sources(p3cppParser P3CPPPARSER_SOURCES)
+
 # Bison is required for CPPParser
 # Check for it here, so that cppparser can be compiled individually
+#TODO rdb: should be global
 if(NOT HAVE_BISON)
 	find_package(BISON REQUIRED QUIET)
-
-	if(NOT BISON_FOUND)
-		message(FATAL_ERROR "CPPParser requires Bison.")
-	endif()
 endif()
 
-# TODO: we should move this to a global macro somewhere.
-if(BISON_FOUND)
-  add_custom_command(
-    OUTPUT cppBison.h cppBison.cxx
-    COMMAND ${BISON_EXECUTABLE}
-      --defines=cppBison.h -o cppBison.cxx -p cppyy
-      "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.yxx"
-    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.yxx"
-  )
-else()
-  add_custom_command(
-    OUTPUT cppBison.h cppBison.cxx
-    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.h.prebuilt" cppBison.h
-    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.cxx.prebuilt" cppBison.cxx
-    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.h.prebuilt" "${CMAKE_CURRENT_SOURCE_DIR}/cppBison.cxx.prebuilt"
-  )
-endif()
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-include_directories(${CMAKE_CURRENT_LIST_DIR})
+add_bison_target(cppBison.cxx cppBison.yxx DEFINES cppBison.h PREFIX cppyy)
 
-add_library(p3cppParser STATIC
-	${P3CPPPARSER_HEADERS}
-	${P3CPPPARSER_SOURCES}
-)
-add_dependencies(p3cppParser cppParser)
+add_library(p3cppParser STATIC ${P3CPPPARSER_HEADERS} ${P3CPPPARSER_SOURCES})
+target_link_libraries(p3cppParser p3dtoolutil)

+ 4 - 7
dtool/src/dconfig/CMakeLists.txt

@@ -1,13 +1,10 @@
-include_directories(../dtoolutil)
-include_directories(../dtoolbase)
-include_directories(../prc)
-
 set(P3DCONFIG_HEADERS
 	config_dconfig.h dconfig.I dconfig.h)
 
 set(P3DCONFIG_SOURCES
 	config_dconfig.cxx dconfig.cxx)
 
-add_library(p3dconfig STATIC
-	${P3DCONFIG_HEADERS}
-	${P3DCONFIG_SOURCES})
+composite_sources(p3dconfig P3DCONFIG_SOURCES)
+
+add_library(p3dconfig ${P3DCONFIG_HEADERS} ${P3DCONFIG_SOURCES})
+target_link_libraries(p3dconfig p3prc)

+ 3 - 4
dtool/src/dtoolbase/CMakeLists.txt

@@ -59,7 +59,6 @@ set(P3DTOOLBASE_SOURCES
     typedObject.cxx
 )
 
-add_library(p3dtoolbase STATIC
-	${P3DTOOLBASE_HEADERS}
-	${P3DTOOLBASE_SOURCES}
-)
+composite_sources(p3dtoolbase P3DTOOLBASE_SOURCES)
+
+add_library(p3dtoolbase	${P3DTOOLBASE_HEADERS} ${P3DTOOLBASE_SOURCES})

+ 7 - 16
dtool/src/dtoolutil/CMakeLists.txt

@@ -1,15 +1,6 @@
-include_directories(../dtoolbase)
-
-configure_file(pandaVersion.h.cmake
-               pandaVersion.h)
-
-configure_file(checkPandaVersion.h.cmake
-               checkPandaVersion.h)
-
-configure_file(checkPandaVersion.cxx.cmake
-               checkPandaVersion.cxx)
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+configure_file(pandaVersion.h.in pandaVersion.h)
+configure_file(checkPandaVersion.h.in checkPandaVersion.h)
+configure_file(checkPandaVersion.cxx.in checkPandaVersion.cxx)
 
 set(P3DTOOLUTIL_HEADERS
 	${CMAKE_CURRENT_BINARY_DIR}/checkPandaVersion.h
@@ -57,7 +48,7 @@ set(P3DTOOLUTIL_SOURCES
 	win32ArgParser.cxx
 )
 
-add_library(p3dtoolutil STATIC
-	${P3DTOOLUTIL_HEADERS}
-	${P3DTOOLUTIL_SOURCES}
-)
+composite_sources(p3dtoolutil P3DTOOLUTIL_SOURCES)
+
+add_library(p3dtoolutil ${P3DTOOLUTIL_HEADERS} ${P3DTOOLUTIL_SOURCES})
+target_link_libraries(p3dtoolutil p3dtoolbase ${CMAKE_DL_LIBS})

+ 0 - 0
dtool/src/dtoolutil/checkPandaVersion.cxx.cmake → dtool/src/dtoolutil/checkPandaVersion.cxx.in


+ 0 - 0
dtool/src/dtoolutil/checkPandaVersion.h.cmake → dtool/src/dtoolutil/checkPandaVersion.h.in


+ 0 - 0
dtool/src/dtoolutil/pandaVersion.h.cmake → dtool/src/dtoolutil/pandaVersion.h.in


+ 3 - 11
dtool/src/interrogate/CMakeLists.txt

@@ -1,11 +1,3 @@
-include_directories(../cppparser)
-include_directories(../interrogatedb)
-include_directories(../dconfig)
-include_directories(../dtoolutil)
-include_directories(../dtoolbase)
-include_directories(../pystub)
-include_directories(../prc)
-
 set(INTERROGATE_HEADERS
 	functionRemap.h
 	functionWriter.h
@@ -53,9 +45,9 @@ set(INTERROGATE_SOURCES
 	parameterRemapToString.cxx parameterRemapUnchanged.cxx
 	typeManager.cxx)
 
-add_executable(interrogate
-	${INTERROGATE_HEADERS}
-	${INTERROGATE_SOURCES})
+composite_sources(interrogate INTERROGATE_SOURCES)
+
+add_executable(interrogate ${INTERROGATE_HEADERS} ${INTERROGATE_SOURCES})
 target_link_libraries(interrogate
 	p3cppParser p3interrogatedb p3dconfig p3prc p3dtoolutil p3dtoolbase
 	p3pystub ${OPENSSL_LIBRARIES})

+ 4 - 8
dtool/src/interrogatedb/CMakeLists.txt

@@ -1,8 +1,3 @@
-include_directories(../dconfig)
-include_directories(../dtoolutil)
-include_directories(../dtoolbase)
-include_directories(../prc)
-
 set(P3INTERROGATEDB_HEADERS
 	config_interrogatedb.h indexRemapper.h interrogateComponent.I
 	interrogateComponent.h interrogateDatabase.I
@@ -32,6 +27,7 @@ set(P3INTERROGATEDB_SOURCES
 	py_panda.cxx
 	vector_int.cxx)
 
-add_library(p3interrogatedb STATIC
-	${P3INTERROGATEDB_HEADERS}
-	${P3INTERROGATEDB_SOURCES})
+composite_sources(p3interrogatedb P3INTERROGATEDB_SOURCES)
+
+add_library(p3interrogatedb ${P3INTERROGATEDB_HEADERS} ${P3INTERROGATEDB_SOURCES})
+target_link_libraries(p3interrogatedb p3dconfig)

+ 5 - 9
dtool/src/prc/CMakeLists.txt

@@ -1,9 +1,4 @@
-include_directories(../dtoolutil)
-include_directories(../dtoolbase)
-
-configure_file(prc_parameters.h.cmake
-               prc_parameters.h)
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+configure_file(prc_parameters.h.in prc_parameters.h)
 
 set(P3PRC_HEADERS
 	bigEndian.h
@@ -67,6 +62,7 @@ set(P3PRC_SOURCES
 	reversedNumericData.cxx
 	streamReader.cxx streamWrapper.cxx streamWriter.cxx)
 
-add_library(p3prc STATIC
-	${P3PRC_HEADERS}
-	${P3PRC_SOURCES})
+composite_sources(p3prc P3PRC_SOURCES)
+
+add_library(p3prc ${P3PRC_HEADERS} ${P3PRC_SOURCES})
+target_link_libraries(p3prc p3dtoolutil p3dtoolbase)

+ 0 - 0
dtool/src/prc/prc_parameters.h.cmake → dtool/src/prc/prc_parameters.h.in


+ 4 - 10
dtool/src/pystub/CMakeLists.txt

@@ -1,11 +1,5 @@
-include_directories(../dtoolbase)
+set(P3PYSTUB_HEADERS pystub.h)
+set(P3PYSTUB_SOURCES pystub.cxx)
 
-set(P3PYSTUB_HEADERS
-	pystub.h)
-
-set(P3PYSTUB_SOURCES
-	pystub.cxx)
-
-add_library(p3pystub STATIC
-	${P3PYSTUB_HEADERS}
-	${P3PYSTUB_SOURCES})
+add_library(p3pystub STATIC ${P3PYSTUB_HEADERS} ${P3PYSTUB_SOURCES})
+target_link_libraries(p3pystub p3dtoolbase)

+ 2 - 6
panda/src/pandabase/CMakeLists.txt

@@ -1,5 +1,3 @@
-include_directories(../../../dtool/src/dtoolbase)
-
 set(P3PANDABASE_HEADERS
     pandabase.h pandasymbols.h
 )
@@ -8,7 +6,5 @@ set(P3PANDABASE_SOURCES
     pandabase.cxx
 )
 
-add_library(p3pandabase STATIC
-	${P3PANDABASE_HEADERS}
-	${P3PANDABASE_SOURCES}
-)
+add_library(p3pandabase ${P3PANDABASE_HEADERS} ${P3PANDABASE_SOURCES})
+target_link_libraries(p3pandabase p3dtoolbase)