kuikuitage

  博客园  ::  :: 新随笔  :: 联系 ::  :: 管理

hello.cpp

#include <iostream>
#include "hello.h"

#ifdef USE_ADD
#include "libtest.h"
#endif

#if defined(HAVE_LOG) && defined(HAVE_EXP)
#include <cmath>
#endif

int main(int argc, char** argv)
{
#ifdef USE_ADD
  std::cout << add(1, 2) << std::endl;
#endif

#if defined(HAVE_LOG) && defined(HAVE_EXP)
  int x = 100;
  double result = exp(log(x) * 0.5);
  std::cout << "Computing sqrt of " << x << " to be " << result
            << " using log and exp" << std::endl;
#endif
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

#直接使用project定义target或者指定下版本,再通过config_file设定版本宏配置自动写入指定头文件
#project(helloworld)
project(helloworld VERSION 1.0)

#option放在configure_file前面否则默认值不生效
option(USE_ADD "Use ADD provided math implementation" ON)

add_executable(helloworld hello.cpp)

#放在配置文件前
include(CheckSymbolExists)
#检查头文件math.h是否具有称为log的符号(可以是函数,常量或任何其他符号)。
#如果存在则在下面的hello.h输出 #define HAVE_LOG否则输出注释 /* #undef HAVE_TEST */
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
check_symbol_exists(test "math.h" HAVE_TEST)
if(NOT (HAVE_LOG AND HAVE_EXP))
  unset(HAVE_LOG CACHE)
  unset(HAVE_EXP CACHE)
  set(CMAKE_REQUIRED_LIBRARIES "m")
  check_symbol_exists(log "math.h" HAVE_LOG)
  check_symbol_exists(exp "math.h" HAVE_EXP)
  if(HAVE_LOG AND HAVE_EXP)
    #用到了target需要放到project()后面
    target_link_libraries(helloworld PRIVATE m)
  endif()
endif()

#cmake执行时将hello.h.in中定义的@${target}_VERSION_MAJOR@和@${target}_VERSION_MINOR@替换为VERSION的1和0
#并重新重定向到${PROJECT_BINARY_DIR}下的新文件hello.h
configure_file(hello.h.in hello.h)

#指定CXX的版本
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

#可选宏需要通过配置文件hello.h.in导入
#配置文件额外添加 #cmakedefine USE_ADD 从CMake导入到hello.h,在工程中可以使用
if(USE_ADD)
    add_subdirectory(add)
    list(APPEND EXTRA_LIBS add)
    list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/add")
endif()



#放在add_executable后面,否则找不到target
#${PROJECT_BINARY_DIR}为CMake的环境变量
target_include_directories(helloworld PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           ${EXTRA_INCLUDES}
                           )

#其他的链接库选项
#target_compile_definitions()
#target_compile_options()
#target_include_directories()
#target_link_libraries()
target_link_libraries(helloworld PUBLIC ${EXTRA_LIBS})

#安装二进制执行文件,默认安装到系统目录/usr/local,
#可以通过命令行指定 cmake --install . --prefix "../"
#或者 cmake -DCMAKE_INSTALL_PREFIX=../ .. 之后在make && make install
install(TARGETS helloworld DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/hello.h"
    DESTINATION include
    )

hello.h.in

#define HELLO_VERSION_MAJOR @helloworld_VERSION_MAJOR@
#define HELLO_VERSION_MINOR @helloworld_VERSION_MINOR@

#cmakedefine USE_ADD

lib\libtest.h

int add(int a, int b);

lib\libtest.cpp

#include "libtest.h"
int add(int a, int b)
{
	return a+b;
}

lib\CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(helloworld VERSION 1.0)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_library(add libtest.cpp)


#这里因为当前库不依赖头文件,可以去掉下面几行
#target_include_directories(add PUBLIC
#                           "."
#                           )


#安装二进制库
install(TARGETS add DESTINATION lib)
install(FILES libtest.h DESTINATION include)

include\hello.h

#define HELLO_VERSION_MAJOR 1
#define HELLO_VERSION_MINOR 0

#define USE_ADD

或者参考如下:

include(CheckFunctionExists)

if(NOT POW_FUNCTION_EXISTS AND NOT NEED_LINKING_AGAINST_LIBM)
  CHECK_FUNCTION_EXISTS(pow POW_FUNCTION_EXISTS)
  if(NOT POW_FUNCTION_EXISTS)
      unset(POW_FUNCTION_EXISTS CACHE)
      list(APPEND CMAKE_REQUIRED_LIBRARIES m)
      CHECK_FUNCTION_EXISTS(pow POW_FUNCTION_EXISTS)
      if(POW_FUNCTION_EXISTS)
          set(NEED_LINKING_AGAINST_LIBM True CACHE BOOL "" FORCE)
      else()
          message(FATAL_ERROR "Failed making the pow() function available")
      endif()
  endif()
endif()

if (NEED_LINKING_AGAINST_LIBM)
     target_link_libraries(your_target_here m)
endif()
posted on 2021-02-08 01:04  kuikuitage  阅读(77)  评论(0编辑  收藏  举报