سؤال

أريد أن منع الناس من التبعثر مصدرنا شجرة ولدت CMake الملفات...والأهم من ذلك عدم السماح لهم من داس على القائمة Makefiles التي لا تشكل جزءا من نفس بناء العملية نقوم باستخدام CMake على.(أفضل أن لا يسأل)

الطريقة التي كنت قد حان حتى مع للقيام بذلك هو أن يكون بضعة أسطر في الجزء العلوي من بلدي CMakeLists.txt, على النحو التالي:

if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
   message(SEND_ERROR "In-source builds are not allowed.")
endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")

بيد أن تفعل ذلك بهذه الطريقة يبدو مطول جدا.بالإضافة إلى ذلك, إذا حاولت في المصدر بناء عليه لا يزال يخلق من CMakeFiles/ الدليل ، CMakeCache.txt الملف في المصدر شجرة قبل أن يتم طرح الخطأ.

أنا في عداد المفقودين أفضل طريقة للقيام بذلك ؟

هل كانت مفيدة؟

المحلول

وأعتقد أنني أحب طريقك. قائمة cmake البريدية يقوم بعمل جيد في الإجابة على هذه الأنواع من الأسئلة.

وكملاحظة جانبية: هل يمكن إنشاء "cmake" الملف القابل للتنفيذ في الدليل الذي فشل. اعتمادا على ما إذا كان أو لا "." في طريقهم (لينكس). هل يمكن حتى الرمزي / بن / خطأ.

في النوافذ، ولست متأكدا إذا تم العثور على الملف في الدليل الحالي الأول أم لا.

نصائح أخرى

وCMake خيارين لا يحملون وثائق: CMAKE_DISABLE_SOURCE_CHANGES وCMAKE_DISABLE_IN_SOURCE_BUILD

cmake_minimum_required (VERSION 2.8)

# add this options before PROJECT keyword
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

project (HELLO)

add_executable (hello hello.cxx)

-

andrew@manchester:~/src% cmake .
CMake Error at /usr/local/share/cmake-2.8/Modules/CMakeDetermineSystem.cmake:160 (FILE):
  file attempted to write a file: /home/andrew/src/CMakeFiles/CMakeOutput.log
  into a source directory.

و/home/selivanov/cmake-2.8.8/Source/cmMakefile.cxx

bool cmMakefile::CanIWriteThisFile(const char* fileName)
{
  if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
    {
    return true;
    }
  // If we are doing an in-source build, than the test will always fail
  if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
                               this->GetHomeOutputDirectory()) )
    {
    if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
      {
      return false;
      }
    return true;
    }

  // Check if this is subdirectory of the source tree but not a
  // subdirectory of a build tree
  if ( cmSystemTools::IsSubDirectory(fileName,
      this->GetHomeDirectory()) &&
    !cmSystemTools::IsSubDirectory(fileName,
      this->GetHomeOutputDirectory()) )
    {
    return false;
    }
  return true;
}

تشمل وظيفة مثل هذا واحد.هو على غرار ما تفعله مع هذه الاختلافات:

  1. وهي مغلفة في وظيفة ، وهو ما يسمى عند وتشمل PreventInSourceBuilds.cmake وحدة نمطية.الرئيسي الخاص بك CMakeLists.txt يجب أن يشمل ذلك:

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake)
    include(PreventInSourceBuilds)
    
  2. ويستخدم get_filename_component() مع REALPATH المعلمة أن يحل روابط الرمزية قبل مقارنة المسارات.

في حالة جيثب الرابط التغييرات هنا هي وحدة شفرة المصدر (والتي ينبغي أن توضع في PreventInSouceBuilds.cmake, في دليل يسمى CMake, في المثال أعلاه):

#
# This function will prevent in-source builds
function(AssureOutOfSourceBuilds)
  # make sure the user doesn't play dirty with symlinks
  get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
  get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)

  # disallow in-source builds
  if("${srcdir}" STREQUAL "${bindir}")
    message("######################################################")
    message("# ITK should not be configured & built in the ITK source directory")
    message("# You must run cmake in a build directory.")
    message("# For example:")
    message("# mkdir ITK-Sandbox ; cd ITK-sandbox")
    message("# git clone http://itk.org/ITK.git # or download & unpack the source tarball")
    message("# mkdir ITK-build")
    message("# this will create the following directory structure")
    message("#")
    message("# ITK-Sandbox")
    message("#  +--ITK")
    message("#  +--ITK-build")
    message("#")
    message("# Then you can proceed to configure and build")
    message("# by using the following commands")
    message("#")
    message("# cd ITK-build")
    message("# cmake ../ITK # or ccmake, or cmake-gui ")
    message("# make")
    message("#")
    message("# NOTE: Given that you already tried to make an in-source build")
    message("#       CMake have already created several files & directories")
    message("#       in your source tree. run 'git status' to find them and")
    message("#       remove them by doing:")
    message("#")
    message("#       cd ITK-Sandbox/ITK")
    message("#       git clean -n -d")
    message("#       git clean -f -d")
    message("#       git checkout --")
    message("#")
    message("######################################################")
    message(FATAL_ERROR "Quitting configuration")
  endif()
endfunction()

AssureOutOfSourceBuilds()

ولدي وظيفة قذيفة cmake() في بلدي .bashrc / .zshrc مشابهة لهذه واحدة:

function cmake() {
  # Don't invoke cmake from the top-of-tree
  if [ -e "CMakeLists.txt" ]
  then
    echo "CMakeLists.txt file present, cowardly refusing to invoke cmake..."
  else
    /usr/bin/cmake $*
  fi
}

وأنا أفضل هذا الحل حفل منخفضة. أنها حصلت على التخلص من أكبر شكوى زملائي عندما تحولنا إلى CMake، لكنه لا يمنع الناس الذين <م> حقا تريد القيام في المصدر / أعلى من شجرة بناء من القيام بذلك، فهم يمكن فقط استدعاء /usr/bin/cmake مباشرة (أو عدم استخدام وظيفة المجمع على الإطلاق). وانها <م> غبي بسيطة.

ويمكنك تكوين ملف .bashrc الخاصة بك مثل هذا واحد

ونظرة على وظائف <م> cmakekde و <م> kdebuild . تعيين BUILD وSRC الحياة الفطرية. المتغيرات وتحرير هذه الوظائف وفقا لاحتياجاتك. وهذا بناء فقط في buildDir بدلا من <م> srcDir

لتلك الموجودة على لينكس:

وإضافة إلى المستوى الأعلى CMakeLists.txt:

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

وإنشاء ملف "dotme" في المستوى الأعلى أو إضافة إلى .bashrc الخاص بك (على مستوى العالم):

#!/bin/bash
cmk() { if [ ! -e $1/CMakeLists.txt ] || ! grep -q "set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)" $1/CMakeLists.txt;then /usr/bin/cmake $*;else echo "CMAKE_DISABLE_IN_SOURCE_BUILD ON";fi }

alias cmake=cmk

وتشغيل الآن:

. ./dotme

وعند محاولة تشغيل cmake في شجرة مصدر رفيع المستوى:

$ cmake .
CMAKE_DISABLE_IN_SOURCE_BUILD ON

ولا CMakeFiles / أو CMakeCache.txt يحصل إنشاؤه.

عند القيام الخروج من مصدر بناء وتحتاج إلى تشغيل cmake مرة الأولى مجرد دعوة للتنفيذ الفعلي:

$ cd build
$ /usr/bin/cmake ..

وجعل مجرد دليل للقراءة فقط من قبل الشعب / العمليات القيام يبني. تكون هناك عملية منفصلة بسحب إلى الدليل من التحكم بالمصادر (كنت تستخدم التحكم بالمصادر، أليس كذلك؟)، ثم يجعل من قراءة فقط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top