Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用了C++20 module的项目生成的CMakeLists.txt不正确 #5765

Open
hghgthifg opened this issue Oct 25, 2024 · 5 comments
Open

使用了C++20 module的项目生成的CMakeLists.txt不正确 #5765

hghgthifg opened this issue Oct 25, 2024 · 5 comments
Labels

Comments

@hghgthifg
Copy link

Xmake 版本

v2.9.5+HEAD.d30de52e9

操作系统版本和架构

Windows11 version 23H2

描述问题

src/main.cpp:

import Vec3;
import std;

int main(int argc, char** argv)
{
	auto point3 = vec3{0, 0, 0};

	int image_width = 256;
	int image_height = 256;

	std::cout << "P3\n"
			  << image_width << " " << image_height << "\n255\n";

	for (int j = 0; j < image_height; j++) {
		std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush;
		for (int i = 0; i < image_width; i++) {
			auto r = double(i) / double(image_width - 1);
			auto g = double(j) / double(image_height - 1);
			auto b = 0.0;

			int ir = int(255.999 * r);
			int ig = int(255.999 * g);
			int ib = int(255.999 * b);

			std::cout << ir << " " << ig << " " << ib << "\n";
		}
	}

	std::clog << "\rDone.                  \n";

	return 0;
}

src/vec3.cppm:

export module Vec3;
import std;

export class vec3
{
public:
	double e[3];

	vec3() : e{0, 0, 0} {}
	vec3(double e0, double e1, double e2) : e{e0, e1, e2} {}

	double x() const { return e[0]; }
	double y() const { return e[1]; }
	double z() const { return e[2]; }

	vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
	double operator[](int i) const { return e[i]; }
	double& operator[](int i) { return e[i]; }

	vec3& operator+=(const vec3& v)
	{
		e[0] += v.e[0];
		e[1] += v.e[1];
		e[2] += v.e[2];
		return *this;
	}

	vec3& operator*=(double t)
	{
		e[0] *= t;
		e[1] *= t;
		e[2] *= t;
		return *this;
	}

	vec3& operator/=(double t) { return *this *= 1 / t; }

	double length() const { return std::sqrt(length_squared()); }

	double length_squared() const
	{
		return e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
	}
};

// point3 is just an alias for vec3, but useful for geometric clarity in the
// code.
export using point3 = vec3;

// Vector Utility Functions

export inline std::ostream& operator<<(std::ostream& out, const vec3& v)
{
	return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2];
}

export inline vec3 operator+(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]);
}

export inline vec3 operator-(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]);
}

export inline vec3 operator*(const vec3& u, const vec3& v)
{
	return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]);
}

export inline vec3 operator*(double t, const vec3& v)
{
	return vec3(t * v.e[0], t * v.e[1], t * v.e[2]);
}

export inline vec3 operator*(const vec3& v, double t) { return t * v; }

export inline vec3 operator/(const vec3& v, double t) { return (1 / t) * v; }

export inline double dot(const vec3& u, const vec3& v)
{
	return u.e[0] * v.e[0] + u.e[1] * v.e[1] + u.e[2] * v.e[2];
}

export inline vec3 cross(const vec3& u, const vec3& v)
{
	return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1],
				u.e[2] * v.e[0] - u.e[0] * v.e[2],
				u.e[0] * v.e[1] - u.e[1] * v.e[0]);
}

export inline vec3 unit_vector(const vec3& v) { return v / v.length(); }

xmake.lua:

add_rules("mode.debug", "mode.release")
set_policy("build.c++.modules", true)

set_languages("c++23")

target("RayTracing")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.cppm")

直接使用 xmake 进行构建是正常的,但是生成的 CMakeLists.txt 无法正常使用。

CMakeLists.txt:

# this is the build file for project 
# it is autogenerated by the xmake build system.
# do not edit by hand.

# project
cmake_minimum_required(VERSION 3.28.0)
cmake_policy(SET CMP0091 NEW)
project(RayTracing LANGUAGES CXX)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)

# target
add_executable(RayTracing "")
set_target_properties(RayTracing PROPERTIES OUTPUT_NAME "RayTracing")
set_target_properties(RayTracing PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/windows/x64/debug")
if(MSVC)
    target_compile_options(RayTracing PRIVATE /EHsc)
elseif(Clang)
    target_compile_options(RayTracing PRIVATE -fexceptions)
    target_compile_options(RayTracing PRIVATE -fcxx-exceptions)
elseif(Gcc)
    target_compile_options(RayTracing PRIVATE -fexceptions)
endif()
set_target_properties(RayTracing PROPERTIES CXX_EXTENSIONS OFF)
target_compile_features(RayTracing PRIVATE cxx_std_23)
if(MSVC)
    target_compile_options(RayTracing PRIVATE $<$<CONFIG:Debug>:-Od>)
else()
    target_compile_options(RayTracing PRIVATE -O0)
endif()
if(MSVC)
    target_compile_options(RayTracing PRIVATE -Zi)
else()
    target_compile_options(RayTracing PRIVATE -g)
endif()
if(MSVC)
    set_property(TARGET RayTracing PROPERTY
        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
target_sources(RayTracing PRIVATE
    src/main.cpp
    src/Vec3.cppm
)

CMake 构建得到的报错:

CMake Error: Output CMakeFiles\RayTracing.dir\src\Vec3.cppm.obj provides the `Vec3` module but it is not found in a `FILE_SET` of type `CXX_MODULES`
ninja: build stopped: subcommand failed.

期待的结果

期待生成的 CMakeLists.txt 能和用 xmake 一样成功构建

工程配置

add_rules("mode.debug", "mode.release")
set_policy("build.c++.modules", true)

set_languages("c++23")

target("RayTracing")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.cppm")

附加信息和错误日志

CMake 构建得到的报错:

CMake Error: Output CMakeFiles\RayTracing.dir\src\Vec3.cppm.obj provides the `Vec3` module but it is not found in a `FILE_SET` of type `CXX_MODULES`
ninja: build stopped: subcommand failed.
@hghgthifg hghgthifg added the bug label Oct 25, 2024
@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Title: The CMakeLists.txt generated by projects using the C++20 module is incorrect

@waruqi
Copy link
Member

waruqi commented Oct 25, 2024

你可以先自己调下 cmakelists.txt 看下哪里不对,xmake 能编译,不代表 cmake 一定也能很好支持 c++ modules。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


You can first adjust cmakelists.txt yourself to see what is wrong. If xmake can compile, it does not mean that cmake can also support c++ modules well.

@Tomcat-42
Copy link

Actually CMake support modules (with one exception, header units). But you should add sources like the following:

target_sources(foo
  PUBLIC
    FILE_SET CXX_MODULES FILES
      foo.cxx
)

Note the FILE_SET CXX_MODULES FILES annotation. This should be rather easy to implement in the XMake side.

Sources:

https://www.kitware.com/import-cmake-the-experiment-is-over/
https://www.kitware.com/import-std-in-cmake-3-30/

@waruqi
Copy link
Member

waruqi commented Oct 28, 2024

Note the FILE_SET CXX_MODULES FILES annotation. This should be rather easy to implement in the XMake side.

You can try add it in generated CMakeLists.txt manually. Does it work?

I think cmake is able to automatically recognize and support .cppm files for compiling as modules. It works for me.

Only non-module file suffixes (.cxx) need to be set CXX_MODULES file type explicitly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants