Configuring the Compilation

The CCompilerDriver package lets you work with C compilers that are installed on your computer. It lets you build executables, libraries, and object files from C source code. It is called automatically by the Wolfram System compiler when you set the option CompilationTarget to "C". It is also useful for building WSTP executables as well as Wolfram Libraries (dynamic linking libraries that can be linked into the Wolfram Language).

This section discusses the various controls the package provides for using a C compiler. Many of the examples will show creating a library, but the general principles also apply to creating an executable and an object file.

To use the package it must first be loaded.

Now you can create a library from a file of C code.

This is a sample source file.

This creates a library and returns the full path.

If you do not have any suitable C compiler the compilation will fail and a message will be generated.

If you want to configure a C compiler when it is called automatically from the Wolfram System compiler you can use Compile`$CCompilerOptions.

Input

C source can be given either as a string or as a file.

Input from a C String

If you have C code in a Wolfram Language string you can compile it into a library.

This loads the package.

Now you can load the C code into a string.

This compiles the C string into a library. The name of the output file is returned; notice how it has been given an extension suitable for the platform.

The output is created in a folder automatically chosen by the Wolfram System. You can change the output folder with the "TargetDirectory" option. The automatic location is given by the variable $CCompilerDefaultDirectory.

You could load and use this in the Wolfram Language with LibraryFunctionLoad. This is made convenient since $CCompilerDefaultDirectory is included in $LibraryPath.

Input from Source Files

If you have C code in one or more files you can compile it into a library.

This loads the package.

This is a sample source file.

Now the code in the file is compiled into a library. The name of the output file is returned; notice how it has been given an extension suitable for the platform.

Note how the name of the file is given in a list. This helps to include several source files; it also distinguishes input from a file from input in a Wolfram Language string.

The library is created in a folder automatically chosen by the Wolfram System. You can change the output folder with the "TargetDirectory" option. The automatic location is given by the variable $CCompilerDefaultDirectory.

You could load and use this library in the Wolfram Language with LibraryFunctionLoad. This is made convenient since $CCompilerDefaultDirectory is included in $LibraryPath.

Output

This loads the package.

The default location for creating output is in $UserBaseDirectory. The value is given by $CCompilerDefaultDirectory.

This is a sample source file.

This changes the location where the output is created; this will use the folder $BaseDirectory.

This deletes the library.

"TargetDirectory"a directory into which output should be written

Option to set the directory for output.

Include Files

The CCompilerDriver package provides two options for setting the path for include files.

"IncludeDirectories" adds extra locations to search for include files; it can take a single string or a list of strings.

In addition to the settings from "IncludeDirectories", other locations are added by default. These include the locations of include files for Wolfram Libraries and for WSTP. The actual locations are set by the option "SystemIncludeDirectories".

This loads the package and finds a sample source file.

This build command adds $UserBaseDirectory as an extra include directory.

"IncludeDirectories"add locations to the include path
"SystemIncludeDirectories"default include locations (includes Wolfram Libraries and WSTP)

Options to work with include files.

Additional Build Libraries

The CCompilerDriver package provides several options to help use additional libraries in your build.

"LibraryDirectories" adds extra locations to search for libraries and "Libraries" gives the names of the libraries. Both can take a single string or a list of strings. When you add the name of a library it will typically be its truncated name.

In addition to these settings, other locations and libraries are also added. These include settings so that WSTP libraries can be found. If you want to modify these standard settings you can use the options "SystemLibraryDirectories" and "SystemLibraries".

This loads the package and finds a sample source file.

This build command adds the Windows library Version.lib as an extra library.

"LibraryDirectories"add locations to the library search path
"Libraries"add libraries to include in the build
"SystemLibraryDirectories"default library locations (includes WSTP)
"SystemLibraries"default libraries (includes WSTP)

Options to work with additional libraries.

Compiler Settings

The CCompilerDriver package provides several options to let you modify the code generated by the compilation process.

The "CompileOptions" option adds compiler-specific flags; it can take a string or a list of strings. In addition to these, other default settings are also added; these are set by "SystemCompileOptions".

This loads the package and finds a sample source file.

This build command turns on warnings for the Visual Studio compiler.

When you set the "CompileOptions" option it will clear the default settings that might be set for the compiler. The compiler-specific documentation describes the default settings.

The "Defines" option adds compiler-specific flags; it can take a string, a list of strings, or a list of rules from string to string.

This build command defines the DEBUG preprocessor macro.

This build command defines the DEBUG preprocessor macro as well as a BUILDNUMBER preprocessor symbol set to a certain value.

"CompileOptions"compiler-specific settings for the compilation
"SystemCompileOptions"default compiler settings for the compilation
"Defines"preprocessor defines to add to the compilation

Options for compiler settings.

Extra Object Files

The CCompilerDriver package typically compiles and links code into an output library or executable. However, it also allows you to include extra object files in your build. This can be useful if you want to compile some files with different settings.

The "ExtraObjectFiles" option adds extra object files. It takes the absolute path to the object file as a string. It can also take a list of object files.

The example will use SymbolicC to create the sample code. First, the packages are loaded.

Now the source for an object file is defined.

This can be compiled into an object file.

Here is another source code fragment. This will call the function defined in the object file.

Now you can compile the second source fragment into a library also using the object file created previously.

Since the extra object file was created with a separate build command, it could take different options.

"ExtraObjectFiles"compiler-specific settings for the compilation

Option for adding object files to the build.

Testing and Monitoring

Several options help you get information about how the compilation process runs. This can be useful if there is a failure.

This loads the package and finds a sample source file.

The "ShellOutputFunction" option can display any messages generated when the compilation runs. This is useful for tracking down an error as the C code runs.

The "ShellCommandFunction" option can display the commands given to the compiler. This is useful for checking the details of what is happening.

The "CreateBinary" option can be used to prevent the actual execution of the compilation. It just shows you what the compilation would do, storing the result in a shell script or batch file.

This prints the contents of the bat file that would run the build. On a Unix operating system this would be called testLib.sh.

This deletes the script.

"ShellOutputFunction"function to display output of the compile process
"ShellCommandFunction"function to display commands used in the compile process
"CreateBinary"whether the compile process should actually execute

Options to control testing and monitoring.

Debugging

You can use a debugger to inspect your code as it executes. This needs various special options to be set. You could use the "CompileOptions" option to set these, but the actual settings are different for each compiler. In addition, you might have to prevent intermediate files from being deleted with "CleanIntermediate".

The "Debug" option does all these for you.

This loads the package and finds a sample source file.

This runs the build to create a debug result.

You will need to delete the temporary files manually, noting the working directory name from the build output. In the example above, this working directory is C:\Users\jfklein\AppData\Roaming\Mathematica\SystemFiles\LibraryResources\Windows-x86-64\Working-xavier-i2win-4848-4428-16.

"Debug"whether to allow debugging in the results of the build

Option to set up C level debugging.

Intermediate Files

Compilation may create various intermediate files, but typically they are not needed and so are deleted at the end of compilation. There is also a decision about what constitutes an intermediate file. For example, when you build a dynamic library on Windows the build will create a DLL file, but also a stub LIB file and an export EXP file.

When you want to debug the C code it is often useful not to clean intermediate files.

How these are all cleaned is controlled by the "CleanIntermediate" option. The possible values are summarized in the following table.

Trueclean all intermediate files
Falsepreserve all intermediate files
Automaticclean all intermediate files, except the stub LIB file and export EXP file in Windows
Fullclean all files in the working directory, without regard to whether they are intermediate files or not

This loads the package and finds a sample source file. It also sets up a temporary directory.

This runs the build to create a debug result.

This shows that the three files for the dynamic library on Windows are kept, a feature of the default setting of Automatic.

This runs the command but uses a "CleanIntermediate" of True.

This has just kept the DLL file. For Unix there will be no difference between the Automatic and True settings.

This creates the library, but sets "CleanIntermediate" to False.

The working directory is named automatically to avoid conflicts.

These are the intermediate files in the working directory.

"CleanIntermediate"whether intermediate files should be deleted

Option to set up C level debugging.

Building for Different Systems

The "TargetSystemID" option allows some degree of control to create results for a specific system. The default setting is to create one compatible with the current version of the Wolfram Language. However, if your compiler can generate other types of output, you can use "TargetSystemID". It can be useful to create 32-bit results when running on a 64-bit machine.

This loads the package and finds a sample source file.

This creates a library that will run on a 64-bit version of Windows (note that this requires that your compiler can generate 64-bit Windows output).

"TargetSystemID"the system where the compiler output will be used

Option to set the target system to build for.

Setting the Compiler

When you use a compilation command such as CreateExecutable, it searches for a compiler that is available and suitable for your system. The details of how this is done are found in the section on Specific Compilers.

However, there are a few options that can be useful for setting the compiler that is used.

The option "Compiler" is used to set the type of compiler, such as Visual Studio or GCC. This might be useful if you have more than one compiler installed, or if the compiler you have is not detected automatically.

The option "CompilerInstallation" is used to set the location of the compiler software. Some compilers use environment variables to advertise their location and some are automatically found on a path. However, if your compiler cannot be found by one of these mechanisms you can use the option.

The option "CompilerName" is used to set the name of the compiler executable. This is useful if the compiler software supports more than one compiler command, for example, gcc can also be known as g++.

"Compiler"which compiler should be used
"CompilerInstallation"the location of the compiler software
"CompilerName"the name of the compile command to use

Options to configure which compiler is used.

You can set these options for individual commands. Alternatively, you can set them globally using $CCompiler; this is described in the section on Setting a Different Compiler.