diff cmake/FindD.cmake @ 132:a860544c5ee8

CMake: initial version of CMakeD script. CMake: MSVC fixes (not work yet). CMake: add experimental option BUILD_SHARED_LIBRARIES.
author SokoL_SD
date Sun, 07 Jun 2009 14:31:36 +0000
parents
children 825ac6364d2f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindD.cmake	Sun Jun 07 14:31:36 2009 +0000
@@ -0,0 +1,532 @@
+##--------------------------------------------
+## Variables.
+##--------------------------------------------
+
+## Find D compiler and parsing its version.
+find_program(DC dmd ldc)
+if (DC)   
+    get_filename_component(dc_path ${DC} PATH)
+    if("${dc_path}" STREQUAL ${CMAKE_BINARY_DIR})
+	get_filename_component(DC ${DC} NAME)
+    endif("${dc_path}" STREQUAL ${CMAKE_BINARY_DIR})
+    exec_program(${DC} ARGS "" OUTPUT_VARIABLE d_output)   
+    string(REGEX MATCH "Digital Mars D Compiler v[0-9]\\.[0-9]+" dmd_version "${d_output}")
+    if (dmd_version)
+	set(D_IS_MARS true)
+	set(D_IS_DMD true)
+	set(D_COMPILER_NAME "Digital Mars D Compiler")
+	string(REGEX REPLACE "Digital Mars D Compiler v([0-9])\\.[0-9]+" "\\1" D_VERSION "${dmd_version}")
+	string(REGEX REPLACE "Digital Mars D Compiler v[0-9]\\.([0-9]+)" "\\1" D_FRONTEND "${dmd_version}")    
+    else (dmd_version)
+	string(REGEX MATCH "LLVM-based D Compiler" is_ldc "${d_output}")   
+	if (is_ldc)
+	    exec_program(${DC} ARGS "--version" OUTPUT_VARIABLE d_output)
+	    string(REGEX MATCH "based on DMD v[0-9]\\.[0-9]+" ldc_version "${d_output}")
+	    set(D_IS_LLVM true)
+	    set(D_IS_LDC true)
+	    if(ldc_version)
+		set(D_IS_LLVM true)
+		set(D_COMPILER_NAME "LLVM-based D Compiler")
+		string(REGEX REPLACE "based on DMD v([0-9])\\.[0-9]+" "\\1" D_VERSION "${ldc_version}")
+		string(REGEX REPLACE "based on DMD v[0-9]\\.([0-9]+)" "\\1" D_FRONTEND "${ldc_version}")	    
+	    else(ldc_version)
+		message(FATAL_ERROR "LDC compiler was found, but the version can not be processed")
+	    endif(ldc_version)
+	else (is_ldc) 
+	    message(FATAL_ERROR "D compliler not found")
+	endif(is_ldc)
+    endif(dmd_version) 
+    message(STATUS "D compiler found -- ${D_COMPILER_NAME} v${D_VERSION}.${D_FRONTEND}")
+else (DC)
+    message(FATAL_ERROR "D compliler not found")
+endif (DC)
+
+## Get D compiler path.
+get_filename_component(DC_PATH ${DC} PATH)
+if("${DC_PATH}" STREQUAL "")
+    find_program(dc_path_tmp ${DC})
+    get_filename_component(DC_PATH ${dc_path_tmp} PATH)
+    mark_as_advanced(dc_path_tmp)
+endif("${DC_PATH}" STREQUAL "")
+get_filename_component(dc_parent_dir ${DC_PATH} NAME)
+if("${dc_parent_dir}" STREQUAL "bin")    	
+    get_filename_component(DC_PATH ${DC_PATH} PATH)
+endif("${dc_parent_dir}" STREQUAL "bin")
+
+#option(ONE_BUILD_COMMAND "Build in one command" "OFF")
+set(ONE_BUILD_COMMAND OFF) ## TODO: test it and uncomment the previous line.
+
+if (NOT ONE_BUILD_COMMAND)
+    ## TODO: disable SINGLE_D_OBJECT option for ldc < rev. 1433.
+    if(D_IS_MARS)
+	set(opt_tmp "ON")
+    else(D_IS_MARS)
+	set(opt_tmp "OFF")
+    endif(D_IS_MARS)   
+    option(SINGLE_D_OBJECT "Build all d sources to one object file" ${opt_tmp})
+    if(SINGLE_D_OBJECT AND D_IS_LLVM)
+	set(D_FLAGS ${D_FLAGS} -singleobj)
+    endif(SINGLE_D_OBJECT AND D_IS_LLVM)
+endif(NOT ONE_BUILD_COMMAND)
+
+## Specifics flags for build configurations.
+## TODO: Add another targets.
+set(D_RELEASE_FLAGS -O -release)
+if(D_IS_LLVM)
+    set(D_RELEASE_FLAGS ${D_RELEASE_FLAGS} -enable-inlining)
+else(D_IS_LLVM)
+    set(D_RELEASE_FLAGS ${D_RELEASE_FLAGS} -inline)
+endif(D_IS_LLVM)
+if(CMAKE_HOST_WIN32)
+    set(D_RELEASE_FLAGS ${D_RELEASE_FLAGS} -L/subsystem:windows)
+endif(CMAKE_HOST_WIN32)   
+set(D_DEBUG_FLAGS -g -gc -debug)
+
+## Settings.
+if(CMAKE_HOST_WIN32)
+    set(D_OBJECT_SUFFIX .obj)
+    if(D_IS_MARS)
+      set(D_LIB_SUFFIX .lib)
+      set(D_LIB_PREFIX )
+    elseif(D_IS_LDC)
+      set(D_LIB_SUFFIX .a)
+      set(D_LIB_PREFIX lib)
+    endif(D_IS_MARS)
+elseif(CMAKE_HOST_UNIX) 
+    set(D_LIB_SUFFIX .a)
+    set(D_LIB_PREFIX lib)
+    set(D_OBJECT_SUFFIX .o)
+endif(CMAKE_HOST_WIN32) 
+
+##--------------------------------------------
+## Macroses and functions.
+##--------------------------------------------
+
+## Make native path.
+## Usage:
+##	set(path c:/file_path/file_name.cpp)
+##	make_native_path(path)
+##	message(STATUS ${path})
+## Output:
+##	-- "c:\file_path\file_name.cpp"
+## Command "file(TO_NATIVE_PATH ...)" is wrong on Windows
+macro(make_native_path pathname)
+    if(CMAKE_HOST_WIN32)
+	# An extra \\ escape is necessary to get a \ through CMake's processing.
+	string(REPLACE "/" "\\" ${pathname} "${${pathname}}")
+	# Enclose with UNESCAPED quotes.  This means we need to escape our
+	# quotes once here, i.e. with \"
+	set(${pathname} \"${${pathname}}\")
+    endif(CMAKE_HOST_WIN32) 
+endmacro(make_native_path)
+
+##
+## Example:
+##	set(path 24.3+23.bin)
+##	obj_path(path)
+##	message(STATUS ${path})
+## Example output:
+##	-- 24\.3\+23\.bin
+macro(regex_safe_string outvariable)
+    set(${outvariable} ${ARGN})
+    set(__regex_chars__ ^ $ . ] [ - * + ? | \( \))
+    foreach(__regex_char__ ${__regex_chars__})
+	string(REPLACE "${__regex_char__}"
+	    "\\${__regex_char__}" ${outvariable} ${${outvariable}}
+	    )
+    endforeach(__regex_char__ ${__regex_chars__})
+endmacro(regex_safe_string outvariable)
+
+## Remove unnecessary path to the object file.
+## path -- path to object file.
+## Example:
+##	set(path ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/target.dir/main.d.obj)
+##	obj_path(path)
+##	message(STATUS ${path})
+## Example output:
+##	-- CMakeFiles/target.dir/main.d.obj
+macro(obj_path path)
+    regex_safe_string(cbd_safe_tmp ${CMAKE_CURRENT_BINARY_DIR})
+    regex_safe_string(csd_safe_tmp ${CMAKE_CURRENT_SOURCE_DIR})
+    set(regexp_str_tmp "(${cbd_safe_tmp}/|${csd_safe_tmp}/|)(.+)")
+    string(REGEX REPLACE ${regexp_str_tmp} "\\2" ${path} "${${path}}") 
+endmacro(obj_path path)
+
+## Compile d files.
+## target -- name of a new target.
+## objects_list -- created object files.
+## params -- sources files.
+macro(compile_d_files target objects_list)
+    set(${objects_list})
+    set(tmp_dir_tmp ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir)
+    
+    set(type_tmp SOURCES)
+    set(SOURCES_tmp )
+    set(FLAGS_tmp )
+
+    ## Parse parameters list.
+    set(params_tmp SOURCES FLAGS)
+    foreach(arg_tmp ${ARGN})
+	set(founded_type_tmp)
+	if(NOT founded_type_tmp)
+	    foreach(param_tmp ${params_tmp})
+		if(arg_tmp STREQUAL param_tmp)	
+		    set(type_tmp ${param_tmp})
+		    set(founded_type_tmp 1)
+		    break(param_tmp ${params_tmp})
+		endif(arg_tmp STREQUAL param_tmp)
+	    endforeach(param_tmp ${params_tmp})	
+	endif(NOT founded_type_tmp)
+	if(NOT founded_type_tmp)
+	    set(${type_tmp}_tmp ${${type_tmp}_tmp} ${arg_tmp})
+	endif(NOT founded_type_tmp)
+    endforeach(arg_tmp ${ARGN})
+
+    if(NOT SINGLE_D_OBJECT)
+	set(${objects_list})
+	foreach (d_source_p_tmp ${SOURCES_tmp})
+	    get_filename_component(ext_tmp ${d_source_p_tmp} EXT)
+	    find_file(d_source_p_tmp ${d_source_p_tmp} PATHS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+		  ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})
+	    set (d_source_tmp ${d_source_p_tmp})
+	    obj_path(d_source_tmp)
+	    set(d_obj_tmp ${tmp_dir_tmp}/${d_source_tmp}${D_OBJECT_SUFFIX})
+	    set(${objects_list} ${${objects_list}} ${d_obj_tmp})
+	    get_filename_component(path_tmp ${d_obj_tmp} PATH)	    
+	    file(MAKE_DIRECTORY ${path_tmp})
+	    set(d_obj_out_tmp ${d_obj_tmp})
+	    obj_path(d_obj_out_tmp)
+	    #get_imported_files(depends_tmp ${d_source_p_tmp}) ## Too slow.....
+	    add_custom_command(OUTPUT "${d_obj_tmp}"
+			COMMAND "${DC}"
+			ARGS ${FLAGS_tmp} ${d_source_p_tmp} -c -of${d_obj_tmp}
+			COMMENT "Building ${d_obj_out_tmp}"
+			DEPENDS ${d_source_p} ${depends_tmp}
+			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+		    )
+	endforeach (d_source_p_tmp ${SOURCES_tmp})
+    else(NOT SINGLE_D_OBJECT)
+	set(object_tmp ${tmp_dir_tmp}/${target}${D_OBJECT_SUFFIX})
+	set(d_obj_out_tmp ${${objects_list}})
+	obj_path(d_obj_out_tmp)
+	set(parameters_tmp ${FLAGS_tmp} -c ${SOURCES_tmp} -of${object_tmp})
+	set(parameters_list_file_tmp ${tmp_dir_tmp}/parameters_obj)
+	if(CMAKE_HOST_WIN32)	
+	    file(REMOVE ${parameters_list_file_tmp})
+	    foreach(arg_tmp ${parameters_tmp})
+		file(APPEND ${parameters_list_file_tmp} "${arg_tmp}\n")
+	    endforeach(arg_tmp)
+	    set(param_tmp @${parameters_list_file_tmp})
+	elseif(CMAKE_HOST_UNIX)
+	    set(param_tmp ${parameters_tmp})
+	endif(CMAKE_HOST_WIN32)
+	#get_imported_files(depends_tmp ${ARGN})
+	add_custom_command(OUTPUT "${object_tmp}"
+			COMMAND "${DC}"
+			ARGS ${param_tmp}
+			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+			DEPENDS ${SOURCES_tmp} ${depends_tmp}
+			COMMENT ""
+		    )
+	set(${objects_list} ${object_tmp})
+    endif(NOT SINGLE_D_OBJECT)
+    #add_custom_target(${target} DEPENDS "${${objects_list}}")
+endmacro(compile_d_files objects_list)
+
+
+## Add D target.
+## name -- target name.
+## Params:
+##	TYPE -- target type.
+##		STATIC -- static library.
+##		SHARED -- shared library.
+##		BINARY -- executable.
+## 	SOURCES -- sources of the target.
+##	INCLUDES -- include paths.
+## 	FLAGS -- build flags.
+##	LIBS -- libraries for link.
+##	LIB_PATHS -- libraries paths.
+##	DEPENDS -- target depends.
+macro(add_d_target name)
+    set(type_tmp SOURCES)
+    set(TYPE_tmp)
+    set(INCLUDES_tmp )
+    set(FLAGS_tmp )
+    set(SOURCES_tmp )
+    set(OBJECTS_tmp )
+    set(LIBS_tmp )
+    set(LIB_PATHS_tmp)
+    set(DEPENDS_tmp)
+    set(OUTPUT_PATH_tmp )
+    set(compile_flags_tmp ${D_FLAGS})
+    set(additional_commands_tmp )
+    set(link_flags_tmp )
+
+    ## Parse parameters list.
+    set(params_tmp TYPE INCLUDES FLAGS SOURCES OBJECTS LIBS LIB_PATHS DEPENDS OUTPUT_PATH)
+    foreach(arg_tmp ${ARGN})
+	set(founded_type_tmp)
+	if(${arg_tmp} STREQUAL "DETECT_DEPENDS")		
+	    set(auto_detect_depentes_tmp 1)
+	    set(founded_type_tmp 1)
+	endif(${arg_tmp} STREQUAL "DETECT_DEPENDS")
+	if(NOT founded_type_tmp)
+	    foreach(param_tmp ${params_tmp})
+		if(arg_tmp STREQUAL param_tmp)	
+		    set(type_tmp ${param_tmp})
+		    set(founded_type_tmp 1)
+		    break(param_tmp ${params_tmp})
+		endif(arg_tmp STREQUAL param_tmp)
+	    endforeach(param_tmp ${params_tmp})	
+	endif(NOT founded_type_tmp)
+	if(NOT founded_type_tmp)
+	    set(${type_tmp}_tmp ${${type_tmp}_tmp} ${arg_tmp})
+	endif(NOT founded_type_tmp)
+    endforeach(arg_tmp ${ARGN})
+
+    ## Init target type.
+    if (OUTPUT_PATH_tmp)
+	set(output_name_tmp "${OUTPUT_PATH_tmp}")
+    endif (OUTPUT_PATH_tmp)
+    if("${TYPE_tmp}" STREQUAL "STATIC")
+	set(link_flags_tmp ${link_flags_tmp} -lib)
+	if(NOT OUTPUT_PATH_tmp)
+	    if(ARCHIVE_OUTPUT_DIRECTORY)
+		set(output_name_tmp ${ARCHIVE_OUTPUT_DIRECTORY})
+	    else(ARCHIVE_OUTPUT_DIRECTORY)
+		set(output_name_tmp ${CMAKE_CURRENT_BINARY_DIR}/lib)	    
+	    endif(ARCHIVE_OUTPUT_DIRECTORY)
+	endif(NOT OUTPUT_PATH_tmp)
+	set(output_name_tmp ${output_name_tmp}/${D_LIB_PREFIX}${name}${D_LIB_SUFFIX})
+    elseif("${TYPE_tmp}" STREQUAL "BINARY")
+	set(build_binary_tmp 1)
+	if(NOT OUTPUT_PATH_tmp)
+	    if(RUNTIME_OUTPUT_DIRECTORY)
+		set(output_name ${RUNTIME_OUTPUT_DIRECTORY})
+	    else(RUNTIME_OUTPUT_DIRECTORY)
+		set(output_name_tmp ${CMAKE_CURRENT_BINARY_DIR}/bin)	    
+	    endif(RUNTIME_OUTPUT_DIRECTORY)
+	endif(NOT OUTPUT_PATH_tmp)
+	set(output_name_tmp ${output_name_tmp}/${name}${CMAKE_EXECUTABLE_SUFFIX})
+    elseif("${TYPE_tmp}" STREQUAL "SHARED")
+	if(D_IS_MARS)
+	    message(FATAL_ERROR "DMD not support building shared library")
+	endif(D_IS_MARS)
+	if(NOT OUTPUT_PATH_tmp)
+	    if(LIBRARY_OUTPUT_DIRECTORY)
+		set(output_name_tmp ${LIBRARY_OUTPUT_DIRECTORY})
+	    else(LIBRARY_OUTPUT_DIRECTORY)
+		set(output_name_tmp ${CMAKE_CURRENT_BINARY_DIR}/lib)	    
+	    endif(LIBRARY_OUTPUT_DIRECTORY)
+	endif(NOT OUTPUT_PATH_tmp)
+	set(build_binary 1)
+	set(output_name_tmp ${output_name_tmp}/${CMAKE_SHARED_LIBRARY_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
+	set(link_flags_tmp ${compile_flags_tmp} -L-shared)
+    else("${TYPE_tmp}" STREQUAL "STATIC")       
+	message(FATAL_ERROR "D target ${TYPE_tmp} not supported")
+    endif("${TYPE_tmp}" STREQUAL "STATIC")
+
+    ## Include paths.
+    foreach(inc_tmp ${INCLUDES_tmp} ${D_INCLUDES})
+	set(compile_flags_tmp ${compile_flags_tmp} -I${inc_tmp})	
+    endforeach(inc_tmp ${INCLUDES_tmp} ${D_INCLUDES})
+    
+    ## Libraries and paths of them.
+    set(libs_tmp)
+    if(build_binary_tmp)
+	if(D_IS_MARS AND CMAKE_HOST_WIN32)
+	    foreach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+		make_native_path(lib_path_tmp)
+		string(REPLACE "/" "\\" lib_path_tmp "${lib_path_tmp}//")
+		set(lib_path_tmp \"${lib_path_tmp}\")
+		set(link_flags_tmp ${link_flags_tmp} -L+${lib_path_tmp})
+	    endforeach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+	    #set(additional_commands_tmp COMMAND set ARGS LIB=)
+	    #foreach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+		#MAKE_NATIVE_PATH(lib_path_tmp)
+		#set(additional_commands_tmp ${additional_commands_tmp}${lib_path_tmp};)
+	    #endforeach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+	else(D_IS_MARS AND CMAKE_HOST_WIN32)
+	    foreach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+		set(link_flags_tmp ${link_flags_tmp} -L-L${lib_path_tmp})
+	    endforeach(lib_path_tmp ${LIB_PATHS_tmp} ${D_LIB_PATHS})
+	endif(D_IS_MARS AND CMAKE_HOST_WIN32)
+	foreach(lib_tmp ${LIBS_tmp} ${D_LIBS})
+	    if(D_IS_MARS AND CMAKE_HOST_WIN32)	    
+		set(link_flags_tmp ${link_flags_tmp} -L+${lib_tmp})
+	    else(D_IS_MARS AND CMAKE_HOST_WIN32)
+		set(link_flags_tmp ${link_flags_tmp} -L-l${lib_tmp})
+	    endif(D_IS_MARS AND CMAKE_HOST_WIN32)
+	endforeach(lib_tmp ${LIBS_tmp} ${D_LIBS})
+    endif(build_binary_tmp)
+		
+    set(not_obj_tmp ${ONE_BUILD_COMMAND})
+    ## Ldc not support -lib flag.
+    if(ONE_BUILD_COMMAND AND ${TYPE_tmp} STREQUAL "STATIC" AND D_IS_LLVM)
+	set(not_obj_tmp OFF)
+    endif(ONE_BUILD_COMMAND AND ${TYPE_tmp} STREQUAL "STATIC" AND D_IS_LLVM)
+
+    if(build_binary_tmp AND NOT D_IS_MARS)
+	set(compile_flags_tmp ${compile_flags_tmp} -od${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}.dir)
+    endif(build_binary_tmp AND NOT D_IS_MARS)
+
+    if(CMAKE_BUILD_TYPE)
+	string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER)
+	set(compile_flags_tmp ${compile_flags_tmp} ${D_${CMAKE_BUILD_TYPE_UPPER}_FLAGS})
+    endif(CMAKE_BUILD_TYPE)
+
+    if(auto_detect_depentes_tmp)
+	get_files_depends(SOURCES_tmp ${SOURCES_tmp})
+    endif(auto_detect_depentes_tmp)
+    
+    set(used_ar_tmp)
+    get_filename_component(output_path_tmp ${output_name_tmp} PATH)
+    if (NOT not_obj_tmp)
+	compile_d_files(${name} objs_tmp ${SOURCES_tmp} FLAGS ${compile_flags_tmp})
+	set(SOURCES_tmp ${objs_tmp})
+	if(NOT D_IS_MARS AND ${TYPE_tmp} STREQUAL "STATIC")
+	    set(parameters_tmp rcs ${output_name_tmp} ${SOURCES_tmp} ${OBJECTS_tmp})
+	    set(parameters_list_file_tmp ${tmp_dir_tmp}/parameters)
+	    if(CMAKE_HOST_WIN32)	
+		file(REMOVE ${parameters_list_file_tmp})
+		foreach(arg_tmp ${parameters_tmp})
+		    file(APPEND ${parameters_list_file_tmp} "${arg_tmp}\n")
+		endforeach(arg_tmp)
+		set(param_tmp @${parameters_list_file_tmp})
+	    elseif(CMAKE_HOST_UNIX)
+		set(param_tmp ${parameters_tmp})
+	    endif(CMAKE_HOST_WIN32)
+	    add_custom_command(
+				OUTPUT "${output_name_tmp}"
+				COMMAND "${CMAKE_AR}"
+				ARGS ${param_tmp}
+				DEPENDS ${SOURCES_tmp}
+				COMMENT "Linking ${lib_name}"
+			    )
+	    set(used_ar_tmp 1)
+	endif(NOT D_IS_MARS AND ${TYPE_tmp} STREQUAL "STATIC")
+    endif (NOT not_obj_tmp)
+
+    if (NOT used_ar_tmp)
+	set(output_name_native_tmp ${output_name_tmp})
+	if(D_IS_MARS)
+	    set(additional_commands_tmp ${additional_commands_tmp} COMMAND ${CMAKE_COMMAND} -E make_directory ${output_path_tmp})
+	    make_native_path(output_name_native_tmp)
+	endif(D_IS_MARS)
+	set(parameters_tmp ${compile_flags_tmp} ${link_flags_tmp} ${SOURCES_tmp} ${OBJECTS_tmp} -of${output_name_native_tmp})
+	set(parameters_list_file_tmp ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}.dir/parameters)
+	if(CMAKE_HOST_WIN32)	
+	    file(REMOVE ${parameters_list_file_tmp})
+	    foreach(arg_tmp ${parameters_tmp})
+		file(APPEND ${parameters_list_file_tmp} "${arg_tmp}\n")
+	    endforeach(arg_tmp)
+	    set(param_tmp @${parameters_list_file_tmp})
+	elseif(CMAKE_HOST_UNIX)
+	    set(param_tmp ${parameters_tmp})
+	endif(CMAKE_HOST_WIN32)	
+	#get_imported_files(depends_tmp ${SOURCES_tmp})
+	add_custom_command(
+		      OUTPUT ${output_name_tmp}
+		      ${additional_commands_tmp}
+		      COMMAND ${DC}
+		      ARGS ${param_tmp}
+		      DEPENDS  ${SOURCES_tmp} ${depends_tmp}
+		      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+		      COMMENT "Linking ${name}"
+		  )
+    endif(NOT used_ar_tmp)
+    add_custom_target(${name} ALL DEPENDS ${DEPENDS_tmp} ${output_name_tmp})
+endmacro(add_d_target name)
+
+## Add static library target.
+macro(add_d_static_lib name)
+    add_d_target(${name} TYPE STATIC SOURCES ${ARGN})
+endmacro(add_d_static_lib name)
+
+## Add binary target.
+macro(add_d_program name)
+    add_d_target(${name} TYPE BINARY SOURCES ${ARGN})
+endmacro(add_d_program name)
+
+## Add shared library target.
+macro(add_d_shared_lib name)
+    add_d_target(${name} TYPE SHARED SOURCES ${ARGN})
+endmacro(add_d_shared_lib name)
+
+## Add library target.
+## If it support library would shared.
+macro(add_d_lib name)
+    if(D_IS_MARS)
+	add_d_target(${name} TYPE STATIC ${ARGN})
+    else(D_IS_MARS)
+	add_d_target(${name} TYPE SHARED ${ARGN})
+    endif(D_IS_MARS)
+endmacro(add_d_lib name)
+
+## 
+macro(get_imported_files imported)
+    execute_process(COMMAND ${DC} -c -o- -v ${compile_flags_tmp} ${ARGN}
+                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                  OUTPUT_VARIABLE dc_output_tmp
+    )
+    string(REGEX MATCHALL "import[^\\(]*([^\\)]*)" dc_output_tmp "${dc_output_tmp}")
+    set(${imported})
+    foreach(import_tmp ${dc_output_tmp})
+	string(REGEX REPLACE "import[^\\(]*\\(([^\\)]*)" "\\1" import_tmp ${import_tmp})
+	set(${imported} ${${imported}} ${import_tmp})
+    endforeach(import_tmp ${dc_output_tmp})
+endmacro(get_imported_files imported)
+
+macro(filter_paths result)
+    set(${result})
+    set(read_now_tmp paths)
+    set(include_tmp)
+    set(paths_tmp)
+    foreach(arg_tmp ${ARGN})
+	set(founded_tmp)
+	if(${arg_tmp} STREQUAL "INCLUDE_PATHS")
+	    set(read_now_tmp includes)
+	    set(founded_tmp 1)
+	elseif(${arg_tmp} STREQUAL "INCLUDE_CURRENT_DIR")
+	    set(locale_tmp 1)
+	    set(read_now_tmp paths)
+	    set(founded_tmp 1)
+	endif(${arg_tmp} STREQUAL "INCLUDE_PATHS")
+	if(NOT founded_tmp)
+	    set(${read_now_tmp}_tmp ${${read_now_tmp}_tmp} ${arg_tmp})
+	endif(NOT founded_tmp)
+    endforeach(arg_tmp ${ARGN}) 
+    regex_safe_string(include_tmp ${includes_tmp})
+    set(regex_include_tmp)
+    set(is_first_tmp 1)
+    foreach(include_tmp ${includes_tmp})
+	if(is_first_tmp)
+	    set(is_first_tmp 1)
+	else(is_first_tmp)
+	    set(regex_includes_tmp ${regex_includes_tmp}|)
+	endif(is_first_tmp)
+	set(regex_includes_tmp ${regex_includes_tmp}${include_tmp})
+    endforeach(include_tmp ${include_tmp})
+    foreach(path_tmp ${paths_tmp})	
+	file(TO_CMAKE_PATH path_tmp ${path_tmp})	
+	string(REGEX MATCH "(${regex_includes_tmp})[^/]*" found "${path_tmp}")	
+	set(full_path_tmp 1)
+	if(locale_tmp)
+	    string(SUBSTRING "${path_tmp}" 0 1 first_sym_tmp)
+	    set(full_path_tmp)
+	    if(${first_sym_tmp} STREQUAL "/")
+		set(full_path_tmp 1)
+	    endif(${first_sym_tmp} STREQUAL "/")
+	endif(locale_tmp)
+	if(NOT found AND full_path_tmp)
+	else(NOT found AND full_path_tmp)	    
+	    set(${result} ${${result}} ${path_tmp})
+	endif(NOT found AND full_path_tmp)		
+    endforeach(path_tmp ${paths_tmp})
+endmacro(filter_paths )
+
+macro(get_files_depends out)
+    get_imported_files(${out} ${ARGN})
+    filter_paths(${out} ${${out}} INCLUDE_CURRENT_DIR INCLUDE_PATHS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+    set(${out} ${ARGN} ${${out}})
+endmacro(get_files_depends out)
\ No newline at end of file