You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FindBANG.cmake 44 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. #.rst:
  2. # FindBANG
  3. # --------
  4. #
  5. # Tools for building BANG C files: libraries and build dependencies.
  6. #
  7. # This script locates the CAMBRICON BANG C tools. It should work on linux,
  8. # windows, and mac and should be reasonably up to date with BANG C
  9. # releases.
  10. #
  11. # This script makes use of the standard find_package arguments of
  12. # <VERSION>, REQUIRED and QUIET. BANG_FOUND will report if an
  13. # acceptable version of BANG was found.
  14. #
  15. # The following variables affect the behavior of the macros in the
  16. # script (in alphebetical order). Note that any of these flags can be
  17. # changed multiple times in the same directory before calling
  18. #
  19. # BANG_CNCC_FLAGS
  20. # -- Additional CNCC command line arguments. NOTE: multiple arguments must be
  21. # semi-colon delimited (e.g. --bang-mlu-arch=xxx;-Wall)
  22. #
  23. # BANG_TARGET_CPU_ARCH
  24. # -- Specify the name of the class of CPU architecture for which the input
  25. # files must be compiled (e.g. specify BANG_TARGET_CPU_ARCH=armv8a,
  26. # will append --target=armv8a to BANG_CNCC_FLAGS)
  27. #
  28. # This code is licensed under the MIT License. See the FindBANG.cmake script
  29. # for the text of the license.
  30. # The MIT License
  31. #
  32. # License for the specific language governing rights and limitations under
  33. # Permission is hereby granted, free of charge, to any person obtaining a
  34. # copy of this software and associated documentation files (the "Software"),
  35. # to deal in the Software without restriction, including without limitation
  36. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  37. # and/or sell copies of the Software, and to permit persons to whom the
  38. # Software is furnished to do so, subject to the following conditions:
  39. #
  40. # The above copyright notice and this permission notice shall be included
  41. # in all copies or substantial portions of the Software.
  42. #
  43. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  44. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  45. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  46. # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  47. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  48. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  49. # DEALINGS IN THE SOFTWARE.
  50. #
  51. # MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  52. #
  53. # Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
  54. #
  55. # Unless required by applicable law or agreed to in writing,
  56. # software distributed under the License is distributed on an
  57. # "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  58. #
  59. # This file has been modified by Megvii ("Megvii Modifications").
  60. # All Megvii Modifications are Copyright (C) 2014-2019 Megvii Inc. All rights reserved
  61. ###############################################################################
  62. # FindBANG.cmake
  63. ###############################################################################
  64. # Check for required components
  65. ###############################################################################
  66. set(BANG_FOUND TRUE)
  67. ###############################################################################
  68. # This macro helps us find the location of helper files we will need the full path to
  69. ###############################################################################
  70. macro(BANG_FIND_HELPER_FILE _name _extension)
  71. set(_full_name "${_name}.${_extension}")
  72. # CMAKE_CURRENT_LIST_FILE contains the full path to the file currently being
  73. # processed. Using this variable, we can pull out the current path, and
  74. # provide a way to get access to the other files we need local to here.
  75. get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
  76. set(BANG_${_name} "${CMAKE_CURRENT_LIST_DIR}/${_full_name}")
  77. if(NOT EXISTS "${BANG_${_name}}")
  78. set(error_message "${_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}")
  79. if(BANG_FIND_REQUIRED)
  80. message(FATAL_ERROR "${error_message}")
  81. else()
  82. if(NOT BANG_FIND_QUIETLY)
  83. message(STATUS "${error_message}")
  84. endif()
  85. endif()
  86. endif()
  87. # Set this variable as internal, so the user isn't bugged with it.
  88. set(BANG_${_name} ${BANG_${_name}} CACHE INTERNAL "Location of ${_full_name}" FORCE)
  89. endmacro()
  90. bang_find_helper_file(parse_cnbin cmake)
  91. bang_find_helper_file(make2cmake cmake)
  92. bang_find_helper_file(run_cncc cmake)
  93. ###############################################################################
  94. # Add include directories to pass to the cncc command.
  95. ###############################################################################
  96. macro(BANG_INCLUDE_DIRECTORIES)
  97. foreach(dir ${ARGN})
  98. list(APPEND BANG_CNCC_INCLUDE_ARGS_USER -I${dir})
  99. endforeach()
  100. endmacro()
  101. ##############################################################################
  102. # Separate the OPTIONS out from the sources
  103. ##############################################################################
  104. macro(BANG_GET_SOURCES_AND_OPTIONS _sources _cmake_options _options)
  105. set( ${_sources} )
  106. set( ${_cmake_options} )
  107. set( ${_options} )
  108. set( _found_options FALSE )
  109. foreach(arg ${ARGN})
  110. if("x${arg}" STREQUAL "xOPTIONS")
  111. set( _found_options TRUE )
  112. elseif(
  113. "x${arg}" STREQUAL "xWIN32" OR
  114. "x${arg}" STREQUAL "xMACOSX_BUNDLE" OR
  115. "x${arg}" STREQUAL "xEXCLUDE_FROM_ALL" OR
  116. "x${arg}" STREQUAL "xSTATIC" OR
  117. "x${arg}" STREQUAL "xSHARED" OR
  118. "x${arg}" STREQUAL "xMODULE"
  119. )
  120. list(APPEND ${_cmake_options} ${arg})
  121. else()
  122. if ( _found_options )
  123. list(APPEND ${_options} ${arg})
  124. else()
  125. # Assume this is a file
  126. list(APPEND ${_sources} ${arg})
  127. endif()
  128. endif()
  129. endforeach()
  130. endmacro()
  131. ##############################################################################
  132. # Parse the OPTIONS from ARGN and set the variables prefixed by _option_prefix
  133. ##############################################################################
  134. macro(BANG_PARSE_CNCC_OPTIONS _option_prefix)
  135. set( _found_config )
  136. foreach(arg ${ARGN})
  137. # Determine if we are dealing with a perconfiguration flag
  138. foreach(config ${BANG_configuration_types})
  139. string(TOUPPER ${config} config_upper)
  140. if (arg STREQUAL "${config_upper}")
  141. set( _found_config _${arg})
  142. # Set arg to nothing to keep it from being processed further
  143. set( arg )
  144. endif()
  145. endforeach()
  146. if ( arg )
  147. list(APPEND ${_option_prefix}${_found_config} "${arg}")
  148. endif()
  149. endforeach()
  150. endmacro()
  151. #####################################################################
  152. # BANG_INCLUDE_CNCC_DEPENDENCIES
  153. # So we want to try and include the dependency file if it exists. If
  154. # it doesn't exist then we need to create an empty one, so we can
  155. # include it.
  156. # If it does exist, then we need to check to see if all the files it
  157. # depends on exist. If they don't then we should clear the dependency
  158. # file and regenerate it later. This covers the case where a header
  159. # file has disappeared or moved.
  160. #####################################################################
  161. macro(BANG_INCLUDE_CNCC_DEPENDENCIES dependency_file)
  162. set(BANG_CNCC_DEPEND)
  163. set(BANG_CNCC_DEPEND_REGENERATE FALSE)
  164. # Include the dependency file. Create it first if it doesn't exist . The
  165. # INCLUDE puts a dependency that will force CMake to rerun and bring in the
  166. # new info when it changes. DO NOT REMOVE THIS (as I did and spent a few
  167. # hours figuring out why it didn't work.
  168. if(NOT EXISTS ${dependency_file})
  169. file(WRITE ${dependency_file} "#FindBANG.cmake generated file. Do not edit.\n")
  170. endif()
  171. # Always include this file to force CMake to run again next
  172. # invocation and rebuild the dependencies.
  173. #message("including dependency_file = ${dependency_file}")
  174. include(${dependency_file})
  175. # Now we need to verify the existence of all the included files
  176. # here. If they aren't there we need to just blank this variable and
  177. # make the file regenerate again.
  178. if(BANG_CNCC_DEPEND)
  179. #message("BANG_CNCC_DEPEND found")
  180. foreach(f ${BANG_CNCC_DEPEND})
  181. # message("searching for ${f}")
  182. if(NOT EXISTS ${f})
  183. #message("file ${f} not found")
  184. set(BANG_CNCC_DEPEND_REGENERATE TRUE)
  185. endif()
  186. endforeach()
  187. else()
  188. #message("BANG_CNCC_DEPEND false")
  189. # No dependencies, so regenerate the file.
  190. set(BANG_CNCC_DEPEND_REGENERATE TRUE)
  191. endif()
  192. #message("BANG_CNCC_DEPEND_REGENERATE = ${BANG_CNCC_DEPEND_REGENERATE}")
  193. # No incoming dependencies, so we need to generate them. Make the
  194. # output depend on the dependency file itself, which should cause the
  195. # rule to re-run.
  196. if(BANG_CNCC_DEPEND_REGENERATE)
  197. set(BANG_CNCC_DEPEND ${dependency_file})
  198. #message("Generating an empty dependency_file: ${dependency_file}")
  199. file(WRITE ${dependency_file} "#FindBANG.cmake generated file. Do not edit.\n")
  200. endif()
  201. endmacro()
  202. ###############################################################################
  203. # Helper to add the include directory for BANG only once
  204. ###############################################################################
  205. function(BANG_ADD_BANG_INCLUDE_ONCE)
  206. get_directory_property(_include_directories INCLUDE_DIRECTORIES)
  207. set(_add TRUE)
  208. if(_include_directories)
  209. foreach(dir ${_include_directories})
  210. if("${dir}" STREQUAL "${BANG_INCLUDE_DIRS}")
  211. set(_add FALSE)
  212. endif()
  213. endforeach()
  214. endif()
  215. if(_add)
  216. include_directories(${BANG_INCLUDE_DIRS})
  217. endif()
  218. endfunction()
  219. ##############################################################################
  220. # Build the shared library
  221. ##############################################################################
  222. function(BANG_BUILD_SHARED_LIBRARY shared_flag)
  223. set(cmake_args ${ARGN})
  224. # If SHARED, MODULE, or STATIC aren't already in the list of arguments, then
  225. # add SHARED or STATIC based on the value of BUILD_SHARED_LIBS.
  226. list(FIND cmake_args SHARED _bang_found_SHARED)
  227. list(FIND cmake_args MODULE _bang_found_MODULE)
  228. list(FIND cmake_args STATIC _bang_found_STATIC)
  229. if( _bang_found_SHARED GREATER -1 OR
  230. _bang_found_MODULE GREATER -1 OR
  231. _bang_found_STATIC GREATER -1)
  232. set(_bang_build_shared_libs)
  233. else()
  234. if (BUILD_SHARED_LIBS)
  235. set(_bang_build_shared_libs SHARED)
  236. else()
  237. set(_bang_build_shared_libs STATIC)
  238. endif()
  239. endif()
  240. set(${shared_flag} ${_bang_build_shared_libs} PARENT_SCOPE)
  241. endfunction()
  242. ##############################################################################
  243. # Helper to avoid clashes of files with the same basename but different paths.
  244. # This doesn't attempt to do exactly what CMake internals do, which is to only
  245. # add this path when there is a conflict, since by the time a second collision
  246. # in names is detected it's already too late to fix the first one. For
  247. # consistency sake the relative path will be added to all files.
  248. ##############################################################################
  249. function(BANG_COMPUTE_BUILD_PATH path build_path)
  250. #message("BANG_COMPUTE_BUILD_PATH([${path}] ${build_path})")
  251. # Only deal with CMake style paths from here on out
  252. file(TO_CMAKE_PATH "${path}" bpath)
  253. if (IS_ABSOLUTE "${bpath}")
  254. # Absolute paths are generally unnessary, especially if something like
  255. # file(GLOB_RECURSE) is used to pick up the files.
  256. string(FIND "${bpath}" "${CMAKE_CURRENT_BINARY_DIR}" _binary_dir_pos)
  257. if (_binary_dir_pos EQUAL 0)
  258. file(RELATIVE_PATH bpath "${CMAKE_CURRENT_BINARY_DIR}" "${bpath}")
  259. else()
  260. file(RELATIVE_PATH bpath "${CMAKE_CURRENT_SOURCE_DIR}" "${bpath}")
  261. endif()
  262. endif()
  263. # This recipe is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the
  264. # CMake source.
  265. # Remove leading /
  266. string(REGEX REPLACE "^[/]+" "" bpath "${bpath}")
  267. # Avoid absolute paths by removing ':'
  268. string(REPLACE ":" "_" bpath "${bpath}")
  269. # Avoid relative paths that go up the tree
  270. string(REPLACE "../" "__/" bpath "${bpath}")
  271. # Avoid spaces
  272. string(REPLACE " " "_" bpath "${bpath}")
  273. # Strip off the filename. I wait until here to do it, since removin the
  274. # basename can make a path that looked like path/../basename turn into
  275. # path/.. (notice the trailing slash).
  276. get_filename_component(bpath "${bpath}" PATH)
  277. set(${build_path} "${bpath}" PARENT_SCOPE)
  278. #message("${build_path} = ${bpath}")
  279. endfunction()
  280. ##############################################################################
  281. # Compute the filename to be used by BANG_LINK_SEPARABLE_COMPILATION_OBJECTS
  282. ##############################################################################
  283. function(BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME output_file_var bang_target object_files)
  284. if (object_files)
  285. set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
  286. set(output_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${bang_target}.dir/${CMAKE_CFG_INTDIR}/${bang_target}_intermediate_link${generated_extension}")
  287. else()
  288. set(output_file)
  289. endif()
  290. set(${output_file_var} "${output_file}" PARENT_SCOPE)
  291. endfunction()
  292. ##############################################################################
  293. # Setup the build rule for the separable compilation intermediate link file.
  294. ##############################################################################
  295. function(BANG_LINK_SEPARABLE_COMPILATION_OBJECTS output_file bang_target options object_files)
  296. if (object_files)
  297. set_source_files_properties("${output_file}"
  298. PROPERTIES
  299. EXTERNAL_OBJECT TRUE # This is an object file not to be compiled, but only
  300. # be linked.
  301. GENERATED TRUE # This file is generated during the build
  302. )
  303. # For now we are ignoring all the configuration specific flags.
  304. set(cncc_flags)
  305. BANG_PARSE_CNCC_OPTIONS(cncc_flags ${options})
  306. # If -ccbin, --compiler-bindir has been specified, don't do anything. Otherwise add it here.
  307. list( FIND cncc_flags "-ccbin" ccbin_found0 )
  308. list( FIND cncc_flags "--compiler-bindir" ccbin_found1 )
  309. if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND BANG_HOST_COMPILER )
  310. # Match VERBATIM check below.
  311. if(BANG_HOST_COMPILER MATCHES "\\$\\(VCInstallDir\\)")
  312. list(APPEND cncc_flags -ccbin "\"${BANG_HOST_COMPILER}\"")
  313. else()
  314. list(APPEND cncc_flags -ccbin "${BANG_HOST_COMPILER}")
  315. endif()
  316. endif()
  317. # Create a list of flags specified by BANG_CNCC_FLAGS_${CONFIG} and CMAKE_${BANG_C_OR_CXX}_FLAGS*
  318. set(config_specific_flags)
  319. set(flags)
  320. foreach(config ${BANG_configuration_types})
  321. string(TOUPPER ${config} config_upper)
  322. # Add config specific flags
  323. foreach(f ${BANG_CNCC_FLAGS_${config_upper}})
  324. list(APPEND config_specific_flags $<$<CONFIG:${config}>:${f}>)
  325. endforeach()
  326. set(important_host_flags)
  327. _bang_get_important_host_flags(important_host_flags "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
  328. foreach(f ${important_host_flags})
  329. list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>)
  330. endforeach()
  331. endforeach()
  332. # Add CMAKE_${BANG_C_OR_CXX}_FLAGS
  333. set(important_host_flags)
  334. _bang_get_important_host_flags(important_host_flags "${CMAKE_${BANG_C_OR_CXX}_FLAGS}")
  335. foreach(f ${important_host_flags})
  336. list(APPEND flags -Xcompiler ${f})
  337. endforeach()
  338. # Add our general BANG_CNCC_FLAGS with the configuration specifig flags
  339. set(cncc_flags ${BANG_CNCC_FLAGS} ${config_specific_flags} ${cncc_flags})
  340. file(RELATIVE_PATH output_file_relative_path "${CMAKE_BINARY_DIR}" "${output_file}")
  341. # Some generators don't handle the multiple levels of custom command
  342. # dependencies correctly (obj1 depends on file1, obj2 depends on obj1), so
  343. # we work around that issue by compiling the intermediate link object as a
  344. # pre-link custom command in that situation.
  345. set(do_obj_build_rule TRUE)
  346. if (MSVC_VERSION GREATER 1599 AND MSVC_VERSION LESS 1800)
  347. # VS 2010 and 2012 have this problem.
  348. set(do_obj_build_rule FALSE)
  349. endif()
  350. set(_verbatim VERBATIM)
  351. if(cncc_flags MATCHES "\\$\\(VCInstallDir\\)")
  352. set(_verbatim "")
  353. endif()
  354. if (do_obj_build_rule)
  355. add_custom_command(
  356. OUTPUT ${output_file}
  357. DEPENDS ${object_files}
  358. COMMAND ${BANG_CNCC_EXECUTABLE} ${cncc_flags} -dlink ${object_files} -o ${output_file}
  359. ${flags}
  360. COMMENT "Building CNCC intermediate link file ${output_file_relative_path}"
  361. ${_verbatim}
  362. )
  363. else()
  364. get_filename_component(output_file_dir "${output_file}" DIRECTORY)
  365. add_custom_command(
  366. TARGET ${bang_target}
  367. PRE_LINK
  368. COMMAND ${CMAKE_COMMAND} -E echo "Building CNCC intermediate link file ${output_file_relative_path}"
  369. COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}"
  370. COMMAND ${BANG_CNCC_EXECUTABLE} ${cncc_flags} ${flags} -dlink ${object_files} -o "${output_file}"
  371. ${_verbatim}
  372. )
  373. endif()
  374. endif()
  375. endfunction()
  376. ##############################################################################
  377. # This helper macro populates the following variables and setups up custom
  378. # commands and targets to invoke the cncc compiler to generate C or MLISA source
  379. # dependent upon the format parameter.
  380. # INPUT:
  381. # bang_target - Target name
  382. # format - MLISA, CNBIN, CNFATBIN or OBJ
  383. # FILE1 .. FILEN - The remaining arguments are the sources to be wrapped.
  384. # OPTIONS - Extra options to CNCC
  385. # OUTPUT:
  386. # generated_files - List of generated files
  387. ##############################################################################
  388. macro(BANG_WRAP_SRCS bang_target format generated_files)
  389. # Set up all the command line flags here, so that they can be overridden on a per target basis.
  390. set(cncc_flags "")
  391. set(BANG_C_OR_CXX CXX)
  392. set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
  393. if(BANG_TARGET_CPU_ARCH)
  394. set(cncc_flags ${cncc_flags} "--target=${BANG_TARGET_CPU_ARCH}")
  395. endif()
  396. set( BANG_build_configuration "${CMAKE_BUILD_TYPE}")
  397. # Get the include directories for this directory and use them for our cncc command.
  398. # Remove duplicate entries which may be present since include_directories
  399. # in CMake >= 2.8.8 does not remove them.
  400. get_directory_property(BANG_CNCC_INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
  401. list(REMOVE_DUPLICATES BANG_CNCC_INCLUDE_DIRECTORIES)
  402. if(BANG_CNCC_INCLUDE_DIRECTORIES)
  403. foreach(dir ${BANG_CNCC_INCLUDE_DIRECTORIES})
  404. list(APPEND BANG_CNCC_INCLUDE_ARGS -I${dir})
  405. endforeach()
  406. endif()
  407. # Reset these variables
  408. set(BANG_WRAP_OPTION_CNCC_FLAGS)
  409. foreach(config ${BANG_configuration_types})
  410. string(TOUPPER ${config} config_upper)
  411. set(BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper})
  412. endforeach()
  413. BANG_GET_SOURCES_AND_OPTIONS(_bang_wrap_sources _bang_wrap_cmake_options _bang_wrap_options ${ARGN})
  414. BANG_PARSE_CNCC_OPTIONS(BANG_WRAP_OPTION_CNCC_FLAGS ${_bang_wrap_options})
  415. # Figure out if we are building a shared library. BUILD_SHARED_LIBS is
  416. # respected in BANG_ADD_LIBRARY.
  417. set(_bang_build_shared_libs FALSE)
  418. # SHARED, MODULE
  419. list(FIND _bang_wrap_cmake_options SHARED _bang_found_SHARED)
  420. list(FIND _bang_wrap_cmake_options MODULE _bang_found_MODULE)
  421. if(_bang_found_SHARED GREATER -1 OR _bang_found_MODULE GREATER -1)
  422. set(_bang_build_shared_libs TRUE)
  423. endif()
  424. # STATIC
  425. list(FIND _bang_wrap_cmake_options STATIC _bang_found_STATIC)
  426. if(_bang_found_STATIC GREATER -1)
  427. set(_bang_build_shared_libs FALSE)
  428. endif()
  429. # BANG_HOST_FLAGS
  430. if(_bang_build_shared_libs)
  431. # If we are setting up code for a shared library, then we need to add extra flags for
  432. # compiling objects for shared libraries.
  433. set(BANG_HOST_SHARED_FLAGS ${CMAKE_SHARED_LIBRARY_${BANG_C_OR_CXX}_FLAGS})
  434. else()
  435. set(BANG_HOST_SHARED_FLAGS)
  436. endif()
  437. # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We
  438. # always need to set the SHARED_FLAGS, though.
  439. set(_bang_host_flags "set(CMAKE_HOST_FLAGS ${CMAKE_${BANG_C_OR_CXX}_FLAGS} ${BANG_HOST_SHARED_FLAGS})")
  440. set(_bang_cncc_flags_config "# Build specific configuration flags")
  441. # Loop over all the configuration types to generate appropriate flags for run_cncc.cmake
  442. foreach(config ${BANG_configuration_types})
  443. string(TOUPPER ${config} config_upper)
  444. # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS
  445. # we convert the strings to lists (like we want).
  446. set(_bang_C_FLAGS "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
  447. set(_bang_host_flags "${_bang_host_flags}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_bang_C_FLAGS})")
  448. # Note that if we ever want BANG_CNCC_FLAGS_<CONFIG> to be string (instead of a list
  449. # like it is currently), we can remove the quotes around the
  450. # ${BANG_CNCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_<CONFIG> variable.
  451. 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}})")
  452. endforeach()
  453. # Process the C++11 flag. If the host sets the flag, we need to add it to cncc and
  454. # remove it from the host. This is because -Xcompile -std=c++ will choke cncc (it uses
  455. # the C preprocessor). In order to get this to work correctly, we need to use cncc's
  456. # specific c++11 flag.
  457. if( "${_bang_host_flags}" MATCHES "-std=c\\+\\+11")
  458. # Add the c++11 flag to cncc if it isn't already present. Note that we only look at
  459. # the main flag instead of the configuration specific flags.
  460. if( NOT "${BANG_CNCC_FLAGS}" MATCHES "-std;c\\+\\+11" )
  461. list(APPEND cncc_flags -std=c++11)
  462. endif()
  463. string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _bang_host_flags "${_bang_host_flags}")
  464. endif()
  465. # Get the list of definitions from the directory property
  466. get_directory_property(BANG_CNCC_DEFINITIONS COMPILE_DEFINITIONS)
  467. if(BANG_CNCC_DEFINITIONS)
  468. foreach(_definition ${BANG_CNCC_DEFINITIONS})
  469. list(APPEND cncc_flags "-D${_definition}")
  470. endforeach()
  471. endif()
  472. if(_bang_build_shared_libs)
  473. list(APPEND cncc_flags "-D${bang_target}_EXPORTS")
  474. endif()
  475. # Reset the output variable
  476. set(_bang_wrap_generated_files "")
  477. # Iterate over the macro arguments and create custom
  478. # commands for all the .cu files.
  479. foreach(file ${ARGN})
  480. # Ignore any file marked as a HEADER_FILE_ONLY
  481. get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
  482. # Allow per source file overrides of the format. Also allows compiling non-.cu files.
  483. get_source_file_property(_bang_source_format ${file} BANG_SOURCE_PROPERTY_FORMAT)
  484. if((${file} MATCHES "\\.mlu$" OR _bang_source_format) AND NOT _is_header)
  485. if(NOT _bang_source_format)
  486. set(_bang_source_format ${format})
  487. endif()
  488. if( ${_bang_source_format} MATCHES "OBJ")
  489. set( bang_compile_to_external_module OFF )
  490. else()
  491. set( bang_compile_to_external_module ON )
  492. if( ${_bang_source_format} MATCHES "MLISA" )
  493. set( bang_compile_to_external_module_type "mlisa" )
  494. elseif( ${_bang_source_format} MATCHES "CNBIN")
  495. set( bang_compile_to_external_module_type "cnbin" )
  496. elseif( ${_bang_source_format} MATCHES "CNFATBIN")
  497. set( bang_compile_to_external_module_type "cnfatbin" )
  498. else()
  499. 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.")
  500. endif()
  501. endif()
  502. if(bang_compile_to_external_module)
  503. # Don't use any of the host compilation flags for MLISA targets.
  504. set(BANG_HOST_FLAGS)
  505. set(BANG_CNCC_FLAGS_CONFIG)
  506. else()
  507. set(BANG_HOST_FLAGS ${_bang_host_flags})
  508. set(BANG_CNCC_FLAGS_CONFIG ${_bang_cncc_flags_config})
  509. endif()
  510. # Determine output directory
  511. bang_compute_build_path("${file}" bang_build_path)
  512. set(bang_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${bang_target}.dir/${bang_build_path}")
  513. if(BANG_GENERATED_OUTPUT_DIR)
  514. set(bang_compile_output_dir "${BANG_GENERATED_OUTPUT_DIR}")
  515. else()
  516. if ( bang_compile_to_external_module )
  517. set(bang_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}")
  518. else()
  519. set(bang_compile_output_dir "${bang_compile_intermediate_directory}")
  520. endif()
  521. endif()
  522. # Add a custom target to generate a c or mlisa file. ######################
  523. get_filename_component( basename ${file} NAME )
  524. if( bang_compile_to_external_module )
  525. set(generated_file_path "${bang_compile_output_dir}")
  526. set(generated_file_basename "${bang_target}_generated_${basename}.${bang_compile_to_external_module_type}")
  527. set(format_flag "-${bang_compile_to_external_module_type}")
  528. file(MAKE_DIRECTORY "${bang_compile_output_dir}")
  529. else()
  530. set(generated_file_path "${bang_compile_output_dir}/${CMAKE_CFG_INTDIR}")
  531. set(generated_file_basename "${bang_target}_generated_${basename}${generated_extension}")
  532. set(format_flag "-c")
  533. endif()
  534. # Set all of our file names. Make sure that whatever filenames that have
  535. # generated_file_path in them get passed in through as a command line
  536. # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time
  537. # instead of configure time.
  538. set(generated_file "${generated_file_path}/${generated_file_basename}")
  539. set(cmake_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.depend")
  540. set(CNCC_generated_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.CNCC-depend")
  541. set(generated_cnbin_file "${generated_file_path}/${generated_file_basename}.cnbin.txt")
  542. set(custom_target_script "${bang_compile_intermediate_directory}/${generated_file_basename}.cmake")
  543. # Setup properties for obj files:
  544. if( NOT bang_compile_to_external_module )
  545. set_source_files_properties("${generated_file}"
  546. PROPERTIES
  547. EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
  548. )
  549. endif()
  550. # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path.
  551. get_filename_component(file_path "${file}" PATH)
  552. if(IS_ABSOLUTE "${file_path}")
  553. set(source_file "${file}")
  554. else()
  555. set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
  556. endif()
  557. # Bring in the dependencies. Creates a variable BANG_CNCC_DEPEND #######
  558. bang_include_cncc_dependencies(${cmake_dependency_file})
  559. # Build the CNCC made dependency file ###################################
  560. set(build_cnbin OFF)
  561. if ( BANG_BUILD_CNBIN )
  562. if ( NOT bang_compile_to_external_module )
  563. set ( build_cnbin ON )
  564. endif()
  565. endif()
  566. # Configure the build script
  567. configure_file("${BANG_run_cncc}" "${custom_target_script}" @ONLY)
  568. # So if a user specifies the same bang file as input more than once, you
  569. # can have bad things happen with dependencies. Here we check an option
  570. # to see if this is the behavior they want.
  571. set(main_dep DEPENDS ${source_file})
  572. if(BANG_VERBOSE_BUILD)
  573. set(verbose_output ON)
  574. elseif(CMAKE_GENERATOR MATCHES "Makefiles")
  575. set(verbose_output "$(VERBOSE)")
  576. else()
  577. set(verbose_output OFF)
  578. endif()
  579. # Create up the comment string
  580. file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
  581. if(bang_compile_to_external_module)
  582. set(bang_build_comment_string "Building CNCC ${bang_compile_to_external_module_type} file ${generated_file_relative_path}")
  583. else()
  584. set(bang_build_comment_string "Building CNCC object ${generated_file_relative_path}")
  585. endif()
  586. set(_verbatim VERBATIM)
  587. if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)")
  588. set(_verbatim "")
  589. endif()
  590. # Build the generated file and dependency file ##########################
  591. add_custom_command(
  592. OUTPUT ${generated_file}
  593. # These output files depend on the source_file and the contents of cmake_dependency_file
  594. ${main_dep}
  595. DEPENDS ${BANG_CNCC_DEPEND}
  596. DEPENDS ${custom_target_script}
  597. # Make sure the output directory exists before trying to write to it.
  598. COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}"
  599. COMMAND ${CMAKE_COMMAND} ARGS
  600. -D verbose:BOOL=${verbose_output}
  601. ${ccbin_flags}
  602. -D build_configuration:STRING=${BANG_build_configuration}
  603. -D "generated_file:STRING=${generated_file}"
  604. -D "generated_cnbin_file:STRING=${generated_cnbin_file}"
  605. -P "${custom_target_script}"
  606. WORKING_DIRECTORY "${bang_compile_intermediate_directory}"
  607. COMMENT "${bang_build_comment_string}"
  608. ${_verbatim}
  609. )
  610. # Make sure the build system knows the file is generated.
  611. set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
  612. list(APPEND _bang_wrap_generated_files ${generated_file})
  613. # Add the other files that we want cmake to clean on a cleanup ##########
  614. list(APPEND BANG_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
  615. list(REMOVE_DUPLICATES BANG_ADDITIONAL_CLEAN_FILES)
  616. set(BANG_ADDITIONAL_CLEAN_FILES ${BANG_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the bang dependency scanning.")
  617. endif()
  618. endforeach()
  619. # Set the return parameter
  620. set(${generated_files} ${_bang_wrap_generated_files})
  621. endmacro()
  622. ###############################################################################
  623. ###############################################################################
  624. # Locate NEUWARE, Set Build Type, etc.
  625. ###############################################################################
  626. ###############################################################################
  627. # BANG_CNCC_EXECUTABLE
  628. find_program(BANG_CNCC_EXECUTABLE
  629. NAMES cncc
  630. PATHS "${NEUWARE_ROOT_DIR}"
  631. ENV NEUWARE_PATH
  632. ENV NEUWARE_BIN_PATH
  633. PATH_SUFFIXES bin bin64
  634. NO_DEFAULT_PATH
  635. )
  636. # Search default search paths, after we search our own set of paths.
  637. find_program(BANG_CNCC_EXECUTABLE cncc)
  638. mark_as_advanced(BANG_CNCC_EXECUTABLE)
  639. ###############################################################################
  640. ###############################################################################
  641. # ADD LIBRARY
  642. ###############################################################################
  643. ###############################################################################
  644. macro(BANG_ADD_LIBRARY bang_target)
  645. BANG_ADD_BANG_INCLUDE_ONCE()
  646. # Separate the sources from the options
  647. BANG_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
  648. BANG_BUILD_SHARED_LIBRARY(_bang_shared_flag ${ARGN})
  649. # Create custom commands and targets for each file.
  650. BANG_WRAP_SRCS( ${bang_target} OBJ _generated_files ${_sources}
  651. ${_cmake_options} ${_bang_shared_flag}
  652. OPTIONS ${_options} )
  653. # Compute the file name of the intermedate link file used for separable
  654. # compilation.
  655. BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${bang_target} "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
  656. # Add the library.
  657. add_library(${bang_target} ${_cmake_options}
  658. ${_generated_files}
  659. ${_sources}
  660. ${link_file}
  661. )
  662. # Add a link phase for the separable compilation if it has been enabled. If
  663. # it has been enabled then the ${bang_target}_SEPARABLE_COMPILATION_OBJECTS
  664. # variable will have been defined.
  665. BANG_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${bang_target} "${_options}" "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
  666. target_link_libraries(${bang_target}
  667. ${BANG_LIBRARIES}
  668. )
  669. # We need to set the linker language based on what the expected generated file
  670. # would be. BANG_C_OR_CXX is computed based on BANG_HOST_COMPILATION_CPP.
  671. set_target_properties(${bang_target}
  672. PROPERTIES
  673. LINKER_LANGUAGE ${BANG_C_OR_CXX}
  674. )
  675. endmacro()
  676. ###############################################################################
  677. ###############################################################################
  678. # ADD EXECUTABLE
  679. ###############################################################################
  680. ###############################################################################
  681. macro(BANG_ADD_EXECUTABLE bang_target)
  682. BANG_ADD_BANG_INCLUDE_ONCE()
  683. # Separate the sources from the options
  684. BANG_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
  685. # Create custom commands and targets for each file.
  686. BANG_WRAP_SRCS( ${bang_target} OBJ _generated_files ${_sources} OPTIONS ${_options} )
  687. # Compute the file name of the intermedate link file used for separable
  688. # compilation.
  689. BANG_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${bang_target} "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
  690. # Add the library.
  691. add_executable(${bang_target} ${_cmake_options}
  692. ${_generated_files}
  693. ${_sources}
  694. ${link_file}
  695. )
  696. # Add a link phase for the separable compilation if it has been enabled. If
  697. # it has been enabled then the ${bang_target}_SEPARABLE_COMPILATION_OBJECTS
  698. # variable will have been defined.
  699. BANG_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${bang_target} "${_options}" "${${bang_target}_SEPARABLE_COMPILATION_OBJECTS}")
  700. target_link_libraries(${bang_target}
  701. ${BANG_LIBRARIES}
  702. )
  703. # We need to set the linker language based on what the expected generated file
  704. # would be. BANG_C_OR_CXX is computed based on BANG_HOST_COMPILATION_CPP.
  705. set_target_properties(${bang_target}
  706. PROPERTIES
  707. LINKER_LANGUAGE ${BANG_C_OR_CXX}
  708. )
  709. endmacro()
  710. #####################################################################################
  711. # This macro invokes the cncc compiler to compile mlu source files, and to generate
  712. # object files.
  713. # INPUT:
  714. # _source_files - List of mlu source files to be compiled
  715. # _include_directories_generator_user - List of user provided include files
  716. # OUTPUT:
  717. # _generated_files - List of generated files
  718. #####################################################################################
  719. macro(BANG_COMPILE _generated_files _source_files _include_directories_generator_user)
  720. # Set up all the command line flags here, so that they can be overridden on a per target basis.
  721. set(cncc_flags "")
  722. set(BANG_C_OR_CXX CXX)
  723. set(generated_extension ${CMAKE_${BANG_C_OR_CXX}_OUTPUT_EXTENSION})
  724. if(BANG_TARGET_CPU_ARCH)
  725. set(cncc_flags ${cncc_flags} "--target=${BANG_TARGET_CPU_ARCH}")
  726. endif()
  727. set( BANG_build_configuration "${CMAKE_BUILD_TYPE}")
  728. set(include_directories_generator ${_include_directories_generator_user})
  729. foreach(dir ${include_directories_generator})
  730. if(dir)
  731. list(APPEND BANG_CNCC_INCLUDE_ARGS -I${dir})
  732. endif()
  733. endforeach()
  734. # Reset these variables
  735. set(BANG_WRAP_OPTION_CNCC_FLAGS)
  736. foreach(config ${BANG_configuration_types})
  737. string(TOUPPER ${config} config_upper)
  738. set(BANG_WRAP_OPTION_CNCC_FLAGS_${config_upper})
  739. endforeach()
  740. BANG_GET_SOURCES_AND_OPTIONS(_bang_wrap_sources _bang_wrap_cmake_options _bang_wrap_options ${_source_files})
  741. BANG_PARSE_CNCC_OPTIONS(BANG_WRAP_OPTION_CNCC_FLAGS ${_bang_wrap_options})
  742. set(BANG_HOST_SHARED_FLAGS)
  743. # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We
  744. # always need to set the SHARED_FLAGS, though.
  745. set(_bang_host_flags "set(CMAKE_HOST_FLAGS ${CMAKE_${BANG_C_OR_CXX}_FLAGS} ${BANG_HOST_SHARED_FLAGS})")
  746. set(_bang_cncc_flags_config "# Build specific configuration flags")
  747. # Loop over all the configuration types to generate appropriate flags for run_cncc.cmake
  748. foreach(config ${BANG_configuration_types})
  749. string(TOUPPER ${config} config_upper)
  750. # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS
  751. # we convert the strings to lists (like we want).
  752. set(_bang_C_FLAGS "${CMAKE_${BANG_C_OR_CXX}_FLAGS_${config_upper}}")
  753. set(_bang_host_flags "${_bang_host_flags}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_bang_C_FLAGS})")
  754. # Note that if we ever want BANG_CNCC_FLAGS_<CONFIG> to be string (instead of a list
  755. # like it is currently), we can remove the quotes around the
  756. # ${BANG_CNCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_<CONFIG> variable.
  757. 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}})")
  758. endforeach()
  759. # Process the C++11 flag. If the host sets the flag, we need to add it to cncc and
  760. # remove it from the host. This is because -Xcompile -std=c++ will choke cncc (it uses
  761. # the C preprocessor). In order to get this to work correctly, we need to use cncc's
  762. # specific c++11 flag.
  763. if( "${_bang_host_flags}" MATCHES "-std=c\\+\\+11")
  764. # Add the c++11 flag to cncc if it isn't already present. Note that we only look at
  765. # the main flag instead of the configuration specific flags.
  766. if( NOT "${BANG_CNCC_FLAGS}" MATCHES "-std;c\\+\\+11" )
  767. list(APPEND cncc_flags -std=c++11)
  768. endif()
  769. string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _bang_host_flags "${_bang_host_flags}")
  770. endif()
  771. # Get the list of definitions from the directory property
  772. get_directory_property(BANG_CNCC_DEFINITIONS COMPILE_DEFINITIONS)
  773. if(BANG_CNCC_DEFINITIONS)
  774. foreach(_definition ${BANG_CNCC_DEFINITIONS})
  775. list(APPEND cncc_flags "-D${_definition}")
  776. endforeach()
  777. endif()
  778. # Reset the output variable
  779. set(_bang_wrap_generated_files "")
  780. # Iterate over the macro arguments and create custom
  781. # commands for all the .cu files.
  782. foreach(file ${_source_files})
  783. # Ignore any file marked as a HEADER_FILE_ONLY
  784. get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
  785. # Allow per source file overrides of the format. Also allows compiling non-.cu files.
  786. get_source_file_property(_bang_source_format ${file} BANG_SOURCE_PROPERTY_FORMAT)
  787. if((${file} MATCHES "\\.mlu$" OR _bang_source_format) AND NOT _is_header)
  788. set(_bang_source_format "OBJ")
  789. set(BANG_HOST_FLAGS ${_bang_host_flags})
  790. set(BANG_CNCC_FLAGS_CONFIG ${_bang_cncc_flags_config})
  791. # Determine output directory
  792. bang_compute_build_path("${file}" bang_build_path)
  793. set(bang_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/bang_compile.dir/${bang_build_path}")
  794. if(BANG_GENERATED_OUTPUT_DIR)
  795. set(bang_compile_output_dir "${BANG_GENERATED_OUTPUT_DIR}")
  796. else()
  797. set(bang_compile_output_dir "${bang_compile_intermediate_directory}")
  798. endif()
  799. # Add a custom target to generate a c or mlisa file. ######################
  800. get_filename_component( basename ${file} NAME )
  801. set(generated_file_path "${bang_compile_output_dir}/${CMAKE_CFG_INTDIR}")
  802. set(generated_file_basename "bang_compile_generated_${basename}${generated_extension}")
  803. set(format_flag "-c")
  804. # Set all of our file names. Make sure that whatever filenames that have
  805. # generated_file_path in them get passed in through as a command line
  806. # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time
  807. # instead of configure time.
  808. set(generated_file "${generated_file_path}/${generated_file_basename}")
  809. set(cmake_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.depend")
  810. set(CNCC_generated_dependency_file "${bang_compile_intermediate_directory}/${generated_file_basename}.CNCC-depend")
  811. set(generated_cnbin_file "${generated_file_path}/${generated_file_basename}.cnbin.txt")
  812. set(custom_target_script "${bang_compile_intermediate_directory}/${generated_file_basename}.cmake")
  813. set_source_files_properties("${generated_file}"
  814. PROPERTIES
  815. EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
  816. )
  817. # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path.
  818. get_filename_component(file_path "${file}" PATH)
  819. if(IS_ABSOLUTE "${file_path}")
  820. set(source_file "${file}")
  821. else()
  822. set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
  823. endif()
  824. # Bring in the dependencies. Creates a variable BANG_CNCC_DEPEND #######
  825. bang_include_cncc_dependencies(${cmake_dependency_file})
  826. # Build the CNCC made dependency file ###################################
  827. set(build_cnbin OFF)
  828. # Configure the build script
  829. configure_file("${BANG_run_cncc}" "${custom_target_script}" @ONLY)
  830. # So if a user specifies the same bang file as input more than once, you
  831. # can have bad things happen with dependencies. Here we check an option
  832. # to see if this is the behavior they want.
  833. set(main_dep DEPENDS ${source_file})
  834. if(BANG_VERBOSE_BUILD)
  835. set(verbose_output ON)
  836. elseif(CMAKE_GENERATOR MATCHES "Makefiles")
  837. set(verbose_output "$(VERBOSE)")
  838. else()
  839. set(verbose_output OFF)
  840. endif()
  841. # Create up the comment string
  842. file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
  843. set(bang_build_comment_string "Building CNCC object ${generated_file_relative_path}")
  844. set(_verbatim VERBATIM)
  845. if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)")
  846. set(_verbatim "")
  847. endif()
  848. # Build the generated file and dependency file ##########################
  849. add_custom_command(
  850. OUTPUT ${generated_file}
  851. # These output files depend on the source_file and the contents of cmake_dependency_file
  852. ${main_dep}
  853. DEPENDS ${BANG_CNCC_DEPEND}
  854. DEPENDS ${custom_target_script}
  855. # Make sure the output directory exists before trying to write to it.
  856. COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}"
  857. COMMAND ${CMAKE_COMMAND} ARGS
  858. -D verbose:BOOL=${verbose_output}
  859. ${ccbin_flags}
  860. -D build_configuration:STRING=${BANG_build_configuration}
  861. -D "generated_file:STRING=${generated_file}"
  862. -D "generated_cnbin_file:STRING=${generated_cnbin_file}"
  863. -P "${custom_target_script}"
  864. WORKING_DIRECTORY "${bang_compile_intermediate_directory}"
  865. COMMENT "${bang_build_comment_string}"
  866. ${_verbatim}
  867. )
  868. # Make sure the build system knows the file is generated.
  869. set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
  870. list(APPEND _bang_wrap_generated_files ${generated_file})
  871. # Add the other files that we want cmake to clean on a cleanup ##########
  872. list(APPEND BANG_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
  873. list(REMOVE_DUPLICATES BANG_ADDITIONAL_CLEAN_FILES)
  874. set(BANG_ADDITIONAL_CLEAN_FILES ${BANG_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the bang dependency scanning.")
  875. endif()
  876. endforeach()
  877. # Set the return parameter
  878. set(${_generated_files} ${_bang_wrap_generated_files})
  879. endmacro()

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台