2012-08-12 15 views
5

पर एक बाहरी स्रोत निर्देशिका जोड़ें मैं अपने प्रोजेक्ट के लिए Google मॉक का उपयोग कर रहा हूं, और निर्देशों का कहना है कि परियोजना के साथ पुस्तकालय का निर्माण करना बेहतर है, क्योंकि विभिन्न कंपाइलर झंडे बग पेश कर सकते हैं। मैं अपने भंडार में gmock/निर्देशिका नहीं जोड़ना चाहता; मैं स्रोतों को बाहरी निर्भरता के रूप में रखना चाहता हूं और इसे अपनी निर्माण प्रक्रिया में प्लग करना चाहता हूं। जो मुझे मेरे प्रश्न पर लाता है: मैं बाहरी स्रोत निर्देशिका को निर्माण में खींचने के लिए सीएमके को कैसे निर्देश दे सकता हूं (यानी इसे मेरे प्रोजेक्ट की बिल्ड निर्देशिका में बनाएं)? मुझे यहां एक similar question मिला, लेकिन उत्तरों के लिए एक कठोर निर्देशिका प्लेसमेंट की आवश्यकता है, और मैं इसके बजाय कॉन्फ़िगर करने योग्य होगा। ऐसा करने का कोई और तरीका?एक सीएमके निर्माण

उत्तर

6

मुझे लगता है कि Google मॉक सीएमके का समर्थन करता है। इस मामले में आप सिर्फ जड़ CMakeLists.txt में इस लाइन

add_subdirectory(${GOOGLE_MOCK_SOURCE_DIR}) 

जोड़ सकते हैं और उपयोगकर्ता विन्यास चरण के दौरान GOOGLE_MOCK_SOURCE_DIR चर सेट कर सकते हैं:

set(GOOGLE_MOCK_SOURCE_DIR "" CACHE PATH "Path to the GMock source") 
if(NOT ${GOOGLE_MOCK_SOURCE_DIR} OR NOT EXISTS "${GOOGLE_MOCK_SOURCE_DIR}/CMakeLists.txt") 
    message(FATAL_ERROR "GOOGLE_MOCK_SOURCE_DIR isn't set properly!") 
endif() 
+0

+1 युक्त है हालांकि आप अभी भी include_directories' '$ {GOOGLE_MOCK_SOURCE_DIR} के लिए कहता है' के एक जोड़े आवश्यकता होगी/googlemock/include' और '$ {GOOGLE_MOCK_SOURCE_DIR}/googlemock/gtest/शामिल करें 'मुझे लगता है। – Fraser

+0

इसके अलावा, यह वास्तव में "बाहरी स्रोत निर्देशिका को निर्माण में खींचता नहीं है", लेकिन यह शायद महत्वपूर्ण नहीं है। – Fraser

+0

यह काम नहीं करेगा, जब तक कि स्रोत निर्देशिका मेरे पेड़ के अंदर न हो (यह नहीं है)। मैंने कोशिश की पहली बात है। :-) –

7

आप इस के लिए ExternalProject_Add इस्तेमाल कर सकते हैं, क्योंकि यह डाउनलोड करने के लिए आप की सुविधा देता है , अपने प्रोजेक्ट के निर्माण पेड़ के भीतर से gmock को कॉन्फ़िगर करें और बनाएं, और उसके बाद gmock लाइब्रेरी से लिंक करें।

@ arrowdodger's answer शायद इस बारे में जाने का अधिक सामान्य तरीका है। अपनी विधि का उपयोग करते हुए, आपके पास आमतौर पर आपके निर्माण पेड़ में जीएमॉक स्रोत नहीं होते हैं। आप जो चाहते हैं उसके आधार पर यह अच्छा या बुरा हो सकता है।

ExternalProject_Add का उपयोग करते हुए, जब भी आप gmock या आश्रित लक्ष्य बनाते हैं तो gmock स्रोत खींचे जाते हैं (svn अद्यतन)। यह थोड़ा धीमा बनाता है, लेकिन स्पष्ट रूप से स्रोतों को अद्यतित रखता है और सुविधाजनक है (डेवलपर्स इंस्टॉल करने के लिए यह एक कम निर्भरता है)। जीएमॉक जैसी परियोजना के लिए जो अक्सर नहीं बदलता है, हालांकि हर समय अपडेट करने का ओवरहेड आपके लिए बहुत अधिक हो सकता है।

निम्नलिखित CMakeLists.txt विजुअल स्टूडियो 2010 & 2012 का उपयोग करके काम करता है - इसे अन्य प्लेटफ़ॉर्म के लिए समायोजित करने की आवश्यकता हो सकती है। विशेष रूप से, gtest वर्तमान में विजुअल स्टूडियो 2012 (इस bug report देखें) का उपयोग करके बॉक्स को बनाने में विफल रहता है, इसलिए पैच फ़ाइल और PATCH_COMMANDExternalProject_Add कॉल में।

cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR) 
project(Test) 

# Create main.cpp which uses gmock 
file(WRITE src/main.cpp "#include \"gmock/gmock.h\"\n\n") 
file(APPEND src/main.cpp "struct A {\n virtual void Do() {}\n};\n\n") 
file(APPEND src/main.cpp "struct MockA : public A {\n MOCK_METHOD0(Do, void());\n};\n\n") 
file(APPEND src/main.cpp "TEST(A, Do) {\n") 
file(APPEND src/main.cpp " MockA mock_a;\n") 
file(APPEND src/main.cpp " EXPECT_CALL(mock_a, Do()).Times(testing::AtLeast(1));\n") 
file(APPEND src/main.cpp " mock_a.Do();\n}\n\n") 
file(APPEND src/main.cpp "int main(int argc, char **argv) {\n") 
file(APPEND src/main.cpp " testing::InitGoogleTest(&argc, argv);\n") 
file(APPEND src/main.cpp " return RUN_ALL_TESTS();\n") 
file(APPEND src/main.cpp "}\n") 

# Create patch file for gtest with MSVC 2012 
if(MSVC_VERSION EQUAL 1700) 
    file(WRITE gtest.patch "Index: cmake/internal_utils.cmake\n") 
    file(APPEND gtest.patch "===================================================================\n") 
    file(APPEND gtest.patch "--- cmake/internal_utils.cmake (revision 643)\n") 
    file(APPEND gtest.patch "+++ cmake/internal_utils.cmake (working copy)\n") 
    file(APPEND gtest.patch "@@ -66,6 +66,9 @@\n") 
    file(APPEND gtest.patch "  # Resolved overload was found by argument-dependent lookup.\n") 
    file(APPEND gtest.patch "  set(cxx_base_flags \"\${cxx_base_flags} -wd4675\")\n") 
    file(APPEND gtest.patch "  endif()\n") 
    file(APPEND gtest.patch "+ if (MSVC_VERSION EQUAL 1700)\n") 
    file(APPEND gtest.patch "+  set(cxx_base_flags \"\${cxx_base_flags} -D_VARIADIC_MAX=10\")\n") 
    file(APPEND gtest.patch "+ endif()\n") 
    file(APPEND gtest.patch "  set(cxx_base_flags \"\${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32\")\n") 
    file(APPEND gtest.patch "  set(cxx_base_flags \"\${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN\")\n") 
    file(APPEND gtest.patch "  set(cxx_exception_flags \"-EHsc -D_HAS_EXCEPTIONS=1\")\n") 
    file(APPEND gtest.patch "Index: include/gtest/internal/gtest-tuple.h\n") 
    file(APPEND gtest.patch "===================================================================\n") 
    file(APPEND gtest.patch "--- include/gtest/internal/gtest-tuple.h (revision 643)\n") 
    file(APPEND gtest.patch "+++ include/gtest/internal/gtest-tuple.h (working copy)\n") 
    file(APPEND gtest.patch "@@ -1,3 +1,4 @@\n") 
    file(APPEND gtest.patch "+#include <tuple> /*\n") 
    file(APPEND gtest.patch " // This file was GENERATED by command:\n") 
    file(APPEND gtest.patch " //  pump.py gtest-tuple.h.pump\n") 
    file(APPEND gtest.patch " // DO NOT EDIT BY HAND!!!\n") 
    file(APPEND gtest.patch "@@ -197,8 +198,8 @@\n") 
    file(APPEND gtest.patch " class tuple<> {\n") 
    file(APPEND gtest.patch " public:\n") 
    file(APPEND gtest.patch " tuple() {}\n") 
    file(APPEND gtest.patch "- tuple(const tuple& /* t */) {}\n") 
    file(APPEND gtest.patch "- tuple& operator=(const tuple& /* t */) { return *this; }\n") 
    file(APPEND gtest.patch "+ tuple(const tuple& t) {}\n") 
    file(APPEND gtest.patch "+ tuple& operator=(const tuple&) { return *this; }\n") 
    file(APPEND gtest.patch " };\n") 
    file(APPEND gtest.patch " \n") 
    file(APPEND gtest.patch " template <GTEST_1_TYPENAMES_(T)>\n") 
    file(APPEND gtest.patch "@@ -946,7 +947,7 @@\n") 
    file(APPEND gtest.patch " template <>\n") 
    file(APPEND gtest.patch " struct SameSizeTuplePrefixComparator<0, 0> {\n") 
    file(APPEND gtest.patch " template <class Tuple1, class Tuple2>\n") 
    file(APPEND gtest.patch "- static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {\n") 
    file(APPEND gtest.patch "+ static bool Eq(const Tuple1&, const Tuple2&) {\n") 
    file(APPEND gtest.patch "  return true;\n") 
    file(APPEND gtest.patch " }\n") 
    file(APPEND gtest.patch " };\n") 
else() 
    file(WRITE gtest.patch "") 
endif() 

# Enable ExternalProject CMake module 
include(ExternalProject) 

# Set default ExternalProject root directory 
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/ThirdParty) 

# Add gmock 
ExternalProject_Add(
    googlemock 
    SVN_REPOSITORY http://googlemock.googlecode.com/svn/trunk/ 
    TIMEOUT 30 
    PATCH_COMMAND svn patch ${CMAKE_SOURCE_DIR}/gtest.patch ${CMAKE_BINARY_DIR}/ThirdParty/src/googlemock/gtest 
    # Force separate output paths for debug and release builds to allow easy 
    # identification of correct lib in subsequent TARGET_LINK_LIBRARIES commands 
    CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs 
       -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs 
       -Dgtest_force_shared_crt=ON 
    # Disable install step 
    INSTALL_COMMAND "" 
    # Wrap download, configure and build steps in a script to log output 
    LOG_DOWNLOAD ON 
    LOG_CONFIGURE ON 
    LOG_BUILD ON) 

# Specify include dir for googlemock and googletest 
ExternalProject_Get_Property(googlemock source_dir) 
include_directories(${source_dir}/include) 
include_directories(${source_dir}/gtest/include) 

if(MSVC_VERSION EQUAL 1700) 
    add_definitions(-D_VARIADIC_MAX=10) 
endif() 

# Add test executable target 
add_executable(MainTest ${PROJECT_SOURCE_DIR}/src/main.cpp) 

# Create dependency of MainTest on googlemock 
add_dependencies(MainTest googlemock) 

# Specify MainTest's link libraries 
ExternalProject_Get_Property(googlemock binary_dir) 
target_link_libraries(MainTest 
         debug ${binary_dir}/DebugLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gmock${CMAKE_FIND_LIBRARY_SUFFIXES} 
         optimized ${binary_dir}/ReleaseLibs/${CMAKE_FIND_LIBRARY_PREFIXES}gmock${CMAKE_FIND_LIBRARY_SUFFIXES}) 

आप एक खाली निर्देशिका में CMakeLists.txt के रूप में इस बनाने (MyTest कहते हैं), तो:

cd MyTest 
mkdir build 
cd build 
cmake .. 

यह MyTest/src में एक बुनियादी main.cpp बना सकते हैं और एक परियोजना फ़ाइल बनाने चाहिए (विंडोज़ पर MyTest/build/Test.sln)

जब आप प्रोजेक्ट बनाते हैं, तो इसे MyTest/build/ThirdParty/src/googlemock पर gmock स्रोत डाउनलोड करना चाहिए, और उन्हें MyTest/Build/ThirdParty/src/googlemock-निर्माण। इसके बाद आपको मेनटेस्ट लक्ष्य को सफलतापूर्वक चलाने में सक्षम होना चाहिए।

ExternalProject_Add आदेश पर आगे की जानकारी के लिए, देखें this article entitled Building External Projects with CMake 2.8

यहाँ a gist इस CMakeLists.txt

+0

सीएमके को 'CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG' और 'CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE' अनदेखा करता है जब यह googlemock बनाने के लिए जाता है । मैंने googlemock के CMakeLists.txt 'cmake_minimum_required' को' cmake_minimum_required (संस्करण 2.8.10) 'पर पैच करने का प्रयास किया है। इसका अभी भी कोई प्रभाव नहीं है। मुझे नहीं लगता कि Googletest या googlemock के अलग-अलग डीबग और रिलीज़/अनुकूलित बिल्ड करना संभव है। 'डीबग' और 'डीबगलिब्स' भाग (और संपूर्ण 'अनुकूलित' लाइन) को हटाएं और यह निर्माण करेगा। – gotgenes

+0

क्या मंच? यह वीसी ++ 2010 के साथ विंडोज पर अलग आउटपुट फ़ोल्डरों के साथ उपरोक्त काम करता है, और वीसी ++ 2012 के साथ कुछ मामूली पैच gtest में जोड़ा गया है। – Fraser

+0

मैंने अब वीसी ++ 2012 के लिए पैच कोड भी जोड़ा है। – Fraser