Introduction

前回の記事で、boostを使った簡単なクロスプラットフォームアプリを作りました。
で、それを会社でテンプレートにして手を加え、Windowsで動かしたらまったく動きませんでした。
というかビルドが通らない。

理由はlibが見つからないこと。

前回のサンプルは、libを使わず、ヘッダーだけで動作したプログラムだった模様。
なので、ちょっと修正します。
ソースは下記になります。

Explanation

まずは、CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
cmake_minimum_required(VERSION 3.9.0)
set(PROJ_NAME Test)

project(${PROJ_NAME} VERSION 1.0.0)

# Select the release build type by default
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()

# target source and header files
FILE(GLOB_RECURSE HEADERS ${PROJECT_SOURCE_DIR}/*.h)
FILE(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/*.cpp)

include_directories(${BOOST_ROOT})

#add_executable(${PROJ_NAME} ${HEADERS} ${SOURCES})
add_executable(${PROJ_NAME} main.cpp)

if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(STATIC_LIBRARIES
${BOOST_LIBRARYDIR}/libboost_system-vc140-mt-1_65_1.lib
${BOOST_LIBRARYDIR}/libboost_filesystem-vc140-mt-1_65_1.lib
)
target_link_libraries(${PROJ_NAME} ${STATIC_LIBRARIES})
else()
set(STATIC_LIBRARIES
${BOOST_LIBRARYDIR}/libboost_system.a
${BOOST_LIBRARYDIR}/libboost_filesystem.a
)
target_link_libraries(${PROJ_NAME} ${STATIC_LIBRARIES})
endif()

set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MDd" "/MD" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

今回の肝は、target_link_librariesの行。
コンパイラがVisual Studioなのかそうでないのかで、リンクするライブラリを変えています。

次に、main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

int main(int argc, char* argv[])
{
const fs::path path(argv[1]);

boost::system::error_code error;
const bool result = fs::exists(path, error);
if (!result || error) {
printf("%s does not exist!!\n", argv[1]);
}
else {
printf("%s exists!!\n", argv[1]);
}
}

引数で渡されたファイルが存在するかどうかを表示するだけです。

Build&Run

ビルドします。
CMakeLists.txtmain.cpが同じ階層にあるものとし、カレントディレクトリがCMakeLists.txtと同じだとします。
また、CMakeのパスは通っているものとします。

Windows

1
2
3
4
5
6
7
8
9
$ mkdir build
$ cd build
$ cmake -G "Visual Studio 14 2015 Win64" -DBOOST_ROOT=D:\boost\1.65.1 -DBOOST_LIBRARYDIR=D:\boost\1.65.1\build\MSVC14.0\x64\lib ..
$ cmake --build . --config Release
$ cd Release
$ Test.exe c:\Windows\System32\zipfldr.dll
c:\Windows\System32\zipfldr.dll exists!!
$ Test.exe c:\Windows\System32\zipfldr.dll2
c:\Windows\System32\zipfldr.dll2 does not exist!!

Linux

1
2
3
4
5
6
7
8
$ mkdir build
$ cd build
$ cmake -DBOOST_ROOT=/usr/include -DBOOST_LIBRARYDIR=/usr/lib64 ..
$ cmake --build . --config Release
$ ./Test /usr/local/bin/CMake2/main.cpp
/usr/local/bin/CMake2/main.cpp exists!!
$ ./Test /usr/local/bin/CMake2/main.cpp2
/usr/local/bin/CMake2/main.cpp2 does not exist!!

Conclusion

今度はきちんと静的リンクできています。

Source Code

https://github.com/takuya-takeuchi/Demo/tree/master/CMake/02_CMake2