2013-10-13 2 views
0

Я пытаюсь изучить CMake, используя примерный проект, который вычисляет фибоначчи определенного числа. Мой проект первоначально включал единственный файл .c и .c. Я смог построить с CMake и работать без проблем. Теперь я пытаюсь научиться связывать библиотеки, переместив мою функцию финоакши в отдельный файл «.c», который я компилирую в библиотеку с возможностью компоновки с помощью CMake. Он строит без проблем, но вызывает ошибку сегментации, когда я запускаю его. Моя структура проекта:Проблема с дефектом сегментации CMake Noob

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

Файл CMakeLists.txt под папкой MathFunctions пуст. Вся логика программы находится в файле fib.c и myfib.c. Все сборки находится в верхней 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) 

После запуска «..cmake» и «make» из папки сборки, которую я запускаю:

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

Куда я иду не так?

+1

Wild догадка: 'myfib.h' не содержит действительный прототип' myfib', вы не обращая внимания на предупреждения компилятора (или не включили их), и вы используете 'atof' где его использование не оправдано (подсказка: 'f' означает' float', числа Фибоначчи - целые числа). –

+0

Если вы собираетесь публиковать код, напишите * минимальный рабочий пример *, а не наполовину ваш код с большими битами - прокомментированный и, следовательно, ненужный. Это раздражает прокрутку кода, который вы явно не используете (закомментирован), но который, по-видимому, достаточно уместен, чтобы добавить к вопросу. Вы также не разместили файлы заголовков. Вы использовали отладчик, чтобы определить, где находится segfault? – simont

+0

Спасибо! Я не понимал (пока вы не указали на atof()), что я опускаю параметр в свою собственную программу! Конечно, я получаю ошибку при сбое, когда парам не хватает ... он пытается получить доступ к памяти, которой он не владеет! Thanx! Я отредактирую свой вопрос, чтобы быть немного более очевидным. – Cliff

ответ

3

Действительно ли вы вы получаете segfault из-за своей системы сборки?

Ваш код требует ввода, и вы делаете Не проверяйте, что ввод указан. Из fib.c:26:

myfib(atof(argv[1])); 

Если аргументы не заданы, ваш код будет пытаться читать данные, которые вы не предоставили (и Segfault). Если вы запустите свой код: ./fibonacci 3, вы напечатаете myfib. Я собираюсь догадаться, что это ваша проблема.


Другие вещи, чтобы рассмотреть следующие вопросы:

  • давая часть кода, попытайтесь убедиться, что это либо минимальное и полное или точно описывает вашу проблему. Большие блоки кода с комментариями не относятся к вопросу, тогда как в этом случае заголовочные файлы и Config.h.in (которые должны получить ваш пример для компиляции), не предоставляются.
  • myfib.c и myfib.h находятся в разных папках. Если myfib.c является частью библиотеки MathFunctions, я бы поместил источники в этот подкаталог. Это объясняется в учебнике я думаю, что вы после: this one, который имеет CMakeLists.txt файл, содержащий строку:

    add_library (MathFunctions mysqrt.cxx)

    в MathFunctions библиотеке.

  • Как указано @n.м в комментариях, atof принимает вход float - последовательность Фибоначчи генерируется с использованием int (поэтому более подходит atoi).

  • Для вашего примера я бы не использовал add_definitions для установки флагов компилятора. Лучший способ сделать это (по всему проекту) - использовать set (CMAKE_CXX_FLAGS "-O0 -g -Wall"). (Есть много useful CMake Variables). Пока работает add_definitions, это не лучший инструмент для работы, которую вы делаете. :)

+0

Я ответил более раннему комментатору перед освежением и увидев этот ответ. Вы абсолютно правы! Я забыл параметр, который вызвал segfault! Спасибо вам обоим! – Cliff

Смежные вопросы