ฉันจะแยกไฟล์เดียวออกจากรูปแบบไฟล์ cmake (GLOB …) `ได้อย่างไร


90

ของฉันCMakeLists.txtมีบรรทัดนี้:

file(GLOB lib_srcs Half/half.cpp Iex/*.cpp IlmThread/*.cpp Imath/*.cpp IlmImf/*.cpp)

และIlmImfโฟลเดอร์นั้นมีb44ExpLogTable.cppซึ่งฉันต้องแยกออกจากบิลด์

จะบรรลุได้อย่างไร?

คำตอบ:


104

คุณสามารถใช้listฟังก์ชันเพื่อจัดการรายการตัวอย่างเช่น:

list(REMOVE_ITEM <list> <value> [<value> ...])

ในกรณีของคุณสิ่งนี้อาจใช้ได้:

list(REMOVE_ITEM lib_srcs "IlmImf/b44ExpLogTable.cpp")

1
นอกจาก lib_srcs แทนที่จะเป็น lib_src และ IlmImf แทน IlmThread นั่นเป็นการหลอกลวง! ขอบคุณมาก!
berak

21
หมายเหตุ: เมื่อลบข้อมูลในรายการตรวจสอบให้แน่ใจว่าค่าที่คุณกำลังค้นหาตรงกับที่อยู่ในรายการ ฉันมีปัญหาในการผสม $ {CMAKE_SOURCE_DIR} /src/file_to_remove.cpp กับ $ {CMAKE_CURRENT_SOURCE_DIR} /../ file_to_remove.cpp มันชี้ไปที่ตำแหน่งเดียวกัน แต่ไม่ใช่สตริงเดียวกัน ข้อความ ("$ {VARIABLE_NAME}") สามารถช่วยคุณแก้ไขข้อบกพร่องของเนื้อหาเหล่านั้นได้
hbobenicio

สิ่งนี้ไม่ได้ช่วยอะไรหากคุณใช้CONFIGURE_DEPENDSและจำเป็นต้องแยกไฟล์ที่สร้างโดยบิลด์ ตัวกรองในรายการหลังการfileโทรยังคงทริกเกอร์การสร้างใหม่ซึ่งในกรณีของฉันฉันพยายามหลีกเลี่ยง
simon.watts

ใช้ดีกว่ามากlist(FILTER
hukeping

3
วิธีแก้ปัญหาข้างต้นใช้ไม่ได้กับฉันกับ camke เวอร์ชัน 3.10.2 แต่วิธีแก้ปัญหาด้านล่าง: list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>) ใช้ได้ดีสำหรับฉัน
MH Yip

44

FILTER เป็นอีกทางเลือกหนึ่งที่อาจสะดวกกว่าในบางกรณี:

list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)

บรรทัดนี้ไม่รวมทุกรายการที่ลงท้ายด้วยชื่อไฟล์ที่ต้องการ:

list(FILTER lib_srcs EXCLUDE REGEX ".*b44ExpLogTable.cpp$")

นี่คือข้อกำหนดของ Regexสำหรับ cmake:

The following characters have special meaning in regular expressions:

^         Matches at beginning of input
$         Matches at end of input
.         Matches any single character
[ ]       Matches any character(s) inside the brackets
[^ ]      Matches any character(s) not inside the brackets
 -        Inside brackets, specifies an inclusive range between
          characters on either side e.g. [a-f] is [abcdef]
          To match a literal - using brackets, make it the first
          or the last character e.g. [+*/-] matches basic
          mathematical operators.
*         Matches preceding pattern zero or more times
+         Matches preceding pattern one or more times
?         Matches preceding pattern zero or once only
|         Matches a pattern on either side of the |
()        Saves a matched subexpression, which can be referenced
          in the REGEX REPLACE operation. Additionally it is saved
          by all regular expression-related commands, including
          e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).

สามารถเชื่อถือได้มากกว่าการคลุกเคล้าด้วยแพทช์แบบสัมบูรณ์ / แบบสัมพัทธ์
EFraim

1
ดีกว่ามากlist(REMOVE_ITEM
ceztko

1
หมายเหตุที่list(FILTER ...)เปิดตัวใน cmake v3.6: stackoverflow.com/a/42167646/3476780
yano

นี่เป็นคำตอบที่ดีกว่าอย่างแน่นอนแม้ว่าคุณจะพยายามใช้สิ่งนี้เพื่อยกเว้นไดเร็กทอรีทั้งหมดหรือถ้า regex ของคุณยุ่งคุณอาจยกเว้นมากกว่าที่คุณต้องการ ตัวอย่างเช่นการพยายามยกเว้น.*test/.*อาจไม่รวมทุกอย่างหากโปรเจ็กต์ของคุณอยู่ภายในแผนผังไดเร็กทอรีซึ่งไดเร็กทอรีพาเรนต์เรียกว่าอย่างใดอย่างmytestหนึ่ง
AnthonyD973

1

ลองสิ่งนี้: CMakeLists.txt

install(DIRECTORY   ${CMAKE_SOURCE_DIR}/ 
            DESTINATION ${CMAKE_INSTALL_PREFIX}
            COMPONENT   copy-files
            PATTERN     ".git*"   EXCLUDE
            PATTERN     "*.in"    EXCLUDE
            PATTERN     "*/build" EXCLUDE)

add_custom_target(copy-files
            COMMAND ${CMAKE_COMMAND} -D COMPONENT=copy-files
            -P cmake_install.cmake)
$cmake <src_path> -DCMAKE_INSTALL_PREFIX=<install_path>
$cmake --build . --target copy-files
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.