[PATCH] [CMake][VS][XCode] Restruct the output directory layout more comfortable, ${BINARY_DIR}/${BUILD_MODE}/(bin|lib)

NAKAMURA Takumi geek4civic at gmail.com
Fri Dec 20 19:12:23 PST 2013


We have been seeing nasty directory layout with CMake multiconfig, such as,
  bin/Release/clang.exe
  lib/clang/3.x/...
  lib/Release/clang/3.x/..
I propose to change the layout similar to autoconf's;
  Release/bin/clang.exe
  Release/lib/clang/3.x/...

I also introduce enhancement to llvm-lit in multiconfig.
To invoke llvm-lit,
  Release/bin/llvm-lit.py <param...>
instead of
  bin/llvm-lit.py --param build_mode=Release <param...>

Checked on Visual Studio 10. Could you guys please confirm my change on XCode(and other multiconfig builders)?

Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more, or a certain builder, for eaxample, msbuild.exe, would be confused.

http://llvm-reviews.chandlerc.com/D2453

Files:
  clang/CMakeLists.txt
  clang/lib/Headers/CMakeLists.txt
  llvm/CMakeLists.txt
  llvm/cmake/modules/AddLLVM.cmake
  llvm/utils/llvm-lit/CMakeLists.txt
  llvm/utils/llvm-lit/llvm-lit.in

Index: clang/CMakeLists.txt
===================================================================
--- clang/CMakeLists.txt
+++ clang/CMakeLists.txt
@@ -174,8 +174,8 @@
 set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
 
-set(CLANG_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR})
-set(CLANG_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib/${CMAKE_CFG_INTDIR})
+set(CLANG_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
+set(CLANG_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
 
 if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
   message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
@@ -340,6 +340,7 @@
     set(libkind)
   endif()
   add_library( ${name} ${libkind} ${srcs} )
+  set_output_directory(${name} ${CLANG_RUNTIME_OUTPUT_INTDIR} ${CLANG_LIBRARY_OUTPUT_INTDIR})
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
   endif( LLVM_COMMON_DEPENDS )
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -47,14 +47,7 @@
   module.map
   )
 
-set(output_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/clang/${CLANG_VERSION}/include)
-
-# If we are in an IDE that has a configuration directory, we need to
-# create a second copy of the headers so that 'clang' can find them if
-# it's run from the build directory.
-if(MSVC_IDE OR XCODE)
-   set(other_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib/clang/${CLANG_VERSION}/include)
-endif()
+set(output_dir ${CLANG_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include)
 
 # Generate arm_neon.h
 clang_tablegen(arm_neon.h -gen-arm-neon
@@ -69,43 +62,17 @@
     COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
     COMMENT "Copying clang's ${f}...")
   list(APPEND out_files ${dst})
-
-  if(other_output_dir)
-   set(other_dst ${other_output_dir}/${f})
-    add_custom_command(OUTPUT ${other_dst}
-      DEPENDS ${src}
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${other_dst}
-      COMMENT "Copying clang's ${f}...")    
-    list(APPEND out_files ${other_dst})
-  endif()
 endforeach( f )
 
 add_custom_command(OUTPUT ${output_dir}/arm_neon.h 
   DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
   COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h ${output_dir}/arm_neon.h
   COMMENT "Copying clang's arm_neon.h...")
 list(APPEND out_files ${output_dir}/arm_neon.h)
 
-if (other_output_dir)
-    set(other_dst ${other_output_dir}/arm_neon.h)
-    add_custom_command(OUTPUT ${other_dst}
-      DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h ${other_dst}
-      COMMENT "Copying clang's arm_neon.h...")
-    list(APPEND out_files ${other_dst})
-endif ()
-
 add_custom_target(clang-headers ALL DEPENDS ${out_files})
 set_target_properties(clang-headers PROPERTIES FOLDER "Misc")
 
-if (other_output_dir)
-  if(UNIX)
-    add_custom_command(TARGET clang-headers POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}"
-    COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib/clang" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang")
-  endif()
-endif ()
-
 install(
   FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
Index: llvm/CMakeLists.txt
===================================================================
--- llvm/CMakeLists.txt
+++ llvm/CMakeLists.txt
@@ -97,8 +97,8 @@
 set(LLVM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
 set(LLVM_LIBDIR_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
 
-set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR})
-set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/lib/${CMAKE_CFG_INTDIR})
+set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
+set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
 
 set(LLVM_ALL_TARGETS
   AArch64
Index: llvm/cmake/modules/AddLLVM.cmake
===================================================================
--- llvm/cmake/modules/AddLLVM.cmake
+++ llvm/cmake/modules/AddLLVM.cmake
@@ -2,9 +2,30 @@
 include(LLVMProcessSources)
 include(LLVM-Config)
 
+# Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}.
+# Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more,
+# or a certain builder, for eaxample, msbuild.exe, would be confused.
+function(set_output_directory target bindir libdir)
+  if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
+    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
+      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
+      string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${bindir})
+      string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${libdir})
+      set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi})
+      set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
+      set_target_properties(${target} PROPERTIES "LIBDIR__OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
+    endforeach()
+  else()
+    set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${bindir})
+    set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libdir})
+    set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libdir})
+  endif()
+endfunction()
+
 macro(add_llvm_library name)
   llvm_process_sources( ALL_FILES ${ARGN} )
   add_library( ${name} ${ALL_FILES} )
+  set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
   set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} )
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
@@ -92,6 +113,7 @@
     add_executable(${name} ${ALL_FILES})
   endif()
   set(EXCLUDE_FROM_ALL OFF)
+  set_output_directory(${name} ${LLVM_RUNTIME_OUTPUT_INTDIR} ${LLVM_LIBRARY_OUTPUT_INTDIR})
   llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
@@ -204,12 +226,13 @@
 
 # Generic support for adding a unittest.
 function(add_unittest test_suite test_name)
-  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
   if( NOT LLVM_BUILD_TESTS )
     set(EXCLUDE_FROM_ALL ON)
   endif()
 
   add_llvm_executable(${test_name} ${ARGN})
+  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
+  set_output_directory(${test_name} ${outdir} ${outdir})
   target_link_libraries(${test_name}
     gtest
     gtest_main
Index: llvm/utils/llvm-lit/CMakeLists.txt
===================================================================
--- llvm/utils/llvm-lit/CMakeLists.txt
+++ llvm/utils/llvm-lit/CMakeLists.txt
@@ -3,7 +3,17 @@
   set(suffix .py)
 endif ()
 
-configure_file(
-  llvm-lit.in
-  ${LLVM_TOOLS_BINARY_DIR}/llvm-lit${suffix}
-  )
+if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
+  foreach (BUILD_MODE ${CMAKE_CONFIGURATION_TYPES})
+    configure_file(
+      llvm-lit.in
+      ${CMAKE_BINARY_DIR}/${BUILD_MODE}/bin/llvm-lit${suffix}
+      )
+  endforeach ()
+else()
+  set(BUILD_MODE .)
+  configure_file(
+    llvm-lit.in
+    ${CMAKE_BINARY_DIR}/bin/llvm-lit${suffix}
+    )
+endif ()
Index: llvm/utils/llvm-lit/llvm-lit.in
===================================================================
--- llvm/utils/llvm-lit/llvm-lit.in
+++ llvm/utils/llvm-lit/llvm-lit.in
@@ -13,7 +13,7 @@
 # Set up some builtin parameters, so that by default the LLVM test suite
 # configuration file knows how to find the object tree.
 builtin_parameters = {
-    'build_mode' : "@CMAKE_CFG_INTDIR@",
+    'build_mode' : "@BUILD_MODE@",
     'llvm_site_config' : os.path.join(llvm_obj_root, 'test', 'lit.site.cfg'),
     'llvm_unit_site_config' : os.path.join(llvm_obj_root, 'test', 'Unit',
                                            'lit.site.cfg')
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2453.1.patch
Type: text/x-patch
Size: 8147 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131220/070f3c6d/attachment.bin>


More information about the cfe-commits mailing list