|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- #.rst:
- # FindBANG
- # --------
- #
- # Tools for building BANG C files: libraries and build dependencies.
- #
- # This script locates the CAMBRICON BANG C tools. It should work on linux,
- # windows, and mac and should be reasonably up to date with BANG C
- # releases.
- #
- # This script makes use of the standard find_package arguments of
- # <VERSION>, REQUIRED and QUIET. BANG_FOUND will report if an
- # acceptable version of BANG was found.
- #
- # The following variables affect the behavior of the macros in the
- # script (in alphebetical order). Note that any of these flags can be
- # changed multiple times in the same directory before calling
- #
- # BANG_CNCC_FLAGS
- # -- Additional CNCC command line arguments. NOTE: multiple arguments must be
- # semi-colon delimited (e.g. --bang-mlu-arch=xxx;-Wall)
- #
- # BANG_TARGET_CPU_ARCH
- # -- Specify the name of the class of CPU architecture for which the input
- # files must be compiled (e.g. specify BANG_TARGET_CPU_ARCH=armv8a,
- # will append --target=armv8a to BANG_CNCC_FLAGS)
- #
- # This code is licensed under the MIT License. See the FindBANG.cmake script
- # for the text of the license.
-
- # The MIT License
- #
- # License for the specific language governing rights and limitations under
- # Permission is hereby granted, free of charge, to any person obtaining a
- # copy of this software and associated documentation files (the "Software"),
- # to deal in the Software without restriction, including without limitation
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
- # and/or sell copies of the Software, and to permit persons to whom the
- # Software is furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included
- # in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- # DEALINGS IN THE SOFTWARE.
- #
- # MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
- #
- # Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
- #
- # Unless required by applicable law or agreed to in writing,
- # software distributed under the License is distributed on an
- # "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- #
- # This file has been modified by Megvii ("Megvii Modifications").
- # All Megvii Modifications are Copyright (C) 2014-2019 Megvii Inc. All rights reserved
- ###############################################################################
-
- # FindBANG.cmake
-
- ###############################################################################
- # Check for required components
- ###############################################################################
- set(BANG_FOUND TRUE)
-
- ###############################################################################
- # This macro helps us find the location of helper files we will need the full path to
- ###############################################################################
- macro(BANG_FIND_HELPER_FILE _name _extension)
- set(_full_name "${_name}.${_extension}")
- # CMAKE_CURRENT_LIST_FILE contains the full path to the file currently being
- # processed. Using this variable, we can pull out the current path, and
- # provide a way to get access to the other files we need local to here.
- get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
- set(BANG_${_name} "${CMAKE_CURRENT_LIST_DIR}/${_full_name}")
- if(NOT EXISTS "${BANG_${_name}}")
- set(error_message "${_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}")
- if(BANG_FIND_REQUIRED)
- message(FATAL_ERROR "${error_message}")
- else()
- if(NOT BANG_FIND_QUIETLY)
- message(STATUS "${error_message}")
- endif()
- endif()
- endif()
- # Set this variable as internal, so the user isn't bugged with it.
- set(BANG_${_name} ${BANG_${_name}} CACHE INTERNAL "Location of ${_full_name}" FORCE)
- endmacro()
-
- bang_find_helper_file(parse_cnbin cmake)
- bang_find_helper_file(make2cmake cmake)
- bang_find_helper_file(run_cncc cmake)
-
- ###############################################################################
- # Add include directories to pass to the cncc command.
- ###############################################################################
- macro(BANG_INCLUDE_DIRECTORIES)
- foreach(dir ${ARGN})
- list(APPEND BANG_CNCC_INCLUDE_ARGS_USER -I${dir})
- endforeach()
- endmacro()
-
- ##############################################################################
- # Separate the OPTIONS out from the sources
- ##############################################################################
- macro(BANG_GET_SOURCES_AND_OPTIONS _sources _cmake_options _options)
- set( ${_sources} )
- set( ${_cmake_options} )
- set( ${_options} )
- set( _found_options FALSE )
- foreach(arg ${ARGN})
- if("x${arg}" STREQUAL "xOPTIONS")
- set( _found_options TRUE )
- elseif(
- "x${arg}" STREQUAL "xWIN32" OR
- "x${arg}" STREQUAL "xMACOSX_BUNDLE" OR
- "x${arg}" STREQUAL "xEXCLUDE_FROM_ALL" OR
- "x${arg}" STREQUAL "xSTATIC" OR
- "x${arg}" STREQUAL "xSHARED" OR
- "x${arg}" STREQUAL "xMODULE"
- )
- list(APPEND ${_cmake_options} ${arg})
- else()
- if ( _found_options )
- list(APPEND ${_options} ${arg})
- else()
- # Assume this is a file
- list(APPEND ${_sources} ${arg})
- endif()
- endif()
- endforeach()
- endmacro()
-
- ##############################################################################
- # Parse the OPTIONS from ARGN and set the variables prefixed by _option_prefix
- ##############################################################################
- macro(BANG_PARSE_CNCC_OPTIONS _option_prefix)
- set( _found_config )
- foreach(arg ${ARGN})
- # Determine if we are dealing with a perconfiguration flag
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- if (arg STREQUAL "${config_upper}")
- set( _found_config _${arg})
- # Set arg to nothing to keep it from being processed further
- set( arg )
- endif()
- endforeach()
-
- if ( arg )
- list(APPEND ${_option_prefix}${_found_config} "${arg}")
- endif()
- endforeach()
- endmacro()
-
- #####################################################################
- # BANG_INCLUDE_CNCC_DEPENDENCIES
- # So we want to try and include the dependency file if it exists. If
- # it doesn't exist then we need to create an empty one, so we can
- # include it.
- # If it does exist, then we need to check to see if all the files it
- # depends on exist. If they don't then we should clear the dependency
- # file and regenerate it later. This covers the case where a header
- # file has disappeared or moved.
- #####################################################################
- macro(BANG_INCLUDE_CNCC_DEPENDENCIES dependency_file)
- set(BANG_CNCC_DEPEND)
- set(BANG_CNCC_DEPEND_REGENERATE FALSE)
-
- # Include the dependency file. Create it first if it doesn't exist . The
- # INCLUDE puts a dependency that will force CMake to rerun and bring in the
- # new info when it changes. DO NOT REMOVE THIS (as I did and spent a few
- # hours figuring out why it didn't work.
- if(NOT EXISTS ${dependency_file})
- file(WRITE ${dependency_file} "#FindBANG.cmake generated file. Do not edit.\n")
- endif()
- # Always include this file to force CMake to run again next
- # invocation and rebuild the dependencies.
- #message("including dependency_file = ${dependency_file}")
- include(${dependency_file})
-
- # Now we need to verify the existence of all the included files
- # here. If they aren't there we need to just blank this variable and
- # make the file regenerate again.
- if(BANG_CNCC_DEPEND)
- #message("BANG_CNCC_DEPEND found")
- foreach(f ${BANG_CNCC_DEPEND})
- # message("searching for ${f}")
- if(NOT EXISTS ${f})
- #message("file ${f} not found")
- set(BANG_CNCC_DEPEND_REGENERATE TRUE)
- endif()
- endforeach()
- else()
- #message("BANG_CNCC_DEPEND false")
- # No dependencies, so regenerate the file.
- set(BANG_CNCC_DEPEND_REGENERATE TRUE)
- endif()
-
- #message("BANG_CNCC_DEPEND_REGENERATE = ${BANG_CNCC_DEPEND_REGENERATE}")
- # No incoming dependencies, so we need to generate them. Make the
- # output depend on the dependency file itself, which should cause the
- # rule to re-run.
- if(BANG_CNCC_DEPEND_REGENERATE)
- set(BANG_CNCC_DEPEND ${dependency_file})
- #message("Generating an empty dependency_file: ${dependency_file}")
- file(WRITE ${dependency_file} "#FindBANG.cmake generated file. Do not edit.\n")
- endif()
-
- endmacro()
-
- ###############################################################################
- # Helper to add the include directory for BANG only once
- ###############################################################################
- function(BANG_ADD_BANG_INCLUDE_ONCE)
- get_directory_property(_include_directories INCLUDE_DIRECTORIES)
- set(_add TRUE)
- if(_include_directories)
- foreach(dir ${_include_directories})
- if("${dir}" STREQUAL "${BANG_INCLUDE_DIRS}")
- set(_add FALSE)
- endif()
- endforeach()
- endif()
- if(_add)
- include_directories(${BANG_INCLUDE_DIRS})
- endif()
- endfunction()
-
- ##############################################################################
- # Build the shared library
- ##############################################################################
- function(BANG_BUILD_SHARED_LIBRARY shared_flag)
- set(cmake_args ${ARGN})
- # If SHARED, MODULE, or STATIC aren't already in the list of arguments, then
- # add SHARED or STATIC based on the value of BUILD_SHARED_LIBS.
- list(FIND cmake_args SHARED _bang_found_SHARED)
- list(FIND cmake_args MODULE _bang_found_MODULE)
- list(FIND cmake_args STATIC _bang_found_STATIC)
- if( _bang_found_SHARED GREATER -1 OR
- _bang_found_MODULE GREATER -1 OR
- _bang_found_STATIC GREATER -1)
- set(_bang_build_shared_libs)
- else()
- if (BUILD_SHARED_LIBS)
- set(_bang_build_shared_libs SHARED)
- else()
- set(_bang_build_shared_libs STATIC)
- endif()
- endif()
- set(${shared_flag} ${_bang_build_shared_libs} PARENT_SCOPE)
- endfunction()
-
- ##############################################################################
- # Helper to avoid clashes of files with the same basename but different paths.
- # This doesn't attempt to do exactly what CMake internals do, which is to only
- # add this path when there is a conflict, since by the time a second collision
- # in names is detected it's already too late to fix the first one. For
- # consistency sake the relative path will be added to all files.
- ##############################################################################
- function(BANG_COMPUTE_BUILD_PATH path build_path)
- #message("BANG_COMPUTE_BUILD_PATH([${path}] ${build_path})")
- # Only deal with CMake style paths from here on out
- file(TO_CMAKE_PATH "${path}" bpath)
- if (IS_ABSOLUTE "${bpath}")
- # Absolute paths are generally unnessary, especially if something like
- # file(GLOB_RECURSE) is used to pick up the files.
-
- string(FIND "${bpath}" "${CMAKE_CURRENT_BINARY_DIR}" _binary_dir_pos)
- if (_binary_dir_pos EQUAL 0)
- file(RELATIVE_PATH bpath "${CMAKE_CURRENT_BINARY_DIR}" "${bpath}")
- else()
- file(RELATIVE_PATH bpath "${CMAKE_CURRENT_SOURCE_DIR}" "${bpath}")
- endif()
- endif()
-
- # This recipe is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the
- # CMake source.
-
- # Remove leading /
- string(REGEX REPLACE "^[/]+" "" bpath "${bpath}")
- # Avoid absolute paths by removing ':'
- string(REPLACE ":" "_" bpath "${bpath}")
- # Avoid relative paths that go up the tree
- string(REPLACE "../" "__/" bpath "${bpath}")
- # Avoid spaces
- string(REPLACE " " "_" bpath "${bpath}")
-
- # Strip off the filename. I wait until here to do it, since removin the
- # basename can make a path that looked like path/../basename turn into
- # path/.. (notice the trailing slash).
- get_filename_component(bpath "${bpath}" PATH)
-
- set(${build_path} "${bpath}" PARENT_SCOPE)
- #message("${build_path} = ${bpath}")
- endfunction()
-
- ##############################################################################
- # Compute the filename to be used by BANG_LINK_SEPARABLE_COMPILATION_OBJECTS
- ##############################################################################
- function(BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME output_file_var bang_target object_files)
- if (object_files)
- set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
- set(output_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${bang_target}.dir/${CMAKE_CFG_INTDIR}/${bang_target}_intermediate_link${generated_extension}")
- else()
- set(output_file)
- endif()
-
- set(${output_file_var} "${output_file}" PARENT_SCOPE)
- endfunction()
-
- ##############################################################################
- # Setup the build rule for the separable compilation intermediate link file.
- ##############################################################################
- function(BANG_LINK_SEPARABLE_COMPILATION_OBJECTS output_file bang_target options object_files)
- if (object_files)
-
- set_source_files_properties("${output_file}"
- PROPERTIES
- EXTERNAL_OBJECT TRUE # This is an object file not to be compiled, but only
- # be linked.
- GENERATED TRUE # This file is generated during the build
- )
-
- # For now we are ignoring all the configuration specific flags.
- set(cncc_flags)
- BANG_PARSE_CNCC_OPTIONS(cncc_flags ${options})
-
- # If -ccbin, --compiler-bindir has been specified, don't do anything. Otherwise add it here.
- list( FIND cncc_flags "-ccbin" ccbin_found0 )
- list( FIND cncc_flags "--compiler-bindir" ccbin_found1 )
- if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND BANG_HOST_COMPILER )
- # Match VERBATIM check below.
- if(BANG_HOST_COMPILER MATCHES "\\$\\(VCInstallDir\\)")
- list(APPEND cncc_flags -ccbin "\"${BANG_HOST_COMPILER}\"")
- else()
- list(APPEND cncc_flags -ccbin "${BANG_HOST_COMPILER}")
- endif()
- endif()
-
- # Create a list of flags specified by BANG_CNCC_FLAGS_${CONFIG} and CMAKE_${BANG_C_OR_CXX}_FLAGS*
- set(config_specific_flags)
- set(flags)
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- # Add config specific flags
- foreach(f ${BANG_CNCC_FLAGS_${config_upper}})
- list(APPEND config_specific_flags $<$<CONFIG:${config}>:${f}>)
- endforeach()
- set(important_host_flags)
- _bang_get_important_host_flags(important_host_flags "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
- foreach(f ${important_host_flags})
- list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>)
- endforeach()
- endforeach()
- # Add CMAKE_${BANG_C_OR_CXX}_FLAGS
- set(important_host_flags)
- _bang_get_important_host_flags(important_host_flags "${CMAKE_${BANG_C_OR_CXX}_FLAGS}")
- foreach(f ${important_host_flags})
- list(APPEND flags -Xcompiler ${f})
- endforeach()
-
- # Add our general BANG_CNCC_FLAGS with the configuration specifig flags
- set(cncc_flags ${BANG_CNCC_FLAGS} ${config_specific_flags} ${cncc_flags})
-
- file(RELATIVE_PATH output_file_relative_path "${CMAKE_BINARY_DIR}" "${output_file}")
-
- # Some generators don't handle the multiple levels of custom command
- # dependencies correctly (obj1 depends on file1, obj2 depends on obj1), so
- # we work around that issue by compiling the intermediate link object as a
- # pre-link custom command in that situation.
- set(do_obj_build_rule TRUE)
- if (MSVC_VERSION GREATER 1599 AND MSVC_VERSION LESS 1800)
- # VS 2010 and 2012 have this problem.
- set(do_obj_build_rule FALSE)
- endif()
-
- set(_verbatim VERBATIM)
- if(cncc_flags MATCHES "\\$\\(VCInstallDir\\)")
- set(_verbatim "")
- endif()
-
- if (do_obj_build_rule)
- add_custom_command(
- OUTPUT ${output_file}
- DEPENDS ${object_files}
- COMMAND ${BANG_CNCC_EXECUTABLE} ${cncc_flags} -dlink ${object_files} -o ${output_file}
- ${flags}
- COMMENT "Building CNCC intermediate link file ${output_file_relative_path}"
- ${_verbatim}
- )
- else()
- get_filename_component(output_file_dir "${output_file}" DIRECTORY)
- add_custom_command(
- TARGET ${bang_target}
- PRE_LINK
- COMMAND ${CMAKE_COMMAND} -E echo "Building CNCC intermediate link file ${output_file_relative_path}"
- COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}"
- COMMAND ${BANG_CNCC_EXECUTABLE} ${cncc_flags} ${flags} -dlink ${object_files} -o "${output_file}"
- ${_verbatim}
- )
- endif()
- endif()
- endfunction()
-
- ##############################################################################
- # This helper macro populates the following variables and setups up custom
- # commands and targets to invoke the cncc compiler to generate C or MLISA source
- # dependent upon the format parameter.
- # INPUT:
- # bang_target - Target name
- # format - MLISA, CNBIN, CNFATBIN or OBJ
- # FILE1 .. FILEN - The remaining arguments are the sources to be wrapped.
- # OPTIONS - Extra options to CNCC
- # OUTPUT:
- # generated_files - List of generated files
- ##############################################################################
- macro(BANG_WRAP_SRCS bang_target format generated_files)
- # Set up all the command line flags here, so that they can be overridden on a per target basis.
-
- set(cncc_flags "")
-
- set(BANG_C_OR_CXX CXX)
-
- set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
-
- if(BANG_TARGET_CPU_ARCH)
- set(cncc_flags ${cncc_flags} "--target=${BANG_TARGET_CPU_ARCH}")
- endif()
-
- set( BANG_build_configuration "${CMAKE_BUILD_TYPE}")
-
- # Get the include directories for this directory and use them for our cncc command.
- # Remove duplicate entries which may be present since include_directories
- # in CMake >= 2.8.8 does not remove them.
- get_directory_property(BANG_CNCC_INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
- list(REMOVE_DUPLICATES BANG_CNCC_INCLUDE_DIRECTORIES)
- if(BANG_CNCC_INCLUDE_DIRECTORIES)
- foreach(dir ${BANG_CNCC_INCLUDE_DIRECTORIES})
- list(APPEND BANG_CNCC_INCLUDE_ARGS -I${dir})
- endforeach()
- endif()
-
- # Reset these variables
- set(BANG_WRAP_OPTION_CNCC_FLAGS)
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- set(BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper})
- endforeach()
-
- BANG_GET_SOURCES_AND_OPTIONS(_bang_wrap_sources _bang_wrap_cmake_options _bang_wrap_options ${ARGN})
- BANG_PARSE_CNCC_OPTIONS(BANG_WRAP_OPTION_CNCC_FLAGS ${_bang_wrap_options})
-
- # Figure out if we are building a shared library. BUILD_SHARED_LIBS is
- # respected in BANG_ADD_LIBRARY.
- set(_bang_build_shared_libs FALSE)
- # SHARED, MODULE
- list(FIND _bang_wrap_cmake_options SHARED _bang_found_SHARED)
- list(FIND _bang_wrap_cmake_options MODULE _bang_found_MODULE)
- if(_bang_found_SHARED GREATER -1 OR _bang_found_MODULE GREATER -1)
- set(_bang_build_shared_libs TRUE)
- endif()
- # STATIC
- list(FIND _bang_wrap_cmake_options STATIC _bang_found_STATIC)
- if(_bang_found_STATIC GREATER -1)
- set(_bang_build_shared_libs FALSE)
- endif()
-
- # BANG_HOST_FLAGS
- if(_bang_build_shared_libs)
- # If we are setting up code for a shared library, then we need to add extra flags for
- # compiling objects for shared libraries.
- set(BANG_HOST_SHARED_FLAGS ${CMAKE_SHARED_LIBRARY_${BANG_C_OR_CXX}_FLAGS})
- else()
- set(BANG_HOST_SHARED_FLAGS)
- endif()
- # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We
- # always need to set the SHARED_FLAGS, though.
- set(_bang_host_flags "set(CMAKE_HOST_FLAGS ${CMAKE_${BANG_C_OR_CXX}_FLAGS} ${BANG_HOST_SHARED_FLAGS})")
-
- set(_bang_cncc_flags_config "# Build specific configuration flags")
- # Loop over all the configuration types to generate appropriate flags for run_cncc.cmake
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS
- # we convert the strings to lists (like we want).
-
- set(_bang_C_FLAGS "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
- set(_bang_host_flags "${_bang_host_flags}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_bang_C_FLAGS})")
-
- # Note that if we ever want BANG_CNCC_FLAGS_<CONFIG> to be string (instead of a list
- # like it is currently), we can remove the quotes around the
- # ${BANG_CNCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_<CONFIG> variable.
- set(_bang_cncc_flags_config "${_bang_cncc_flags_config}\nset(BANG_CNCC_FLAGS_${config_upper} ${BANG_CNCC_FLAGS_${config_upper}} ;; ${BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper}})")
- endforeach()
-
- # Process the C++11 flag. If the host sets the flag, we need to add it to cncc and
- # remove it from the host. This is because -Xcompile -std=c++ will choke cncc (it uses
- # the C preprocessor). In order to get this to work correctly, we need to use cncc's
- # specific c++11 flag.
- if( "${_bang_host_flags}" MATCHES "-std=c\\+\\+11")
- # Add the c++11 flag to cncc if it isn't already present. Note that we only look at
- # the main flag instead of the configuration specific flags.
- if( NOT "${BANG_CNCC_FLAGS}" MATCHES "-std;c\\+\\+11" )
- list(APPEND cncc_flags -std=c++11)
- endif()
- string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _bang_host_flags "${_bang_host_flags}")
- endif()
-
- # Get the list of definitions from the directory property
- get_directory_property(BANG_CNCC_DEFINITIONS COMPILE_DEFINITIONS)
- if(BANG_CNCC_DEFINITIONS)
- foreach(_definition ${BANG_CNCC_DEFINITIONS})
- list(APPEND cncc_flags "-D${_definition}")
- endforeach()
- endif()
-
- if(_bang_build_shared_libs)
- list(APPEND cncc_flags "-D${bang_target}_EXPORTS")
- endif()
-
- # Reset the output variable
- set(_bang_wrap_generated_files "")
-
- # Iterate over the macro arguments and create custom
- # commands for all the .cu files.
- foreach(file ${ARGN})
- # Ignore any file marked as a HEADER_FILE_ONLY
- get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
- # Allow per source file overrides of the format. Also allows compiling non-.cu files.
- get_source_file_property(_bang_source_format ${file} BANG_SOURCE_PROPERTY_FORMAT)
- if((${file} MATCHES "\\.mlu$" OR _bang_source_format) AND NOT _is_header)
-
- if(NOT _bang_source_format)
- set(_bang_source_format ${format})
- endif()
-
- if( ${_bang_source_format} MATCHES "OBJ")
- set( bang_compile_to_external_module OFF )
- else()
- set( bang_compile_to_external_module ON )
- if( ${_bang_source_format} MATCHES "MLISA" )
- set( bang_compile_to_external_module_type "mlisa" )
- elseif( ${_bang_source_format} MATCHES "CNBIN")
- set( bang_compile_to_external_module_type "cnbin" )
- elseif( ${_bang_source_format} MATCHES "CNFATBIN")
- set( bang_compile_to_external_module_type "cnfatbin" )
- else()
- message( FATAL_ERROR "Invalid format flag passed to BANG_WRAP_SRCS or set with BANG_SOURCE_PROPERTY_FORMAT file property for file '${file}': '${_bang_source_format}'. Use OBJ, MLISA, CNBIN or CNFATBIN.")
- endif()
- endif()
-
- if(bang_compile_to_external_module)
- # Don't use any of the host compilation flags for MLISA targets.
- set(BANG_HOST_FLAGS)
- set(BANG_CNCC_FLAGS_CONFIG)
- else()
- set(BANG_HOST_FLAGS ${_bang_host_flags})
- set(BANG_CNCC_FLAGS_CONFIG ${_bang_cncc_flags_config})
- endif()
-
- # Determine output directory
- bang_compute_build_path("${file}" bang_build_path)
- set(bang_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${bang_target}.dir/${bang_build_path}")
- if(BANG_GENERATED_OUTPUT_DIR)
- set(bang_compile_output_dir "${BANG_GENERATED_OUTPUT_DIR}")
- else()
- if ( bang_compile_to_external_module )
- set(bang_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}")
- else()
- set(bang_compile_output_dir "${bang_compile_intermediate_directory}")
- endif()
- endif()
-
- # Add a custom target to generate a c or mlisa file. ######################
-
- get_filename_component( basename ${file} NAME )
- if( bang_compile_to_external_module )
- set(generated_file_path "${bang_compile_output_dir}")
- set(generated_file_basename "${bang_target}_generated_${basename}.${bang_compile_to_external_module_type}")
- set(format_flag "-${bang_compile_to_external_module_type}")
- file(MAKE_DIRECTORY "${bang_compile_output_dir}")
- else()
- set(generated_file_path "${bang_compile_output_dir}/${CMAKE_CFG_INTDIR}")
- set(generated_file_basename "${bang_target}_generated_${basename}${generated_extension}")
- set(format_flag "-c")
- endif()
-
- # Set all of our file names. Make sure that whatever filenames that have
- # generated_file_path in them get passed in through as a command line
- # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time
- # instead of configure time.
- set(generated_file "${generated_file_path}/${generated_file_basename}")
- set(cmake_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.depend")
- set(CNCC_generated_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.CNCC-depend")
- set(generated_cnbin_file "${generated_file_path}/${generated_file_basename}.cnbin.txt")
- set(custom_target_script "${bang_compile_intermediate_directory}/${generated_file_basename}.cmake")
-
- # Setup properties for obj files:
- if( NOT bang_compile_to_external_module )
- set_source_files_properties("${generated_file}"
- PROPERTIES
- EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
- )
- endif()
-
- # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path.
- get_filename_component(file_path "${file}" PATH)
- if(IS_ABSOLUTE "${file_path}")
- set(source_file "${file}")
- else()
- set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
- endif()
-
- # Bring in the dependencies. Creates a variable BANG_CNCC_DEPEND #######
- bang_include_cncc_dependencies(${cmake_dependency_file})
-
- # Build the CNCC made dependency file ###################################
- set(build_cnbin OFF)
- if ( BANG_BUILD_CNBIN )
- if ( NOT bang_compile_to_external_module )
- set ( build_cnbin ON )
- endif()
- endif()
-
- # Configure the build script
- configure_file("${BANG_run_cncc}" "${custom_target_script}" @ONLY)
-
- # So if a user specifies the same bang file as input more than once, you
- # can have bad things happen with dependencies. Here we check an option
- # to see if this is the behavior they want.
- set(main_dep DEPENDS ${source_file})
-
- if(BANG_VERBOSE_BUILD)
- set(verbose_output ON)
- elseif(CMAKE_GENERATOR MATCHES "Makefiles")
- set(verbose_output "$(VERBOSE)")
- else()
- set(verbose_output OFF)
- endif()
-
- # Create up the comment string
- file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
- if(bang_compile_to_external_module)
- set(bang_build_comment_string "Building CNCC ${bang_compile_to_external_module_type} file ${generated_file_relative_path}")
- else()
- set(bang_build_comment_string "Building CNCC object ${generated_file_relative_path}")
- endif()
-
- set(_verbatim VERBATIM)
- if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)")
- set(_verbatim "")
- endif()
-
- # Build the generated file and dependency file ##########################
- add_custom_command(
- OUTPUT ${generated_file}
- # These output files depend on the source_file and the contents of cmake_dependency_file
- ${main_dep}
- DEPENDS ${BANG_CNCC_DEPEND}
- DEPENDS ${custom_target_script}
- # Make sure the output directory exists before trying to write to it.
- COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}"
- COMMAND ${CMAKE_COMMAND} ARGS
- -D verbose:BOOL=${verbose_output}
- ${ccbin_flags}
- -D build_configuration:STRING=${BANG_build_configuration}
- -D "generated_file:STRING=${generated_file}"
- -D "generated_cnbin_file:STRING=${generated_cnbin_file}"
- -P "${custom_target_script}"
- WORKING_DIRECTORY "${bang_compile_intermediate_directory}"
- COMMENT "${bang_build_comment_string}"
- ${_verbatim}
- )
-
- # Make sure the build system knows the file is generated.
- set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
-
- list(APPEND _bang_wrap_generated_files ${generated_file})
-
- # Add the other files that we want cmake to clean on a cleanup ##########
- list(APPEND BANG_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
- list(REMOVE_DUPLICATES BANG_ADDITIONAL_CLEAN_FILES)
- set(BANG_ADDITIONAL_CLEAN_FILES ${BANG_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the bang dependency scanning.")
-
- endif()
- endforeach()
-
- # Set the return parameter
- set(${generated_files} ${_bang_wrap_generated_files})
- endmacro()
-
- ###############################################################################
- ###############################################################################
- # Locate NEUWARE, Set Build Type, etc.
- ###############################################################################
- ###############################################################################
-
- # BANG_CNCC_EXECUTABLE
- find_program(BANG_CNCC_EXECUTABLE
- NAMES cncc
- PATHS "${NEUWARE_ROOT_DIR}"
- ENV NEUWARE_PATH
- ENV NEUWARE_BIN_PATH
- PATH_SUFFIXES bin bin64
- NO_DEFAULT_PATH
- )
- # Search default search paths, after we search our own set of paths.
- find_program(BANG_CNCC_EXECUTABLE cncc)
- mark_as_advanced(BANG_CNCC_EXECUTABLE)
-
- ###############################################################################
- ###############################################################################
- # ADD LIBRARY
- ###############################################################################
- ###############################################################################
- macro(BANG_ADD_LIBRARY bang_target)
-
- BANG_ADD_BANG_INCLUDE_ONCE()
-
- # Separate the sources from the options
- BANG_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
- BANG_BUILD_SHARED_LIBRARY(_bang_shared_flag ${ARGN})
- # Create custom commands and targets for each file.
- BANG_WRAP_SRCS( ${bang_target} OBJ _generated_files ${_sources}
- ${_cmake_options} ${_bang_shared_flag}
- OPTIONS ${_options} )
-
- # Compute the file name of the intermedate link file used for separable
- # compilation.
- BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${bang_target} "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
-
- # Add the library.
- add_library(${bang_target} ${_cmake_options}
- ${_generated_files}
- ${_sources}
- ${link_file}
- )
-
- # Add a link phase for the separable compilation if it has been enabled. If
- # it has been enabled then the ${bang_target}_SEPARABLE_COMPILATION_OBJECTS
- # variable will have been defined.
- BANG_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${bang_target} "${_options}" "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
-
- target_link_libraries(${bang_target}
- ${BANG_LIBRARIES}
- )
-
- # We need to set the linker language based on what the expected generated file
- # would be. BANG_C_OR_CXX is computed based on BANG_HOST_COMPILATION_CPP.
- set_target_properties(${bang_target}
- PROPERTIES
- LINKER_LANGUAGE ${BANG_C_OR_CXX}
- )
-
- endmacro()
-
-
- ###############################################################################
- ###############################################################################
- # ADD EXECUTABLE
- ###############################################################################
- ###############################################################################
- macro(BANG_ADD_EXECUTABLE bang_target)
-
- BANG_ADD_BANG_INCLUDE_ONCE()
-
- # Separate the sources from the options
- BANG_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
- # Create custom commands and targets for each file.
- BANG_WRAP_SRCS( ${bang_target} OBJ _generated_files ${_sources} OPTIONS ${_options} )
-
- # Compute the file name of the intermedate link file used for separable
- # compilation.
- BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${bang_target} "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
-
- # Add the library.
- add_executable(${bang_target} ${_cmake_options}
- ${_generated_files}
- ${_sources}
- ${link_file}
- )
-
- # Add a link phase for the separable compilation if it has been enabled. If
- # it has been enabled then the ${bang_target}_SEPARABLE_COMPILATION_OBJECTS
- # variable will have been defined.
- BANG_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${bang_target} "${_options}" "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
-
- target_link_libraries(${bang_target}
- ${BANG_LIBRARIES}
- )
-
- # We need to set the linker language based on what the expected generated file
- # would be. BANG_C_OR_CXX is computed based on BANG_HOST_COMPILATION_CPP.
- set_target_properties(${bang_target}
- PROPERTIES
- LINKER_LANGUAGE ${BANG_C_OR_CXX}
- )
-
- endmacro()
-
- #####################################################################################
- # This macro invokes the cncc compiler to compile mlu source files, and to generate
- # object files.
- # INPUT:
- # _source_files - List of mlu source files to be compiled
- # _include_directories_generator_user - List of user provided include files
- # OUTPUT:
- # _generated_files - List of generated files
- #####################################################################################
- macro(BANG_COMPILE _generated_files _source_files _include_directories_generator_user)
- # Set up all the command line flags here, so that they can be overridden on a per target basis.
- set(cncc_flags "")
-
- set(BANG_C_OR_CXX CXX)
-
- set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
-
- if(BANG_TARGET_CPU_ARCH)
- set(cncc_flags ${cncc_flags} "--target=${BANG_TARGET_CPU_ARCH}")
- endif()
-
- set( BANG_build_configuration "${CMAKE_BUILD_TYPE}")
-
- set(include_directories_generator ${_include_directories_generator_user})
- foreach(dir ${include_directories_generator})
- if(dir)
- list(APPEND BANG_CNCC_INCLUDE_ARGS -I${dir})
- endif()
- endforeach()
-
- # Reset these variables
- set(BANG_WRAP_OPTION_CNCC_FLAGS)
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- set(BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper})
- endforeach()
-
- BANG_GET_SOURCES_AND_OPTIONS(_bang_wrap_sources _bang_wrap_cmake_options _bang_wrap_options ${_source_files})
- BANG_PARSE_CNCC_OPTIONS(BANG_WRAP_OPTION_CNCC_FLAGS ${_bang_wrap_options})
-
- set(BANG_HOST_SHARED_FLAGS)
- # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We
- # always need to set the SHARED_FLAGS, though.
- set(_bang_host_flags "set(CMAKE_HOST_FLAGS ${CMAKE_${BANG_C_OR_CXX}_FLAGS} ${BANG_HOST_SHARED_FLAGS})")
-
- set(_bang_cncc_flags_config "# Build specific configuration flags")
- # Loop over all the configuration types to generate appropriate flags for run_cncc.cmake
- foreach(config ${BANG_configuration_types})
- string(TOUPPER ${config} config_upper)
- # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS
- # we convert the strings to lists (like we want).
-
- set(_bang_C_FLAGS "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
- set(_bang_host_flags "${_bang_host_flags}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_bang_C_FLAGS})")
-
- # Note that if we ever want BANG_CNCC_FLAGS_<CONFIG> to be string (instead of a list
- # like it is currently), we can remove the quotes around the
- # ${BANG_CNCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_<CONFIG> variable.
- set(_bang_cncc_flags_config "${_bang_cncc_flags_config}\nset(BANG_CNCC_FLAGS_${config_upper} ${BANG_CNCC_FLAGS_${config_upper}} ;; ${BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper}})")
- endforeach()
-
- # Process the C++11 flag. If the host sets the flag, we need to add it to cncc and
- # remove it from the host. This is because -Xcompile -std=c++ will choke cncc (it uses
- # the C preprocessor). In order to get this to work correctly, we need to use cncc's
- # specific c++11 flag.
- if( "${_bang_host_flags}" MATCHES "-std=c\\+\\+11")
- # Add the c++11 flag to cncc if it isn't already present. Note that we only look at
- # the main flag instead of the configuration specific flags.
- if( NOT "${BANG_CNCC_FLAGS}" MATCHES "-std;c\\+\\+11" )
- list(APPEND cncc_flags -std=c++11)
- endif()
- string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _bang_host_flags "${_bang_host_flags}")
- endif()
-
- # Get the list of definitions from the directory property
- get_directory_property(BANG_CNCC_DEFINITIONS COMPILE_DEFINITIONS)
- if(BANG_CNCC_DEFINITIONS)
- foreach(_definition ${BANG_CNCC_DEFINITIONS})
- list(APPEND cncc_flags "-D${_definition}")
- endforeach()
- endif()
-
- # Reset the output variable
- set(_bang_wrap_generated_files "")
-
- # Iterate over the macro arguments and create custom
- # commands for all the .cu files.
- foreach(file ${_source_files})
- # Ignore any file marked as a HEADER_FILE_ONLY
- get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
- # Allow per source file overrides of the format. Also allows compiling non-.cu files.
- get_source_file_property(_bang_source_format ${file} BANG_SOURCE_PROPERTY_FORMAT)
- if((${file} MATCHES "\\.mlu$" OR _bang_source_format) AND NOT _is_header)
-
- set(_bang_source_format "OBJ")
-
- set(BANG_HOST_FLAGS ${_bang_host_flags})
- set(BANG_CNCC_FLAGS_CONFIG ${_bang_cncc_flags_config})
-
- # Determine output directory
- bang_compute_build_path("${file}" bang_build_path)
- set(bang_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/bang_compile.dir/${bang_build_path}")
- if(BANG_GENERATED_OUTPUT_DIR)
- set(bang_compile_output_dir "${BANG_GENERATED_OUTPUT_DIR}")
- else()
- set(bang_compile_output_dir "${bang_compile_intermediate_directory}")
- endif()
-
- # Add a custom target to generate a c or mlisa file. ######################
-
- get_filename_component( basename ${file} NAME )
- set(generated_file_path "${bang_compile_output_dir}/${CMAKE_CFG_INTDIR}")
- set(generated_file_basename "bang_compile_generated_${basename}${generated_extension}")
- set(format_flag "-c")
-
- # Set all of our file names. Make sure that whatever filenames that have
- # generated_file_path in them get passed in through as a command line
- # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time
- # instead of configure time.
- set(generated_file "${generated_file_path}/${generated_file_basename}")
- set(cmake_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.depend")
- set(CNCC_generated_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.CNCC-depend")
- set(generated_cnbin_file "${generated_file_path}/${generated_file_basename}.cnbin.txt")
- set(custom_target_script "${bang_compile_intermediate_directory}/${generated_file_basename}.cmake")
-
- set_source_files_properties("${generated_file}"
- PROPERTIES
- EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
- )
-
- # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path.
- get_filename_component(file_path "${file}" PATH)
- if(IS_ABSOLUTE "${file_path}")
- set(source_file "${file}")
- else()
- set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
- endif()
-
- # Bring in the dependencies. Creates a variable BANG_CNCC_DEPEND #######
- bang_include_cncc_dependencies(${cmake_dependency_file})
-
- # Build the CNCC made dependency file ###################################
- set(build_cnbin OFF)
-
- # Configure the build script
- configure_file("${BANG_run_cncc}" "${custom_target_script}" @ONLY)
-
- # So if a user specifies the same bang file as input more than once, you
- # can have bad things happen with dependencies. Here we check an option
- # to see if this is the behavior they want.
- set(main_dep DEPENDS ${source_file})
-
- if(BANG_VERBOSE_BUILD)
- set(verbose_output ON)
- elseif(CMAKE_GENERATOR MATCHES "Makefiles")
- set(verbose_output "$(VERBOSE)")
- else()
- set(verbose_output OFF)
- endif()
-
- # Create up the comment string
- file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
- set(bang_build_comment_string "Building CNCC object ${generated_file_relative_path}")
-
- set(_verbatim VERBATIM)
- if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)")
- set(_verbatim "")
- endif()
-
- # Build the generated file and dependency file ##########################
- add_custom_command(
- OUTPUT ${generated_file}
- # These output files depend on the source_file and the contents of cmake_dependency_file
- ${main_dep}
- DEPENDS ${BANG_CNCC_DEPEND}
- DEPENDS ${custom_target_script}
- # Make sure the output directory exists before trying to write to it.
- COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}"
- COMMAND ${CMAKE_COMMAND} ARGS
- -D verbose:BOOL=${verbose_output}
- ${ccbin_flags}
- -D build_configuration:STRING=${BANG_build_configuration}
- -D "generated_file:STRING=${generated_file}"
- -D "generated_cnbin_file:STRING=${generated_cnbin_file}"
- -P "${custom_target_script}"
- WORKING_DIRECTORY "${bang_compile_intermediate_directory}"
- COMMENT "${bang_build_comment_string}"
- ${_verbatim}
- )
-
- # Make sure the build system knows the file is generated.
- set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
-
- list(APPEND _bang_wrap_generated_files ${generated_file})
-
- # Add the other files that we want cmake to clean on a cleanup ##########
- list(APPEND BANG_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
- list(REMOVE_DUPLICATES BANG_ADDITIONAL_CLEAN_FILES)
- set(BANG_ADDITIONAL_CLEAN_FILES ${BANG_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the bang dependency scanning.")
-
- endif()
- endforeach()
-
- # Set the return parameter
- set(${_generated_files} ${_bang_wrap_generated_files})
- endmacro()
|