CMake 正则表达式匹配包含声明中的标头名称

CMake regex match header names in include declarations

本文关键字:声明 正则表达式 包含 CMake      更新时间:2023-10-16

我正在尝试获取机器人中所有 #include 声明的标头名称.cpp即,如果我有一个示例.cpp有两个声明:

示例.cpp

#include "MyLib.h"
#include <iosream>
//some code

我想在我的输出中看到这样的东西:

INCLUDE_NAME MyLib.h
INCLUDE_NAME iosream

我有这些robot.cppCMakeLists.txt文件(它们是简化的):

CMakeList.txt

...
   file(STRINGS ${SRC_FILE} SRC_CONTENT) #copy the file content
   foreach(SRC_LINE ${SRC_CONTENT})
     if("${SRC_LINE }" MATCHES "^ *#include *[<"](.*)[>"]")
        message("INCLUDE_NAME ${CMAKE_MATCH_1}")
...

机器人.cpp

#include "ArduinoRobot.h"
#include "EasyTransfer2.h"
void RobotControl::pointTo(int angle){
    int target=angle;
    uint8_t speed=80;
    target=target%360;
    if(target<0){
        target+=360;
    }
    int direction=angle;
    while(1){
        if(direction>0){
            motorsWrite(speed,-speed);//right
            delay(10);
        }else{
            motorsWrite(-speed,speed);//left
            delay(10);
        }
        int currentAngle=compassRead();
        int diff=target-currentAngle;
        if(diff<-180) 
            diff += 360;
        else if(diff> 180) 
            diff -= 360;
        direction=-diff;
        if(abs(diff)<5){
            motorsWrite(0,0);
            return;
        }
    }
}

然后,如果我在控制台中执行我的 CMakeList.txt,我会得到以下输出:

...
    INCLUDE_NAME ArduinoRobot.h"#include "EasyTransfer2.h"void RobotControl::pointTo(int angle){     int target=angle;       uint8_t speed=80;       target=target%360;      if(target<0){           target+=360; }       int direction=angle;    while(1){               if(direction>0){                        motorsWrite(speed,-speed);//right                       delay(10);              }else{                  motorsWrite(-speed,speed);//left                     delay(10);              }               int currentAngle=compassRead();         int diff=target-currentAngle;           if(diff<-180)                   diff += 360;            else if(diff    
...

但是,如果我将所有>符号更改为 < ,结果正常,并且得到以下输出:

...
INCLUDE_NAME ArduinoRobot.h
INCLUDE_NAME EasyTransfer2.h
...

我想这是因为正则表达式,但我不知道如何修复它。

有人吗?

我认为

有两个问题。 第一个,我强烈怀疑,是源代码中的行尾。您的代码会像您最初一样工作,只是您正在解析的代码可能是从某个地方下载的,并且该文件可能具有不同的行尾。 例如,如果原版是在 Linux 下开发的,而您在 Windows 下操作,则可能会发生这种情况。 这需要首先解决。

其次,您真正想要的是一个正则表达式,它不接受中间的任何字符,而只接受与">不匹配的字符。 这是我刚才测试的内容:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(NONSENSE NONE)
file(STRINGS "silly.txt" SRC_CONTENT)
foreach(SRC_LINE ${SRC_CONTENT})
    if("${SRC_LINE}" MATCHES "^[ t]*#[ t]*include[ t]*[<"]([^>"]*)[>"]")
        message("INCLUDE_NAME ${CMAKE_MATCH_1}")
    endif()
ENDFOREACH()

傻.txt的内容:

#  include "foo.h"
#include    "bar.h"
#include "ArduinoRobot.h"#include "EasyTransfer2.h"int main()
{
    printf("This is not a header.n");
    return 0;
}
    #include "surprise.h"

请注意,bar.h行中间和surprise.h行的开头有一个制表符。 奇怪的是,但仍然被预处理器接受的是foo.h行上显示的变化,其中#和指令之间有空格或制表符。 显示的正则表达式处理所有这些。

这是它的输出:

INCLUDE_NAME foo
INCLUDE_NAME bar
INCLUDE_NAME foo.h
INCLUDE_NAME bar.h
INCLUDE_NAME ArduinoRobot.h
INCLUDE_NAME surprise.h

CMake 正则表达式是贪婪的,因此输出。

也许尝试在撇号之间匹配更少的东西:

"^ *#include *[<"](w+)[>"]"

我想知道 CMake 是否接受明确的非贪婪语法,例如

"^ *#include *[<"]\(.*)\[>"]"

(未测试!