cmake could not find openssl_使用CMake构建C++项目
背景
現代CMake如今開始轉向使用targets和properties,比如下面文章介紹的這樣:
https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/?pabloariasal.github.io然而仍然有很多C++項目基于傳統CMake構建,閱讀本文有助于理解傳統CMake的使用。文中引用了libdeepvac項目的CMakeLists.txt來作為參考:
https://github.com/DeepVAC/libdeepvac?github.com有現代CMake實踐經驗的同學也可以參與該項目,將上述CMakeLists.txt重構為基于targets和properties。
CMake語句
set
設置變量。你甚至可以直接把多個值直接set給一個變量:
set(SYSZUX_HEADERSinclude/detail/class.hinclude/detail/common.hinclude/detail/descr.hinclude/detail/init.hinclude/internals.hincludedetail/typeid.h)file
使用正則匹配文件,并將文件路徑賦值給第一個參數(為變量),通常和GLOB搭配:
file(GLOB gemfield_src_list ${Root}/*/*.cpp ${Root}/*/*.h ${Root}/*/*.c)list
針對list進行各種操作,如增刪改查,比如:
list(REMOVE_ITEM ......) list(APPEND ......)project
設置項目的名字。
project(SYSZUXrtp)#還可以設置更多的參數 project(libdeepvacLANGUAGES CXXVERSION "1.0.0")add_library
#語法 add_library(<name> [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL]source1 [source2 ...])#舉例 add_library(gemfield_static STATIC ${gemfield_src_list})Adds a library target called<name>to be built from the source files listed in the command invocation. The<name>corresponds to the logical target name and must be globally unique within a project.
aux_source_directory
#語法 aux_source_directory(<dir> <variable>)Collects the names of all the source files in the specified directory and stores the list in the <variable> provided.
aux_source_directory(${gemfield_root}/include gemfield_src)比如上面的例子就是,將${gemfield_root}/include目錄下的所有源文件找到并且賦值給gemfield_src變量。
add_definitions
Adds -D define flags to the compilation of source files.比如:
add_definitions(-DENABLE_GEMFIELD)add_executable
Add an executable to the project using the specified source files.
#語法: add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL]source1 [source2 ...])Adds an executable target called<name>to be built from the source files listed in the command invocation. The<name>corresponds to the logical target name and must be globally unique within a project. The actual file name of the executable built is constructed based on conventions of the native platform (such as<name>.exeor just<name>.舉例:
add_executable(gemfield_proxy ${gemfield_src_list})target_link_libraries
Link a target to given libraries.
#語法 target_link_libraries(<target> [item1 [item2 [...]]][[debug|optimized|general] <item>] ...)Specify libraries or flags to use when linking a given target. The named <target> must have been created in the current directory by a command such as add_executable() or add_library(). The remaining arguments specify library names or flags. Repeated calls for the same <target> append items in the order called.
If a library name matches that of another target in the project a dependency will automatically be added in the build system to make sure the library being linked is up-to-date before the target links. Item names starting with -, but not -l or -framework, are treated as linker flags.
比如:
target_link_libraries(gemfield_proxyshared_staticjson_staticmpeg_static${LINK_LIB_LIST})意思是說,要鏈接出目標gemfield_proxy的時候,需要有后面的庫(shared_static、json_static...)或者flag。
link_directories
指定要搜尋的庫所在的目錄,相當于link工具的 -L參數。
#語法 link_directories(directory1 directory2 ...)注意,這個變量很少必須使用,最好用find_library()來替代。
find_library
尋找一個庫,將找到的庫的絕對路徑賦值給變量。
#簡單語法 find_library(<VAR> lib_name1 [path1 path2 ...]) #相當于 find_library(<VAR> lib_name1 [PATHS path1 path2 ...])#復雜語法 find_library(<VAR>name | NAMES name1 [name2 ...][HINTS path1 [path2 ... ENV var]][PATHS path1 [path2 ... ENV var]][PATH_SUFFIXES suffix1 [suffix2 ...]][DOC "cache documentation string"][NO_DEFAULT_PATH][NO_CMAKE_ENVIRONMENT_PATH][NO_CMAKE_PATH][NO_SYSTEM_ENVIRONMENT_PATH][NO_CMAKE_SYSTEM_PATH][CMAKE_FIND_ROOT_PATH_BOTH |ONLY_CMAKE_FIND_ROOT_PATH |NO_CMAKE_FIND_ROOT_PATH])舉例:
find_library(LIBGEMFIELD_PATH libgemfield.so PATHS ${CUDA_TOOLKIT_ROOT_DIR}/lib64/)include_directories
將目錄中加入搜索頭文件時的路徑,不支持通配符:
include_directories(${CMAKE_SOURCE_DIR}/gemfield/include)include
CMake中的流程控制
if else
if else等條件控制,使用如下的語句:
#if if(邏輯表達式) ... endif()#if else if(邏輯表達式) ... else() ... endif()#if elseif if(邏輯表達式) ... elseif(邏輯表達式) ... endif()if中的邏輯與為AND關鍵字,非為NOT關鍵字。
for循環
for循環使用如下語句:
foreach(變量 變量的列表) ... endforeach()CMake中的系統變量
CMake中編譯相關的變量
- CMAKE_CXX_STANDARD:設置C++標準;
- CMAKE_CXX_FLAGS:設置C++編譯參數;
- CMAKE_C_FLAGS:設置C編譯參數;
- BUILD_SHARED_LIBS : if this is set to ON, then all libraries are built as shared libraries by default. SET(BUILD_SHARED_LIBS ON) ;
- CMAKE_BUILD_TYPE : A variable which controls the type of build when using a single-configuration generator like the Makefile generator. It is case-insensitive;If you are using the Makefile generator, you can create your own build type like this:
Note that CMAKE_BUILD_TYPE is not initialized with a readable value at configuration time. This is because the user is free to select a build type at build time. Use CMAKE_CFG_INTDIR if you need a variable that evaluates to the correct build time directory;
- CMAKE_CONFIGURATION_TYPES : When using a multi-configuration generator, such as the one for Visual Studio, this variable contains a list of the available configurations.
- CMAKE_C_COMPILER : the compiler used for C files. Normally it is detected and set during the CMake run, but you can override it at configuration time. Note! It can not be changed after the first cmake or ccmake run. Although the gui allows to enter an alternative, it will be ignored in the next 'configure' run. Use for example: CC=gcc-3.3 CXX=g++-3.3 cmake to set the compiler. (You can also set CMAKE_C_COMPILER_INIT, before any PROJECT() or ENABLE_LANGUAGE() command.) Any other way (like writing make CC=gcc-3.3 CXX=g++-3.3) will not work. When using distcc or similar tools, you need to write: CC="distcc gcc-3.3" CXX="distcc g++-3.3" cmake However, this will empty all your CMAKE_...FLAGS... above.
- CMAKE_C_FLAGS : the compiler flags for compiling C sources. Note you can also specify switches with ADD_COMPILE_OPTIONS().
- CMAKE_C_FLAGS_ : compiler flags for a specific build configuration. Replace "" in the name with a specific build configuration name.
- CMAKE_C_OUTPUT_EXTENSION : what C object files end in. Typically .o or .obj.
- CMAKE_CFG_INTDIR : meta-variable! Please note that this is an important variable, since on multi-configuration generators it will be generated into dynamically switched content based on the configuration that the user currently selected within the generated build environment. Indicates the name of the current configuration (~ directory) for the project. May be used for any purpose which needs per-configuration-dynamic switching of strings, not just OutputDir configuration. For multi-configuration generators (e.g. MSVC) the resulting strings are typically some of "Debug", "Release", "RelWithDebInfo", or "MinSizeRel". For other compiler generators (single-configuration ones) it is typically ".", as they don't use MSVC-style configuration directories.
- CMAKE_CXX_COMPILER : the compiler used for C++ files. Normally it is detected and set during the CMake run, but you can override it at configuration time. Note! It can not be changed after the first cmake or ccmake run. See CMAKE_C_COMPILER above.
- CMAKE_CXX_FLAGS : the compiler flags for compiling C++ sources. Note you can also specify switches with ADD_COMPILE_OPTIONS().
- CMAKE_CXX_FLAGS_ : compiler flags for a specific configuration for C++ sources. Replace "" in the name with a specific build configuration name.
- CMAKE_SHARED_LINKER_FLAGS : additional compiler flags for building shared libraries, e.g.:set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") On Unix systems, this will make linker report any unresolved symbols from object files (which is quite typical when you compile many targets in CMake projects, but do not bother with linking target dependencies in proper order). On mac, the flag is -Wl,-undefined-error;
- CMAKE_SKIP_RULE_DEPENDENCY : set this to true if you don't want to rebuild the object files if the rules have changed, but not the actual source files or headers (e.g. if you changed the some compiler switches)
- CMAKE_SKIP_INSTALL_ALL_DEPENDENCY : since CMake 2.1 the install rule depends on all, i.e. everything will be built before installing. If you don't like this, set this one to true.
- CMAKE_INCLUDE_CURRENT_DIR : automatically add CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to the include directories in every processed CMakeLists.txt. It behaves as if you had used INCLUDE_DIRECTORIES in every CMakeLists.txt file or your project. The added directory paths are relative to the being-processed CMakeLists.txt, which is different in each directory. (See this thread for more details).
- CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE : order the include directories so that directories which are in the source or build tree always come before directories outside the project.
- CMAKE_VERBOSE_MAKEFILE : set this to true if you are using makefiles and want to see the full compile and link commands instead of only the shortened ones
- CMAKE_SUPPRESS_REGENERATION : this will cause CMake to not put in the rules that re-run CMake. This might be useful if you want to use the generated build files on another machine.
- CMAKE_COLOR_MAKEFILE : create Makefiles with colored output (defaults to on)
- CMAKE_SKIP_PREPROCESSED_SOURCE_RULES : (since 2.4.4) if set to TRUE, the generated Makefiles will not contain rules for creating preprocessed files (foo.i)
- CMAKE_SKIP_ASSEMBLY_SOURCE_RULES : (since 2.4.4) if set to TRUE, the generated Makefiles will not contain rules for creating compiled, but not yet assembled files (foo.s);
- INCLUDE_DIRECTORIES:Add the given directories to those the compiler uses to search for include files. Relative paths are interpreted as relative to the current source directory;
CMake中路徑相關的變量
CMake有兩類變量,PROJECT_<var> 和 CMAKE_<var>,CMAKE_*系列變量指的是最頂層的CMakeLists.txt所在的目錄或者所描述的東西;而PROJECT_*系列變量指的是最近的含有project()命令的CMakeLists.txt所在的目錄或者所描述的東西。
CMake中的環境變量
有一些環境變量影響CMake的行為;另外,你也可以在CMake腳本中主動讀取環境變量的值。實際上,你可以在CMake命令執行后,在CMakeCache.txt中看到打印的各種CMake變量的值。
CMake中變量的打印
可以用MESSAGE語句打印CMake變量:
# if you are building in-source, this is the same as CMAKE_SOURCE_DIR, otherwise # this is the top level directory of your build tree MESSAGE( STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR} )# if you are building in-source, this is the same as CMAKE_CURRENT_SOURCE_DIR, otherwise this # is the directory where the compiled or generated files from the current CMakeLists.txt will go to MESSAGE( STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR} )# this is the directory, from which cmake was started, i.e. the top level source directory MESSAGE( STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR} )# this is the directory where the currently processed CMakeLists.txt is located in MESSAGE( STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR} )# contains the full path to the top level directory of your build tree MESSAGE( STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR} )# contains the full path to the root of your project source directory, # i.e. to the nearest directory where CMakeLists.txt contains the PROJECT() command MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} )......CMake的編譯過程中詳細log的查看
我們知道,對于GNU Make來說,要想看編譯的詳細日志(也就是具體的源文件路徑、編譯參數、輸入路徑等),可以使用make命令的VERBOSE參數:
make VERBOSE=1而因為CMake封裝了make,那么如何通過CMake達到同樣的效果呢?
選項1:自然而然的,還是上面的方法
cmake . make VERBOSE=1選項2:在cmake命令行上加參數-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON . make#如果想要減少一些信息量少的打印信息: cmake -DCMAKE_RULE_MESSAGES:BOOL=OFF -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON . make --no-print-directory選項3:修改CMakeLists.txt
在CMakeLists.txt中加上:
set(CMAKE_VERBOSE_MAKEFILE ON)缺點是要修改文件,還要修改每個CMakeLists.txt文件。
CMake使用subdirectory
參考下面項目的CMakeLists.txt,其重度使用了add_subdirectory:
https://github.com/DeepVAC/libdeepvac/blob/master/CMakeLists.txt?github.comCMake的Installation
使用install語句。一個生動的例子可以參考:
https://github.com/DeepVAC/libdeepvac/blob/master/CMakeLists.txt?github.com集成一個CMake項目到另外的CMake項目
為了讓別的C++項目在CMakeLists.txt中使用find_package來引用自己的C++項目,則需要在自己項目的CMakeLists.txt中使用EXPORT語法和install(EXPORT ...)語法。一個生動的例子可以參考:
https://github.com/DeepVAC/libdeepvac/blob/master/CMakeLists.txt?github.com和:
DeepVAC/libdeepvac?github.com總結
以上是生活随笔為你收集整理的cmake could not find openssl_使用CMake构建C++项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在html标签中写三元运算符,如何在剃须
- 下一篇: 数字电路设计200例_惊险!200米高空