Criando uma dynamic library

Uma dynamic library pode ser carregada no momento da execução do executável, isto é, dinamicamente. Diferente das static libraries, cujo código objeto é adicionado ao executável no momento da linkagem.

Para um exemplo menos detalhado que o exemplo prático, visite: dynamic libraries

Vamos a um exemplo prático:

  1. Crie dois projetos: libmath e app. (Você pode dar os nomes que quiser).
  2. Agora, vá para o projeto libmath, crie o arquivo "libmath.h" com o seguinte conteúdo:

    Se estiver no linux, faça assim:

    libmath.h
    #ifndef LIBMATH_H
    #define LIBMATH_H
    
    namespace libmath {
    
        int fatorial( int n );
    
    }
    
    #endif
    

    Se estiver no windows, faça assim:

    libmath.h
    #ifndef LIBMATH_H
    #define LIBMATH_H
    
    #ifdef BUILDING_DLL
        #define LIBMATH_API __declspec(dllexport)
    #else
        #define LIBMATH_API __declspec(dllimport)
    #endif
    
    namespace libmath {
    
        LIBMATH_API int fatorial( int n );
    
    }
    
    #endif
    
  3. Agora crie o arquivo "libmath.cpp" com o seguinte conteúdo:

    Se estiver no linux, faça assim:

    libmath.cpp
    #include "libmath.h"
    
    namespace libmath {
    
        int fatorial( int n ) {
            if ( n <= 1 )
                return 1;
            return n * fatorial( n-1 );
        }
    
    }
    

    Se estiver no windows, faça assim:

    libmath.cpp
    #include "libmath.h"
    
    namespace libmath {
    
        LIBMATH_API int fatorial( int n ) {
            if ( n <= 1 )
                return 1;
            return n * fatorial( n-1 );
        }
    
    }
    
  4. Agora crie o arquivo FoxMakefile com o seguinte conteúdo:

    Se estiver no linux, crie assim:

    FoxMakefile
    output.file.name=libmath.so
    
    linker.params=-fPIC
    

    No linux é necessário passar o parâmetro -fPIC para o compilador para criar uma shared library .so.


    Se estiver no windows, crie assim:

    FoxMakefile
    output.file.name=libmath.dll
    
    defines=BUILDING_DLL
    

    O "defines=BUILDING_DLL" é necessário porque no código, há algo como:

    #ifdef BULDING_DLL
    

    Após tudo isso, seu projeto deve ter agora a seguinte estrutura:

    libmath
    ├── FoxMakefile
    ├── libmath.cpp
    └── libmath.h
    
  5. Feito isto, pode executar o seguinte comando, estando na raiz do projeto:
    foxmake buildall

    Com o comando acima, o foxmake entende que deve gerar uma dynamic library tipo .dll, ao invés de um executável, por causa da extensão do arquivo de saída "libestruturas.dll".

    Agora, deve ter sido criado na pasta "build" o arquivo libmath.so, ou libmath.dll, se estiver no windows.

  6. Agora vá para o projeto app e copie o arquivo "libmath.so" (ou "libmath.dll") para a raiz do projeto.
  7. Na raiz do seu projeto, crie uma pasta chamada "include" e copie para ela o header "libmath.h" do projeto "libmath".
  8. Depois, crie o arquivo "main.cpp" com o seguinte conteúdo:

    main.cpp
    #include <libmath.h>
    
    #include <iostream>
    
    using namespace std;
    
    
    int main() {
        int num;
        cout << "Informe um numero: " << std::flush;
        cin >> num;
    
        int fat = libmath::fatorial( num );
    
        cout << endl;
        cout << "O fatorial de " << num << " eh: " << fat << endl;
    
        return 0;
    }
    
  9. Agora crie o FoxMakefile para este projeto com o seguinte conteúdo:

    Se estiver no linux, crie assim:

    FoxMakefile
    output.file.name=app
    
    build.files=libmath.so
    
    lib.dirs=.
    include.dirs=include
    libs=math
    

    Se estiver no windows, crie assim: FoxMakefile
    output.file.name=app.exe
    
    build.files=libmath.dll
    
    lib.dirs=.
    include.dirs=include
    libs=math
    

    A propriedade "build.files" serve apenas para copiar a lib libmath.dll para pasta "build"

    Agora seu projeto deve ter a seguinte estrutura de arquivos:

    app
    ├── FoxMakefile
    ├── include
    │   └── libmath.h
    ├── libmath.so
    └── main.cpp
    
  10. Feito isso, pode executar o seguinte comando:
    foxmake buildall
  11. Agora navegue até a pasta build e execute o executável de nome "app", conforme a seguir:
    cd build
    export LD_LIBRARY_PATH=.
    ./app
    

    o "export LD_LIBRARY_PATH=." serve para a lib "libmath.a" ser encontrada. Isto é, ela está no diretório corrente: ".".

    Agora você pode interagir com o programa conforme a seguir:

Para baixar o projeto "dynamic-library-linux" abordado nessa página (versão linux), acesse:

Download: dynamic-library-linux.zip.

Para baixar o projeto "dynamic-library-windows" abordado nessa página (versão windows), acesse:

Download: dynamic-library-windows.zip.

Finalizando

Esta é a última aula sobre o foxmake. Espero que tenha gostado do conteúdo e, divirta-se, automatizando o build de seus projetos em C/C++ com o foxmake.