A Objective
Linux has a wealth of source code resources, but most of the code is not compiled properly on Windows platform. These source code resources are not directly available to the Windows platform at all. If you want to use the complete code, you need to do a transplant. Because of the different and other reasons for the C + + library, porting C + + code is a difficult task. This article will use a practical example (Tar) to illustrate how to migrate Linux code to the Windows platform. The migration process will modify the code as little as possible so that the logic of the code is not changed. Retain most of the main features of the software.
Two Preparatory work
Tar is a packaged tool underneath the Linux platform. Porting such a program to the Windows platform what do you need to do with those jobs?
The first is some preparation work, install the latest version of Cygwin on the Windows platform, and install the development tools such as GCC in Cygwin. You also need a Windows development environment. You can use the latest version of Visual Studio, Microsoft Visual Studio. NET 2003. Get the latest source code for tar from www.gnu.org, version 1.13. Untie the tar-1.13.tar.gz under the Cygwin. Source code package. Note Do not use WinRAR or WinZip to decompress under Windows. WinRAR and WinZip can be problematic when extracting some tar.gz packets. Causes an exception to the directory and file after the unpack. If it is a source package, it may not compile correctly under Cygwin. After you unpack the package, go to the tar-1.13 directory and enter it below the current directory.
./configure
command, once the operation is complete, enter again
Make
Command. Start compiling the Cygwin version of tar.
The compiler basically does not have the question, enters the SRC directory, may see the newly compiled tar program Tar.exe.
Cygwin is an API layer of Linux simulation environment. If you can compile and run under Cygwin. In fact, you can compile and run under windows, just a layer of intermediate APIs to simulate some Linux-specific operations. Simply determine if a Linux program can be ported to the Windows platform to see if you can compile the source code under Cygwin and run the program.
Compiling the source code of tar in the Cygwin is one of the reasons why the porting is possible. Another reason is that a special header file Config.h is required during the porting of code. Config.h is the most important source code file in the porting process. Config.h files are not part of the source code itself. The file is generated when the "./configure" command runs under Cygwin. When you run the./configure command under Cygwin, config.h files are generated according to the Cygwin Platform development environment. Compile-time also requires config.h files to control code-compiled items. Porting work is also based on config.h files.
The next step is to construct Windows engineering. First create an empty project (project) with Visual Studio. NET 2003, named Wintar. Based on the compiled output information in Cygwin, the main code for tar is in Src and lib two directories. Copy the two directories into the new project and add the code to the project. Then copy the Config.h to the Wintar engineering directory below.
The preparations are basically complete, followed by the transplant. The migration process can be divided into 3 parts.
Three The first goal: to enable Wintar to compile (Compiler)
The completion of the first goal is mainly accomplished around Config.h. A big difference between the Linux development environment and the Windows Development environment is that the C library header file differs from the various types of definitions. Instead, Config.h provides a complete compiler switch to handle the differences that are brought about by different development environments across platforms. Now you need to manually modify this file so that the tar source code can be adapted to the Windows platform.
First, adjust the inclusion of various C library header files (header file). Many similar have_xxxx_h are defined in the Config.h. For example, the definition of have_config_h 1 means that config.h can be used in engineering.
#define HAVE_MALLOC_H 1 indicates that the MALLOC.H header file can be used in the project. By adjusting these values, you can remove header files that are not included under some Windows platforms. Maybe there's a lot of other places. header files contain relationships that need to be handled, but the definition here basically solves most of the header file inclusion issues.
/* Define If you have the <linux/fd.h> header file. */
* * #undef have_linux_fd_h * *
/* Define If you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define If you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define If you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define If you have the <ndir.h> header file. */
* * #undef have_ndir_h * *
The second step is to adjust the definition of various data types, there may be many special data type definitions under Linux, and the Config.h file contains some data type definitions that can be changed. These definitions are generally redefined as basic data types. Can be patched according to the data type definitions under the Windows platform. For example, there is a data type mode_t in the Cygwin development environment, but in Visual Studio C library (the author is very earthy, contact method jackforce at 163 dot com) could not find such a data type. A large number of mode_t data types are used in the TAR code. Config.h provides modifications to allow the developer to modify the definition of mode_t, and suggests that if mode_t is not defined in <sys/types.h>, it can be defined as int. So in Config.h plus #define MODE_T Int. This solves the problem that the mode_t does not define. Other data types are treated similarly.
* Define to ' int ' if <sys/types.h> doesn ' t Define. */
#define MODE_T INT
/* Define to ' long ' if <sys/types.h> doesn ' t Define. */
* * #undef off_t * *
/* Define to ' int ' if <sys/types.h> doesn ' t Define. */
#define PID_T INT
The third step is to adjust various function definitions. In addition to Have_xxxxx_h in Config.h, there is also a predefined, have_xxxx. Here are some optional function definition switches. #define HAVE_MEMSET 1 indicates that the Memset function can be used in engineering. This means that this function has already been implemented in the class library used by the project. If not, then you need to #undef have_memset, and of course you can provide these functions yourself.
/* Define If you have the Memset function. */
#define HAVE_MEMSET 1
/* Define If you have the mkdir function. */
#define HAVE_MKDIR 1
/* Define If you have the Mkfifo function. */
#define HAVE_MKFIFO 1
/* Define If you have the Munmap function. */
#define HAVE_MUNMAP 1
Finally, in addition to the header files, functions, data type compilation options above, there are other things, such as environment variables, and other compilation options in the Config.h file. The content will vary greatly depending on the project. However, it can be seen from the Config.h the workload of the transplant is much.
After the adjustment, is bound (the author is very soil, other articles please see vchelp very soil column) because there are no headers in Windows environment, such as poll.h, there will be no poll function, no dirent.h will not have dirent structure body. and continue to make Wintar compile however. This time it is necessary to modify the details according to the specific compilation error information. When you need to use some special definitions of Windows, don't forget to join #include <windows.h> at the front of the Config.h.
For details, give an example to illustrate. For example, there's an option Have_inttypes_h
/* Define If <inttypes.h> exists, doesn ' t clash with <sys/types.h>
and declares uintmax_t. * *
#define HAVE_INTTYPES_H 1
By analyzing the code, you can see that the code does not require a complete inttypes.h file, but rather a uintmax_t definition. There is no inttypes.h this file in the C Library of visual stdio and there is no uintmax_t this definition. Backtracking cygwin the Include directory of the Inttypes.h file, found the definition of uintmax_t
typedef unsigned long long uintmax_t;
Very simple data type redefinition. This simple definition can be taken out of the Cygwin's include directory separately for a dedicated version of Inttypes.h to join the Wintar project. This solves the problem that uintmax_t does not define during the compilation process. The general approach to solving this type of problem is to take the relevant header files from the Cygwin include directory for modification or to copy them separately to the Wintar directory. [This article was completed in 2003. If you need to reprint please contact Jackforce at 163 dot com] The principle of modifying or copying code is not to introduce more definitions or headers, just the required parts. Other similar issues include the direct structure definition and related functions.
In the process of compiling, many errors are generated by the files in the Lib directory, but the files in the Lib directory are not completely required. The Lib directory is just a supplemental repository for tar. The required code needs to be compiled. One way to make a specific judgment is to refer to the contents of the Windows C Library. If the same function, the data type is already defined, it does not require the definition and function implementations of the same data type in the Lib directory. Another method is to remove the Lib directory of C files, only the header file, and make the compilation can pass, according to link error information to check those Lib C file is needed.
In addition to modifying the various header files around the perimeter, don't forget to modify the project's compilation options, especially the predefined options. The following predefined have_config_h,_posix_source,msdos are required for the migration process in tar. Have_config_h indicates that a config.h file is required for program compilation. For convenience, it is placed in the precompiled option of the project during the TAR migration process. MSDOS, the porting is a Linux console program, and the Windows platform closest to the Linux console is DOS, especially some environment variable settings and global constants defined. Some of the code in tar has been partially modified for the MSDOS environment, which can be exploited during the porting process. There is also an option to be __cygwin__. Some Linux programs make special code settings for the Cygwin platform. When this code is encountered, it is important to add __cygwin__ predefined meanings, which can greatly reduce the amount of effort required for porting. Also, the various CYGWIN codes introduced in the porting process may also require __cygwin__ definitions (sometimes other definitions, such as _posix_source, or __inside_cygwin__).
After a few of these steps. The first goal, the code can be compiled through basically is not a problem. Just grasp the two basic principles of code modification, first. Introduce new code without modifying the original code. It is not allowed to modify the source code before it can be debugged, and a bad modification can cause chaos in the final code run logic, and it is difficult to find the problem before the code is able to run. So do not modify the source code of the transplanted project unless you are very sure. Second, with the introduction of new code, it is not necessary to introduce new code again because of this introduction. This way, it goes into the dead loop. To address the definition of a data type, a new type of data that cannot be interpreted is introduced. It would be better not to introduce new code. So introduce new code, especially a lot of header files. Make sure you change it before you introduce it, just keep the part of the project that you need, and remove the unwanted code. Until it can be compiled. Third: The second goal, so that the code can link to take over (link)
After you have completed your first goal, you will have a large number of link errors. The reason for this is that many external functions have been introduced before, and the external global constants are defined and have no entities, and a link error is generated. What is needed now is to provide the introduced function entity, the external global variable entity, to the code. It's usually a function link (this article was completed in 2003. If you need to reprint please contact Jackforce at 163.com) less than more.
To resolve link errors, you need to understand the difference between functional operations on different platforms, especially some concepts. The best references here are two. One is Windows Services for UNIX (SFU) Help files, one is an article in MSDN, "UNIX application migration Guide." SFU is Microsoft offers a UNIX-compliant environment, a bit like Cygwin. There is a help file after the SFU is installed. Part of this is the description of the Unix,linux function, some of which provide information that can be substituted with those functions in the Windows Library. This is important for transplants (easy to do). UNIX Application Migration Guide should be a bit like a book rather than an article. It illustrates many of the different concepts in Windows and UNIX systems (Unix-like systems), and provides a lot of relevant information on how to simulate these differences for these different concepts. For example, the signals concept in UNIX systems can be replaced with event in Windows environment. SIGALRM uses Windows message to replace the.
The SFU Help file provides a piece of information on which low-level functions (C function Libraries) in the Windows platform can replace the related UNIX functions. The UNIX application migration Guide provides a way to convert some OS-level concepts on UNIX platforms to Windows. In fact, many of these conversions are also done under Cygwin. When solving the link problem concretely, we can refer to the realization of Cygwin itself.
But some concepts, such as the concept of security permissions. The Linux platform and the Windows platform are completely interchangeable. and the permission function operation in the Windows platform (this article was completed in 2003. If you need to reprint please contact jackforce@163.com) is too complex. This is true for some Linux functions. For example, Getuid processing can refer to the Cygwin treatment method. Do nothing directly returns 0 (return 0). When you encounter these functions in your code, you can copy a getuid from the Cygwin code. Into the project.
Using this information, and through relevant tools such as sourceinsight to search the source code of the Cygwin itself, link problem is not difficult to deal with. It is only possible to revert to the problem in the process of dealing with the link problem, compiled however. This time the code changes must be careful not to introduce too many new code, lest the problem become more complex.
Four: The code runs normally
In fact, when the link problem is resolved, the program can run in the Windows environment, and everything is under control. If you do not consider the long platform program, this time can be arbitrary to modify the program. However, you may need a reference in the code debugging process to see what happens to the normal program's running process. Just transplant the program in many places and can not immediately normal operation. Back in Cygwin, recompile a version that you can debug (with the GCC compilation option plus-g3), and you can debug the program in Cygwin when needed. Debugging can be in gdb or insight. If you are accustomed to programming under the Windows platform, you can use the insight, a TCL/TK script that provides a Windows interface to facilitate user debugging, but the insight eventually calls GDB. Here the specific debugging is not detailed description.
Five: Multi-platform Code
The migrated code (this article was completed in 2003. If you need to reprint please contact jackforce@163.com) If you need to run on more than one platform, it is necessary to make a fuss in the Lib directory. Provide your own library of functions and adjust to each platform. The TAR code consists of Config.h and some compilation options to control how to compile on various platforms. LIB provides a number of alternate versions of the C library function or other functions below different platforms. As a result, tar will not compile in the process of some of the platform under certain functions of the lack of compilation. Multi-platform support, usually in the code with a lot of compiler switches, during the compilation to separate linux,windows or other platform under the special code. For example, the Utime.h header file contains problems. Because the files are under Linux (GCC) and are different from the C library directory under Windows (CL). The methods included are not the same. You may need to write this to fully correct inclusion.
#if Have_utime_h----If there are utime.h files
# ifdef Win32-----If it's Win32 environment
# include <sys/utime.h>-----contains sys/utime.h
# endif
# ifdef Linux----If it's a LINUX environment
# include <utime.h>----contains utime.h
# endif
#else ---If no utime.h define the required structure
struct UTIMBUF
{
Long Actime;
Long Modtime;
};
#endif
This is essentially the case with other code. Compile the different code according to the different compilation environment. The define of such a partition is mainly for the different nuances of different platforms. Some of the differences may be that some constants are not defined, and some differences are that some functions do not exist. If the calling function in your code does not exist under some platforms, you need to provide a lib to provide these functions. So is the role of the tar Lib.
Basically the code transplant is difficult before easy. First of all to ensure that the source code itself can not change the logic, so modify the code can only try to modify the peripheral code, rather than modify the source code itself. If link has passed, then is the general windows below the programming, can modify the transplanted code according to the requirement arbitrarily. Perhaps the hardest part is the replacement of different concepts at the OS level. Although the C library is different on each platform, but always relatively close, different places can provide their own written code to replace. However, the OS-level concept, and platform dependencies are too large, generally not easy to replace.
VI. expansion issues, issues to be resolved
If you need to change the migrated code to a DLL or LIB to other engineering calls. For example, the other works to provide a solution to the tar file function. If you do not modify it, the code you have migrated has many flaws.
First, multithreading support issues. If there are many global variables in the code, then the DLL or LIB can not be invoked under multithreading.
Second, the DLL interface table. The code entry after the transplant is the main function, although the entire project has many independent functions, but these independent function calls are implemented by using different parameters. How to output the interface table to other engineering use, need to do some effort.
Third, the control of the original console program after running the parameters, is generally a run to the end, but also may be in the middle of some requirements to enter some information. How are such programs integrated into other projects and controlled by other projects? For example, if you encounter some errors to return. Exit the program directly if you encounter an error in the TAR code. Obviously these places are not the same as the DLL design requirements. You may need to redesign the structure of your code.
Four, output information. The TAR project contains a lot of information that is output to the console. This information output needs to be redirected or masked.
The third part can refer to the Frontend program under Linux, that is, a GUI interface program provided for a particular program. Frontend program is to control the operation of the main program and redirect output information to the GUI interface.
Note 1. Cygwin is a Linux simulation environment underneath the Windows platform. All content can be downloaded from the www.Cygwin.com.
Note 2. Windows Services for UNIX (SFU) SDK can be obtained from the Microsoft Web site http://www.microsoft.com/windows/sfu/
Note 3. UNIX application Migration Guide can be obtained from MSDN if no MSDN is available from the Microsoft MSDN Web site. Http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/ucmglp.asp
Note 4. Tar, cygwin under tar. However, you can only run under Cygwin or you must provide a Cygwin platform DLL to use the TAR program separately under Windows.
Note 5. CL is a Microsoft C + + compiler, included in various versions of Visual Studio
This article was completed in 2003. If you need to reprint, please contact jackforce@163.com, if you see some interference information. Please forgive me. The author mainly avoids the loss of information in the process of reprint. Please forgive me for not thinking of it.
Ps:
Use an example to illustrate some of the issues and solutions that need to be addressed from porting Linux platforms to Windows platforms.
Examples are used only to illustrate problems with the porting process.