###| CMAKE Kiibohd Controller Source Configurator |###
#
-# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller
+# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller
#
# Released into the Public Domain
#
###
+###
+# CMake Custom Modules Path
+#
+
+set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/Lib/CMake/" )
+
+
###
# Module Overrides (Used in the buildall.bash script)
+
###
# Path Setup
#
# Module Check Function
#
-#| Usage:
-#| PathPrepend( ModulePath <ListOfFamiliesSupported> )
-#| Uses the ${COMPILER_FAMILY} variable
-function( ModuleCompatibility ModulePath )
- foreach( mod_var ${ARGN} )
+function ( ModuleCompatibility ModulePath )
+ foreach ( mod_var ${ARGN} )
if ( ${mod_var} STREQUAL ${COMPILER_FAMILY} )
# Module found, no need to scan further
return()
endif ()
- endforeach()
+ endforeach ()
- message( FATAL_ERROR "${ModulePath} does not support the ${COMPILER_FAMILY} family..." )
-endfunction()
+ message ( FATAL_ERROR "${ModulePath} does not support the ${COMPILER_FAMILY} family..." )
+endfunction ()
###
-# Module Configuration
+# Module Processing
#
-#| Additional options, usually define settings
-add_definitions()
+#| Go through lists of sources and append paths
+#| Usage:
+#| PathPrepend( OutputListOfSources <Prepend Path> <InputListOfSources> )
+macro ( PathPrepend Output SourcesPath )
+ unset ( tmpSource )
-#| Include path for each of the modules
-add_definitions(
- -I${HEAD_DIR}/${ScanModulePath}
- -I${HEAD_DIR}/${MacroModulePath}
- -I${HEAD_DIR}/${OutputModulePath}
- -I${HEAD_DIR}/${DebugModulePath}
-)
+ # Loop through items
+ foreach ( item ${ARGN} )
+ # Set the path
+ set ( tmpSource ${tmpSource} "${SourcesPath}/${item}" )
+ endforeach ()
+ # Finalize by writing the new list back over the old one
+ set ( ${Output} ${tmpSource} )
+endmacro ()
###
-# Module Processing
+# Add Module Macro
#
+# Optional Arg 1: Main Module Check, set to True/1 if adding a main module
+
+function ( AddModule ModuleType ModuleName )
+ # Module path
+ set ( ModulePath ${ModuleType}/${ModuleName} )
+ set ( ModuleFullPath ${HEAD_DIR}/${ModuleType}/${ModuleName} )
+
+ # Include setup.cmake file
+ include ( ${ModuleFullPath}/setup.cmake )
+
+ # Check if this is a main module add
+ foreach ( extraArg ${ARGN} )
+ # Make sure this isn't a submodule
+ if ( DEFINED SubModule )
+ message ( FATAL_ERROR
+ "The '${ModuleName}' module is not a stand-alone module, and requires further setup."
+ )
+ endif ()
+ endforeach ()
-#| Go through lists of sources and append paths
-#| Usage:
-#| PathPrepend( OutputListOfSources <Prepend Path> <InputListOfSources> )
-macro( PathPrepend Output SourcesPath )
- unset( tmpSource )
+ # PathPrepend to give proper paths to each of the source files
+ PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} )
- # Loop through items
- foreach( item ${ARGN} )
- # Set the path
- set( tmpSource ${tmpSource} "${SourcesPath}/${item}" )
- endforeach()
+ # Check the current scope to see if a sub-module added some source files
+ # Append each of the sources to each type of module srcs list
+ set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} )
- # Finalize by writing the new list back over the old one
- set( ${Output} ${tmpSource} )
-endmacro()
+ # Add .h files
+ add_definitions ( -I${ModuleFullPath} )
+ # Check module compatibility
+ ModuleCompatibility( ${ModulePath} ${ModuleCompatibility} )
-#| Scan Module
-include ( "${ScanModulePath}/setup.cmake" )
-PathPrepend( SCAN_SRCS ${ScanModulePath} ${SCAN_SRCS} )
+ # Check if this is a main module add
+ foreach ( extraArg ${ARGN} )
+ # Display detected source files
+ if ( NOT DEFINED SubModule )
+ message ( STATUS "Detected ${ModuleType} Module Source Files:" )
+ message ( "${${ModuleType}_SRCS}" )
+ endif ()
+ endforeach ()
+
+ # Check for any capabilities.kll files in the Module
+ set ( kll_capabilities_file "${ModuleFullPath}/capabilities.kll" )
+ if ( EXISTS ${kll_capabilities_file} )
+ # Add the kll file and any submodule kll files to the running list
+ set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} ${kll_capabilities_file} )
+ endif ()
-#| Macro Module
-include ( "${MacroModulePath}/setup.cmake" )
-PathPrepend( MACRO_SRCS ${MacroModulePath} ${MACRO_SRCS} )
-#| Output Module
-include ( "${OutputModulePath}/setup.cmake" )
-PathPrepend( OUTPUT_SRCS ${OutputModulePath} ${OUTPUT_SRCS} )
+ # Finally, add the sources and kll files to the parent scope (i.e. return)
+ set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} PARENT_SCOPE )
+ set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} PARENT_SCOPE )
+endfunction ()
-#| Debugging Module
-include ( "${DebugModulePath}/setup.cmake" )
-PathPrepend( DEBUG_SRCS ${DebugModulePath} ${DEBUG_SRCS} )
+#| Add main modules
+AddModule ( Scan ${ScanModule} 1 )
+AddModule ( Macro ${MacroModule} 1 )
+AddModule ( Output ${OutputModule} 1 )
+AddModule ( Debug ${DebugModule} 1 )
-#| Default Map
-# TODO Add support for different defaultMaps
-configure_file( "${ScanModulePath}/defaultMap.h" defaultMap.h )
-#| Print list of all module sources
-message( STATUS "Detected Scan Module Source Files:" )
-message( "${SCAN_SRCS}" )
-message( STATUS "Detected Macro Module Source Files:" )
-message( "${MACRO_SRCS}" )
-message( STATUS "Detected Output Module Source Files:" )
-message( "${OUTPUT_SRCS}" )
-message( STATUS "Detected Debug Module Source Files:" )
-message( "${DEBUG_SRCS}" )
+###
+# CMake Module Checking
+#
+find_package ( Git REQUIRED )
+find_package ( Ctags ) # Optional
#
#| Manufacturer name
-set( MANUFACTURER "Kiibohd" )
+set ( MANUFACTURER "Kiibohd" )
#| Serial Number
#| Modified
#| Takes a bit of work to extract the "M " using CMake, and not using it if there are no modifications
-execute_process( COMMAND git status -s -uno --porcelain
+execute_process ( COMMAND ${GIT_EXECUTABLE} status -s -uno --porcelain
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Modified_INFO
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
-string( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH )
-set( Git_Modified_Status "Clean" )
+string ( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH )
+set ( Git_Modified_Status "Clean" )
if ( ${Git_Modified_LENGTH} GREATER 2 )
- string( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO )
- set( Git_Modified_Status "Dirty" )
+ string ( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO )
+ set ( Git_Modified_Status "Dirty" )
endif ()
+#| List of modified files
+execute_process ( COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE Git_Modified_Files
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+string ( REGEX REPLACE "\n" "\\\\r\\\\n\\\\t" Git_Modified_Files "${Git_Modified_Files}" )
+set ( Git_Modified_Files "\\r\\n\\t${Git_Modified_Files}" )
+
#| Branch
-execute_process( COMMAND git rev-parse --abbrev-ref HEAD
+execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Branch_INFO
ERROR_QUIET
)
#| Date
-execute_process( COMMAND git show -s --format=%ci
+execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Date_INFO
ERROR_QUIET
)
#| Commit Author and Email
-execute_process( COMMAND git show -s --format="%cn <%ce>"
+execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Author
ERROR_QUIET
)
#| Commit Revision
-execute_process( COMMAND git show -s --format=%H
+execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%H
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Revision
ERROR_QUIET
)
#| Origin URL
-execute_process( COMMAND git config --get remote.origin.url
+execute_process ( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Origin_URL
ERROR_QUIET
)
#| Build Date
-execute_process( COMMAND "date" "+%Y-%m-%d %T %z"
+execute_process ( COMMAND "date" "+%Y-%m-%d %T %z"
OUTPUT_VARIABLE Build_Date
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
#| Last Commit Date
-set( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" )
+set ( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" )
#| Uses CMake variables to include as defines
#| Primarily for USB configuration
-configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h )
+configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h )
###
# Source Defines
#
-set( SRCS
+set ( SRCS
${MAIN_SRCS}
${COMPILER_SRCS}
- ${SCAN_SRCS}
- ${MACRO_SRCS}
- ${OUTPUT_SRCS}
- ${DEBUG_SRCS}
+ ${Scan_SRCS}
+ ${Macro_SRCS}
+ ${Output_SRCS}
+ ${Debug_SRCS}
)
#| Directories to include by default
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
-
-
-
-###
-# Module Compatibility Check
-#
-
-#| Check for whether the set modules are compatible with the specified compiler family
-ModuleCompatibility( ${ScanModulePath} ${ScanModuleCompatibility} )
-ModuleCompatibility( ${MacroModulePath} ${MacroModuleCompatibility} )
-ModuleCompatibility( ${OutputModulePath} ${OutputModuleCompatibility} )
-ModuleCompatibility( ${DebugModulePath} ${DebugModuleCompatibility} )
-
-
-
-###
-# CMake Module Checking
-#
-find_package( Git REQUIRED )
-
-
-###
-# Build Targets
-#
-
-#| Create the .ELF file
-set( TARGET_ELF ${TARGET}.elf )
-add_executable( ${TARGET_ELF} ${SRCS} )
-
-
-#| .ELF Properties
-set_target_properties( ${TARGET_ELF} PROPERTIES
- LINK_FLAGS ${LINKER_FLAGS}
- SUFFIX "" # XXX Force Windows to keep the .exe off
-)
-
-
-#| Convert the .ELF into a .HEX to load onto the Teensy
-set( TARGET_HEX ${TARGET}.hex )
-add_custom_command( TARGET ${TARGET_ELF} POST_BUILD
- COMMAND ${CMAKE_OBJCOPY} ${HEX_FLAGS} ${TARGET_ELF} ${TARGET_HEX}
- COMMENT "Creating load file for Flash: ${TARGET_HEX}"
-)
-
-
-#| Generate the Extended .LSS
-set( TARGET_LSS ${TARGET}.lss )
-add_custom_command( TARGET ${TARGET_ELF} POST_BUILD
- COMMAND ${CMAKE_OBJDUMP} ${LSS_FLAGS} ${TARGET_ELF} > ${TARGET_LSS}
- COMMENT "Creating Extended Listing: ${TARGET_LSS}"
-)
-
-
-#| Generate the Symbol Table .SYM
-set( TARGET_SYM ${TARGET}.sym )
-add_custom_command( TARGET ${TARGET_ELF} POST_BUILD
- COMMAND ${CMAKE_NM} -n ${TARGET_ELF} > ${TARGET_SYM}
- COMMENT "Creating Symbol Table: ${TARGET_SYM}"
-)
-
-
-
-###
-# Size Information
-#
-
-#| After Changes Size Information
-#| TODO Do lookup on Flash and RAM sizes and do % used
-add_custom_target( SizeAfter ALL
- COMMAND ${CMAKE_SIZE} --target=${FORMAT} ${TARGET_HEX} ${TARGET_ELF}
- DEPENDS ${TARGET_ELF}
- COMMENT "Size after generation\n\tFlash Usage: data (hex)\n\t RAM Usage: data (elf)"
-)
+include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
###
-# Setup Loader Script and Program
+# ctag Generation
#
-
-#| Provides the user with the correct teensy-loader-cli command for the built .HEX file
-#| Windows
-if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
- configure_file( LoadFile/winload load NEWLINE_STYLE UNIX )
-#| Default
-else()
- configure_file( LoadFile/load load NEWLINE_STYLE UNIX )
-endif()
-
+if ( CTAGS_EXECUTABLE )
+ # Populate list of directories for ctags to parse
+ # NOTE: Doesn't support dots in the folder names...
+ foreach ( filename ${SRCS} )
+ string ( REGEX REPLACE "/[a-zA-Z0-9_-]+.c$" "" pathglob ${filename} )
+ file ( GLOB filenames "${pathglob}/*.c" )
+ set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} )
+ file ( GLOB filenames "${pathglob}/*.h" )
+ set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} )
+ endforeach ()
+
+ # Generate the ctags
+ execute_process ( COMMAND ctags --fields=+l ${CTAG_PATHS}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+endif ()