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

Two mutually exclusive clang flags for C++20 modules compilation are included #3009

Closed
aacirino opened this issue Nov 1, 2022 · 18 comments
Closed
Labels
Milestone

Comments

@aacirino
Copy link
Contributor

aacirino commented Nov 1, 2022

Xmake Version

2.7.1

Operating System Version and Architecture

Fedora 36, clang 15

Describe Bug

Since some time I've had problems building C++20 projects with modules. I had to resort to adding some compile flags but got tired of it and noticed that the compiler flags generation is including two mutually exclusive flags. In xmake/rules/c++/modules/modules_support/clang.lua we have

local implicitmodulesflag = get_implicitmodulesflag(target)
local noimplicitmodulemapsflag = get_noimplicitmodulemapsflag(target)

and then

target:add("cxxflags", implicitmodulesflag, {force = true})
target:add("cxxflags", noimplicitmodulemapsflag, {force = true})

Xmake should include only the implicit modules flag, allowing us to use clang's module maps transparently. Unfortunately xmake will not build in my environment due to an error something like No rule to build the target 'lua/lapi.c' (my system is in Brazilian Portuguese so I have to guess this is how it is phrased in English). I would change the modules flag generation myself and submit a pull request if I could build xmake.
In the meantime I have to keep adding the following flags to xmake.lua:

"-fimplicit-module-maps",
"-fmodule-map-file=$(shell brew --prefix)/include/c++/v1/module.modulemap",

Expected Behavior

xmake should include only the -fimplicit-modules flag.

Project Configuration

trouble.zip

Additional Information and Error Logs

[~/git/trouble]$ xmake -bv
[ 0%]: generating.cxx.module.deps src/my_module.cpp
[ 23%]: generating.cxx.module.bmi my_module
/home/linuxbrew/.linuxbrew/opt/llvm/bin/clang -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -fmodules -fbuiltin-module-map -fimplicit-modules -fno-implicit-module-maps -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -c -x c++-module --precompile src/my_module.mpp -o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm
src/my_module.mpp:3:8: fatal error: module 'std' not found
import std;

1 error generated.
@aacirino aacirino added the bug label Nov 1, 2022
@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

Unfortunately xmake will not build in my environment due to an error something like No rule to build the target 'lua/lapi.c' (my system is in Brazilian Portuguese so I have to guess this is how it is phrased in English). I would change the modules flag generation myself and submit a pull request if I could build xmake.

you need download full source code (contains git submodules), see
https://xmake.io/#/guide/faq?id=how-to-debug-xmake-source-code

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

xmake should include only the -fimplicit-modules flag.
"-fmodule-map-file=$(shell brew --prefix)/include/c++/v1/module.modulemap",

Even when I add these flags, it still doesn't seem to work.

@Arthapz Any idea about this?

/usr/bin/clang -c -x c++-module --precompile -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -fmodules -fbuiltin-module-map -fimplicit-modules -fimplicit-module-maps -fmodule-map-file=/usr/lib/llvm-15/lib/clang/15.0.2/include/module.modulemap -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm src/my_module.mpp
/usr/bin/clang -c -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -fmodules -fbuiltin-module-map -fimplicit-modules -fimplicit-module-maps -fmodule-map-file=/usr/lib/llvm-15/lib/clang/15.0.2/include/module.modulemap -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.objs/trouble/linux/x86_64/release/src/my_module.mpp.o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
error: src/my_module.mpp:3:8: fatal error: module 'std' not found
import std;
~~~~~~~^~~
1 error generated.

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

That was the smallest non-building modules project I was able to create to illustrate the issue. I modified the xmake.lua build script to include the additions that I've been using to be able to build my projects. This is the outcome of the attached build file:

[  0%]: generating.cxx.module.deps test/test.cpp
[  0%]: generating.cxx.module.deps src/my_module.cpp
[  0%]: generating.cxx.module.deps src/my_module.mpp
[ 23%]: generating.cxx.module.bmi my_module
[ 38%]: cache compiling.release src/my_module.cpp
[ 42%]: linking.release libtrouble.so
[ 85%]: cache compiling.release test/test.cpp
[ 90%]: linking.release test
[100%]: build ok!
[doctest] doctest version is "2.4.9"
[doctest] run with "--help" for options
===============================================================================
[doctest] test cases: 1 | 1 passed | 0 failed | 0 skipped
[doctest] assertions: 1 | 1 passed | 0 failed |
[doctest] Status: SUCCESS!

Please note that I had to add link flags, link dirs, include dirs and compile flags for this to work.

trouble.zip

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

I have not linuxbrew and mold. I modified llvm path, but it does not work for me.

/usr/bin/clang -c -x c++-module --precompile -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -I/usr/local/include -I/usr/lib/llvm-15/include -I/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1 -fmodules -fcxx-modules -fmodule-maps -fimplicit-module-maps -fbuiltin-module-map -fmodule-map-file=/usr/lib/llvm-15/lib/clang/15.0.2/include/module.modulemap -fvisibility=default -fimplicit-modules -fno-implicit-module-maps -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm src/my_module.mpp
/usr/bin/clang -c -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -I/usr/local/include -I/usr/lib/llvm-15/include -I/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1 -fmodules -fcxx-modules -fmodule-maps -fimplicit-module-maps -fbuiltin-module-map -fmodule-map-file=/usr/lib/llvm-15/lib/clang/15.0.2/include/module.modulemap -fvisibility=default -fimplicit-modules -fno-implicit-module-maps -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.objs/trouble/linux/x86_64/release/src/my_module.mpp.o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm
error: src/my_module.mpp:3:8: fatal error: module 'std' not found
import std;
~~~~~~~^~~
1 error generated.

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

By commenting out target:add("cxxflags", noimplicitmodulemapsflag, {force = true}) in xmake/rules/c++/modules/modules_support/clang.lua this is the smallest xmake.lua build scrit that works for me:

add_rules("mode.debug", "mode.release")
set_languages("c++20")

target()
add_includedirs(
	"$(shell brew --prefix)/include/",
	"$(shell brew --prefix)/opt/llvm/include/c++/v1"
)
add_cxxflags(
	"-fvisibility=default",
	{ force = true }
)
add_ldflags("-nostdlib++", "-stdlib=libc++", "-lc++")
target_end()

target("trouble")
    set_kind("shared")
    add_files("src/*.cpp", "src/*.mpp")

target("test")
    set_kind("binary")
    add_files("test/*.cpp")
    add_deps("trouble")

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

I cannot run this script, because I have not brew on my ubuntu.

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

@waruqi the problem is that your compiler flags include the undesired -fno-implicit-module-maps flag. This flag excludes clang's module.modulemap files from the compilation. I managed to comment-out the generation of this flag in xmake and built it again.

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

But now I can't use your example to test it, even if I delete -fno-implicit-module-maps, I still have the same problem.

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

Use this build script

set_config("toolchain", "clang")
add_rules("mode.debug", "mode.release")
set_languages("c++20")

target()
add_includedirs(
	"/usr/local/include",
	"/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1"
)
add_cxxflags(
	"-fvisibility=default",
	{ force = true }
)
add_ldflags("-nostdlib++", "-stdlib=libc++", "-lc++")
target_end()

target("trouble")
    set_kind("shared")
    add_files("src/*.cpp", "src/*.mpp")

target("test")
    set_kind("binary")
    add_files("test/*.cpp")
    add_deps("trouble")

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

Is xmake able to get clang's installation dir?

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

Is xmake able to get clang's installation dir?

/usr/lib/llvm-15/lib
/usr/bin/clang

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

Use this build script

set_config("toolchain", "clang")
add_rules("mode.debug", "mode.release")
set_languages("c++20")

target()
add_includedirs(
	"/usr/local/include",
	"/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1"
)
add_cxxflags(
	"-fvisibility=default",
	{ force = true }
)
add_ldflags("-nostdlib++", "-stdlib=libc++", "-lc++")
target_end()

target("trouble")
    set_kind("shared")
    add_files("src/*.cpp", "src/*.mpp")

target("test")
    set_kind("binary")
    add_files("test/*.cpp")
    add_deps("trouble")
/usr/bin/clang -c -x c++-module --precompile -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -I/usr/local/include -I/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1 -fvisibility=default -fmodules -fbuiltin-module-map -fimplicit-modules -fno-implicit-module-maps -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm src/my_module.mpp
/usr/bin/clang -c -Qunused-arguments -m64 -fPIC -O3 -std=c++20 -I/usr/local/include -I/usr/lib/llvm-15/lib/clang/15.0.2/include/c++/v1 -fvisibility=default -fmodules -fbuiltin-module-map -fimplicit-modules -fno-implicit-module-maps -DNDEBUG -fmodules-cache-path=build/.gens/trouble/linux/x86_64/release/rules/modules/cache -o build/.objs/trouble/linux/x86_64/release/src/my_module.mpp.o build/.gens/trouble/linux/x86_64/release/rules/modules/cache/my_module.pcm
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
error: src/my_module.mpp:3:8: fatal error: module 'std' not found
import std;
~~~~~~~^~~
1 error generated.

it does not work.

@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

If it works on your machine, you can open a pr first.

@aacirino
Copy link
Contributor Author

aacirino commented Nov 2, 2022

PR created

@waruqi
Copy link
Member

waruqi commented Nov 3, 2022

see #3016

But I still need to solve the compatibility problem between libc++ and libstdc++.

@waruqi
Copy link
Member

waruqi commented Nov 4, 2022

try it again. xmake update -s dev

@waruqi
Copy link
Member

waruqi commented Nov 5, 2022

https://github.com/xmake-io/xmake/blob/7c5bd94cde348e8d656a0cb577bef83c7e20a070/tests/projects/c%2B%2B/modules/stdmodules/xmake.lua

we need use -stdlib=libc++ for clang if we use import std

add_rules("mode.debug", "mode.release")
set_languages("c++20")

add_cxxflags("clang::-stdlib=libc++")

target("mod")
    set_kind("shared")
    add_files("src/*.cpp", "src/*.mpp")

target("test")
    set_kind("binary")
    add_files("test/*.cpp")
    add_deps("mod")

@waruqi
Copy link
Member

waruqi commented Nov 7, 2022

It should work now.

@waruqi waruqi closed this as completed Nov 7, 2022
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

2 participants