当前位置 博文首页 > fareast_mzh的博客:CMake教程 Step 2: Adding a Library
Step 2: Adding a Library
?
?* ../Step2/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# set the project name and version
project(Tutorial VERSION 1.1)
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
# add the MathFunctions library
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
configure_file(TutorialConfig.h.in TutorialConfig.h)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# 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}"
${EXTRA_INCLUDES}
)
*?../Step2/TutorialConfig.h.in
#cmakedefine USE_MYMATH
* ../Step2/tutorial.cxx
#include <iostream>
#include <string>
#include <cstdlib>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
#ifndef INPUT_VALUE
#define INPUT_VALUE 3.0f
#endif
int main(int argc, char *argv[]) {
double inputValue = 0;
if (argc < 2) {
inputValue = INPUT_VALUE;
} else {
inputValue = atof(argv[1]);
}
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << outputValue << std::endl;
}
*?../Step2/MathFunctions/CMakeLists.txt
add_library(MathFunctions mysqrt.cxx)
*?../Step2/MathFunctions/MathFunctions.h
#ifndef MATH_FUNCTIONS
#define MATH_FUNCTIONS
#define NaN -2147483648.0
#define abs(v) ((v)>0?(v):(-v))
double mysqrt(double c);
#endif
*?../Step2/MathFunctions/mysqrt.cxx
#include "MathFunctions.h"
double mysqrt(double c) {
if (c < 0) {
return NaN;
}
double err = 1e-15;
double t = c;
while (abs(t - c/t) > err * t) {
t = (c/t + t) / 2.0;
}
return t;
}
?编译测试
cmake ../Step2
make
./Tutorial 6
关掉USE_MYMATH试试:
cmake ../Step2 -DUSE_MYMATH=OFF
make
需要引入math头文件
?
?../Step2/tutorial.cxx
#include <iostream>
#include <string>
#include <cstdlib>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
# include "MathFunctions.h"
#else
# include <cmath>
#endif
#ifndef INPUT_VALUE
#define INPUT_VALUE 3.0f
#endif
int main(int argc, char *argv[]) {
double inputValue = 0;
if (argc < 2) {
inputValue = INPUT_VALUE;
} else {
inputValue = atof(argv[1]);
}
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
std::cout << "System cmath\n";
const double outputValue = sqrt(inputValue);
#endif
std::cout << outputValue << std::endl;
}
abs用宏定义有bug, ./Tutorial 0.0001这个case跑不过。
================================================================
添加install, test命令
../Step2/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# set the project name and version
project(Tutorial VERSION 1.1)
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
# add the MathFunctions library
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
# list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
configure_file(TutorialConfig.h.in TutorialConfig.h)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# 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}"
)
install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include
)
enable_testing()
# 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_test)
# 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")
../Step2/tutorial.cxx
#include <iostream>
#include <string>
#include <cstdlib>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
# include "MathFunctions.h"
#else
# include <cmath>
#endif
int main(int argc, char *argv[]) {
double inputValue = 0;
if (argc < 2) {
std::cout << "Usage: "<< argv[0] << "number\n";
return 0;
}
inputValue = atof(argv[1]);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
std::cout << "System cmath\n";
const double outputValue = sqrt(inputValue);
#endif
std::cout << "sqrt " << inputValue << " is " << outputValue << "\n";
}
../Step2/MathFunctions/CMakeLists.txt
add_library(MathFunctions mysqrt.cxx)
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
../Step2/MathFunctions/MathFunctions.h
#ifndef MATH_FUNCTIONS
#define MATH_FUNCTIONS
#define NaN 0
double mysqrt(double c);
#endif
../Step2/MathFunctions/mysqrt.cxx
#include "MathFunctions.h"
double abs(double x) {
if (x >= 0) {
return x;
}
return 0-x;
}
double mysqrt(double c) {
if (c < 0) {
return NaN;
}
double err = 1e-15;
double t = c;
while (abs(t - c/t) > err * t) {
t = (c/t + t) / 2.0;
}
return t;
}
编译安装测试
mkdir Step2_build
cd Step2_build
cmake ../Step2
make install
make test
cs