libiconv-1.11.1-windows编译

        本文操作按照《c&c++开源库编译指南》中内容规范编写,编译环境配置、工具下载、目录规划,及更多其他开源库编译方法请参考该文章。

        c&c++开源库编译指南:https://blog.csdn.net/binary0006/article/details/144086155

        本文章中的源代码已提交到gitee仓库,地址:https://gitee.com/binary0010/depends/tree/master/c/libiconv-1.11.1

1.libiconv 概述

        libiconv 是一个广泛使用的字符编码转换库,由 GNU 项目开发并维护,旨在解决不同字符编码之间的转换问题,确保软件在多语言环境下能正确处理文本数据。

        从技术实现上看,libiconv 支持多种常见的字符编码,如 ASCII、UTF - 8、GBK、ISO - 8859 等。它提供了一套简洁的 API 接口,包括 iconv_open 用于打开一个编码转换描述符,iconv 进行实际的编码转换操作,以及 iconv_close 关闭转换描述符。这些接口可以方便地集成到各种 C 或 C++ 程序中,也可通过包装器供其他编程语言调用。编译时,libiconv 具有良好的跨平台性,能在 Linux、Windows、macOS 等多种操作系统上进行编译,并且依赖较少,通常只需标准的 C 库支持。

        在应用场景方面,libiconv 具有广泛的用途。在 Web 开发中,当服务器接收来自不同客户端的多语言数据时,可使用 libiconv 将其转换为统一的编码格式进行处理和存储;在文本处理工具中,如编辑器、翻译软件等,libiconv 能帮助用户在不同编码的文本文件之间进行转换。在开源社区,libiconv 基于 GPL 许可发布,代码托管在 GNU 的官方仓库。社区活跃度高,持续对其进行维护和更新,修复潜在的漏洞,添加对新编码格式的支持,拥有大量的用户和开发者群体,被众多知名项目所采用。

2.libiconv编译

2.1.源代码下载

        libiconv源代码可以在gun的官方ftp上下载,源代码下载地址:https://ftp.gnu.org/pub/gnu/libiconv/,根据网上查到的资料显示支持vs编译最后一个版本为1.11.1版本,该版本的发布日期是2007-12-10,虽然看着有点老旧,实践测试功能是可以正常使用的,这里我们会使用vs2008来进行编译,选这个低版本也可以避免在vs2008中编译报错。

        也可以自己复制这个地址下载:https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.11.1.tar.gz 

2.2.windows编译

        先解压源代码到指定目录,libiconv-1.11.1版本中中没有提供CMakeLists.txt编译脚步,提供了makefile文件,在windows上可以使用nmake来构建和编译,但是实际操作已经通过网上查阅的资料,在编译过程中始终会出现问题。这里我们自己编译CMakeLists.txt脚本来构建。

2.2.1.源代码分析

2.2.1.1.makfile文件分析 

        在编译CMakeLists.txt脚本之前我们先分析一下源代码目录中的Makefile.msvc,他会编译libcharsets、lib、srclib、src、po、man、tests等多个子工程,还会拷贝vs特化的一些头文件iconv.h.msvc-static|iconv.h.msvc-shared、config.h.msvc

        实际上以sdk方式做开发时,只需要libcharsetslib子工程编译的库就可以了,后面根据Makefile.msvc文件的分析编写我们规范的CMakeLists.txt脚本文件,同时还会对源代码做部分修改。

2.2.1.2.源代码修改

        针对libiconv源代码修改,实际上是新增源代码下lib、libcharset工程中需要使用的头文件,共有四个,后面会给出每个文件的源代码:

libiconv-1.11.1/include/iconv.h

libiconv-1.11.1/lib/config.h

libiconv-1.11.1/libcharset/config.h

libiconv-1.11.1/libcharset/include/localcharset.h

libiconv-1.11.1/include/iconv.h代码:

/* Copyright (C) 1999-2003, 2005-2006 Free Software Foundation, Inc.
   This file is part of the GNU LIBICONV Library.

   The GNU LIBICONV Library is free software; you can redistribute it
   and/or modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   The GNU LIBICONV Library is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU LIBICONV Library; see the file COPYING.LIB.
   If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
   Fifth Floor, Boston, MA 02110-1301, USA.  */

/* When installed, this file is called "iconv.h". */

#ifndef _LIBICONV_H
#define _LIBICONV_H

#define _LIBICONV_VERSION 0x010B    /* version number: (major<<8) + minor */

#if defined(__GNUC__) && !defined(__MINGW32__)
#  if HAVE_VISIBILITY && BUILDING_LIBICONV
#     define LIBICONV_DLL_EXPORTED __attribute__((__visibility__("default")))
#  else
#     define LIBICONV_DLL_EXPORTED
#  endif
#elif defined(__MINGW32__)

#elif defined(_MSC_VER)
#  include <Windows.h>
#  ifdef ICONV_DLL
#     ifdef BUILDING_LIBICONV
#        define LIBICONV_DLL_EXPORTED __declspec(dllexport)
#     else
#        define LIBICONV_DLL_EXPORTED __declspec(dllimport)
#     endif // ICONV_DLL
#  else
#  define LIBICONV_DLL_EXPORTED
#  endif
#endif

extern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */

/* We would like to #include any system header file which could define
   iconv_t, 1. in order to eliminate the risk that the user gets compilation
   errors because some other system header file includes /usr/include/iconv.h
   which defines iconv_t or declares iconv after this file, 2. when compiling
   for LIBICONV_PLUG, we need the proper iconv_t type in order to produce
   binary compatible code.
   But gcc's #include_next is not portable. Thus, once libiconv's iconv.h
   has been installed in /usr/local/include, there is no way any more to
   include the original /usr/include/iconv.h. We simply have to get away
   without it.
   Ad 1. The risk that a system header file does
   #include "iconv.h"  or  #include_next "iconv.h"
   is small. They all do #include <iconv.h>.
   Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It
   has to be a scalar type because (iconv_t)(-1) is a possible return value
   from iconv_open().) */

/* Define iconv_t ourselves. */
#undef iconv_t
#define iconv_t libiconv_t
typedef void* iconv_t;

/* Get size_t declaration.
   Get wchar_t declaration if it exists. */
#include <stddef.h>

/* Get errno declaration and values. */
#include <errno.h>
/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS,
   have EILSEQ in a different header.  On these systems, define EILSEQ
   ourselves. */
#ifndef EILSEQ
#define EILSEQ @EILSEQ@
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Allocates descriptor for code conversion from encoding `fromcode' to
   encoding `tocode'. */
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
extern LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode);

/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes
   starting at `*inbuf', writing at most `*outbytesleft' bytes starting at
   `*outbuf'.
   Decrements `*inbytesleft' and increments `*inbuf' by the same amount.
   Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */
#ifndef LIBICONV_PLUG
#define iconv libiconv
#endif
extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);

/* Frees resources allocated for conversion descriptor `cd'. */
#ifndef LIBICONV_PLUG
#define iconv_close libiconv_close
#endif
extern LIBICONV_DLL_EXPORTED int iconv_close (iconv_t cd);

#ifndef LIBICONV_PLUG

/* Nonstandard extensions. */

/* Control of attributes. */
#define iconvctl libiconvctl
extern LIBICONV_DLL_EXPORTED int iconvctl (iconv_t cd, int request, void* argument);

/* Hook performed after every successful conversion of a Unicode character. */
typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data);
/* Hook performed after every successful conversion of a wide character. */
typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data);
/* Set of hooks. */
struct iconv_hooks {
  iconv_unicode_char_hook uc_hook;
  iconv_wide_char_hook wc_hook;
  void* data;
};

/* Fallback function.  Invoked when a small number of bytes could not be
   converted to a Unicode character.  This function should process all
   bytes from inbuf and may produce replacement Unicode characters by calling
   the write_replacement callback repeatedly.  */
typedef void (*iconv_unicode_mb_to_uc_fallback)
             (const char* inbuf, size_t inbufsize,
              void (*write_replacement) (const unsigned int *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
/* Fallback function.  Invoked when a Unicode character could not be converted
   to the target encoding.  This function should process the character and
   may produce replacement bytes (in the target encoding) by calling the
   write_replacement callback repeatedly.  */
typedef void (*iconv_unicode_uc_to_mb_fallback)
             (unsigned int code,
              void (*write_replacement) (const char *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
#if 1
/* Fallback function.  Invoked when a number of bytes could not be converted to
   a wide character.  This function should process all bytes from inbuf and may
   produce replacement wide characters by calling the write_replacement
   callback repeatedly.  */
typedef void (*iconv_wchar_mb_to_wc_fallback)
             (const char* inbuf, size_t inbufsize,
              void (*write_replacement) (const wchar_t *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
/* Fallback function.  Invoked when a wide character could not be converted to
   the target encoding.  This function should process the character and may
   produce replacement bytes (in the target encoding) by calling the
   write_replacement callback repeatedly.  */
typedef void (*iconv_wchar_wc_to_mb_fallback)
             (wchar_t code,
              void (*write_replacement) (const char *buf, size_t buflen,
                                         void* callback_arg),
              void* callback_arg,
              void* data);
#else
/* If the wchar_t type does not exist, these two fallback functions are never
   invoked.  Their argument list therefore does not matter.  */
typedef void (*iconv_wchar_mb_to_wc_fallback) ();
typedef void (*iconv_wchar_wc_to_mb_fallback) ();
#endif
/* Set of fallbacks. */
struct iconv_fallbacks {
  iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback;
  iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback;
  iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback;
  iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback;
  void* data;
};

/* Requests for iconvctl. */
#define ICONV_TRIVIALP            0  /* int *argument */
#define ICONV_GET_TRANSLITERATE   1  /* int *argument */
#define ICONV_SET_TRANSLITERATE   2  /* const int *argument */
#define ICONV_GET_DISCARD_ILSEQ   3  /* int *argument */
#define ICONV_SET_DISCARD_ILSEQ   4  /* const int *argument */
#define ICONV_SET_HOOKS           5  /* const struct iconv_hooks *argument */
#define ICONV_SET_FALLBACKS       6  /* const struct iconv_fallbacks *argument */

/* Listing of locale independent encodings. */
#define iconvlist libiconvlist
extern LIBICONV_DLL_EXPORTED void iconvlist (int (*do_one) (unsigned int namescount,
                                      const char * const * names,
                                      void* data),
                       void* data);

/* Canonicalize an encoding name.
   The result is either a canonical encoding name, or name itself. */
extern LIBICONV_DLL_EXPORTED const char * iconv_canonicalize (const char * name);

/* Support for relocatable packages.  */

/* Sets the original and the current installation prefix of the package.
   Relocation simply replaces a pathname starting with the original prefix
   by the corresponding pathname with the current prefix instead.  Both
   prefixes should be directory names without trailing slash (i.e. use ""
   instead of "/").  */
extern LIBICONV_DLL_EXPORTED void libiconv_set_relocation_prefix (const char *orig_prefix,
                   const char *curr_prefix);

#endif

#ifdef __cplusplus
}
#endif

#endif /* _LIBICONV_H */

 libiconv-1.11.1/lib/config.h代码:

/* Copyright (C) 1999-2003, 2005 Free Software Foundation, Inc.
   This file is part of the GNU LIBICONV Library.

   The GNU LIBICONV Library is free software; you can redistribute it
   and/or modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   The GNU LIBICONV Library is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU LIBICONV Library; see the file COPYING.LIB.
   If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
   Fifth Floor, Boston, MA 02110-1301, USA.  */

#if defined(__GNUC__) && !defined(__MINGW32__)
/* Define to 1 if the package shall run at any location in the filesystem. */
#undef ENABLE_RELOCATABLE

/* Define to 1 if you have the setlocale() function. */
#undef HAVE_SETLOCALE

/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Define if the machine's byte ordering is little endian. */
#undef WORDS_LITTLEENDIAN

/* Define to the value of ${prefix}, as a string. */
#undef INSTALLPREFIX

#elif defined(__MINGW32__)

#elif defined(_MSC_VER)
/* Define to 1 if the package shall run at any location in the filesystem. */
#define ENABLE_RELOCATABLE 1

/* Define to 1 if you have the setlocale() function. */
#define HAVE_SETLOCALE 1

/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define if the machine's byte ordering is little endian. */
#define WORDS_LITTLEENDIAN 1
#endif

/* Define to 1 to enable a few rarely used encodings. */
#undef ENABLE_EXTRA

/* Define to a type if <wchar.h> does not define. */
#undef mbstate_t

/* Define if you have <iconv.h>, the iconv_t type, and the
   iconv_open, iconv, iconv_close functions. */
#undef HAVE_ICONV
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST const

/* Define to 1 if you have the getc_unlocked() function. */
#undef HAVE_GETC_UNLOCKED

/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET

/* Define if you have the mbrtowc() function. */
#undef HAVE_MBRTOWC

/* Define to 1 or 0, depending whether the compiler supports simple visibility
   declarations. */
#undef HAVE_VISIBILITY

/* Define if you have the wcrtomb() function. */
#undef HAVE_WCRTOMB

/* Define to the value of ${prefix}, as a string. */
libiconv-1.11.1/libcharset/config.h代码:
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET

/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
#if defined(__GNUC__) && !defined(__MINGW32__)
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE

/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

#elif defined(__MINGW32__)

#elif defined(_MSC_VER)
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1

/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

#endif

/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Define to 1 or 0, depending whether the compiler supports simple visibility
   declarations. */
#undef HAVE_VISIBILITY

/* Define to the value of ${prefix}, as a string. */

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

/* Define to 1 if on AIX 3.
   System headers sometimes define this.
   We just want to avoid a redefinition error message.  */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif

/* Define to 1 if on MINIX. */
#undef _MINIX

/* Define to 2 if the system does not provide POSIX.1 features except with
   this defined. */
#undef _POSIX_1_SOURCE

/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE

libiconv-1.11.1/libcharset/include/localcharset.h代码:

/* Determine a canonical name for the current locale's character encoding.
   Copyright (C) 2000-2003 Free Software Foundation, Inc.
   This file is part of the GNU CHARSET Library.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library General Public License as published
   by the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.  */

#ifndef _LOCALCHARSET_H
#define _LOCALCHARSET_H

#ifdef __cplusplus
extern "C" {
#endif

/* Determine the current locale's character encoding, and canonicalize it
   into one of the canonical names listed in config.charset.
   The result must not be freed; it is statically allocated.
   If the canonical name cannot be determined, the result is a non-canonical
   name.  */
extern const char * locale_charset (void);

#ifdef __cplusplus
}
#endif

#endif /* _LOCALCHARSET_H */
2.2.1.3.增加测试代码

        后面为了验证编译的库是否能正常使用,增加一个测试的源代码文件libiconv-1.11.1/iconv_demo.cpp,注意这个文件使用GB2312格式保存。

#include <iostream>
#include <cstring>
#include <iconv.h>
#include <cstdlib>
#include <string>
#include <windows.h>

#define BUFFER_SIZE 1024

// 编码转换函数
std::string convert_encoding(const std::string& input, const std::string& from_encoding, const std::string& to_encoding) {
    iconv_t cd;
    const char* inbuf = input.c_str();
    size_t inbytesleft = input.length();
    char* outbuf = new char[BUFFER_SIZE];
    char* outptr = outbuf;
    size_t outbytesleft = BUFFER_SIZE;

    // 打开转换描述符
    cd = iconv_open(to_encoding.c_str(), from_encoding.c_str());
    if (cd == (iconv_t)-1) {
        std::cerr << "iconv_open failed: " << std::strerror(errno) << std::endl;
        delete[] outbuf;
        return "";
    }

    // 进行编码转换
    if (iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft) == (size_t)-1) {
        std::cerr << "iconv failed: " << std::strerror(errno) << std::endl;
        iconv_close(cd);
        delete[] outbuf;
        return "";
    }

    // 关闭转换描述符
    iconv_close(cd);

    std::string output(outbuf, BUFFER_SIZE - outbytesleft);
    delete[] outbuf;
    return output;
}

int main() {
    std::string input = "你好,世界!";
    std::cout << "转换前(GBK): " << input << std::endl;
    std::string gbk_encoding = "GBK";
    std::string utf8_encoding = "UTF-8";

    // 进行编码转换
    std::string output = convert_encoding(input, gbk_encoding, utf8_encoding);
    std::cout << "转换后(UTF-8): " << output << std::endl;
    if (!output.empty()) {
        // 将 GBK 转换回 UTF-8 以便在控制台正确显示
        std::string output_utf8 = convert_encoding(output, utf8_encoding, gbk_encoding);
        std::cout << "转换回去(GBK): " << output_utf8 << std::endl;
    }

    // 添加暂停操作
    system("pause");
    return 0;
}

 2.2.2.编写CMake脚本

        前面我们已经对libiconv源代码做出了相应的调整,现在按照我们的设计的编译规范来编写CMakeLists.txt脚本进行构建和编译,在源代码根目录下的创建一个CMakeLists.txt

        脚本涉及的内容主要是使用我们编译规范来对工程命名和输出,以及mt工程的链接库设置。

        CMakeLists.txt完整内容:

cmake_minimum_required(VERSION 3.15)

project(iconv LANGUAGES C CXX)

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake ${CMAKE_MODULE_PATH})
include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/third-common.cmake)

set(ICONV_VERSION "1.11.1")
set(INSTALL_BIN_DIR "${third-bin}/${PROJECT_NAME}-${ICONV_VERSION}" CACHE PATH "Installation directory for executables")
set(INSTALL_LIB_DIR "${third-lib}/${PROJECT_NAME}-${ICONV_VERSION}" CACHE PATH "Installation directory for libraries")
set(INSTALL_INC_DIR "${third-include}/${PROJECT_NAME}-${ICONV_VERSION}" CACHE PATH "Installation directory for headers")
set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")

add_definitions(-DHAVE_CONFIG_H)

set(iconv_pub_include
    include/iconv.h
)

set(libcharset_pub_include
    libcharset/config.h
    libcharset/include/localcharset.h
)

set(libcharset_privite_src
    libcharset/lib/localcharset.c
)

set(lib_pub_include
    lib/config.h
)
set(lib_privite_src
    lib/iconv.c
)

add_library(iconvlib STATIC
    ${iconv_pub_include}
    ${libcharset_pub_include}
    ${libcharset_privite_src}
    ${lib_pub_include}
    ${lib_privite_src})
target_include_directories(iconvlib
    PUBLIC
    include
    libcharset/include
    libcharset
)
get_target_property(iconvlib_files iconvlib SOURCES)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${iconvlib_files})

add_library(iconvdll SHARED
    ${iconv_pub_include}
    ${libcharset_pub_include}
    ${libcharset_privite_src}
    ${lib_pub_include}
    ${lib_privite_src})
target_include_directories(iconvdll
    PUBLIC
    include
    libcharset/include
    libcharset
)
get_target_property(iconvdll_files iconvdll SOURCES)
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${iconvdll_files})
target_compile_definitions(iconvdll PRIVATE ICONV_DLL BUILDING_LIBICONV)

if(MSVC)
    # 静态库mt工程
    add_library(iconvlibmt STATIC
        ${iconv_pub_include}
        ${libcharset_pub_include}
        ${libcharset_privite_src}
        ${lib_pub_include}
        ${lib_privite_src})
    set_property(TARGET iconvlibmt PROPERTY
        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    target_include_directories(iconvlibmt
        PUBLIC
        include
        libcharset/include
        libcharset
    )
    get_target_property(iconvlibmt_files iconvlibmt SOURCES)
    source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${iconvlibmt_files})

    # 动态库mt工程
    add_library(iconvdllmt
        SHARED
        ${iconv_pub_include}
        ${libcharset_pub_include}
        ${libcharset_privite_src}
        ${lib_pub_include}
        ${lib_privite_src})
    set_property(TARGET iconvdllmt PROPERTY
        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    target_include_directories(iconvdllmt
        PUBLIC
        include
        libcharset/include
        libcharset
    )
    get_target_property(iconvdllmt_files iconvdllmt SOURCES)
    target_compile_definitions(iconvdllmt PRIVATE ICONV_DLL BUILDING_LIBICONV)
    source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${iconvdllmt_files})

    add_executable(iconvlibmt_demo iconv_demo.cpp)
    set_property(TARGET iconvlibmt_demo PROPERTY
        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    target_link_libraries(iconvlibmt_demo PRIVATE iconvlibmt)

    add_executable(iconvdllmt_demo iconv_demo.cpp)
    set_property(TARGET iconvdllmt_demo PROPERTY
        MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    target_link_libraries(iconvdllmt_demo PRIVATE iconvdllmt)

      # 设置静态库pdb文件
  set_lib_pdb_file(iconv lib)
  set_lib_pdb_file(iconv libmt)
endif()

add_executable(iconvlib_demo iconv_demo.cpp)
target_link_libraries(iconvlib_demo PRIVATE iconvlib)

add_executable(iconvdll_demo iconv_demo.cpp)
target_link_libraries(iconvdll_demo PRIVATE iconvdll)

# 安装sdk相关文件
# 安装头文件
if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
    install(FILES ${iconv_pub_include}
        DESTINATION "${INSTALL_INC_DIR}"
    )
endif()

if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
    # 安装库文件
    set(iconv_targets iconvlib iconvdll)

    if(MSVC)
        list(APPEND iconv_targets iconvlibmt iconvdllmt)
    endif()

    install(TARGETS ${iconv_targets}
        RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
        ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
        LIBRARY DESTINATION "${INSTALL_LIB_DIR}")
endif()

# 安装pdb文件
if(NOT SKIP_INSTALL_PDB AND NOT SKIP_INSTALL_ALL)
    install(FILES $<TARGET_PDB_FILE:iconvdll> $<TARGET_PDB_FILE:iconvdllmt>
        DESTINATION "${INSTALL_BIN_DIR}"
        OPTIONAL)

    # 静态库pdb调用函数安装
    install_lib_pdb_file(iconv lib)
    install_lib_pdb_file(iconv libmt)
endif()

2.2.3.vs2008编译

        前面我们已经把vs2008编译需要处理的源代码以及CMakeLists.txt脚本按照规范修改完毕,下面我们将使用cmake来构建vs2008的工程和编译。

2.2.3.1.cmake构建目录设置

        选择源代码根目录(CMakeLists.txt文件在这个目录),设置build目录为源代码根目录下的cmake-vs2008绝对路径为D:/x-app/depends/c/libiconv-1.11.1/cmake-vs2008,保证源代码目录干净,会生成工程和临时文件,同时也方便后续有其他的构建工具扩展管理。

2.2.3.2.应用CMake配置 

        点击“Configure”会弹出编译器选择对话框,这里选择“Visual Studio 9 2008”点击“Finish”按钮等待配置参数完成。

 2.2.3.3.生成vs解决方案

        下面的红色警告忽略不用管,意思是未来的cmake版本不再支持生成vs2008的解决方案。

2.2.3.4.编译工程 

        使用vs2008打开“iconv.sln”解决方案文件,分别编译Debug和RelWithDebInfo配置。

2.2.3.5.测试验证

        执行libiconv-1.11.1\cmake-vs2008\output\bin\Debug目录下的iconvlib_demo.exe、iconvdll_demo.exe、iconvlibmt_demo.exe、iconvdllmt_demo.exe测试程序,都是能够正常输出结果在控制台中。  

2.2.3.6.安装库文件、头文件 

        编译Install工程的Debug和RelWithDebInfo配置,.h文件和编译生成.dll、.lib、pdb文件会拷贝CMakeList.txt中设置的路径下。

        至此通过一个CMakeLists配置文件将windows下vs2008常用编译类型的库全部编译出来了,最终库的对应关系如下。  

库类型

运行库类型

库文件

动态库

mdd

iconvdlld.dll、iconvdlld.lib

md

iconvdll.dll、iconvdll.lib

mtd

iconvdllmtd.dll、iconvdllmtd.lib

mt

iconvdllmt.dll、iconvdllmt.lib

静态库

mdd

iconvlibd.lib

md

iconvlib.lib

mtd

iconvlibmtd.lib

mt

iconvlibmt.lib

 2.2.4.vs2015编译

        vs2015编译与vs2008相同的,只需要在CMake生成工程时选择vs2015即可,其他版本的vs也是一样的,选择需要使用的vs版本即可,此处只演示一下vs2015的编译。

        因为前面生成过vs2008的工程,需要将build目录设置成cmake-vs2015,再“Configure”选择vs2015即可,其他操作就是一样的了。

2.2.4.1.vs2015测试 

        运行cmake-vs2015目录下的编译输出的测试exe文件,在控制台中显示的结果与vs2008编译的一致的,这么vs2015编译的库也是没有问题的。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

binary0010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值