เพิ่มไฟล์ทั้งหมดในโฟลเดอร์ไปยังเป้าหมายโดยอัตโนมัติโดยใช้ CMake หรือไม่


163

ฉันกำลังพิจารณาเปลี่ยนโครงการข้ามแพลตฟอร์มจากระบบการจัดการการสร้างที่แยกต่างหากใน Visual C ++, XCode และ makefiles เป็น CMake

คุณสมบัติที่สำคัญอย่างหนึ่งที่ฉันต้องการคือการเพิ่มไฟล์ทั้งหมดในไดเรกทอรีไปยังเป้าหมายโดยอัตโนมัติ แม้ว่าสิ่งนี้จะง่ายต่อการทำ แต่ก็ไม่สามารถทำได้ด้วย Visual C ++ และ XCode (แก้ไขฉันถ้าฉันผิด) เป็นไปได้ไหมที่จะทำใน CMake โดยตรง อย่างไร?


Btw ใน Visual Studio อย่างน้อยในโครงการ C # จะมีปุ่มแถบเครื่องมือใน project explorer ชื่อแสดงไฟล์ทั้งหมด มันทำให้ไดเรกทอรีย่อยทั้งหมดของโครงการมองเห็นเป็นสีเทาหากไม่มีไฟล์ใด ๆ ที่รวมอยู่ในโครงการด้วยเหตุผล คุณสามารถรวมไดเรกทอรีเหล่านี้ผ่านทางเมนูบริบทซึ่งรวมถึงไฟล์ต้นฉบับทั้งหมดที่อยู่ภายในพวกมันซ้ำ ๆ :)
Yeoman

คำตอบ:


228

มันเป็นไปได้. เช่นกับfile(GLOB:

cmake_minimum_required(VERSION 2.8)

file(GLOB helloworld_SRC
    "*.h"
    "*.cpp"
)

add_executable(helloworld ${helloworld_SRC})

โปรดทราบว่าสิ่งนี้ต้องมีการเรียกใช้ใหม่ด้วยตนเองcmakeหากไฟล์ต้นฉบับถูกเพิ่มหรือลบออกเนื่องจากระบบการสร้างที่สร้างขึ้นไม่ทราบว่าเมื่อใดที่จะให้ CMake ทำการสร้างใหม่


11
อีกทางเลือกหนึ่งสำหรับการเรียกใช้ cmake ด้วยตนเองอีกครั้งคือการสัมผัสไฟล์ CMakeLists.txt ก่อนทำการรัน
เชมัสคอนเนอร์


8
> "เราไม่แนะนำให้ใช้ GLOB เพื่อรวบรวมรายการไฟล์ต้นฉบับจากซอร์สทรีของคุณหากไม่มีไฟล์ CMakeLists.txt เปลี่ยนแปลงเมื่อมีการเพิ่มหรือลบซอร์สระบบสร้างที่สร้างขึ้นจะไม่รู้ว่าจะให้ CMake สร้างใหม่เมื่อใด" สิ่งนี้ไม่แนะนำในเอกสาร CMAKE3.7 ที่ลิงก์เกี่ยวกับ Hand1Cloud อีกต่อไป
สาม

4
GLOBAL มีทางเลือกอะไรอีก?
Shayne

13
วิธีที่ดีกว่าตั้งแต่แนะนำ v3.1 ที่นี่: target_sources () crascit.com/2016/01/31/…
เงา

34

คำตอบโดย Kleist ใช้งานได้จริง แต่มีข้อแม้ที่สำคัญ:

เมื่อคุณเขียนMakefileด้วยตนเองคุณอาจสร้างSRCSตัวแปรโดยใช้ฟังก์ชั่นเพื่อเลือกทั้งหมด.cppและ.hไฟล์ หากมีการเพิ่มไฟล์ต้นฉบับในภายหลังการรันซ้ำmakeจะรวมอยู่ด้วย

อย่างไรก็ตาม CMake (ด้วยคำสั่งเช่นfile(GLOB ...)) จะสร้างรายการไฟล์อย่างชัดเจนและวางไว้ในการสร้างMakefileอัตโนมัติ หากคุณมีไฟล์ต้นฉบับใหม่คุณจะต้องสร้างไฟล์Makefileขึ้นใหม่โดยการรันcmakeซ้ำ

แก้ไข: ไม่จำเป็นต้องลบ Makefile


4
ไม่สามารถเรียกใช้ซ้ำได้ซึ่งควรลบ / ปรับเปลี่ยน Makefile ที่ล้าสมัยหรือไม่
Ethan

25
นี่ไม่ใช่คำตอบมันเป็นความคิดเห็นเกี่ยวกับคำตอบของ @ Kleist
Neowizard

3
@Nowowizard ไม่ได้อยู่ในคำศัพท์ Stackoverflow
kara deniz

1
ความคิดเห็นนี้ดี แต่มันเป็น "มาตรฐาน" ใช่ไหม ผู้ถามใช้ cmake อยู่แล้วดังนั้นการแนะนำการสร้างอาจเป็น "ฉลาด" ไม่ได้มีประโยชน์
frankliuao

ดังนั้นจะมีวิธีการเพิ่มไฟล์ต้นฉบับใหม่แล้วสร้างโดยไม่ต้องเรียกใช้ cmake?
artin

6

ส่วนขยายสำหรับ@Kleist คำตอบ :

ตั้งแต่ CMake 3.12 เลือกเพิ่มเติมCONFIGURE_DEPENDSจะได้รับการสนับสนุนโดยคำสั่งและfile(GLOB) file(GLOB_RECURSE)ด้วยตัวเลือกนี้มีความต้องการไม่มีการด้วยตนเองอีกครั้งเรียก CMake หลังจากนอกจากนี้ / ลบไฟล์ที่มาในไดเรกทอรี - CMake จะเป็นเรื่องการทำงานโดยอัตโนมัติเมื่อต่อไปการสร้างโครงการ

แต่ตัวเลือกCONFIGURE_DEPENDSหมายความว่าไดเรกทอรีที่เกี่ยวข้องจะต้องตรวจสอบอีกครั้งทุกครั้งที่มีการร้องขออาคารเพื่อสร้างกระบวนการจะใช้เวลามากขึ้นกว่าโดยไม่ต้องCONFIGURE_DEPENDS

ถึงแม้จะมีตัวเลือกCONFIGURE_DEPENDSก็ตามCMake ยังไม่แนะนำให้ใช้file(GLOB)หรือfile(GLOB_RECURSE)เก็บรวบรวมแหล่งข้อมูล


"เอกสารของ CMake ยังไม่แนะนำให้ใช้file(GLOB)หรือfile(GLOB_RECURSE)รวบรวมแหล่งที่มา" พวกเขาแนะนำอะไร? ใช้อย่างอื่นเพื่อรวบรวมแหล่งที่มาหรือเพื่อแสดงรายการทุกไฟล์ต้นฉบับด้วยตนเองหรือไม่
โธมัส

1
@Thomas: พวกเขาแนะนำให้ทำรายการไฟล์ทุกไฟล์ด้วยตนเอง คำตอบนั้นให้คำอธิบายที่ดีเกี่ยวกับข้อเสนอแนะ
Tsyvarev

-2

ดังนั้นทำไมไม่ใช้ PowerShell เพื่อสร้างรายการไฟล์ต้นฉบับให้คุณ ลองดูที่สคริปต์นี้

param (
    [Parameter(Mandatory=$True)]
    [string]$root 
)

if (-not (Test-Path  -Path $root)) {    
throw "Error directory does not exist"
}

#get the full path of the root
$rootDir = get-item -Path $root
$fp=$rootDir.FullName;


$files = Get-ChildItem -Path $root -Recurse -File | 
         Where-Object { ".cpp",".cxx",".cc",".h" -contains $_.Extension} | 
         Foreach {$_.FullName.replace("${fp}\","").replace("\","/")}

$CMakeExpr = "set(SOURCES "

foreach($file in $files){

    $CMakeExpr+= """$file"" " ;
}
$CMakeExpr+=")"
return $CMakeExpr;

สมมติว่าคุณมีโฟลเดอร์ที่มีโครงสร้างนี้

C:\Workspace\A
--a.cpp
C:\Workspace\B 
--b.cpp

ตอนนี้บันทึกไฟล์นี้เป็น "generateSourceList.ps1" ตัวอย่างเช่นและเรียกใช้สคริปต์เป็น

~>./generateSourceList.ps1 -root "C:\Workspace" > out.txt

ไฟล์ out.txt จะมี

set(SOURCE "A/a.cpp" "B/b.cpp")

คำถามถูกแท็กข้ามแพลตฟอร์ม - PowerShell ไม่ใช่ข้ามแพลตฟอร์ม
reichhart

@reichhart powershell ใช้งานได้กับ linux และและ mac ด้วย
no

ฉันรู้ว่า. แต่ไม่มีแท็กสำหรับ powershell และ "CMake" เป็นแพลตฟอร์มข้ามแพลตฟอร์มอยู่แล้ว "Powershell" จะเป็นการพึ่งพาเพิ่มเติมและไม่ค่อยมีใครใช้บนระบบปฏิบัติการอื่นนอกเหนือจาก Windows คุณอาจพบนักพัฒนา C # บน Linux มากกว่าคนที่มี PowerShell และความจริงที่สำคัญที่สุดคือคำถาม: "เป็นไปได้หรือไม่ที่จะทำใน CMake โดยตรงได้อย่างไร"
reichhart
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.