[libcxx-commits] [libcxx] [libc++][doc] Use installed std modules in external projects. (PR #80601)

Runzhong Li via libcxx-commits libcxx-commits at lists.llvm.org
Sun Mar 3 09:46:03 PST 2024


https://github.com/a858438680 updated https://github.com/llvm/llvm-project/pull/80601

>From e2d2cd0dca5d0ea037c51fc1fcaa2f79b111c21b Mon Sep 17 00:00:00 2001
From: LI Runzhong <858438680 at qq.com>
Date: Sun, 4 Feb 2024 23:51:16 +0800
Subject: [PATCH 1/2] [libc++][doc] Use installed std modules in external
 projects.

---
 libcxx/docs/Modules.rst | 111 ++++++++++++++++++++++++++--------------
 1 file changed, 74 insertions(+), 37 deletions(-)

diff --git a/libcxx/docs/Modules.rst b/libcxx/docs/Modules.rst
index 533c3fbd2a1eea..5aeeb0dfc2460e 100644
--- a/libcxx/docs/Modules.rst
+++ b/libcxx/docs/Modules.rst
@@ -105,36 +105,36 @@ Users need to be able to build their own BMI files.
    system vendors, with the goal that building the BMI files is done by
    the build system.
 
-Currently this requires a local build of libc++ with modules enabled. Since
-modules are not part of the installation yet, they are used from the build
-directory. First libc++ needs to be build with module support enabled.
+Currently this requires a local build of libc++ with modules installation enabled.
+Since modules are not installed by default. You can build and install the modules
+to ``<install_prefix>`` with the following commands.
 
 .. code-block:: bash
 
-  $ git clone https://github.com/llvm/llvm-project.git
+  $ git clone https://github.com/llvm/llvm-project.git --depth 1
   $ cd llvm-project
   $ mkdir build
-  $ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
-  $ ninja -C build
-
-The above ``build`` directory will be referred to as ``<build>`` in the
-rest of these instructions.
+  $ cmake -G Ninja -S runtimes -B build -DCMAKE_C_COMPILER=<path-to-compiler> -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_INSTALL_MODULES=ON -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
+  $ cmake --build build -- -j $(nproc)
+  $ cmake --install build --prefix <install_prefix>
 
 This is a small sample program that uses the module ``std``. It consists of a
-``CMakeLists.txt`` and a ``main.cpp`` file.
+``CMakeLists.txt``, an ``std.cmake``, and a ``main.cpp`` file.
 
 .. code-block:: cpp
 
+  // main.cpp
   import std; // When importing std.compat it's not needed to import std.
   import std.compat;
 
   int main() {
-    std::cout << "Hello modular world\n";
+    std::println("Hello modular world");
     ::printf("Hello compat modular world\n");
   }
 
 .. code-block:: cmake
 
+  # CMakeLists.txt
   cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
   project("module"
     LANGUAGES CXX
@@ -168,58 +168,95 @@ This is a small sample program that uses the module ``std``. It consists of a
   #
   # Import the modules from libc++
   #
+  include(std.cmake)
+
+  add_executable(main main.cpp)
+
+.. code-block:: cmake
 
+  # std.cmake
   include(FetchContent)
   FetchContent_Declare(
-    std
-    URL "file://${LIBCXX_BUILD}/modules/c++/v1/"
+    std_module
+    URL "file://${LIBCXX_INSTALLED_DIR}/share/libc++/v1"
     DOWNLOAD_EXTRACT_TIMESTAMP TRUE
     SYSTEM
   )
-  FetchContent_MakeAvailable(std)
+
+  if (NOT std_module_POPULATED)
+    FetchContent_Populate(std_module)
+  endif()
 
   #
-  # Adjust project compiler flags
+  # Add std static library
   #
 
-  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fprebuilt-module-path=${std_BINARY_DIR}/CMakeFiles/std.dir/>)
-  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fprebuilt-module-path=${std_BINARY_DIR}/CMakeFiles/std.compat.dir/>)
-  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-nostdinc++>)
-  # The include path needs to be set to be able to use macros from headers.
-  # For example from, the headers <cassert> and <version>.
-  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-isystem>)
-  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${LIBCXX_BUILD}/include/c++/v1>)
+  add_library(std)
+
+  target_sources(std
+    PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES
+      ${std_module_SOURCE_DIR}/std.cppm
+      ${std_module_SOURCE_DIR}/std.compat.cppm
+  )
 
   #
-  # Adjust project linker flags
+  # Adjust project include directories
   #
 
-  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-nostdlib++>)
-  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-L${LIBCXX_BUILD}/lib>)
-  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-Wl,-rpath,${LIBCXX_BUILD}/lib>)
-  # Linking against the standard c++ library is required for CMake to get the proper dependencies.
-  link_libraries(std c++)
-  link_libraries(std.compat c++)
+  target_include_directories(std SYSTEM PUBLIC ${LIBCXX_INSTALLED_DIR}/include/c++/v1)
 
   #
-  # Add the project
+  # Adjust project compiler flags
   #
 
-  add_executable(main)
-  target_sources(main
+  target_compile_options(std
     PRIVATE
-      main.cpp
+      -Wno-reserved-module-identifier
+      -Wno-reserved-user-defined-literal
+  )
+
+  target_compile_options(std
+    PUBLIC
+      -nostdinc++
+  )
+
+  #
+  # Adjust project linker flags
+  #
+
+  target_link_options(std
+    INTERFACE
+      -nostdlib++
+      -L${LIBCXX_INSTALLED_DIR}/lib
+      -Wl,-rpath,${LIBCXX_INSTALLED_DIR}/lib
+  )
+
+  target_link_libraries(std
+    INTERFACE
+      c++
   )
+  
+  #
+  # Link to the std modules by default
+  #
+
+  link_libraries(std)
 
 Building this project is done with the following steps, assuming the files
-``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory.
+``main.cpp``, ``CMakeLists.txt``, and ``std.cmake`` are copied in the current directory.
 
 .. code-block:: bash
 
   $ mkdir build
-  $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_BUILD=<build>
-  $ ninja -C build
-  $ build/main
+  $ cmake -S . -B build -G Ninja -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_INSTALLED_DIR=<install_prefix>
+  $ cmake --build build
+  $ ./build/main
+
+.. warning:: You need more than clang itself to build a project using modules.
+             Specifically, you will need ``clang-scan-deps``. For example, in Ubuntu, you
+             need to use ``sudo ./llvm.sh 17 all`` rather than ``sudo ./llvm.sh 17`` showed
+             in `LLVM Debian/Ubuntu nightly packages <https://apt.llvm.org>`__ to install
+             essential components to build this project.
 
 .. warning:: ``<path-to-compiler>`` should point point to the real binary and
              not to a symlink.

>From bc6fc4f8b6fabf6af82af280425fba6d052de6a5 Mon Sep 17 00:00:00 2001
From: LI Runzhong <858438680 at qq.com>
Date: Mon, 4 Mar 2024 01:45:46 +0800
Subject: [PATCH 2/2] [libc++][doc] Use installed std modules with the previous
 version kept.

---
 libcxx/docs/Modules.rst | 122 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 110 insertions(+), 12 deletions(-)

diff --git a/libcxx/docs/Modules.rst b/libcxx/docs/Modules.rst
index 5aeeb0dfc2460e..b6947424cfef24 100644
--- a/libcxx/docs/Modules.rst
+++ b/libcxx/docs/Modules.rst
@@ -105,33 +105,131 @@ Users need to be able to build their own BMI files.
    system vendors, with the goal that building the BMI files is done by
    the build system.
 
-Currently this requires a local build of libc++ with modules installation enabled.
-Since modules are not installed by default. You can build and install the modules
-to ``<install_prefix>`` with the following commands.
+Currently this requires a local build of libc++ with modules enabled. Since
+modules are not part of the installation yet, they are used from the build
+directory. First libc++ needs to be build with module support enabled. If
+the libc++ is built with installation of modules enabled, they can also be
+used from the installation directory. The following instructions enable the
+installation of modules and install the modules into ``<install_prefix>``.
 
 .. code-block:: bash
 
-  $ git clone https://github.com/llvm/llvm-project.git --depth 1
+  $ git clone https://github.com/llvm/llvm-project.git
   $ cd llvm-project
   $ mkdir build
-  $ cmake -G Ninja -S runtimes -B build -DCMAKE_C_COMPILER=<path-to-compiler> -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_INSTALL_MODULES=ON -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
-  $ cmake --build build -- -j $(nproc)
-  $ cmake --install build --prefix <install_prefix>
+  $ cmake -G Ninja -S runtimes -B build -DLIBCXX_INSTALL_MODULES=ON -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
+  $ ninja --build build -- -j $(nproc)
+  $ ninja --install build --prefix <install_prefix>
 
-This is a small sample program that uses the module ``std``. It consists of a
-``CMakeLists.txt``, an ``std.cmake``, and a ``main.cpp`` file.
+The above ``build`` directory will be referred to as ``<build>`` in the
+rest of these instructions.
+
+This is a small sample program that uses the module ``std`` from build
+directory. It consists of a ``CMakeLists.txt`` and a ``main.cpp`` file.
 
 .. code-block:: cpp
 
-  // main.cpp
   import std; // When importing std.compat it's not needed to import std.
   import std.compat;
 
   int main() {
-    std::println("Hello modular world");
+    std::cout << "Hello modular world\n";
     ::printf("Hello compat modular world\n");
   }
 
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
+  project("module"
+    LANGUAGES CXX
+  )
+
+  #
+  # Set language version used
+  #
+
+  set(CMAKE_CXX_STANDARD 23)
+  set(CMAKE_CXX_STANDARD_REQUIRED YES)
+  # Libc++ doesn't support compiler extensions for modules.
+  set(CMAKE_CXX_EXTENSIONS OFF)
+
+  #
+  # Enable modules in CMake
+  #
+
+  # This is required to write your own modules in your project.
+  if(CMAKE_VERSION VERSION_LESS "3.28.0")
+    if(CMAKE_VERSION VERSION_LESS "3.27.0")
+      set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
+    else()
+      set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
+    endif()
+    set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+  else()
+    cmake_policy(VERSION 3.28)
+  endif()
+
+  #
+  # Import the modules from libc++
+  #
+
+  include(FetchContent)
+  FetchContent_Declare(
+    std
+    URL "file://${LIBCXX_BUILD}/modules/c++/v1/"
+    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
+    SYSTEM
+  )
+  FetchContent_MakeAvailable(std)
+
+  #
+  # Adjust project compiler flags
+  #
+
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fprebuilt-module-path=${std_BINARY_DIR}/CMakeFiles/std.dir/>)
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fprebuilt-module-path=${std_BINARY_DIR}/CMakeFiles/std.compat.dir/>)
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-nostdinc++>)
+  # The include path needs to be set to be able to use macros from headers.
+  # For example from, the headers <cassert> and <version>.
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-isystem>)
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${LIBCXX_BUILD}/include/c++/v1>)
+
+  #
+  # Adjust project linker flags
+  #
+
+  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-nostdlib++>)
+  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-L${LIBCXX_BUILD}/lib>)
+  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-Wl,-rpath,${LIBCXX_BUILD}/lib>)
+  # Linking against the standard c++ library is required for CMake to get the proper dependencies.
+  link_libraries(std c++)
+  link_libraries(std.compat c++)
+
+  #
+  # Add the project
+  #
+
+  add_executable(main)
+  target_sources(main
+    PRIVATE
+      main.cpp
+  )
+
+Building this project is done with the following steps, assuming the files
+``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory.
+
+.. code-block:: bash
+
+  $ mkdir build
+  $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_BUILD=<build>
+  $ ninja -C build
+  $ build/main
+
+This is another small sample program that uses the module ``std`` from
+installation directory. It consists of a ``CMakeLists.txt``, an
+``std.cmake``, and a ``main.cpp`` file. The ``main.cpp`` is the same as
+the previous example.
+
 .. code-block:: cmake
 
   # CMakeLists.txt
@@ -191,7 +289,7 @@ This is a small sample program that uses the module ``std``. It consists of a
   # Add std static library
   #
 
-  add_library(std)
+  add_library(std STATIC)
 
   target_sources(std
     PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES



More information about the libcxx-commits mailing list