2013-10-13 7 views
0

J'essaie d'apprendre CMake en utilisant un exemple de projet qui calcule le fibonacci d'un nombre donné. Mon projet comprenait à l'origine un seul fichier ".c" et un en-tête. J'ai pu construire avec CMake et courir sans problème. Maintenant, j'essaie d'apprendre à lier les bibliothèques en déplaçant ma fonction fibnoacci dans un fichier ".c" séparé que je compile dans une bibliothèque connectable en utilisant CMake. Il se construit sans problème mais lance une erreur de segmentation quand je l'exécute. Ma structure du projet est:Problème de faute de segmentation CMake Noob

fib 
| 
*---MathFunctions 
| | 
| *----CMakeLists.txt 
| | 
| *----myfib.h 
| 
*---CMakeLists.txt 
| 
*---fib.c 
| 
*---fib.h 
| 
*---myfib.c 
| 
*---Config.in.h 

Le CMakeLists.txt dans le dossier MathFunctions est vide. Toute la logique du programme est dans fib.c et myfib.c. Tout de la construction se trouve dans la partie supérieure CMakeLists.txt

fib.c:

# include "stdio.h" 
# include "stdlib.h" 
# include "Config.h" 
#include "myfib.h" 

void internalfib(int num) 
{ 
    printf("Internally defined fib\n"); 
    int a, b; 
    a = 0; 
    b = 1; 
    printf("custom fib of %d", b); 
    for(int i = 0; i + a <= num; b = i) { 
     i = a + b; 
     a = b; 
     printf(", %d", i); 
    } 
} 

int main(int argc, char** argv) { 
    fprintf(stdout,"%s Version %d.%d\n", 
       argv[0], 
       VERSION_MAJOR, 
       VERSION_MINOR); 
#ifdef SHOW_OWNER 
    fprintf(stdout, "Project Owner: %s\n", OWNER); 
#endif 
    myfib(atof(argv[1])); 
    printf("\n"); 
    return EXIT_SUCCESS; 
} 

myfib.c:

# include "stdio.h" 
# include "stdlib.h" 

void myfib(int num) 
{ 
    printf("custom myfib"); 
    int a, b; 
    a = 0; 
    b = 1; 
    printf("custom fib of %d", b); 
    for(int i = 0; i + a <= num; b = i) { 
     i = a + b; 
     a = b; 
     printf(", %d", i); 
    } 
} 

CMakeLists.txt:

#Specify the version being used aswell as the language 
cmake_minimum_required(VERSION 2.6) 
#Name your project here 
project(fibonacci) 
enable_testing() 
set (VERSION_MAJOR 1) 
set (VERSION_MINOR 0) 

configure_file (
    "${PROJECT_SOURCE_DIR}/Config.h.in" 
    "${PROJECT_BINARY_DIR}/Config.h" 
) 

option (SHOW_OWNER "Show the name of the project owner" ON) 

#Sends the -std=c99 flag to the gcc compiler 
add_definitions(-std=c99) 

include_directories("${PROJECT_BINARY_DIR}") 
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") 
add_subdirectory (MathFunctions) 
add_library(MathFunctions myfib.c) 

#This tells CMake to fib.c and name it fibonacci 
add_executable(fibonacci fib.c) 
target_link_libraries (fibonacci MathFunctions) 

#test that fibonacci runs 
add_test (FibonacciRuns fibonacci 5) 
#Test the fibonacci of 5 
add_test (FibonacciCompare5 fibonacci 5) 

set_tests_properties (FibonacciCompare5 PROPERTIES PASS_REGULAR_EXPRESSION "1, 1, 2, 3, 5") 

install (TARGETS fibonacci DESTINATION ${PROJECT_BINARY_DIR}/bin) 

Après l'exécution "..cmake" et "make" du dossier de construction que je cours:

~/dev/cworkshop/fib/build$ ./fibonacci 
./fibonacci Version 1.0 
Project Owner: Clifton C. Craig 
Segmentation fault: 11 

Où est-ce que je me trompe?

+1

conjecture sauvage: 'myfib.h' ne contient pas un prototype valide de' myfib', vous ne faites pas attention aux avertissements du compilateur (ou ne les ont pas permis), et que vous utilisez 'atof' où son utilisation n'est pas garantie (indice: 'f' signifie' float', les nombres de Fibonacci sont des entiers). –

+0

Si vous allez poster du code, veuillez publier un * exemple de travail minimal *, pas la moitié de votre code-avec-grand-bits-commenter-out-et-donc-inutile. C'est ennuyeux de faire défiler le code que vous n'utilisez clairement pas (commenté) mais qui est apparemment assez pertinent pour ajouter à la question. Vous n'avez également pas publié les fichiers d'en-tête. Avez-vous utilisé un débogueur pour déterminer où est la segfault? – simont

+0

Merci! Je n'ai pas réalisé (jusqu'à ce que vous ayez signalé la chose atof()) que j'omettais le paramètre à mon propre programme! Bien sûr, je reçois un défaut lorsque le param est parti ... il essaie d'accéder à la mémoire qu'il ne possède pas! Merci! Je vais éditer ma question pour être un peu plus évident. – Cliff

Répondre

3

Etes-vous réellement vous avez une erreur de segmentation due à votre système de construction?

Votre code requiert l'entrée, et ne vérifie pas que l'entrée est. De fib.c:26:

myfib(atof(argv[1])); 

Si aucun argument ne donne, votre code va essayer de lire les données que vous n'avez pas fourni (et segfault). Si vous exécutez votre code: ./fibonacci 3, vous allez imprimer myfib. Je vais deviner c'est quel est votre problème.


Autres choses à considérer:

  • en donnant une partie de code, essayer de faire en sorte que ce soit est minime et complète, ou décrit avec précision votre problème. Les gros blocs de code commentés ne sont pas pertinents pour la question, alors que dans ce cas, les fichiers d'en-tête et Config.h.in (qui sont requis pour obtenir votre exemple à compiler) ne sont pas fournis.
  • myfib.c et myfib.h sont dans des dossiers différents. Si myfib.c fait partie de la bibliothèque MathFunctions, je placerais les sources dans ce sous-répertoire. Ceci est expliqué dans le tutoriel, je pense que vous suivez: this one, qui a un fichier CMakeLists.txt contenant la ligne:

    add_library (MathFunctions mysqrt.cxx)

    dans la bibliothèque MathFunctions.

  • Comme indiqué par @n.m dans les commentaires, atof prend un float en entrée - la séquence Fibonacci est générée en utilisant un int (donc atoi est plus approprié).

  • Pour votre exemple, je n'utiliserais pas add_definitions pour définir les indicateurs du compilateur. La meilleure façon de le faire (à l'échelle du projet) est d'utiliser set (CMAKE_CXX_FLAGS "-O0 -g -Wall"). (Il y a beaucoup de useful CMake Variables). Alors que add_definitions fonctionne, ce n'est pas le meilleur outil pour le travail que vous faites. :)

+0

J'ai répondu à l'intervenant précédent avant de rafraîchir et de voir cette réponse. Vous avez absolument raison! J'oubliais le paramètre qui a déclenché le segfault! Merci à vous deux! – Cliff

Questions connexes