Exercise16

Confgiure.h.in file

ubuntu@ubuntu:$ vim TutorialConfig.h.in 
ubuntu@ubuntu:$ cat TutorialConfig.h.in 
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
ubuntu@ubuntu:$ 

Cxx file

ubuntu@ubuntu:$ vim tutorial.cxx 
ubuntu@ubuntu:$ cat tutorial.cxx 
// A simple program that computes the square root of a number
#include <iostream>
#include <sstream>
#include <string>

#include "MathFunctions.h"
#include "TutorialConfig.h"

int main(int argc, char* argv[])
{
  if (argc < 2) {
    // report version
    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
              << Tutorial_VERSION_MINOR << std::endl;
    std::cout << "Usage: " << argv[0] << " number" << std::endl;
    return 1;
  }

  // convert input to double
  const double inputValue = std::stod(argv[1]);

  const double outputValue = mathfunctions::sqrt(inputValue);

  std::cout << "The square root of " << inputValue << " is " << outputValue
            << std::endl;
  return 0;
}
ubuntu@ubuntu:$ 

License.txt file

ubuntu@ubuntu:$ vim License.txt 
ubuntu@ubuntu:$ cat License.txt 
This is the open source License.txt file introduced in
CMake/Tutorial/Step9...
ubuntu@ubuntu:$

Top CMake file

ubuntu@ubuntu:$ vim CMakeLists.txt 
ubuntu@ubuntu:$ cat CMakeLists.txt 
cmake_minimum_required(VERSION 3.15)

# set the project name and version

project(Tutorial VERSION 1.0)

# specify the C++ standard

add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)

# add compiler warning flags just when building this project via

# the BUILD_INTERFACE genex

set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)

# control where the static and shared libraries are built so that on windows

# we don't need to tinker with the path to run the executable

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

# configure a header file to pass the version number only

configure_file(TutorialConfig.h.in TutorialConfig.h)

# add the MathFunctions library

add_subdirectory(MathFunctions)

# add the executable

add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)

# add the binary tree to the search path for include files

# so that we will find TutorialConfig.h

target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           )

# add the install targets

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  DESTINATION include
  )

# enable testing

include(CTest)

# does the application run

add_test(NAME Runs COMMAND Tutorial 25)

# does the usage message work?

add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
  )

# define a function to simplify adding tests

function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endfunction()

# do a bunch of result based tests

do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")

# setup installer

include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
set(CPACK_SOURCE_GENERATOR "TGZ")
include(CPack)


install(EXPORT MathFunctionsTargets
        FILE MathFunctionsTargets.cmake
        DESTINATION lib/cmake/MathFunctions
       )

include(CMakePackageConfigHelpers)

# generate the config file that is includes the exports

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
    "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
    INSTALL_DESTINATION "lib/cmake/example"
    NO_SET_AND_CHECK_MACRO
    NO_CHECK_REQUIRED_COMPONENTS_MACRO
    )

write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
    VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
    COMPATIBILITY AnyNewerVersion
    )


install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake
    DESTINATION lib/cmake/MathFunctions
    )

export(EXPORT MathFunctionsTargets
    FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
    )


ubuntu@ubuntu:$

CTestConfig.cmake file

ubuntu@ubuntu:$ vim CTestConfig.cmake 
ubuntu@ubuntu:$ cat CTestConfig.cmake 
set(CTEST_PROJECT_NAME "CMakeTutorial")
set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")

set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
set(CTEST_DROP_SITE_CDASH TRUE)
ubuntu@ubuntu:$

Config.cmake.in

ubuntu@ubuntu:$ vim Config.cmake.in 
ubuntu@ubuntu:$ cat Config.cmake.in 
@CKAGE_INIT@

include ("${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake")
ubuntu@ubuntu:$

MathFunctions directory

ubuntu@ubuntu:$ ls -trl
total 32
-rw-r--r-- 1 ubuntu ubuntu  719 Oct 12 22:26 tutorial.cxx
-rw-r--r-- 1 ubuntu ubuntu  164 Oct 12 22:26 TutorialConfig.h.in
-rw-r--r-- 1 ubuntu ubuntu   79 Oct 12 22:26 License.txt
-rw-r--r-- 1 ubuntu ubuntu  245 Oct 12 22:26 CTestConfig.cmake
drwxr-xr-x 2 ubuntu ubuntu 4096 Oct 21 16:53 MathFunctions
-rw-rw-r-- 1 ubuntu ubuntu   79 Oct 21 17:30 Config.cmake.in
-rw-r--r-- 1 ubuntu ubuntu 3778 Oct 21 18:13 CMakeLists.txt
ubuntu@ubuntu:$ 

MathFunctions Cxx file

ubuntu@ubuntu:$ vim MathFunctions.cxx 
ubuntu@ubuntu:$ cat MathFunctions.cxx 

#include "MathFunctions.h"

#include <cmath>

#ifdef USE_MYMATH

#  include "mysqrt.h"

#endif

namespace mathfunctions {
double sqrt(double x)
{
#ifdef USE_MYMATH
  return detail::mysqrt(x);
#else
  return std::sqrt(x);
#endif
}
}
ubuntu@ubuntu:$

MathFunctions header file

ubuntu@ubuntu:$ vim MathFunctions.h
ubuntu@ubuntu:$ cat MathFunctions.h

#if defined(_WIN32)

#  if defined(EXPORTING_MYMATH)

#    define DECLSPEC __declspec(dllexport)

#  else

#    define DECLSPEC __declspec(dllimport)

#  endif

#else // non windows

#  define DECLSPEC

#endif

namespace mathfunctions {
double DECLSPEC sqrt(double x);
}
ubuntu@ubuntu:$

MakeTable Cxx file

ubuntu@ubuntu:$ vim MakeTable.cxx 
ubuntu@ubuntu:$ cat MakeTable.cxx 
// A simple program that builds a sqrt table
#include <cmath>
#include <fstream>
#include <iostream>

int main(int argc, char* argv[])
{
  // make sure we have enough arguments
  if (argc < 2) {
    return 1;
  }

  std::ofstream fout(argv[1], std::ios_base::out);
  const bool fileOpen = fout.is_open();
  if (fileOpen) {
    fout << "double sqrtTable[] = {" << std::endl;
    for (int i = 0; i < 10; ++i) {
      fout << sqrt(static_cast<double>(i)) << "," << std::endl;
    }
    // close the table with a zero
    fout << "0};" << std::endl;
    fout.close();
  }
  return fileOpen ? 0 : 1; // return 0 if wrote the file
}
ubuntu@ubuntu:$ 

mysqrt header file

ubuntu@ubuntu:$ vim mysqrt.h 
ubuntu@ubuntu:$ cat mysqrt.h

namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}
ubuntu@ubuntu:$ 

mysqrt Cxx file

ubuntu@ubuntu:$ vim mysqrt.cxx 
ubuntu@ubuntu:$ cat mysqrt.cxx 
#include <iostream>

#include "MathFunctions.h"

// include the generated table
#include "Table.h"

namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
  if (x <= 0) {
    return 0;
  }

  // use the table to help find an initial value
  double result = x;
  if (x >= 1 && x < 10) {
    std::cout << "Use the table to help find an initial value " << std::endl;
    result = sqrtTable[static_cast<int>(x)];
  }

  // do ten iterations
  for (int i = 0; i < 10; ++i) {
    if (result <= 0) {
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
  }

  return result;
}
}
}
ubuntu@ubuntu:$ 

MathFunctions CMake file

ubuntu@ubuntu:$ vim CMakeLists.txt 
ubuntu@ubuntu:$ cat CMakeLists.txt 

# add the library that runs

add_library(MathFunctions MathFunctions.cxx)

# state that anybody linking to us needs to include the current source dir

# to find MathFunctions.h, while we don't.

target_include_directories(MathFunctions
                           INTERFACE
                           $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
                           $<INSTALL_INTERFACE:include>
                           )

# should we use our own math functions

option(USE_MYMATH "Use tutorial provided math implementation" ON)
if(USE_MYMATH)

  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")

  # first we add the executable that generates the table

  add_executable(MakeTable MakeTable.cxx)
  target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)

  # add the command to generate the source code

  add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
    COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
    DEPENDS MakeTable
    )

  # library that just does sqrt

  add_library(SqrtLibrary STATIC
              mysqrt.cxx
              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
              )

  # state that we depend on our binary dir to find Table.h

  target_include_directories(SqrtLibrary PRIVATE
                             ${CMAKE_CURRENT_BINARY_DIR}
                             )

  # state that SqrtLibrary need PIC when the default is shared libraries

  set_target_properties(SqrtLibrary PROPERTIES
                        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
                        )

  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)

# define the symbol stating we are using the declspec(dllexport) when

# building on windows

target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")

# install libs

set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
  list(APPEND installable_libs SqrtLibrary)
endif()

install(TARGETS ${installable_libs}
        EXPORT MathFunctionsTargets
        DESTINATION lib)

# install include headers

install(FILES MathFunctions.h DESTINATION include)
ubuntu@ubuntu:$ 

构建cmake工程

ubuntu@ubuntu:$ cd exercise16_build/
ubuntu@ubuntu:$ ls -tlr
total 0
ubuntu@ubuntu:$ cmake ..
-- Build files have been written to: /home/ubuntu/study/cmake-learning/cmake-3.25.0-rc1-tutorial-source/Step11/exercise16_build
ubuntu@ubuntu:$ ls -tlr
total 100
-rw-r--r--  1 ubuntu ubuntu   118 Oct 21 18:31 TutorialConfig.h
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:31 Testing
-rw-r--r--  1 ubuntu ubuntu  2689 Oct 21 18:31 DartConfiguration.tcl
-rw-r--r--  1 ubuntu ubuntu  3568 Oct 21 18:31 CPackConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  4033 Oct 21 18:31 CPackSourceConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  1975 Oct 21 18:31 MathFunctionsConfigVersion.cmake
-rw-rw-r--  1 ubuntu ubuntu    67 Oct 21 18:31 MathFunctionsConfig.cmake
-rw-rw-r--  1 ubuntu ubuntu 18183 Oct 21 18:31 CMakeCache.txt
-rw-rw-r--  1 ubuntu ubuntu 24411 Oct 21 18:31 Makefile
-rw-rw-r--  1 ubuntu ubuntu  4806 Oct 21 18:31 CTestTestfile.cmake
-rw-rw-r--  1 ubuntu ubuntu  5559 Oct 21 18:31 cmake_install.cmake
-rw-rw-r--  1 ubuntu ubuntu  3921 Oct 21 18:31 MathFunctionsTargets.cmake
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:31 MathFunctions
drwxrwxr-x 35 ubuntu ubuntu  4096 Oct 21 18:31 CMakeFiles
ubuntu@ubuntu:$ cmake --build .
ubuntu@ubuntu:$ ls -tlr
total 148
-rw-r--r--  1 ubuntu ubuntu   118 Oct 21 18:31 TutorialConfig.h
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:31 Testing
-rw-r--r--  1 ubuntu ubuntu  2689 Oct 21 18:31 DartConfiguration.tcl
-rw-r--r--  1 ubuntu ubuntu  3568 Oct 21 18:31 CPackConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  4033 Oct 21 18:31 CPackSourceConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  1975 Oct 21 18:31 MathFunctionsConfigVersion.cmake
-rw-rw-r--  1 ubuntu ubuntu    67 Oct 21 18:31 MathFunctionsConfig.cmake
-rw-rw-r--  1 ubuntu ubuntu 18183 Oct 21 18:31 CMakeCache.txt
-rw-rw-r--  1 ubuntu ubuntu 24411 Oct 21 18:31 Makefile
-rw-rw-r--  1 ubuntu ubuntu  4806 Oct 21 18:31 CTestTestfile.cmake
-rw-rw-r--  1 ubuntu ubuntu  5559 Oct 21 18:31 cmake_install.cmake
-rw-rw-r--  1 ubuntu ubuntu  3921 Oct 21 18:31 MathFunctionsTargets.cmake
-rwxrwxr-x  1 ubuntu ubuntu 13752 Oct 21 18:32 MakeTable
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:32 MathFunctions
-rw-rw-r--  1 ubuntu ubuntu  3922 Oct 21 18:32 libSqrtLibrary.a
-rwxrwxr-x  1 ubuntu ubuntu  8904 Oct 21 18:32 libMathFunctions.so
-rwxrwxr-x  1 ubuntu ubuntu 14880 Oct 21 18:32 Tutorial
drwxrwxr-x 35 ubuntu ubuntu  4096 Oct 21 18:32 CMakeFiles
ubuntu@ubuntu:$ cmake --install . --prefix=.
-- Installing: /home/ubuntu/study/cmake-learning/cmake-3.25.0-rc1-tutorial-source/Step11/exercise16_build/./lib/cmake/MathFunctions/MathFunctionsTargets.cmake
-- Installing: /home/ubuntu/study/cmake-learning/cmake-3.25.0-rc1-tutorial-source/Step11/exercise16_build/./lib/cmake/MathFunctions/MathFunctionsTargets-noconfig.cmake
-- Installing: /home/ubuntu/study/cmake-learning/cmake-3.25.0-rc1-tutorial-source/Step11/exercise16_build/./lib/cmake/MathFunctions/MathFunctionsConfig.cmake
-- Installing: /home/ubuntu/study/cmake-learning/cmake-3.25.0-rc1-tutorial-source/Step11/exercise16_build/./lib/cmake/MathFunctions/MathFunctionsConfigVersion.cmake
ubuntu@ubuntu:$ ls -tlr
total 164
-rw-r--r--  1 ubuntu ubuntu   118 Oct 21 18:31 TutorialConfig.h
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:31 Testing
-rw-r--r--  1 ubuntu ubuntu  2689 Oct 21 18:31 DartConfiguration.tcl
-rw-r--r--  1 ubuntu ubuntu  3568 Oct 21 18:31 CPackConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  4033 Oct 21 18:31 CPackSourceConfig.cmake
-rw-r--r--  1 ubuntu ubuntu  1975 Oct 21 18:31 MathFunctionsConfigVersion.cmake
-rw-rw-r--  1 ubuntu ubuntu    67 Oct 21 18:31 MathFunctionsConfig.cmake
-rw-rw-r--  1 ubuntu ubuntu 18183 Oct 21 18:31 CMakeCache.txt
-rw-rw-r--  1 ubuntu ubuntu 24411 Oct 21 18:31 Makefile
-rw-rw-r--  1 ubuntu ubuntu  4806 Oct 21 18:31 CTestTestfile.cmake
-rw-rw-r--  1 ubuntu ubuntu  5559 Oct 21 18:31 cmake_install.cmake
-rw-rw-r--  1 ubuntu ubuntu  3921 Oct 21 18:31 MathFunctionsTargets.cmake
-rwxrwxr-x  1 ubuntu ubuntu 13752 Oct 21 18:32 MakeTable
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:32 MathFunctions
-rw-rw-r--  1 ubuntu ubuntu  3922 Oct 21 18:32 libSqrtLibrary.a
-rwxrwxr-x  1 ubuntu ubuntu  8904 Oct 21 18:32 libMathFunctions.so
-rwxrwxr-x  1 ubuntu ubuntu 14880 Oct 21 18:32 Tutorial
drwxrwxr-x 35 ubuntu ubuntu  4096 Oct 21 18:32 CMakeFiles
drwxrwxr-x  3 ubuntu ubuntu  4096 Oct 21 18:32 lib
drwxrwxr-x  2 ubuntu ubuntu  4096 Oct 21 18:32 include
drwxrwxr-x  2 ubuntu ubuntu  4096 Oct 21 18:32 bin
-rw-rw-r--  1 ubuntu ubuntu  1161 Oct 21 18:32 install_manifest.txt
ubuntu@ubuntu:$ cd lib/
ubuntu@ubuntu:$ ls -lr
total 20
-rw-r--r-- 1 ubuntu ubuntu 3922 Oct 21 18:32 libSqrtLibrary.a
-rw-r--r-- 1 ubuntu ubuntu 8904 Oct 21 18:32 libMathFunctions.so
drwxrwxr-x 3 ubuntu ubuntu 4096 Oct 21 18:32 cmake
ubuntu@ubuntu:$ cd cmake/
ubuntu@ubuntu:$ ls -tlr
total 4
drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 21 18:32 MathFunctions
ubuntu@ubuntu:$ cd MathFunctions/
ubuntu@ubuntu:$ ls -tlr
total 20
-rw-r--r-- 1 ubuntu ubuntu 1276 Oct 21 18:31 MathFunctionsTargets-noconfig.cmake
-rw-r--r-- 1 ubuntu ubuntu 4644 Oct 21 18:31 MathFunctionsTargets.cmake
-rw-r--r-- 1 ubuntu ubuntu 1975 Oct 21 18:31 MathFunctionsConfigVersion.cmake
-rw-r--r-- 1 ubuntu ubuntu   67 Oct 21 18:31 MathFunctionsConfig.cmake
ubuntu@ubuntu:$ cd ../../../
ubuntu@ubuntu:$ 

运行可执行文件

ubuntu@ubuntu:$ ./Tutorial 4294967296
Computing sqrt of 4.29497e+09 to be 2.14748e+09
Computing sqrt of 4.29497e+09 to be 1.07374e+09
Computing sqrt of 4.29497e+09 to be 5.36871e+08
Computing sqrt of 4.29497e+09 to be 2.68435e+08
Computing sqrt of 4.29497e+09 to be 1.34218e+08
Computing sqrt of 4.29497e+09 to be 6.71089e+07
Computing sqrt of 4.29497e+09 to be 3.35545e+07
Computing sqrt of 4.29497e+09 to be 1.67773e+07
Computing sqrt of 4.29497e+09 to be 8.38878e+06
Computing sqrt of 4.29497e+09 to be 4.19465e+06
The square root of 4.29497e+09 is 4.19465e+06
ubuntu@ubuntu:$ ./Tutorial 10
Computing sqrt of 10 to be 5.5
Computing sqrt of 10 to be 3.65909
Computing sqrt of 10 to be 3.19601
Computing sqrt of 10 to be 3.16246
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
Computing sqrt of 10 to be 3.16228
The square root of 10 is 3.16228
ubuntu@ubuntu:$ ./Tutorial
./Tutorial Version 1.0
Usage: ./Tutorial number
ubuntu@ubuntu:$ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值