cmake: Update internal docs

This commit is contained in:
Corentin Le Molgat
2022-03-24 17:19:17 +01:00
parent cce9c57758
commit 660b2005a5
6 changed files with 269 additions and 138 deletions

View File

@@ -1,12 +1,19 @@
# CI: Makefile/Docker/Vagrant testing
To test the build on various distro, I'm using docker containers and a Makefile for orchestration.
To test the build on various distro, I'm using docker containers and a Makefile
for orchestration.
pros:
* You are independent of third party CI runner config (e.g. github actions runners or Travis-CI VM images).
* You can run it locally on your linux system.
* Most CI provide runner with docker and Makefile already installed (e.g. tarvis-ci [minimal images](https://docs.travis-ci.com/user/languages/minimal-and-generic/).
* You are independent of third party CI runner config (e.g. github actions
runners or Travis-CI VM images).
* You can run it locally on your linux system.
* Most CI provide runner with docker and Makefile already installed (e.g.
tarvis-ci
[minimal images](https://docs.travis-ci.com/user/languages/minimal-and-generic/).
cons:
* Only GNU/Linux distro supported.
* Could take few GiB (~30 GiB for all distro and all languages)
* ~500MiB OS + C++/CMake tools,
@@ -14,72 +21,86 @@ cons:
* ~400 MiB dotnet-sdk,
* ~400 MiB java-jdk.
# Usage
## Usage
To get the help simply type:
```sh
make
```
note: you can also use from top directory
```sh
make --directory=cmake
```
## Example
### Example
For example to test `Python` inside an `Alpine` container:
```sh
make alpine_python_test
```
# Docker
## Docker
[Docker](https://www.docker.com/resources/what-container) is a set of platform
as a service products that use OS-level virtualization to deliver software in
packages called containers.
You can find official base image on the Docker registry [Docker Hub](https://hub.docker.com/search?type=image)
## Layers
Dockerfile is splitted in several stages.
### Layers
Dockerfile is split in several stages.
![docker](docker.svg)
# Vagrant
[Vagrant](https://www.vagrantup.com/intro) is a tool for building and managing virtual machine environments in a single workflow.
It is currently used to test FreeBSD inside a VirtualBox since we don't have any
FreeBSD machine.
Vagrant call a base image a *box*.
## Vagrant
[Vagrant](https://www.vagrantup.com/intro) is a tool for building and managing
virtual machine environments in a single workflow. It is currently used to test
FreeBSD inside a VirtualBox since we don't have any FreeBSD machine. \
Vagrant call a base image a *box*. \
Vagrant call a container a *vagrant machine*.
You can find official box on the Vagrant registry [Vagrant Cloud](https://app.vagrantup.com/boxes/search)
note: Currently only github MacOS runner provide virtualization support (i.e. [VirtualBox](https://www.virtualbox.org/)).
## Basic usage
Once `vagrant` and `VirtualBox` are installed, all commands must be run where the `Vagrantfile` is
located.
### Basic usage
Once `vagrant` and `VirtualBox` are installed, all commands must be run where
the `Vagrantfile` is located.
Generate a `Vagrantfile` skeleton, e.g. using the box `generic/freebsd12`:
```sh
vagrant init generic/freebsd12
```
Build and run a new *vagrant machine*:
```sh
vagrant up
```
note: If you run `virtualbox` you should see it.
Connect to a *vagrant machine*:
```sh
vagrant ssh
[vagrant@freebsd12 ~]$ ...
```
Execute few commands:
```sh
vagrant ssh -c "pwd; ls project ..."
```
Stop and delete a *vagrant machine*:
```sh
vagrant destroy -f
```

View File

@@ -1,6 +1,6 @@
| Linux | macOS | Windows |
|-------|-------|---------|
| [![Status][linux_cpp_svg]][linux_cpp_link] | [![Status][macos_cpp_svg]][macos_cpp_link] | [![Status][windows_cpp_svg]][windows_cpp_link] |
Linux | macOS | Windows
------------------------------------------ | ------------------------------------------ | -------
[![Status][linux_cpp_svg]][linux_cpp_link] | [![Status][macos_cpp_svg]][macos_cpp_link] | [![Status][windows_cpp_svg]][windows_cpp_link]
[linux_cpp_svg]: https://github.com/google/or-tools/actions/workflows/cmake_linux_cpp.yml/badge.svg?branch=master
[linux_cpp_link]: https://github.com/google/or-tools/actions/workflows/cmake_linux_cpp.yml
@@ -10,55 +10,72 @@
[windows_cpp_link]: https://github.com/google/or-tools/actions/workflows/cmake_windows_cpp.yml
# Introduction
For building OR-Tools as a CMake standalone project, you can read the following instructions.
For building OR-Tools as a CMake standalone project, you can read the following
instructions.
This project should run on GNU/Linux, MacOS and Windows.
# C++ Project Build
## C++ Project Build
1. Get the source code and change to it.
```sh
git clone https://github.com/google/or-tools.git
cd or-tools
```
```sh
git clone https://github.com/google/or-tools.git
cd or-tools
```
2. Run CMake to configure the build tree.
```sh
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_DEPS=ON
```
note: To get the list of available generators (e.g. Visual Studio), use `-G ""`
```sh
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_DEPS=ON
```
note: To get the list of available generators (e.g. Visual Studio), use `-G`
3. Afterwards, generated files can be used to compile the project.
```sh
cmake --build build --config Release -v
```
```sh
cmake --build build --config Release -v
```
4. Test the build software (optional).
```sh
cmake --build build --target test
```
```sh
cmake --build build --target test
```
5. Install the built files (optional).
```sh
cmake --build build --target install
```
# Testing
```sh
cmake --build build --target install
```
## Testing
To list tests:
```sh
cd build
ctest -N
```
To only run C++ tests
To only run C++ tests:
```sh
cd build
ctest -R "cxx_.*"
```
# Technical Notes
## Managing RPATH
Since we want to use the [CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html) to generate the wrapper package (e.g. python wheel package) as well as be able to test from the build directory.
## Technical Notes
### Managing RPATH
Since we want to use the
[CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html)
to generate the wrapper package (e.g. python wheel package) as well as be able
to test from the build directory. \
We need to enable:
```cmake
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
```

View File

@@ -1,6 +1,6 @@
| Linux | macOS | Windows |
|-------|-------|---------|
| [![Status][linux_dotnet_svg]][linux_dotnet_link] | [![Status][macos_dotnet_svg]][macos_dotnet_link] | [![Status][windows_dotnet_svg]][windows_dotnet_link] |
Linux | macOS | Windows
------------------------------------------------ | ------------------------------------------------ | -------
[![Status][linux_dotnet_svg]][linux_dotnet_link] | [![Status][macos_dotnet_svg]][macos_dotnet_link] | [![Status][windows_dotnet_svg]][windows_dotnet_link]
[linux_dotnet_svg]: https://github.com/google/or-tools/actions/workflows/cmake_linux_dotnet.yml/badge.svg?branch=master
[linux_dotnet_link]: https://github.com/google/or-tools/actions/workflows/cmake_linux_dotnet.yml
@@ -10,35 +10,47 @@
[windows_dotnet_link]: https://github.com/google/or-tools/actions/workflows/cmake_windows_dotnet.yml
# Introduction
Try to build a .NetStandard2.0 native (for win-x64, linux-x64 and osx-x64) nuget multi package using [`dotnet/cli`](https://github.com/dotnet/cli) and the *new* .csproj format.
# Build the Binary Packages
Try to build a .NetStandard2.0 native (for win-x64, linux-x64 and osx-x64) nuget
multi package using [`dotnet/cli`](https://github.com/dotnet/cli) and the *new*
.csproj format.
## Build the Binary Packages
To build the .Net nuget packages, simply run:
```sh
cmake -S. -Bbuild -DBUILD_DOTNET=ON
cmake --build build --target dotnet_package -v
```
note: Since `dotnet_package` is in target `all`, you can also ommit the
note: Since `dotnet_package` is in target `all`, you can also omit the
`--target` option.
# Testing
## Testing
To list tests:
```sh
cd build
ctest -N
```
To only run .NET tests:
```sh
cd build
ctest -R "dotnet_.*"
```
# Technical Notes
First you should take a look at the [ortools/dotnet/README.md](../../ortools/dotnet/README.md) to understand the layout.
## Technical Notes
First you should take a look at the
[ortools/dotnet/README.md](../../ortools/dotnet/README.md) to understand the
layout. \
Here I will only focus on the CMake/SWIG tips and tricks.
## Build directory layout
### Build directory layout
Since .Net use a `.csproj` project file to orchestrate everything we need to
generate them and have the following layout:
@@ -89,4 +101,5 @@ generate them and have the following layout:
├── replace.cmake
└── replace_runtime.cmake
```
src: `tree build/dotnet --prune -I "obj|bin"`

View File

@@ -1,6 +1,6 @@
| Linux | macOS | Windows |
|-------|-------|---------|
| [![Status][linux_java_svg]][linux_java_link] | [![Status][macos_java_svg]][macos_java_link] | [![Status][windows_java_svg]][windows_java_link] |
Linux | macOS | Windows
-------------------------------------------- | -------------------------------------------- | -------
[![Status][linux_java_svg]][linux_java_link] | [![Status][macos_java_svg]][macos_java_link] | [![Status][windows_java_svg]][windows_java_link]
[linux_java_svg]: https://github.com/google/or-tools/actions/workflows/cmake_linux_java.yml/badge.svg?branch=master
[linux_java_link]: https://github.com/google/or-tools/actions/workflows/cmake_linux_java.yml
@@ -11,16 +11,18 @@
# Introduction
First, verify you have the `JAVA_HOME` environment variable set otherwise CMake and Maven won't be able to find your Java SDK.
First, verify you have the `JAVA_HOME` environment variable set otherwise CMake
and Maven won't be able to find your Java SDK.
## Build the Binary Package
To build the java maven packages, simply run:
```sh
cmake -S. -Bbuild -DBUILD_JAVA=ON
cmake --build build --target java_package -v
```
note: Since `java_package` is in target `all`, you can also ommit the
note: Since `java_package` is in target `all`, you can also omit the
`--target` option.
## Testing
@@ -41,13 +43,16 @@ ctest -R "java_.*"
## Technical Notes
First you should take a look at the [ortools/java/README.md](../../ortools/java/README.md) to understand the layout.
First you should take a look at the
[ortools/java/README.md](../../ortools/java/README.md) to understand the layout.
\
Here I will only focus on the CMake/SWIG tips and tricks.
### Build directory layout
Since Java use the directory layout and we want to use the [CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html)
to generate the Java binary package.
Since Java use the directory layout and we want to use the
[CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html)
to generate the Java binary package.
We want this layout:
@@ -70,7 +75,7 @@ We want this layout:
│   ├── constraintsolver
│   │   ├── ConstraintSolver.java
│   │   └── ...
│   ├── ...
│   ├── ...
│   └── sat
│   ├── CpModel.java
│   └── ...
@@ -81,24 +86,31 @@ We want this layout:
   └── com/google/ortools
   └── Tsp.java
```
src: `tree build/java --prune -U -P "*.java|*.xml|*.so*" -I "target"`
### Managing SWIG generated files
You can use `CMAKE_SWIG_DIR` to change the output directory for the `.java` file e.g.:
You can use `CMAKE_SWIG_DIR` to change the output directory for the `.java` file
e.g.:
```cmake
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/..)
```
And you can use `CMAKE_LIBRARY_OUTPUT_DIRECTORY` to change the output directory for the `.so` file e.g.:
And you can use `CMAKE_LIBRARY_OUTPUT_DIRECTORY` to change the output directory
for the `.so` file e.g.:
```cmake
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..)
```
[optional]You can use `SWIG_OUTFILE_DIR` to change the output directory for the `.cxx` file e.g.:
[optional]You can use `SWIG_OUTFILE_DIR` to change the output directory for the
`.cxx` file e.g.:
```cmake
set(SWIG_OUTFILE_DIR ${CMAKE_CURRENT_BINARY_DIR}/..)
```
Then you only need to create a `pom.xml` file in `build/java` to be able to use
the build directory to generate the Java package.

View File

@@ -1,6 +1,6 @@
| Linux | macOS | Windows |
|-------|-------|---------|
| [![Status][linux_python_svg]][linux_python_link] | [![Status][macos_python_svg]][macos_python_link] | [![Status][windows_python_svg]][windows_python_link] |
Linux | macOS | Windows
------------------------------------------------ | ------------------------------------------------ | -------
[![Status][linux_python_svg]][linux_python_link] | [![Status][macos_python_svg]][macos_python_link] | [![Status][windows_python_svg]][windows_python_link]
[linux_python_svg]: https://github.com/google/or-tools/actions/workflows/cmake_linux_python.yml/badge.svg?branch=master
[linux_python_link]: https://github.com/google/or-tools/actions/workflows/cmake_linux_python.yml
@@ -9,69 +9,92 @@
[windows_python_svg]: https://github.com/google/or-tools/actions/workflows/cmake_windows_python.yml/badge.svg?branch=master
[windows_python_link]: https://github.com/google/or-tools/actions/workflows/cmake_windows_python.yml
# Introduction
To be compliant with [PEP513](https://www.python.org/dev/peps/pep-0513/#the-manylinux1-policy) a python package should embbed all its C++ shared libraries.
# Introduction
Creating a Python native package containing all `.py` and `.so` (with good rpath/loaderpath) is not so easy...
To be compliant with
[PEP513](https://www.python.org/dev/peps/pep-0513/#the-manylinux1-policy) a
python package should embbed all its C++ shared libraries.
Creating a Python native package containing all `.py` and `.so` (with good
rpath/loaderpath) is not so easy...
## Build the Binary Package
# Build the Binary Package
To build the Python wheel package, simply run:
```sh
cmake -S. -Bbuild -DBUILD_PYTHON=ON
cmake --build build --target python_package -v
```
note: Since `python_package` is in target `all`, you can also ommit the
note: Since `python_package` is in target `all`, you can also omit the
`--target` option.
# Testing
## Testing
To list tests:
```sh
cd build
ctest -N
```
To only run Python tests:
```sh
cd build
ctest -R "python_.*"
```
# Technical Notes
First you should take a look at the [ortools/python/README.md](../../ortools/python/README.md) to understand the layout.
## Technical Notes
First you should take a look at the
[ortools/python/README.md](../../ortools/python/README.md) to understand the
layout. \
Here I will only focus on the CMake/SWIG tips and tricks.
## Build directory layout
### Build directory layout
Since Python use the directory name where `__init__.py` file is located and we
want to use the [CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html)
to generate the Python binary package.
want to use the
[CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html)
to generate the Python binary package.
We want this layout:
```shell
<CMAKE_BINARY_DIR>/python
├── setup.py
└── ortools
├── __init__.py
├── algorithms
   ├── __init__.py
   ├── _pywrap.so
   └── pywrap.py
├── __init__.py
├── _pywrap.so
└── pywrap.py
├── graph
   ├── __init__.py
   ├── pywrapgraph.py
   └── _pywrapgraph.so
├── __init__.py
├── pywrapgraph.py
└── _pywrapgraph.so
├── ...
└── .libs
├── libXXX.so.1.0
└── libXXX.so.1.0
```
src: `tree build --prune -U -P "*.py|*.so*" -I "build"`
note: On UNIX you always need `$ORIGIN/../../${PROJECT_NAME}/.libs` since `_pywrapXXX.so` will depend on `libortools.so`.
note: On APPLE you always need `"@loader_path;@loader_path/../../${PROJECT_NAME}/.libs` since `_pywrapXXX.so` will depend on `libortools.dylib`.
note: on Windows since we are using static libraries we won't have the `.libs` directory...
note: On UNIX you always need `$ORIGIN/../../${PROJECT_NAME}/.libs` since
`_pywrapXXX.so` will depend on `libortools.so`. \
note: On APPLE you always need
`"@loader_path;@loader_path/../../${PROJECT_NAME}/.libs` since `_pywrapXXX.so`
will depend on `libortools.dylib`. \
note: on Windows since we are using static libraries we won't have the `.libs`
directory...
So we also need to create few `__init__.py` files to be able to use the build directory to generate the Python package.
So we also need to create few `__init__.py` files to be able to use the build
directory to generate the Python package.
### Why on APPLE lib must be .so
## Why on APPLE lib must be .so
Actually, the cpython code responsible for loading native libraries expect `.so`
on all UNIX platforms.
@@ -90,17 +113,26 @@ const char *_PyImport_DynLoadFiletab[] = {
NULL,
};
```
ref: https://github.com/python/cpython/blob/master/Python/dynload_shlib.c#L36-L48
ref:
https://github.com/python/cpython/blob/master/Python/dynload_shlib.c#L36-L48
i.e. `pywrapXXX` -> `_pywrapXXX.so` -> `libortools.dylib`
## Why setup.py has to be generated
To avoid to put hardcoded path to SWIG `.so/.dylib` generated files,
we could use `$<TARGET_FILE_NAME:tgt>` to retrieve the file (and also deal with Mac/Windows suffix, and target dependencies).
### Why setup.py has to be generated
To avoid to put hardcoded path to SWIG `.so/.dylib` generated files, we could
use `$<TARGET_FILE_NAME:tgt>` to retrieve the file (and also deal with
Mac/Windows suffix, and target dependencies). \
In order for `setup.py` to use
[cmake generator expression](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#informational-expressions)
(e.g. $<TARGET_FILE_NAME:_pyFoo>). We need to generate it at build time (e.g. using
[add_custom_command()](https://cmake.org/cmake/help/latest/command/add_custom_command.html)).
note: This will also add automatically a dependency between the command and the TARGET !
(e.g. `$<TARGET_FILE_NAME:_pyFoo>`). We need to generate it at build time (e.g.
using
[add_custom_command()](https://cmake.org/cmake/help/latest/command/add_custom_command.html)).
todo(mizux): try to use [`file(GENERATE ...)`](https://cmake.org/cmake/help/latest/command/file.html#generate) instead.
note: This will also add automatically a dependency between the command and the
TARGET !
todo(mizux): try to use
[`file(GENERATE ...)`](https://cmake.org/cmake/help/latest/command/file.html#generate)
instead.

View File

@@ -1,41 +1,51 @@
# SWIG Wrapper Generation
Using [swig](https://github.com/swig/swig) to generate wrapper it's easy thanks to the modern
[UseSWIG](https://cmake.org/cmake/help/latest/module/UseSWIG.html) module (**CMake >= 3.14**).
note: SWIG automatically put its target(s) in `all`, thus `cmake --build build` will also call
swig and generate `_module.so`.
Using [swig](https://github.com/swig/swig) to generate wrapper it's easy thanks
to the modern [UseSWIG](https://cmake.org/cmake/help/latest/module/UseSWIG.html)
module (**CMake >= 3.14**).
note: SWIG automatically put its target(s) in `all`, thus `cmake --build build`
will also call swig and generate `_module.so`.
## Policy
# Policy
UseSWIG is impacted by two policies:
* [CMP0078](https://cmake.org/cmake/help/latest/policy/CMP0078.html):UseSWIG generates standard target names (CMake 3.13+).
* [CMP0086](https://cmake.org/cmake/help/latest/policy/CMP0086.html): UseSWIG honors `SWIG_MODULE_NAME` via `-module` flag (CMake 3.14+).
That's why I recommnend to use CMake >= 3.14 with both policies set to new for
SWIG development.
# int64_t Management
When working on a `k8` (aka `x86_64`) architecture, you may face issue with `int64_t`
and `uint64_t` management.
## int64_t Management
When working on a `k8` (aka `x86_64`) architecture, you may face issue with
`int64_t` and `uint64_t` management.
First `long long` and `long int` are **different** types and `int64_t` is just a
typedef on one of them...
## Linux
### Linux
On Linux we have:
```
sizeof(long long): 8
sizeof(long int): 8
sizeof(int64_t): 8
```
### Gcc
#### Gcc
First try to find where and how the compiler define `int64_t` and `uint64_t`.
```sh
grepc -rn "typedef.*int64_t;" /lib/gcc
/lib/gcc/x86_64-linux-gnu/9/include/stdint-gcc.h:43:typedef __INT64_TYPE__ int64_t;
/lib/gcc/x86_64-linux-gnu/9/include/stdint-gcc.h:55:typedef __UINT64_TYPE__ uint64_t;
```
So we need to find this compiler macro definition
```sh
gcc -dM -E -x c /dev/null | grep __INT64
#define __INT64_C(c) c ## L
@@ -48,51 +58,63 @@ gcc -dM -E -x c /dev/null | grep __UINT64
#define __UINT64_TYPE__ long unsigned int
```
### Clang
#### Clang
```sh
clang -dM -E -x c++ /dev/null | grep INT64_TYPE
#define __INT64_TYPE__ long int
#define __UINT64_TYPE__ long unsigned int
```
Clang, GNU compilers:
`-dM` dumps a list of macros.
`-E` prints results to stdout instead of a file.
`-x c` and `-x c++` select the programming language when using a file without a filename extension, such as `/dev/null`
Clang, GNU compilers: \
`-dM` dumps a list of macros. \
`-E` prints results to stdout instead of a file. \
`-x c` and `-x c++` select the programming language when using a file without a
filename extension, such as `/dev/null`
Ref: https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros
Ref:
https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros
### MacOS
## MacOS
On Catalina 10.15 we have:
```
sizeof(long long): 8
sizeof(long int): 8
sizeof(int64_t): 8
```
### Clang
#### Clang
```sh
clang -dM -E -x c++ /dev/null | grep INT64_TYPE
#define __INT64_TYPE__ long long int
#define __UINT64_TYPE__ long long unsigned int
```
with:
`-dM` dumps a list of macros.
`-E` prints results to stdout instead of a file.
`-x c` and `-x c++` select the programming language when using a file without a filename extension, such as `/dev/null`
Ref: https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros
with: `-dM` dumps a list of macros. \
`-E` prints results to stdout instead of a file. \
`-x c` and `-x c++` select the programming language when using a file without a
filename extension, such as `/dev/null`
Ref:
https://web.archive.org/web/20190803041507/http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros
### Windows
## Windows
Contrary to macOS and Linux, Windows 64bits (x86_64) try hard to keep compatibility, so we have:
```
sizeof(long int): 4
sizeof(long long): 8
sizeof(int64_t): 8
```
### Visual Studio 2019
#### Visual Studio 2019
Thus, in `stdint.h` we have:
```cpp
#if _VCRT_COMPILER_PREPROCESSOR
@@ -106,16 +128,22 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
```
## SWIG int64_t management stuff
First, take a look at [Swig stdint.i](https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/stdint.i#L20-L24).
So, when targeting Linux you **must use define SWIGWORDSIZE64** (i.e. `-DSWIGWORDSIZE64`) while
on macOS and Windows you **must not define it**.
### SWIG int64_t management stuff
Now the bad news, even if you can control the SWIG typedef using `SWIGWORDSIZE64`,
[SWIG Java](https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/java/java.swg#L74-L77) and
[SWIG CSHARP](https://github.com/swig/swig/blob/1e36f51346d95f8b9848e682c2eb986e9cb9b4f4/Lib/csharp/csharp.swg#L117-L120) do not take it into account for typemaps...
First, take a look at
[Swig stdint.i](https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/stdint.i#L20-L24).
So, when targeting Linux you **must use define SWIGWORDSIZE64** (i.e.
`-DSWIGWORDSIZE64`) while on macOS and Windows you **must not define it**.
Now the bad news, even if you can control the SWIG typedef using
`SWIGWORDSIZE64`,
[SWIG Java](https://github.com/swig/swig/blob/3a329566f8ae6210a610012ecd60f6455229fe77/Lib/java/java.swg#L74-L77)
and
[SWIG CSHARP](https://github.com/swig/swig/blob/1e36f51346d95f8b9848e682c2eb986e9cb9b4f4/Lib/csharp/csharp.swg#L117-L120)
do not take it into account for typemaps...
So you may want to use this for Java:
```swig
#if defined(SWIGJAVA)
#if defined(SWIGWORDSIZE64)
@@ -157,10 +185,13 @@ PRIMITIVE_TYPEMAP(unsigned long int, unsigned long long);
#endif // defined(SWIGCSHARP)
```
So `int64_t` (i.e. `long int` in this case) will be correctly bind to Java/.Net primitive type `long`.
So `int64_t` (i.e. `long int` in this case) will be correctly bind to Java/.Net
primitive type `long`.
## swig_add_library()
# swig_add_library()
You can use `OUTPUT_DIR` to change the output directory for the `.py` file e.g.:
```cmake
swig_add_library(pyFoo
TYPE SHARED
@@ -169,9 +200,14 @@ swig_add_library(pyFoo
SOURCES foo.i)
```
# Doxygen
Since swig 4.0, swig can now [extract doxygen comments](http://www.swig.org/Doc4.0/Doxygen.html) from C++ to inject it in
Python and Java.
## Doxygen
## Csharp documentation
note: Doxygen to csharp was [planned](https://github.com/swig/swig/wiki/SWIG-4.0-Development#doxygen-documentation) but currently is not supported.
Since swig 4.0, swig can now
[extract doxygen comments](http://www.swig.org/Doc4.0/Doxygen.html) from C++ to
inject it in Python and Java.
### Csharp documentation
note: Doxygen to csharp was
[planned](https://github.com/swig/swig/wiki/SWIG-4.0-Development#doxygen-documentation)
but currently is not supported.