CMake学习教程(一)

news2024/11/27 18:43:14

前言

看到陈皓大神写作的《跟我一起写 Makefile》,我也想出一个CMake学习的专栏。

距离我接触CMake已经过了3年,那是我还是研一,不懂得底层编译的事情,因为导师的项目才突然转到这个方向(项目是做工业软件的)。

当初学习的挣扎、难受都还历历在目,我知道自己一定能学会,但是需要时间,我在心里默默立下了一个Flag,学成之后我一定要写出一篇精彩全面的文章来记录,让后来人入门不再那么艰难。

为什么我一直没动笔呢?即使是现在的我也会认为CMake设计到的知识繁杂,尝试过几次都是浅尝辄止,现在工作了,目前是周末,我又想起了这件事,似乎我的写作能力也得到了提升,才鼓起勇气动笔。

这篇文章使用了官网中的文档,运用我在开发中的经验,采用ParaView这个软件的CMake编写习惯来写作。

希望我写的一点点文字能够对大家有用,不至于如同垃圾文章一样占用资源。

CMake相关知识

CMake是由KitWare公司开发的一款编译工具,Kitware[1]位于美国纽约,其致力于开源软件开发和软件开发服务,其产品和开源项目在计算机视觉、医学成像、科学可视化等领域得到了广泛应用。其中出品的CMake、VTK以及ParaView是对我最熟悉的三款产品。我也从其中ParaView的源代码中学习到了许多开发的精髓,不止一次感叹于其开发人员的专业性。

我认为学习一项技术不能不知道其历史来源,否则就只是使用技术的工具人而已,我想站在科学技术和人文艺术的交叉点思考问题,我从苹果创始人乔布斯那里学来了这一思维方式。

在CMake出来之前,如何实现从代码的文本文件到可执行的二进制文件的呢?如果只有一个源代码文件main.cpp,那么你在Linux平台下执行gcc main.cpp,就会默认生成名为a.out的可执行文件。随着技术的发展,结构化思维被引入到软件工程之中,每一个人只负责某个模块的开发,最后将所有人的代码文件集中到一起编译,生成最后的可执行文件。很明显这个时候你要依赖别人编译的库,这个时候一定会定义调用和编译他人库的规则才可以使用,于是MakeFile出现了,它包含了如何编译一个项目的流程、规则等,目前Linux平台下许多开源软件仍然使用MakeFile,就在你执行make&&make install命令时,就根据MakeFile文件的规则生成二进制文件。

随意打开一个Linux软件的仓库,VIM,可以看到其使用MakeFile定义编译流程。

点击打开MakeFile文件,我截取了部分代码,我相信没有长时间的学习语法,这是很难掌握的,说实话,我在本科阶段上过一门接近底层编译的课程,其中就有MakeFile的学习,但是我是一点没学会,仅仅知道几个命令而已,根本就不知道如何使用MakeFIle来编写适用于大型工程的规则。

indenttest:
	cd runtime/indent && \
		$(MAKE) clean && \
		$(MAKE) test VIM="$(VIM_FOR_INDENTTEST)"

# Executable used for running the syntax tests.
VIM_FOR_SYNTAXTEST = ../../src/vim

syntaxtest:
	cd runtime/syntax && \
		$(MAKE) clean && \
		$(MAKE) test VIMPROG="$(VIM_FOR_SYNTAXTEST)"

我再打开一个使用Cmake的仓库,ParaView,截取部分,其使用了if语句,对于程序员而言是否更加易懂呢?各位看官自行评价。

# Set up our directory structure for output libraries and binaries
include(GNUInstallDirs)
if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
endif ()
if (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
endif ()
if (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
endif ()

记得某个计算机科学家曾经说过,软件中你要解决某个问题,那么都可以通过多加一层来实现。

软件的发展也是符合进化论的,软件变的越来越抽象,人们在前人的基础上开发出越来越高层的东西,比如以前的软件是无法在硬件通用的,但是斯托曼自己开发了一个编译器GCC,使得程序员开发的代码使用GCC编译后,都可以在平台上面运行。

CMake的出现是因为什么呢?依我之见,正是时代的发展,往昔MakeFile并不适用于目前大型的软件工程了,学习成本也过高。但是CMake并没有替代MakeFile,它也是在MakeFile上面加了一层,将其语法简化了而已,其实CMake还是会生成MakeFile文件。所以你看,软件的传承就是这样的,站在巨人的肩膀上。

CMake的hello world初探

每个程序员的起点都是hello world,我也打算从CMake的hello world开始写。

我的实验环境使用Kali 2023,,只是因为当前的电脑上面刚好有这个虚拟机,十分方便而已,后续可能会演示Visual Studio的使用方式,毕竟咱们很多时候还是用VS来。

如果是在Windows上面安装也是非常简单的,CMake官网下载之后傻瓜式安装即可,我不再赘述CMake - Upgrade Your Software Build System

Linux平台直接apt install cmake -y,或者yum install cmake -y。如果报没有GCC编译器,install安装即可。

┌──(root㉿kidfu)-[~]
└─# apt install cmake
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
  libcbor0.8
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  cmake-data libjsoncpp25 librhash0
Suggested packages:
  cmake-doc cmake-format elpa-cmake-mode ninja-build
The following NEW packages will be installed:
  cmake cmake-data libjsoncpp25 librhash0
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 12.7 MB of archives.
After this operation, 48.6 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 https://mirrors.aliyun.com/kali kali-rolling/main amd64 libjsoncpp25 amd64 1.9.5-6 [79.8 kB]
Get:2 https://mirrors.aliyun.com/kali kali-rolling/main amd64 librhash0 amd64 1.4.3-3 [134 kB]
Get:3 https://mirrors.aliyun.com/kali kali-rolling/main amd64 cmake-data all 3.27.7-1 [2,104 kB]
Get:4 https://mirrors.aliyun.com/kali kali-rolling/main amd64 cmake amd64 3.27.7-1 [10.4 MB]
Fetched 12.7 MB in 2s (5,897 kB/s)
Selecting previously unselected package libjsoncpp25:amd64.
(Reading database ... 403674 files and directories currently installed.)
Preparing to unpack .../libjsoncpp25_1.9.5-6_amd64.deb ...
Unpacking libjsoncpp25:amd64 (1.9.5-6) ...
Selecting previously unselected package librhash0:amd64.
Preparing to unpack .../librhash0_1.4.3-3_amd64.deb ...
Unpacking librhash0:amd64 (1.4.3-3) ...
Selecting previously unselected package cmake-data.
Preparing to unpack .../cmake-data_3.27.7-1_all.deb ...
Unpacking cmake-data (3.27.7-1) ...
Selecting previously unselected package cmake.
Preparing to unpack .../cmake_3.27.7-1_amd64.deb ...
Unpacking cmake (3.27.7-1) ...
Setting up libjsoncpp25:amd64 (1.9.5-6) ...
Setting up librhash0:amd64 (1.4.3-3) ...
Setting up cmake-data (3.27.7-1) ...
Setting up cmake (3.27.7-1) ...
Processing triggers for libc-bin (2.37-12) ...
ldconfig: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link

Processing triggers for man-db (2.11.2-3) ...
Processing triggers for kali-menu (2023.4.5) ...

安装完成之后,目前在Kali家目录,新建目录cmake

┌──(root㉿kidfu)-[~]
└─# mkdir cmake

┌──(root㉿kidfu)-[~]
└─# cd cmake/

在此目录之下新建main.cpp与CMakeLists.txt。注意名字不要写错了。并且粘贴以下内容

main.cpp

#include<iostream>
int main()
{
        std::cout << "cmake hello world";
        return 0;
}

CMakeLists.txt,相信看名字就知道,第一行是定义cmake最低版本,第二行定义项目名称,第三行生成可执行二进制程序。

cmake_minimum_required (VERSION 3.10)
project(test)
add_executable(test main.cpp)

然后执行编译命令:

┌──(root㉿kidfu)-[~/cmake]
└─# mkdir build

┌──(root㉿kidfu)-[~/cmake]
└─# cd build

┌──(root㉿kidfu)-[~/cmake/build]
└─# cmake ..
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (8.3s)
-- Generating done (0.0s)
-- Build files have been written to: /root/cmake/build

 查看当前目录内容,看看都生成了哪些程序。可以看到其实CMake也生成了Makefile文件。

┌──(root㉿kidfu)-[~/cmake/build]
└─# ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile

打开Makefile看看都有什么东西,这是一段很长的代码。所以可以想象CMake为我们忽略了多少底层的信息。

┌──(root㉿kidfu)-[~/cmake/build]
└─# cat Makefile
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.27

# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target

# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:

#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:

# Disable VCS-based implicit rules.
% : %,v

# Disable VCS-based implicit rules.
% : RCS/%

# Disable VCS-based implicit rules.
% : RCS/%,v

# Disable VCS-based implicit rules.
% : SCCS/s.%

# Disable VCS-based implicit rules.
% : s.%

.SUFFIXES: .hpux_make_needs_suffix_list

# Command-line flag to silence nested $(MAKE).
$(VERBOSE)MAKESILENT = -s

#Suppress display of executed commands.
$(VERBOSE).SILENT:

# A target that is always out of date.
cmake_force:
.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake

# The command to remove a file.
RM = /usr/bin/cmake -E rm -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /root/cmake

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /root/cmake/build

#=============================================================================
# Targets provided globally by CMake.

# Special rule for the target edit_cache
edit_cache:
        @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "No interactive CMake dialog available..."
        /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
.PHONY : edit_cache

# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast

# Special rule for the target rebuild_cache
rebuild_cache:
        @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..."
        /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache

# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast

# The main all target
all: cmake_check_build_system
        $(CMAKE_COMMAND) -E cmake_progress_start /root/cmake/build/CMakeFiles /root/cmake/build//CMakeFiles/progress.marks
        $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
        $(CMAKE_COMMAND) -E cmake_progress_start /root/cmake/build/CMakeFiles 0
.PHONY : all

# The main clean target
clean:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
.PHONY : clean

# The main clean target
clean/fast: clean
.PHONY : clean/fast

# Prepare targets for installation.
preinstall: all
        $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall

# Prepare targets for installation.
preinstall/fast:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast

# clear depends
depend:
        $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend

#=============================================================================
# Target rules for targets named test

# Build rule for target.
test: cmake_check_build_system
        $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 test
.PHONY : test

# fast build rule for target.
test/fast:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/build
.PHONY : test/fast

main.o: main.cpp.o
.PHONY : main.o

# target to build an object file
main.cpp.o:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/main.cpp.o
.PHONY : main.cpp.o

main.i: main.cpp.i
.PHONY : main.i

# target to preprocess a source file
main.cpp.i:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/main.cpp.i
.PHONY : main.cpp.i

main.s: main.cpp.s
.PHONY : main.s

# target to generate assembly for a file
main.cpp.s:
        $(MAKE) $(MAKESILENT) -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/main.cpp.s
.PHONY : main.cpp.s

# Help Target
help:
        @echo "The following are some of the valid targets for this Makefile:"
        @echo "... all (the default if no target is provided)"
        @echo "... clean"
        @echo "... depend"
        @echo "... edit_cache"
        @echo "... rebuild_cache"
        @echo "... test"
        @echo "... main.o"
        @echo "... main.i"
        @echo "... main.s"
.PHONY : help



#=============================================================================
# Special targets to cleanup operation of make.

# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
        $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

然后编译可执行文件。可以看到其生成了二进制程序test,其实这里生成test的名字和目录都是可选的,CMake支持高度可定制的功能,目前我还没发现CMake无法完成的。

┌──(root㉿kidfu)-[~/cmake/build]
└─# make
[ 50%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[100%] Linking CXX executable test
[100%] Built target test

┌──(root㉿kidfu)-[~/cmake/build]
└─# ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  test

┌──(root㉿kidfu)-[~/cmake/build]
└─# ./test
cmake hello world

总结

今天这篇文章讲解了CMake相关的背景知识,并且run了一个基本的hello world。

接下来我会从官方手册和自己的开发经验,一点一点记录CMake学习的经验,由于CMake涉及到编译原理,链接等,要做到深入浅出讲解是非常麻烦的,所以我可能会慢慢更新,今天就先到这里。

准备以后更新,如何建立一个大型工程的编译目录,如何包含三方库文件等。

引用

[1] Kitware Inc. - Delivering Innovation - Customized Software Solutions for Complex Scientific Challenges

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1146374.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

问题 R: 超级楼梯(递推,基础DP)查表

得到递推表达式&#xff1a; f(1)0&#xff0c;因为开始就站在第1级台阶上&#xff1b; f(2)1&#xff0c;只能从第1级台阶上1级&#xff1b; f(3)2&#xff0c;只能从第1级台阶上2级&#xff0c;或只能从第2级台阶上1级&#xff1b; f(n)f(n-2)f(n-1)&#xff0c;n>3 …

Linux学习第25天:Linux 阻塞和非阻塞 IO 实验(二): 挂起

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 为方便和上一节的衔接&#xff0c;在正式开始学习前&#xff0c;先把本节的思维导图引入&#xff1a; 二、阻塞IO实验 1.硬件原理图分析 2.实验程序 #define I…

Linux两条服务器实现相互免密登录

1.准备两台虚拟机&#xff0c;一台充当服务器端&#xff08;server&#xff09;&#xff0c;一台充当客户端&#xff08;client&#xff09; 服务器端&#xff08;server&#xff09;&#xff1a;192.168.75.139 客户端&#xff08;client&#xff09;&#xff1a;192.168.75…

腾讯云和阿里云双11优惠大战,服务器价格相差1块钱?

2023双十一优惠活动来了&#xff0c;同配置轻量应用服务器2核2G3M带宽&#xff0c;阿里云87元一年&#xff0c;腾讯云88元一年&#xff0c;阿里云不限制月流量&#xff0c;腾讯云限制200GB月流量&#xff0c;阿里云系统盘是50GB高效云盘&#xff0c;腾讯云是40GB SSD云硬盘&…

redis6.0源码分析:跳表skiplist

文章目录 前言什么是跳表跳表&#xff08;redis实现&#xff09;的空间复杂度相关定义 跳表&#xff08;redis实现&#xff09;相关操作创建跳表插入节点查找节点删除节点 前言 太长不看版 跳跃表是有序集合zset的底层实现之一&#xff0c; 除此之外它在 Redis 中没有其他应用。…

LED主流光源-高均匀条形光源

&#xff08;1&#xff09;产品特点&#xff1a; ① 高均匀条形照明光源&#xff0c;可制作长度最长为 2000mm 的光源&#xff1b; ② 可用 M3 螺纹孔安装&#xff0c;也可以在三个挤型槽内插入 M3 螺母安装。 &#xff08;2&#xff09;应用领域&#xff1a; ① 电子元件识别与…

掌握Python:开启未来的大门

Python&#xff0c;一门以其简洁性和多才多艺而著称的编程语言&#xff0c;正成为未来的关键技能之一。随着数字时代的到来&#xff0c;Python的发展前景愈发广泛&#xff0c;而且其易学性吸引着越来越多的学习者。 1.Python的发展前景&#xff1a; Python在数据科学、人工智能…

任正非说:我们要改善和媒体的关系,而不是要利用媒体,不要自以为聪明。

嗨&#xff0c;你好&#xff01;这是华研荟【任正非说】系列的第22篇文章&#xff0c;让我们继续聆听任正非先生的真知灼见&#xff0c;学习华为的管理思想和管理理念。 一、我曾经在与一个世界著名公司&#xff0c;也是我司全方位的竞争对手的合作时讲过&#xff0c;我是拉宾的…

【数学基础】【进制转换】十进制转其他进制、其他进制转十进制

十进制转其他进制 JavaScript实现 const convert (num,base2)>{return !num?0:convert(~~(num/base),base)*10(num%base); } convert(8,2) // 1000 convert(8,8) // 10 convert(8,16) // 8其他进制转十进制 JavaScript实现 const reconvert (num,base2,curr1)>{retu…

代码随想录算法训练营第4天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交 、142.环形链表II

JAVA语言编写 24. 两两交换链表中的节点 谷歌、亚马逊、字节、奥多比、百度 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。…

浙大网新:重视AI驱动,就是重视未来发展

【科技明说 &#xff5c; 重磅专题】 对于浙大网新在AI方面的发展情况&#xff0c;我是看到一个消息之后才开始有了关注&#xff0c;之前总感觉浙大网新在AI方面战略雷声大雨点小&#xff0c;然而当我看到这个消息后才发现&#xff0c;浙大网新其实也非常重视AI方面的发展。 …

【微信小程序】WXML的模板语法与WXSS模板样式

&#x1f5a5;️&#x1f5a5;️&#x1f5a5;️ 博主主页&#xff1a; &#x1f449;&#x1f3fb; &#x1f449;&#x1f3fb; &#x1f449;&#x1f3fb; 糖 &#xff0d;O&#xff0d; &#x1f6a9;&#x1f6a9;&#x1f6a9;微信小程序专栏&#xff1a;微信小程序 &…

聚量推客升级啦,加入了外卖cps、话费充值等

“聚量推客”升级啦&#xff0c;加入了生活cps模块&#xff0c;包含美团外卖cps、滴滴打车出行cps、电影票推广、话费充值等cps推广场景&#xff0c;聚量推客不止是app地推拉新和网推拉新平台&#xff0c;更是一个 综合性推广平台&#xff0c;未来会接入越来越多的推广场景&…

OpenCV官方教程中文版 —— Hough 直线变换

OpenCV官方教程中文版 —— Hough 直线变换 前言一、原理二、OpenCV 中的霍夫变换三、Probabilistic Hough Transform 前言 目标 • 理解霍夫变换的概念 • 学习如何在一张图片中检测直线 • 学习函数&#xff1a;cv2.HoughLines()&#xff0c;cv2.HoughLinesP() 一、原理…

基础课13——数据异常处理

数据异常是指数据不符合预期或不符合常识的情况。数据异常可能会导致数据分析结果不准确&#xff0c;甚至是错误&#xff0c;因此在进行数据分析之前需要对数据进行清洗和验证。 常见的数据异常包括缺失值、重复值、异常值等。 缺失值是指数据中存在未知值或未定义的值&#…

Winform 多语言化快速解析替换工具-1分钟一个界面

随着业务的扩展&#xff0c;有的软件有多语言化的需求。那么如果软件已经很多写死的文字内容如何快速进行语言化替换呢&#xff0c;一个一个去改工作量太大。 于是开发了个小工具用来替换现有内容并生成语音包&#xff0c;原理就是采用正则表达式进行匹配控件关键字以及中文进…

使用MLC-LLM将RWKV 3B模型跑在Android手机上

0x0. 前言 这篇文章主要是填一下 MLC-LLM 部署RWKV World系列模型实战&#xff08;3B模型Mac M2解码可达26tokens/s&#xff09; 这里留下来的坑&#xff0c;这篇文章里面介绍了如何使用 MLC-LLM 在A100/Mac M2上部署 RWKV 模型。但是探索在Android端部署一个RWKV对话模型的ap…

宇信科技:强势行业加速融入AIGC,同时做深做细

【科技明说 &#xff5c; 重磅专题】 大家可能没有想到&#xff0c;一向对外低调行事的宇信科技&#xff0c;在AIGC方面2023年就已经训练出了适配金融场景的垂直模型&#xff0c;并应用到了各产品线上&#xff0c;同时结合通用大模型预研了宇信金融系统编程大模型。宇信金融系…

IOC课程整理-15 Spring 类型转换

1. Spring 类型转换的实现 2. 使用场景 3. 基于 JavaBeans 接口的类型转换 4. Spring 內建 PropertyEditor 扩展 5. 自定义 PropertyEditor 扩展 6. Spring PropertyEditor 的设计缺陷 7. Spring 3 通用类型转换接口 8. Spring 內建类型转换器 9. Converter 接口的局限性 10. G…

Azure - 机器学习:使用 Apache Spark 进行交互式数据整理

目录 本文内容先决条件使用 Apache Spark 进行交互式数据整理Azure 机器学习笔记本中的无服务器 Spark 计算从 Azure Data Lake Storage (ADLS) Gen 2 导入和整理数据从 Azure Blob 存储导入和处理数据从 Azure 机器学习数据存储导入和整理数据 关注TechLead&#xff0c;分享AI…