完整代码
先给出完整CMakeLists.txt文件,复制到IDE里面,方便对应行号。
注释部分其实和没备注的语法之类的都是一样的,对照例子看就明白了。
(下面代码先不用看,直接跳下一节)
cmake_minimum_required(VERSION 3.0)
project(sylar)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/yaml-cpp)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/jsoncpp-1.8.4)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/sqlite-3.28.0)
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/tinyxml2-7.0.1)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include (cmake/utils.cmake)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")
set(CMAKE_C_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")
include_directories(.)
include_directories(/apps/sylar/include)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/yaml-cpp/include)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/jsoncpp-1.8.4/include)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/sqlite-3.28.0)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdpart/tinyxml2-7.0.1)
link_directories(/apps/sylar/lib)
link_directories(/apps/sylar/lib64)
option(BUILD_TEST "ON for complile test" OFF)
find_package(Boost REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
find_package(MySQL REQUIRED)
if(MYSQL_FOUND)
include_directories(${MYSQL_INCLUDE_DIR})
endif()
find_package(Protobuf)
if(Protobuf_FOUND)
include_directories(${Protobuf_INCLUDE_DIRS})
endif()
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
find_package(ZLIB REQUIRED)
if(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR})
endif()
set(LIB_SRC
sylar/address.cc
sylar/bytearray.cc
sylar/config.cc
sylar/db/fox_thread.cc
sylar/db/mysql.cc
sylar/db/redis.cc
sylar/db/sqlite3.cc
sylar/ds/bitmap.cc
sylar/ds/roaring_bitmap.cc
sylar/ds/roaring.c
sylar/ds/util.cc
sylar/email/email.cc
sylar/email/smtp.cc
sylar/env.cc
sylar/daemon.cc
sylar/fd_manager.cc
sylar/fiber.cc
sylar/http/http.cc
sylar/http/http_connection.cc
sylar/http/http_parser.cc
sylar/http/http_session.cc
sylar/http/http_server.cc
sylar/http/servlet.cc
sylar/http/servlets/config_servlet.cc
sylar/http/servlets/status_servlet.cc
sylar/http/session_data.cc
sylar/http/ws_connection.cc
sylar/http/ws_session.cc
sylar/http/ws_server.cc
sylar/http/ws_servlet.cc
sylar/hook.cc
sylar/iomanager.cc
sylar/library.cc
sylar/log.cc
sylar/module.cc
sylar/mutex.cc
sylar/ns/name_server_module.cc
sylar/ns/ns_client.cc
sylar/ns/ns_protocol.cc
sylar/protocol.cc
sylar/rock/rock_protocol.cc
sylar/rock/rock_server.cc
sylar/rock/rock_stream.cc
sylar/scheduler.cc
sylar/socket.cc
sylar/stream.cc
sylar/streams/async_socket_stream.cc
sylar/streams/socket_stream.cc
sylar/streams/load_balance.cc
sylar/streams/service_discovery.cc
sylar/streams/zlib_stream.cc
sylar/tcp_server.cc
sylar/timer.cc
sylar/thread.cc
sylar/util.cc
sylar/util/crypto_util.cc
sylar/util/json_util.cc
sylar/util/hash_util.cc
sylar/worker.cc
sylar/application.cc
sylar/zk_client.cc
)
ragelmaker(sylar/http/http11_parser.rl LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sylar/http)
ragelmaker(sylar/http/httpclient_parser.rl LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sylar/http)
ragelmaker(sylar/uri.rl LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sylar)
protobufmaker(sylar/ns/ns_protobuf.proto LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR})
#PROTOBUF_GENERATE_CPP(PB_SRCS PB_HDRS sylar/ns/ns_protobuf.proto)
#message("****${PB_SRCS}***${PB_HDRS}****")
#list(APPEND LIB_SRC ${PB_SRCS})
#
#message(STATUS ${LIB_SRC})
add_library(sylar SHARED ${LIB_SRC})
force_redefine_file_macro_for_sources(sylar)
#add_library(sylar_static STATIC ${LIB_SRC})
#SET_TARGET_PROPERTIES (sylar_static PROPERTIES OUTPUT_NAME "sylar")
#find_library(YAMLCPP yaml-cpp)
find_library(PTHREAD pthread)
#set(LIBS ${LIBS} sylar)
#set(LIBS ${LIBS} dl)
#set(LIBS ${LIBS} ${YAMLCPP})
#set(LIBS ${LIBS} ${PTHREAD})
set(LIBS
sylar
dl
pthread
yaml-cpp
jsoncpp
${ZLIB_LIBRARIES}
${OPENSSL_LIBRARIES}
${PROTOBUF_LIBRARIES}
event
hiredis_vip
mysqlclient_r
zookeeper_mt
sqlite3
tinyxml2
jemalloc
)
sylar_add_executable(test_util "tests/test_util.cc" sylar "${LIBS}")
sylar_add_executable(test_hashmultimap "tests/test_hashmultimap.cc" sylar "${LIBS}")
sylar_add_executable(test_hashmap "tests/test_hashmap.cc" sylar "${LIBS}")
sylar_add_executable(test_dict "tests/test_dict.cc" sylar "${LIBS}")
sylar_add_executable(test_array "tests/test_array.cc" sylar "${LIBS}")
if(BUILD_TEST)
sylar_add_executable(test1 "tests/test.cc" sylar "${LIBS}")
sylar_add_executable(test_config "tests/test_config.cc" sylar "${LIBS}")
sylar_add_executable(test_thread "tests/test_thread.cc" sylar "${LIBS}")
sylar_add_executable(test_fiber "tests/test_fiber.cc" sylar "${LIBS}")
sylar_add_executable(test_scheduler "tests/test_scheduler.cc" sylar "${LIBS}")
sylar_add_executable(test_iomanager "tests/test_iomanager.cc" sylar "${LIBS}")
sylar_add_executable(test_hook "tests/test_hook.cc" sylar "${LIBS}")
sylar_add_executable(test_address "tests/test_address.cc" sylar "${LIBS}")
sylar_add_executable(test_socket "tests/test_socket.cc" sylar "${LIBS}")
sylar_add_executable(test_bytearray "tests/test_bytearray.cc" sylar "${LIBS}")
sylar_add_executable(test_http "tests/test_http.cc" sylar "${LIBS}")
sylar_add_executable(test_http_parser "tests/test_http_parser.cc" sylar "${LIBS}")
sylar_add_executable(test_tcp_server "tests/test_tcp_server.cc" sylar "${LIBS}")
sylar_add_executable(echo_server "examples/echo_server.cc" sylar "${LIBS}")
sylar_add_executable(test_http_server "tests/test_http_server.cc" sylar "${LIBS}")
sylar_add_executable(test_uri "tests/test_uri.cc" sylar "${LIBS}")
sylar_add_executable(my_http_server "samples/my_http_server.cc" sylar "${LIBS}")
sylar_add_executable(echo_server_udp "examples/echo_server_udp.cc" sylar "${LIBS}")
sylar_add_executable(echo_udp_client "examples/echo_udp_client.cc" sylar "${LIBS}")
sylar_add_executable(test_daemon "tests/test_daemon.cc" sylar "${LIBS}")
sylar_add_executable(test_env "tests/test_env.cc" sylar "${LIBS}")
sylar_add_executable(test_ws_server "tests/test_ws_server.cc" sylar "${LIBS}")
sylar_add_executable(test_ws_client "tests/test_ws_client.cc" sylar "${LIBS}")
sylar_add_executable(test_application "tests/test_application.cc" sylar "${LIBS}")
sylar_add_executable(test_http_connection "tests/test_http_connection.cc" sylar "${LIBS}")
sylar_add_executable(test_lru "tests/test_lru.cc" sylar "${LIBS}")
sylar_add_executable(test_timed_cache "tests/test_timed_cache.cc" sylar "${LIBS}")
sylar_add_executable(test_timed_lru_cache "tests/test_timed_lru_cache.cc" sylar "${LIBS}")
sylar_add_executable(test_zlib_stream "tests/test_zlib_stream.cc" sylar "${LIBS}")
endif()
sylar_add_executable(test_crypto "tests/test_crypto.cc" sylar "${LIBS}")
sylar_add_executable(test_sqlite3 "tests/test_sqlite3.cc" sylar "${LIBS}")
sylar_add_executable(test_rock "tests/test_rock.cc" sylar "${LIBS}")
sylar_add_executable(test_email "tests/test_email.cc" sylar "${LIBS}")
sylar_add_executable(test_mysql "tests/test_mysql.cc" sylar "${LIBS}")
sylar_add_executable(test_nameserver "tests/test_nameserver.cc" sylar "${LIBS}")
sylar_add_executable(test_bitmap "tests/test_bitmap.cc" sylar "${LIBS}")
sylar_add_executable(test_zkclient "tests/test_zookeeper.cc" sylar "${LIBS}")
sylar_add_executable(test_service_discovery "tests/test_service_discovery.cc" sylar "${LIBS}")
set(ORM_SRCS
sylar/orm/table.cc
sylar/orm/column.cc
sylar/orm/index.cc
sylar/orm/orm.cc
sylar/orm/util.cc
)
sylar_add_executable(orm "${ORM_SRCS}" sylar "${LIBS}")
add_library(test_module SHARED tests/test_module.cc)
sylar_add_executable(bin_sylar "sylar/main.cc" sylar "${LIBS}")
set_target_properties(bin_sylar PROPERTIES OUTPUT_NAME "sylar")
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/orm_out)
#set(OLIBS ${LIBS} orm_data)
#sylar_add_executable(test_orm "tests/test_orm.cc" orm_data "${OLIBS}")
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
初始设置 1-2句
# 设置CMake的最低版本要求为3.0
cmake_minimum_required(VERSION 3.0)
# 设置项目名称为sylar
project(sylar)
宏的解释说明
PROJECT_SOURCE_DIR
和
CMAKE_CURRENT_SOURCE_DIR
区别与联系
9-14句
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include (cmake/utils.cmake)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")
set(CMAKE_C_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")
第9句:用于设置 CMake 模块路径,告诉 CMake 在哪里查找自定义的 CMake 配置文件(即 .cmake 文件)。
目前没啥用
第10句:include() 是 CMake 的一个命令,用于加载并执行指定路径的 CMake 脚本文件(通常是 .cmake 文件)。如果该文件中有任何 CMake 命令,它们会被执行
总结:set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}${CMAKE_CURRENT_SOURCE_DIR}/cmake)
这行将项目的 cmake 目录添加到 CMake 的模块搜索路径中,允许 CMake 查找并使用该目录下的自定义 CMake 脚本。
include(cmake/utils.cmake) 这行通过 include 指令执行 cmake/utils.cmake 文件中的内容,通常用于引入一些自定义的函数、宏或者工具。
可以看到我们的确在CMAKE目录下有一些cmake文件
第12句:set(CMAKE_VERBOSE_MAKEFILE ON)
:启用详细的编译输出,这有助于调试构建过程,看到每个编译步骤的具体命令。
第13句:设置了 C++ 编译器的标志,这些标志会影响 C++ 源代码的编译过程。
-rdynamic:使得动态链接器可以访问程序的符号,通常用于调试时。
-O3:启用优化级别 3,表示最大程度的优化。
-fPIC:生成位置无关代码(Position Independent Code),通常用于生成共享库。
-ggdb:生成调试信息,并特别适用于 GDB 调试器。
-std=c++11:使用 C++11 标准进行编译。
-Wall:启用所有的警告。
-Wno-deprecated:禁用关于废弃函数的警告。
-Werror:将所有警告视为错误,编译时如果出现警告会导致编译失败。
-Wno-unused-function:禁用未使用函数的警告。
-Wno-builtin-macro-redefined:禁用宏重新定义警告。
-Wno-deprecated-declarations:禁用废弃声明的警告。
第14句:这行代码设置了 C 编译器的标志,与第13行代码类似,只是针对 C 语言的编译。
16-17句
include_directories 语句的作用是告诉 CMake 在编译时,如何查找头文件。这是用来配置 编译器 在寻找头文件时,在哪些目录中查找的指令
第17句是:include_directories(/apps/sylar/include)
,但是其实我们的文件结构不是这样的,所以这一句可以注释掉。
23-24句和225句
link_directories(/apps/sylar/lib)
link_directories(/apps/sylar/lib64)
link_directories() 指定了编译时链接器查找库文件的目录。它告诉 CMake 在链接时在哪里寻找需要链接的库文件。对于 link_directories(/apps/sylar/lib) 和 link_directories(/apps/sylar/lib64) 这两句,它们的作用是让编译器在 /apps/sylar/lib 和 /apps/sylar/lib64 目录下寻找链接库(.so、.a、.dylib 等)
目前没用
注意和225句SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
进行区分
- link_directories() 只是用来告诉编译器在哪里查找依赖库文件,不涉及到你自己生成的库文件。
- LIBRARY_OUTPUT_PATH 只是用来指定你自己生成的库文件存放位置,并不影响链接过程。
26句
option(BUILD_TEST "ON for compile test" OFF)
这一句的意思是定义了一个名为 BUILD_TEST 的选项,它是一个布尔值(ON 或 OFF),用来控制是否构建测试代码,默认为OFF。
28-50句
find_package(Boost REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
find_package 是 CMake 提供的一个命令,用来查找并加载指定的外部库或者模块。
Boost 是你要查找的库。CMake 会尝试在系统中查找 Boost 库。
REQUIRED 表示如果 CMake 没有找到 Boost 库,则会终止配置过程,并报错,它确保了 Boost 库是必需的。
同理接下来几个库也是一样的。
52-114句
这几行代码是 CMake 配置文件中的一个变量赋值语句,它定义了一个名为 LIB_SRC
的变量,并将其赋值为一系列的源代码文件路径。这些文件都属于 sylar 目录下的 C++ 源文件和一些模块实现文件。
可以看到,确实如此。
116-118句
ragelmaker(sylar/http/http11_parser.rl LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/sylar/http)
ragelmaker
:这个是 CMake 脚本中的一个自定义命令或宏。它的作用是用来处理 Ragel .rl 文件
sylar/http/http11_parser.rl
:这是 Ragel 文件的路径
LIB_SRC
:是之前定义的 CMake 变量,代表最终需要编译成库的源文件列表。通过调用 ragelmaker,会将 .rl 文件生成的 C++ 源文件添加到 LIB_SRC
中,这些源文件会成为库的一部分。
${CMAKE_CURRENT_SOURCE_DIR}/sylar/http
:这是 .rl 文件所在的目录
120句
这行代码是用来生成 Protocol Buffers(简称 Protobuf)相关代码的。
和上面的意思差不多
127-128句
add_library(sylar SHARED ${LIB_SRC})
force_redefine_file_macro_for_sources(sylar)
是 CMake 中用来创建一个共享库(Shared Library)的命令,具体来说,它创建了一个名为 sylar 的共享库,并将源文件列表 LIB_SRC 中列出的文件编译成这个库。
而force_redefine_file_macro_for_sources(sylar)
是自定义的一个函数
在我们之前提到的cmake/utils.cmake中有
function(force_redefine_file_macro_for_sources targetname)
# 获取指定目标 (targetname) 的源文件列表
get_target_property(source_files "${targetname}" SOURCES)
# 遍历所有源文件
foreach(sourcefile ${source_files})
# 获取当前源文件的编译时定义的宏 (compile definitions)
get_property(defs SOURCE "${sourcefile}" PROPERTY COMPILE_DEFINITIONS)
# 获取源文件的绝对路径
get_filename_component(filepath "${sourcefile}" ABSOLUTE)
# 将绝对路径转换为相对路径,去掉项目根目录部分
string(REPLACE ${PROJECT_SOURCE_DIR}/ "" relpath ${filepath})
# 在当前的编译宏中追加 `__FILE__` 的新定义,指向相对路径
list(APPEND defs "__FILE__=\"${relpath}\"")
# 将修改后的编译宏重新设置回源文件
set_property(
SOURCE "${sourcefile}"
PROPERTY COMPILE_DEFINITIONS ${defs}
)
endforeach()
endfunction()
force_redefine_file_macro_for_sources(targetname) 这个 CMake 函数的主要目的是 重定义源文件中的 _ _ FILE _ _ 宏,使其包含相对于项目根目录的文件路径,而不是默认的绝对路径。通过这种方式,可以使 _ _ FILE _ _ 输出更具可读性或者更符合项目的结构需求。
第133句
find_library(PTHREAD pthread)
在大多数 Linux 系统中,pthread 库用于支持多线程编程。调用 find_library(PTHREAD pthread)
目的是检查系统是否有 pthread 库,并获取它的路径。
139-155句
将这些库通过 set(LIBS ...)
定义到 LIBS
变量中
其中:
-
sylar: 自己的项目库
-
dl: 这个是动态链接库 (libdl) 的标志
-
pthread: 这是 POSIX 线程库(libpthread)。
-
yaml-cpp: 这是一个用于解析和生成 YAML 文件的 C++ 库。它可以让你在 C++ 程序中处理 YAML 格式的数据。这个库可能通过 find_package(yaml-cpp) 或 add_subdirectory 引入。
-
jsoncpp: 这是一个用于处理 JSON 格式数据的 C++ 库。它可以用来解析 JSON 数据或将 C++ 对象序列化为 JSON 格式。
-
${ZLIB_LIBRARIES}: 这个变量存储了与 Zlib 相关的库文件,通常用于处理压缩和解压缩操作。
-
${OPENSSL_LIBRARIES}: 这个变量包含 OpenSSL 库的路径,通常用于加密、SSL/TLS 通信等操作。
-
${PROTOBUF_LIBRARIES}: 这个变量包含了 Protocol Buffers 库的路径,通常用于处理序列化协议。
-
event: 这是 libevent 库,提供异步事件通知机制。它通常用于处理事件驱动的编程,支持多种 I/O 操作。
-
hiredis_vip: 这是 Redis 客户端库的一个变种,hiredis_vip 提供了与 Redis 服务器通信的 API。
-
mysqlclient_r: 这是 MySQL 客户端库的线程安全版本,通常用于与 MySQL 数据库通信。
-
zookeeper_mt: 这是 ZooKeeper 客户端库的线程安全版本。ZooKeeper 是一个分布式协调服务,常用于管理和同步分布式系统中的配置信息、命名和选举等。
-
sqlite3: 这是 SQLite 数据库库,SQLite 是一个轻量级的关系型数据库,通常用于嵌入式系统或轻量级应用中。
-
tinyxml2: 这是一个轻量级的 XML 解析库。它用于读取和写入 XML 数据,并提供了简洁的 API。
-
jemalloc: 这是一个高效的内存分配库,通常用于提高多线程程序的内存分配性能。它是替代标准
-
malloc 的一个选项,尤其在高并发环境下,jemalloc 可以提供更好的内存分配和回收性能。
不需要太看,到时候debug就可以了。
156-160句
sylar_add_executable(test_util "tests/test_util.cc" sylar "${LIBS}")
自定义的方法,同样在cmake/utils.cmake下
# 定义一个创建可执行文件并链接相关依赖库的函数
function(sylar_add_executable targetname srcs depends libs)
# 使用指定的源文件(srcs)创建一个可执行文件(targetname)
add_executable(${targetname} ${srcs})
# 添加构建依赖关系,确保在构建 targetname 之前,depends 中的目标已构建
# 比如,如果 depends 是 sylar,则 sylar 目标会在 test_util 构建之前构建
add_dependencies(${targetname} ${depends})
# 调用 force_redefine_file_macro_for_sources 函数修改源文件的 __FILE__ 宏
# 这个宏会被替换为源文件的相对路径,通常用于调试时跟踪源文件位置
force_redefine_file_macro_for_sources(${targetname})
# 将指定的库列表(libs)链接到目标可执行文件(targetname)
# 这些库会在可执行文件编译时被链接,以便在运行时找到所需的依赖
target_link_libraries(${targetname} ${libs})
endfunction()
封装了 add_executable 和一些额外的操作
结果是生成可执行文件
161-195句
只有在 BUILD_TEST
(12行)被设置为 ON 的时候,下面的测试可执行文件才会被编译。
内容同上
195-204句
同上
206-213句
set
定义了一个名为 ORM_SRCS
的变量,并将其值设置为一组源文件列表。
ORM_SRCS
被用在 sylar_add_executable
命令中来生成一个可执行文件
215句
同127句
创建一个共享库 test_module,它的源代码是 tests/test_module.cc。
这个库会被编译成动态链接库(在 Linux 上是 .so,在 Windows 上是 .dll)。
创建的库可以在其他目标中进行链接和使用。
217-218句
sylar_add_executable(bin_sylar
"sylar/main.cc" sylar "${LIBS}")
创建可执行文件bin_sylar,将 sylar/main.cc 作为源文件编译
而
set_target_properties(bin_sylar
PROPERTIES OUTPUT_NAME "sylar")
这行 CMake 代码的作用是为已创建的目标 bin_sylar 设置输出名称,使得构建生成的可执行文件的名称为 sylar,而不是默认的 bin_sylar。
224句
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
这行代码设置了 所有可执行文件 的输出路径为项目的根目录下的 bin 文件夹下。
完结!!!
标签:CMakeLists,cc,executable,test,add,sylar,txt,LIBS From: https://blog.csdn.net/fcopy/article/details/144215117