ldc/cmake/Modules/BuildDExecutable.cmake
Martin Kinkelin e445d9e03e CMake: Add option COMPILE_D_MODULES_SEPARATELY
And enable it for 1st Shippable build, decreasing the build time by a
very rough 3 minutes.
2018-11-17 14:29:55 +01:00

76 lines
3.2 KiB
CMake

# Depends on these global variables:
# - COMPILE_D_MODULES_SEPARATELY
# - D_COMPILER
# - D_COMPILER_FLAGS
# - DDMD_DFLAGS
# - DDMD_LFLAGS
# - LDC_LINK_MANUALLY
# - LDC_LINKERFLAG_LIST
# - LDC_TRANSLATED_LINKER_FLAGS
function(build_d_executable output_exe d_src_files compiler_args linker_args extra_compile_deps link_deps)
set(dflags "${D_COMPILER_FLAGS} ${DDMD_DFLAGS}")
if(UNIX)
separate_arguments(dflags UNIX_COMMAND "${dflags}")
else()
separate_arguments(dflags WINDOWS_COMMAND "${dflags}")
endif()
get_filename_component(exe_basename ${output_exe} NAME_WE) # no path, no extension
set(object_files)
if(NOT COMPILE_D_MODULES_SEPARATELY)
# Compile all D modules to a single object.
set(object_file ${PROJECT_BINARY_DIR}/obj/${exe_basename}${CMAKE_CXX_OUTPUT_EXTENSION})
add_custom_command(
OUTPUT ${object_file}
COMMAND ${D_COMPILER} -c ${dflags} -of${object_file} ${compiler_args} ${d_src_files}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${d_src_files} ${extra_compile_deps}
)
set(object_files ${object_file})
else()
# Compile each D module separately.
foreach(f ${d_src_files})
file(RELATIVE_PATH object_file ${PROJECT_SOURCE_DIR} ${f}) # make path relative to PROJECT_SOURCE_DIR
string(REGEX REPLACE "[/\\\\]" "." object_file "${object_file}") # replace path separators with '.'
string(REGEX REPLACE "^\\.+" "" object_file "${object_file}") # strip leading dots (e.g., from original '../dir/file.d' => '...dir.file.d' => 'dir.file.d')
set(object_file ${PROJECT_BINARY_DIR}/obj/${exe_basename}/${object_file}${CMAKE_CXX_OUTPUT_EXTENSION})
add_custom_command(
OUTPUT ${object_file}
COMMAND ${D_COMPILER} -c ${dflags} -of${object_file} ${compiler_args} ${f}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${f} ${extra_compile_deps}
)
list(APPEND object_files ${object_file})
endforeach()
endif()
# Use a response file on Windows when compiling separately, in order not to
# exceed the max command-line length.
set(objects_args "${object_files}")
if(WIN32 AND COMPILE_D_MODULES_SEPARATELY)
string(REPLACE ";" " " objects_args "${object_files}")
file(WRITE ${output_exe}.rsp ${objects_args})
set(objects_args "@${output_exe}.rsp")
endif()
# Link to an executable.
if(LDC_LINK_MANUALLY)
add_custom_command(
OUTPUT ${output_exe}
COMMAND ${CMAKE_CXX_COMPILER} -o ${output_exe} ${objects_args} ${linker_args} ${LDC_LINKERFLAG_LIST}
DEPENDS ${object_files} ${link_deps}
)
else()
set(translated_linker_args "")
foreach(f ${linker_args})
list(APPEND translated_linker_args "-L${f}")
endforeach()
add_custom_command(
OUTPUT ${output_exe}
COMMAND ${D_COMPILER} ${dflags} ${DDMD_LFLAGS} -of${output_exe} ${objects_args} ${translated_linker_args} ${LDC_TRANSLATED_LINKER_FLAGS}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${object_files} ${link_deps}
)
endif()
endfunction()