cmake: Reorganize macros, and cleanup related files (add docs, etc)

This commit is contained in:
kestred 2013-12-21 13:44:05 -07:00
parent 3fa270b302
commit c579f87007
11 changed files with 282 additions and 217 deletions

View File

@ -3,18 +3,25 @@
cmake_minimum_required(VERSION 2.8.4)
project(Panda3D)
# Set Panda's CMake module path
# Add generic modules to cmake module path,
# and add Panda3D specific modules to cmake module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/macros/")
# This is where dtool_config.h gets generated.
# Include global modules
include(AutoInclude) # Implements automatic include_directories finding
include(AddBisonTarget) # Defines add_bison_target function
include(CompositeSources) # Defines composite_sources function
include(ConfigPackage) # Defines config_package function
include(Interrogate) # Defines target_interrogate AND add_python_module
# Add the include path for source and header files generated by CMake
include_directories("${CMAKE_BINARY_DIR}")
# Configure Panda3D
include(dtool/PandaMacros.cmake)
include(dtool/PandaVersion.cmake)
include(dtool/Packages.cmake)
include(dtool/Package.cmake)
include(dtool/Config.cmake)
include(dtool/Interrogate.cmake)
# Determine which trees to build.
option(BUILD_DTOOL "Build the dtool source tree." ON)

View File

@ -0,0 +1,73 @@
# Filename: AddBisonTarget.cmake
# Description: This file defines the function add_bison_target which instructs
# cmake to use bison on an input .yxx file. If bison is not available on
# the system, add_bison_target tries to use .prebuilt .cxx files instead.
#
# Usage:
# add_bison_target(output_cxx input_yxx [DEFINES output_h] [PREFIX prefix])
#
# Define add_bison_target()
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)
get_source_file_property(input_yxx "${input_yxx}" LOCATION)
# 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)

View File

@ -0,0 +1,101 @@
# Filename: CompositeSources.cmake
# Description: This file defines the function composite_sources which looks at
# a provided list of sources, generates _compositeN.cxx, and appends the
# composites to the list. The original files in the list are marked as headers
# so that they will be available in an IDE, but not compiled at build time.
#
# Usage:
# composite_sources(target source_var)
#
# Example:
# set(MY_SOURCES a.cxx b.cxx c.cxx)
# composite_sources(my_lib MY_SOURCES)
# add_library(my_lib ${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.
#
# Settings for composite builds. Should be moved to Config.cmake?
set(COMPOSITE_SOURCE_LIMIT "30" CACHE STRING
"Setting this to a value higher than 1 will enable unity builds, also
known as SCU (single compilation unit). A high value will speed up the
build dramatically but will be more memory intensive than a low value.")
set(COMPOSITE_SOURCE_EXTENSIONS "cxx;c;mm" CACHE STRING
"Only files of these extensions will be added to composite files.")
set(COMPOSITE_GENERATOR "${CMAKE_SOURCE_DIR}/cmake/scripts/MakeComposite.cmake")
# Define composite_sources()
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)

View File

@ -1,4 +1,4 @@
# Filename: ConfigurePackage.cmake
# Filename: ConfigPackage.cmake
# Author: kestred (30 Nov, 2013)
#
# This modules defines a function which finds and configures libraries
@ -6,6 +6,9 @@
#
# Assumes the file has already been found with find_package().
#
# Usage:
# config_package(package_name)
#
# The following variables can be set to override the cached values of USE_XYZZY
# CONFIG_DISABLE_EVERYTHING - always set USE_XYZZY to false
# CONFIG_DISABLE_MISSING - set USE_XYZZY to false if it was not found

View File

@ -1,9 +1,11 @@
# Filename: Interrogate.cmake
#
# dtool/Interrogate.cmake
# Description: This file contains macros and functions that are used to invoke
# interrogate, to generate wrappers for Python and/or other languages.
#
# This file contains macros and functions that are used to invoke
# interrogate, in order to generate wrappers for Python and/or other
# languages.
# Functions:
# target_interrogate(target [ALL] [source1 [source2 ...]])
# add_python_module(module [lib1 [lib2 ...]])
#
set(IGATE_FLAGS ${INTERROGATE_OPTIONS} -DCPPPARSER -D__cplusplus -Dvolatile -Dmutable)

9
cmake/macros/README.md Normal file
View File

@ -0,0 +1,9 @@
Directory Info
--------------
**Directory:** /cmake/macros
**License:** Unlicense
**Description:** This directory is used for CMake modules which may be _unsafe_
to use outside of a Panda3D project. These modules may rely on Panda3D specific
cmake variables, Panda3D's directory structure, or some other dependency.
They are not intended to be included in other projects directly, though you
are free to copy and adapt them to your own needs.

View File

@ -0,0 +1,50 @@
# Filename: AutoInclude.cmake
# Description: This file backports the CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
# introduced in CMake 2.8.11 to previous versions of cmake, and enables the
# behavior by default.
#
# 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)
if(lib_interface_dirs)
list(APPEND interface_dirs ${lib_interface_dirs})
endif()
endforeach()
list(REMOVE_DUPLICATES interface_dirs)
#NB. target_include_directories is new in 2.8.8.
#target_include_directories("${target}" ${interface_dirs})
include_directories(${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(${target} ${ARGN})
endfunction()
else()
# 2.8.11 supports this natively.
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)

7
cmake/modules/README.md Normal file
View File

@ -0,0 +1,7 @@
Directory Info
--------------
**Directory:** /cmake/modules
**License:** Unlicense
**Description:** This directory is used for standard CMake modules which are safe
to use outside of a Panda3D project. This should be the normal location for
most FindXYZZY packages that are written for Panda3D.

View File

@ -1,5 +1,13 @@
# 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"
# Filename: MakeComposite.cmake
#
# Description: When run, creates a single C++ file which includes multiple
# other C++ files, to help facilitate unity builds.
# Unity builds provide significantly increased compile speed.
#
# Usage:
# 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)

10
cmake/scripts/README.md Normal file
View File

@ -0,0 +1,10 @@
Directory Info
--------------
**Directory:** /cmake/scripts
**License:** Unlicense
**Description:** This directory is used for cmake files which are not meant to
be included using CMake's normal include() directive. Typically, files in this
directory will be invoked as a custom command/target in the form of:
```
cmake -P <CustomScriptName.cmake> [... other options ...]
```

View File

@ -1,205 +0,0 @@
# Settings for composite builds. Should be moved to Config.cmake?
set(COMPOSITE_SOURCE_LIMIT "30" CACHE STRING
"Setting this to a value higher than 1 will enable unity builds, also
known as SCU (single compilation unit). A high value will speed up the
build dramatically but will be more memory intensive than a low value.")
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")
#
# 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)
get_source_file_property(input_yxx "${input_yxx}" LOCATION)
# 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)
if(lib_interface_dirs)
list(APPEND interface_dirs ${lib_interface_dirs})
endif()
endforeach()
list(REMOVE_DUPLICATES interface_dirs)
#NB. target_include_directories is new in 2.8.8.
#target_include_directories("${target}" ${interface_dirs})
include_directories(${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(${target} ${ARGN})
endfunction()
else()
# 2.8.11 supports this natively.
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)