No CMAKE_CXX_COMPILER could be found.

错误信息

在使用cmake 编译 flex&bison程序时,使用cmake的project()指令,编译报以下错误,错误具体信息:

CMake Error at CMakeLists.txt:3 (project):
  No CMAKE_CXX_COMPILER could be found.

  Tell CMake where to find the compiler by setting either the environment
  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
  to the compiler, or to the compiler name if it is in the PATH.


-- Configuring incomplete, errors occurred!

原因是:cmake 的project() 命令在没有指定 LANGUAGES 选项时,默认是C和CXX(注意cmake 3.0之前的版本不支持LANGUAGES 关键字),CXX编译时需要指定 g++编译器。

解决方法

有2种方式:

方式一

在project() 命令中指定LANGUAGES 选项为C:

project(test1 LANGUAGES C)

方式二

安装g++ :

apt install g++

使用cmake编译flex

环境

Linux系统

cmake版本:cmake version 3.25.1

make版本:GNU Make 4.3

flex版本:flex 2.6.4

flex源文件

catcot.l 文件

%{
    #include <stdio.h>    
%}

%%
c.t { printf("mumble mumble"); }
cot { printf("portable bed"); }
cat { printf("thankless pet"); }
cats { printf("anti-herd");}

%%

int main()
{
    /* 调用获取token */
    yylex();
    return 0;
}

CMakeLists.txt文件

# 指定cmake 最低版本号
cmake_minimum_required(VERSION 3.20)

# 指定项目名称 和 语言
project(catcot1 LANGUAGES C)

# 查找依赖包
find_package(FLEX)

# 使用宏定义生成规则
FLEX_TARGET(catcotScanner catcot.l ${CMAKE_CURRENT_BINARY_DIR}/catcot.lex.c)

# 设置主要包含的c文件
set(MAIN_SRC ${CMAKE_CURRENT_BINARY_DIR}/catcot.lex.c)

# 使用源文件生成可以执行文件
add_executable(catcotTest ${MAIN_SRC})

编译

# 第一步
mkdir build
# 第二步
cd build
# 第三步
cmake ../
# 第四步
make 

问题

在编译部分 第四步 时会出现如下的错误提示:

/usr/bin/ld: CMakeFiles/catcotTest.dir/catcot.lex.c.o: in function `yylex':
catcot.lex.c:(.text+0x4e0): undefined reference to `yywrap'
/usr/bin/ld: CMakeFiles/catcotTest.dir/catcot.lex.c.o: in function `input':
catcot.lex.c:(.text+0x10de): undefined reference to `yywrap'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/catcotTest.dir/build.make:101: catcotTest] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/catcotTest.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

问题解决

解决上面的undefined reference to `yywrap’问题,有以下三种方法:

  • 方法1:在 catcot.l 文件头部添加:%option noyywrap
  • 方法2:在 catcot.l 文件中添加自己的yywrap()函数,返回值1
int yywrap()
{
   return 1;
}
  • 方法3:在CMakeLists.txt文件末尾追加:
# 添加 libfl.a 库
find_library(LEX_LIB fl)
# 链接 libfl.a 库
TARGET_LINK_LIBRARIES(catcotTest ${LEX_LIB})

这样可以使用默认flex的库libfl.a 生成的默认yywrap函数。

以上3种方法,均已验证是可以的。

推荐使用第 1 种方法