উত্তর:
'কোটিয়ার' নামে একটি তৃতীয় পক্ষের সিএমকে মডিউল রয়েছে যা সিএমকে ভিত্তিক বিল্ড সিস্টেমের জন্য প্রম্পম্পাইল্ড শিরোনামগুলি স্বয়ংক্রিয়ভাবে ব্যবহার করে এবং unityক্যবদ্ধতাগুলিকে সমর্থন করে।
আমি পূর্বনির্ধারিত শিরোনাম উত্পন্ন এবং ব্যবহার করতে নিম্নলিখিত ম্যাক্রো ব্যবহার করছি:
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
IF(MSVC)
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
SET(Sources ${${SourcesVar}})
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_OUTPUTS "${PrecompiledBinary}")
SET_SOURCE_FILES_PROPERTIES(${Sources}
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_DEPENDS "${PrecompiledBinary}")
# Add precompiled header to SourcesVar
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
আপনার সমস্ত সোর্সফাইলে আপনার একটি ভেরিয়েবল {S মাইসোর্সস have রয়েছে বলুন, আপনি যে কোডটি ব্যবহার করতে চান সেটি সহজ হবে
ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
ADD_LIBRARY(MyLibrary ${MySources})
কোডটি এখনও নন-এমএসভিসি প্ল্যাটফর্মগুলিতে ঠিক ঠিক কাজ করবে function বেশ ঝরঝরে :)
/Yu
এবং /FI
যুক্তিগুলি সংশোধন করুন , সেগুলি হওয়া উচিত ${PrecompiledHeader}
এবং না হওয়া উচিত ${PrecompiledBinary}
।
/YuC:/foo/bar.h
আপনাকে /FpC:/foo/bar.h
পতাকাটি পাস করতে বাধ্য করবে বা #include <C:/foo/bar.h>
প্রথম অন্তর্ভুক্ত বিবৃতি হিসাবে আপনার .cpp ফাইলগুলির শীর্ষে রাখবে। এমএসভিসি #include
আর্গুমেন্টের সাথে একটি স্ট্রিং তুলনা করে, এটি যা দেওয়া হয়েছিল সেই একই ফাইলটিতে এটি নির্দেশ করে কিনা তা পরীক্ষা করে না /Yu
। অতএব, #include <bar.h>
হবে কাজ এবং নির্গত ত্রুটি C2857 না।
সিএমকে পিইচসি-র জন্য সবেমাত্র সমর্থন পেয়েছে, এটি আসন্ন 3.16 প্রকাশে, 2019-10-01 এর কারণে পাওয়া উচিত:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3553
target_precompile_headers(<target>
<INTERFACE|PUBLIC|PRIVATE> [header1...]
[<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
লক্ষ্যমাত্রার মধ্যে PCHs ভাগ করে নেওয়ার বিষয়ে চলমান আলোচনা চলছে: https://gitlab.kitware.com/cmake/cmake/issues/19659
Https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-une-jumbo-builds-in-up आगामी-cmake/ এ কিছু অতিরিক্ত প্রসঙ্গ (প্রেরণা, সংখ্যা) উপলব্ধ
আপনাকে আপনার প্রকল্পের জন্য পূর্বনির্ধারিত শিরোনাম ব্যবহারের অনুমতি দেওয়ার জন্য এখানে একটি কোড স্নিপেট। আপনার সিএমকেলিস্ট.টেক্সট প্রতিস্থাপন myprecompiledheaders
এবং myproject_SOURCE_FILES
যথাযথ হিসাবে নিম্নলিখিতটি যুক্ত করুন :
if (MSVC)
set_source_files_properties(myprecompiledheaders.cpp
PROPERTIES
COMPILE_FLAGS "/Ycmyprecompiledheaders.h"
)
foreach( src_file ${myproject_SOURCE_FILES} )
set_source_files_properties(
${src_file}
PROPERTIES
COMPILE_FLAGS "/Yumyprecompiledheaders.h"
)
endforeach( src_file ${myproject_SOURCE_FILES} )
list(APPEND myproject_SOURCE_FILES myprecompiledheaders.cpp)
endif (MSVC)
with set( CMAKE_AUTOMOC ON )
।
myprecompiledheader.cpp
এটি প্রথম সংকলিত হয়েছে? এই স্নিপেট থেকে দেখে মনে হচ্ছে এটি শেষটি সংকলিত হবে, তাই সম্ভবত এটিই বিলম্বের কারণ হতে পারে। myprecompiledheader.h
আমার কোড ব্যবহার করে এমন সর্বাধিক সাধারণ এসটিএল শিরোনাম রয়েছে।
আমি লার্সম ম্যাক্রোর একটি অভিযোজিত সংস্করণ ব্যবহার করে শেষ করেছি। Pch পাথের জন্য $ (IntDir) ব্যবহার করা ডিবাগের জন্য পূর্বনির্ধারিত শিরোনাম রাখে এবং রিলিজ পৃথক করে দেয়।
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
IF(MSVC)
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
SET(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
SET(Sources ${${SourcesVar}})
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_OUTPUTS "${PrecompiledBinary}")
SET_SOURCE_FILES_PROPERTIES(${Sources}
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_DEPENDS "${PrecompiledBinary}")
# Add precompiled header to SourcesVar
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" MY_SRCS)
ADD_EXECUTABLE(MyApp ${MY_SRCS})
ডেভ থেকে অভিযোজিত, তবে আরও দক্ষ (প্রতিটি ফাইলের জন্য নয়, লক্ষ্য বৈশিষ্ট্যগুলি সেট করে):
if (MSVC)
set_target_properties(abc PROPERTIES COMPILE_FLAGS "/Yustd.h")
set_source_files_properties(std.cpp PROPERTIES COMPILE_FLAGS "/Ycstd.h")
endif(MSVC)
abc
আপনার উদাহরণে?
আপনি যদি চক্রটি পুনরায় উদ্ভাবন করতে না চান, তবে উপরের উত্তরের পরামর্শ অনুসারে কোটায়ারটিকে ব্যবহার করুন বা একটি সহজ - cmake-precompiled-header এখানে । এটি ব্যবহার করতে কেবল মডিউল এবং কলটি অন্তর্ভুক্ত করুন:
include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( targetName StdAfx.h FORCEINCLUDE SOURCE_CXX StdAfx.cpp )
সিএমকে ৩.১16 প্রম্পম্পাইল্ড হেডারের জন্য সমর্থন প্রবর্তন করেছে। একটি নতুন সিএমকে কমান্ড রয়েছে target_precompile_headers
যা হুডের নীচে আপনার প্রয়োজনীয় সমস্ত কাজ করে। আরও তথ্যের জন্য এর ডকুমেন্টেশন দেখুন: https://cmake.org/cmake/help/latest/command/target_precompile_headers.html
"stdafx.h", "stdafx.cpp" - প্রাকম্পম্পিত শিরোনামের নাম।
নীচে রুট cmake ফাইলে রাখুন।
if (MSVC)
# For precompiled header.
# Set
# "Precompiled Header" to "Use (/Yu)"
# "Precompiled Header File" to "stdafx.h"
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Yustdafx.h /FIstdafx.h")
endif()
প্রকল্পের চেক ফাইলটিতে নীচে রাখুন।
"src" - উত্স ফাইল সহ একটি ফোল্ডার।
set_source_files_properties(src/stdafx.cpp
PROPERTIES
COMPILE_FLAGS "/Ycstdafx.h"
)
আইএমএইচও সবচেয়ে ভাল উপায় হ'ল পুরো প্রকল্পের জন্য পিসিএইচ স্থাপন করা, যেমন মার্টজ্নো পরামর্শ দিয়েছেন, প্রয়োজনে কিছু উত্সের জন্য পি সি সি উপেক্ষা করার ক্ষমতা সহ (যেমন উত্পন্ন উত্স):
# set PCH for VS project
function(SET_TARGET_PRECOMPILED_HEADER Target PrecompiledHeader PrecompiledSource)
if(MSVC)
SET_TARGET_PROPERTIES(${Target} PROPERTIES COMPILE_FLAGS "/Yu${PrecompiledHeader}")
set_source_files_properties(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc${PrecompiledHeader}")
endif(MSVC)
endfunction(SET_TARGET_PRECOMPILED_HEADER)
# ignore PCH for a specified list of files
function(IGNORE_PRECOMPILED_HEADER SourcesVar)
if(MSVC)
set_source_files_properties(${${SourcesVar}} PROPERTIES COMPILE_FLAGS "/Y-")
endif(MSVC)
endfunction(IGNORE_PRECOMPILED_HEADER)
সুতরাং, আপনার যদি কিছু লক্ষ্য MY_TARGET থাকে এবং উত্পন্ন উত্সগুলির তালিকা থাকে IGNORE_PCH_SRC_LIST আপনি কেবল তা করতে পারেন:
SET_TARGET_PRECOMPILED_HEADER(MY_TARGET stdafx.h stdafx.cpp)
IGNORE_PRECOMPILED_HEADER(IGNORE_PCH_SRC_LIST)
এই অ্যাপ্রোচ পরীক্ষিত এবং পুরোপুরি কাজ করে।
ভাল যখন বিল্ডগুলি প্রতিটি কোয়াড কোর মেশিনে 10+ মিনিট সময় নেয় আপনি যখন কোনও প্রকল্পের ফাইলগুলিতে একটি লাইন পরিবর্তন করেন তখন এটি আপনাকে উইন্ডোজের জন্য পূর্বনির্ধারিত শিরোনাম যুক্ত করার সময় বলে দেয়। * Nux এ আমি কেবল ccache ব্যবহার করব এবং এটি নিয়ে চিন্তা করব না।
আমি আমার প্রধান অ্যাপ্লিকেশন এবং এটি ব্যবহার করে এমন কয়েকটি লাইব্রেরি প্রয়োগ করেছি। এটি এই মুহুর্তে দুর্দান্ত কাজ করে। একটি জিনিস যা প্রয়োজন তা হ'ল আপনাকে পিএইচ উত্স এবং শিরোনাম ফাইলটি তৈরি করতে হবে এবং উত্স ফাইলে এমন সমস্ত শিরোনাম অন্তর্ভুক্ত করা হয়েছে যা আপনি পূর্বনির্ধারিত হতে চান। আমি এমএফসি দিয়ে 12 বছর এটি করেছি তবে তা স্মরণ করতে আমার কয়েক মিনিট সময় লেগেছে ..
সবচেয়ে পরিষ্কার উপায় হ'ল প্রাক-কম্পাইল বিকল্পটি বিশ্বব্যাপী বিকল্প হিসাবে যুক্ত করা। Vcxproj ফাইলে এটি প্রদর্শিত হবে<PrecompiledHeader>Use</PrecompiledHeader>
প্রতিটি পৃথক ফাইলের জন্য প্রদর্শিত হবে এবং না।
তারপরে আপনাকে Create
StdAfx.cpp এ বিকল্পটি যুক্ত করতে হবে। নিম্নলিখিতটি আমি কীভাবে এটি ব্যবহার করি:
MACRO(ADD_MSVC_PRECOMPILED_HEADER SourcesVar)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /YuStdAfx.h")
set_source_files_properties(StdAfx.cpp
PROPERTIES
COMPILE_FLAGS "/YcStdAfx.h"
)
list(APPEND ${${SourcesVar}} StdAfx.cpp)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
file(GLOB_RECURSE MYDLL_SRC
"*.h"
"*.cpp"
"*.rc")
ADD_MSVC_PRECOMPILED_HEADER(MYDLL_SRC)
add_library(MyDll SHARED ${MYDLL_SRC})
এটি পরীক্ষা করা হয়েছে এবং এমএসভিসি ২০১০-এর জন্য কাজ করে এবং একটি মাইডিএল.পিএইচচি ফাইল তৈরি করবে, কোন ফাইলের নাম ব্যবহার করা হচ্ছে তা নিয়ে আমি বিরক্ত নই তাই আমি এটি নির্দিষ্ট করার জন্য কোনও চেষ্টা করি নি।
পূর্বনির্ধারিত শিরোনাম বিকল্পটি আরসি ফাইলগুলির জন্য কাজ করে না, আমার জারি দ্বারা সরবরাহিত ম্যাক্রো সামঞ্জস্য করা দরকার।
#######################################################################
# Makro for precompiled header
#######################################################################
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
IF(MSVC)
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
SET(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
SET(Sources ${${SourcesVar}})
# generate the precompiled header
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
PROPERTIES COMPILE_FLAGS "/Zm500 /Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_OUTPUTS "${PrecompiledBinary}")
# set the usage of this header only to the other files than rc
FOREACH(fname ${Sources})
IF ( NOT ${fname} MATCHES ".*rc$" )
SET_SOURCE_FILES_PROPERTIES(${fname}
PROPERTIES COMPILE_FLAGS "/Zm500 /Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_DEPENDS "${PrecompiledBinary}")
ENDIF( NOT ${fname} MATCHES ".*rc$" )
ENDFOREACH(fname)
# Add precompiled header to SourcesVar
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
সম্পাদনা করুন: এই পূর্বনির্ধারিত শিরোনামগুলির ব্যবহার আমার মূল প্রকল্পের সামগ্রিক গড় সময়কে 4 মিনিট 30 থেকে কমিয়ে 1 মিনিট 40-এ নামিয়েছে। এটি আমার পক্ষে সত্যই ভাল জিনিস। প্রম্পম্পাইল শিরোনামে কেবল বুস্ট / স্টিল / উইন্ডোজ / এমএফসি এর মতো শিরোনাম থাকে।
এমনকি সেখানেও যাবেন না। প্রাক-কম্পাইল করা শিরোনামের অর্থ হ'ল যখনই কোনও শিরোনাম পরিবর্তিত হয়, আপনাকে সবকিছু পুনর্নির্মাণ করতে হবে । আপনি ভাগ্যবান যদি আপনার কাছে এমন একটি বিল্ড সিস্টেম থাকে যা এটি উপলব্ধি করে। কখনও কখনও কখনও না, আপনার বিল্ডটি কেবল ব্যর্থ হবে যতক্ষণ না আপনি বুঝতে পেরেছেন যে আপনি এমন কিছু পরিবর্তন করেছেন যা পূর্বনির্ধারিত হচ্ছে এবং তাই আপনাকে একটি পূর্ণ পুনর্নির্মাণের প্রয়োজন। আপনি এগুলি বেশিরভাগই শিরোনামকে পূর্বনির্ধারিত করে এড়াতে পারবেন যে আপনি একেবারে ইতিবাচক, কোনও পরিবর্তন হবে না, তবে আপনি গতি অর্জনের একটি বড় অংশটি ত্যাগ করবেন।
অন্য সমস্যাটি হ'ল আপনার নেমস্পেস এমন সমস্ত ধরণের চিহ্নের সাথে দূষিত হয়ে যায় যা আপনি জানেন না বা যত্ন করছেন না এমন অনেক জায়গায় যেখানে আপনি পূর্বনির্ধারিত শিরোনাম ব্যবহার করছেন।