admin管理员组文章数量:1279124
In the last few weeks, I've been experimenting for the first time with C++20 modules after reading about them for years. I extensively worked with them in Visual Studio and I did some successful test with cmake (using nmake as generator) and had little to no issue setting up the project.
Now I have to switch to an environment where only GCC and GNU make are available. I have an old project that I want to migrate to using modules, whose current GNUmakefile looks like this:
SOURCE_EXTENSION := cpp
SOURCES := $(shell find $(SOURCE_DIRECTORY) -type f -name *.$(SOURCE_EXTENSION))
OBJECTS := $(patsubst $(SOURCE_DIRECTORY)/%,$(OBJECT_DIRECTORY)/%,$(SOURCES:.$(SOURCE_EXTENSION)=.o))
COMPILATION_FLAGS := -g -Wall
$(TARGET): $(OBJECTS)
@mkdir -p $(BINARY_DIRECTORY)
$(GCC) $^ -o $(BINARY_DIRECTORY)/$(TARGET)
$(OBJECT_DIRECTORY)/%.o: $(SOURCE_DIRECTORY)/%.$(SOURCE_EXTENSION)
@mkdir -p $(dir $@)
$(GCC) $(COMPILATION_FLAGS) $(INCLUDES) -c -o $@ $<
Which is a fast way to build everything in my code folder, creating an object folder with a mirroring structure and then linking everything together. I was wondering if and how you could do the same thing with modules, given that they seem very sensible to ordering, so that I don't have to list every single module, manually managing its dependencies.
In the last few weeks, I've been experimenting for the first time with C++20 modules after reading about them for years. I extensively worked with them in Visual Studio and I did some successful test with cmake (using nmake as generator) and had little to no issue setting up the project.
Now I have to switch to an environment where only GCC and GNU make are available. I have an old project that I want to migrate to using modules, whose current GNUmakefile looks like this:
SOURCE_EXTENSION := cpp
SOURCES := $(shell find $(SOURCE_DIRECTORY) -type f -name *.$(SOURCE_EXTENSION))
OBJECTS := $(patsubst $(SOURCE_DIRECTORY)/%,$(OBJECT_DIRECTORY)/%,$(SOURCES:.$(SOURCE_EXTENSION)=.o))
COMPILATION_FLAGS := -g -Wall
$(TARGET): $(OBJECTS)
@mkdir -p $(BINARY_DIRECTORY)
$(GCC) $^ -o $(BINARY_DIRECTORY)/$(TARGET)
$(OBJECT_DIRECTORY)/%.o: $(SOURCE_DIRECTORY)/%.$(SOURCE_EXTENSION)
@mkdir -p $(dir $@)
$(GCC) $(COMPILATION_FLAGS) $(INCLUDES) -c -o $@ $<
Which is a fast way to build everything in my code folder, creating an object folder with a mirroring structure and then linking everything together. I was wondering if and how you could do the same thing with modules, given that they seem very sensible to ordering, so that I don't have to list every single module, manually managing its dependencies.
Share Improve this question edited Feb 24 at 10:24 prapin 6,8985 gold badges29 silver badges54 bronze badges asked Feb 24 at 7:22 Andrea BoccoAndrea Bocco 9746 silver badges16 bronze badges 11 | Show 6 more comments1 Answer
Reset to default 0Here's an example of a build with GCC using the command line as a starting reference. The module interface (MIU) and implementation units are American.Bobtail.cppm
and american_bobtail.cpp
, respectively. main.cpp
is obvious.
Command Lines
+ g++ -std=c++23 -fmodules-ts -x c++ American.Bobtail.cppm -o bin/American.Bobtail.o -c
+ g++ -std=c++23 -fmodules-ts -c american_bobtail.cpp -o bin/American.Bobtail.All.o
+ g++ -std=c++23 -fmodules-ts -c main.cpp -o bin/main.o
+ g++ -std=c++23 -fmodules-ts bin/main.o bin/American.Bobtail.All.o -o bin/main
+ bin/main
American Bobtail cat says 'meow'
The output looks like:
├── bin
│ ├── American.Bobtail.o
│ ├── american_bobtail.o
│ ├── main
│ └── main.o
├──gcm.cache
└── American.Bobtail.gcm
Make
I don't know make enough to present it, but I will show CMake below.
There are additional dependencies that make would need to deal with. CMake does not support make, only Ninja.
GCC puts the build of a module with a .gcm
extension into the directory gcm_cache.
Make would need to check if this exists for any modules. The first line above also puts the binary for the MIU in the bin
directory.
The following line builds the implementation unit and links its output with the MIU to build the All
binary.
Then, main
is built and linked with the All
binary. I suggest you start with this example to create a make file and then work to see if it will handle your project.
CMake Build
I don't want to edit much so I have to provide the parent directory and the subdirectory CMake files:
Parent
cmake_minimum_required(VERSION 3.30.5) # can be 28
project(my_modules LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_subdirectory(American.Bobtail)
Subdirectory
cmake_minimum_required(VERSION 3.30.5)
project(American.Bobtail LANGUAGES CXX)
set(module_name american_bobtail)
add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
target_link_libraries(${PROJECT_NAME} ${module_name})
add_library(${module_name})
target_compile_features(${module_name} PUBLIC cxx_std_23)
target_sources(${module_name}
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES
FILES ${PROJECT_NAME}.cppm
PRIVATE ${module_name}.cpp
)
# command line build
# rm -rf build && cmake -B build -G Ninja && cmake --build build --verbose && build/American.Bobtail
I won't go through all this, but if you get lost, ask in the comments. The commented-out line at the end will be built using CMake from the parent directory.
本文标签: cAutomatic GNU make with C20 moduleStack Overflow
版权声明:本文标题:c++ - Automatic GNU make with C++20 module - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741288957a2370435.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
$(TARGET)
is never made by its recipe so$(BINARY_DIRECTORY)/$(TARGET)
will be re-linked when there is no need. The right target is$(BINARY_DIRECTORY)/$(TARGET)
.mkdir -p ...
is fine but not every time a file is made and is foisting superflous makes of a target's prerequisite into its own recipe.$(BINARY_DIRECTORY)
and$(OBJECT_DIRECTORY)
are actually order-only prerequisites of the targets they are conflated with and if distinguished as such would only be updated when they don't exist. – Mike Kinghan Commented Feb 24 at 12:29cmake modules Bill Hoffman
, he is explaining how modules are introducing dependency relation between sources, which was previously hidden by header files. This means that simple recipe: object file depends on respective source file; is not enough. – Marek R Commented Feb 24 at 17:22