{"action":"created","issue":{"url":"https://api.github.com/repos/stan-dev/math/issues/311","repository_url":"https://api.github.com/repos/stan-dev/math","labels_url":"https://api.github.com/repos/stan-dev/math/issues/311/labels{/name}","comments_url":"https://api.github.com/repos/stan-dev/math/issues/311/comments","events_url":"https://api.github.com/repos/stan-dev/math/issues/311/events","html_url":"https://github.com/stan-dev/math/issues/311","id":163025070,"number":311,"title":"Multiple definitions when including Stan headers in several source files","user":{"login":"rgiordan","id":4494910,"avatar_url":"https://avatars.githubusercontent.com/u/4494910?v=3","gravatar_id":"","url":"https://api.github.com/users/rgiordan","html_url":"https://github.com/rgiordan","followers_url":"https://api.github.com/users/rgiordan/followers","following_url":"https://api.github.com/users/rgiordan/following{/other_user}","gists_url":"https://api.github.com/users/rgiordan/gists{/gist_id}","starred_url":"https://api.github.com/users/rgiordan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rgiordan/subscriptions","organizations_url":"https://api.github.com/users/rgiordan/orgs","repos_url":"https://api.github.com/users/rgiordan/repos","events_url":"https://api.github.com/users/rgiordan/events{/privacy}","received_events_url":"https://api.github.com/users/rgiordan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":19,"created_at":"2016-06-29T20:58:59Z","updated_at":"2016-07-09T19:45:18Z","closed_at":null,"body":"#### Summary:\r\nStan headers cause multiple definition errors when included in several source files that are linked together in a library.\r\n\r\n#### Description:\r\nIf the Stan headers are included in several source files that are compiled separately and then linked, the compiler fails with multiple definition errors.  I am a C++ novice, but I believe this is because non-inline functions are being instantiated in the header files (e.g. ```print_mat_size```).\r\n\r\n#### Reproducible Steps:\r\nA minimal example to reproduce can be found in [this repo](https://github.com/rgiordan/StanHeaderExample).  In short, it has two `cpp` files that each instantiate templates using Stan variables.  They can be successfully compiled into object files, but the linker fails with multiple definition errors.\r\n\r\n```\r\n// source1.hpp:\r\n# ifndef SOURCE1_H\r\n# define SOURCE1_H\r\n\r\n#include <boost/math/special_functions/digamma.hpp>\r\n#include <boost/math/special_functions/gamma.hpp>\r\n\r\nusing boost::math::lgamma;\r\nusing boost::math::digamma;\r\n\r\n# include <stan/math.hpp>\r\n# include \"stan/math/fwd/scal.hpp\"\r\n\r\nusing var = stan::math::var;\r\nusing fvar = stan::math::fvar<var>;\r\n\r\ntemplate <typename T> T multivariate_lgamma(T x, int p) {\r\n  T result = log(M_PI) * p * (p - 1.0) / 4.0;\r\n  for (int i = 1; i <= p; i++) {\r\n    result += lgamma(x + 0.5 * (1 - (double)i));\r\n  }\r\n  return result;\r\n}\r\n\r\nextern template double multivariate_lgamma(double x, int p);\r\nextern template var multivariate_lgamma(var x, int p);\r\nextern template fvar multivariate_lgamma(fvar x, int p);\r\n\r\n# endif\r\n\r\n// source1.cpp:\r\n# include \"source1.hpp\"\r\n# include <stan/math.hpp>\r\n# include <stan/math/fwd/scal.hpp>\r\n\r\nusing var = stan::math::var;\r\nusing fvar = stan::math::fvar<var>;\r\n\r\ntemplate double multivariate_lgamma(double x, int p);\r\ntemplate var multivariate_lgamma(var x, int p);\r\ntemplate fvar multivariate_lgamma(fvar x, int p);\r\n\r\n\r\n// source1.hpp:\r\n# ifndef SOURCE2_H\r\n# define SOURCE2_H\r\n\r\n#include <boost/math/special_functions/digamma.hpp>\r\n#include <boost/math/special_functions/gamma.hpp>\r\n\r\nusing boost::math::lgamma;\r\nusing boost::math::digamma;\r\n\r\n# include <stan/math.hpp>\r\n# include \"stan/math/fwd/scal.hpp\"\r\n\r\nusing var = stan::math::var;\r\nusing fvar = stan::math::fvar<var>;\r\n\r\ntemplate <typename T> T multivariate_digamma(T x, int p) {\r\n  T result = 0.0;\r\n  for (int i = 1; i <= p; i++) {\r\n    result += digamma(x + 0.5 * (1 - (double)i));\r\n  }\r\n  return result;\r\n}\r\n\r\nextern template double multivariate_digamma(double x, int p);\r\nextern template var multivariate_digamma(var x, int p);\r\nextern template fvar multivariate_digamma(fvar x, int p);\r\n\r\n# endif\r\n\r\n// source2.cpp:\r\n# include \"source2.hpp\"\r\n# include <stan/math.hpp>\r\n# include <stan/math/fwd/scal.hpp>\r\n\r\nusing var = stan::math::var;\r\nusing fvar = stan::math::fvar<var>;\r\n\r\ntemplate double multivariate_digamma(double x, int p);\r\ntemplate var multivariate_digamma(var x, int p);\r\ntemplate fvar multivariate_digamma(fvar x, int p);\r\n\r\n```\r\n\r\n#### Current Output:\r\nThe linker fails with errors like this:\r\n```\r\n[ 33%] Building CXX object CMakeFiles/StanHeaderExample.dir/source2.cpp.o\r\nLinking CXX shared library libStanHeaderExample.so\r\nCMakeFiles/StanHeaderExample.dir/source2.cpp.o: In function `stan::math::print_mat_size(int, std::ostream&)':\r\nsource2.cpp:(.text+0x1390): multiple definition of `stan::math::print_mat_size(int, std::ostream&)'\r\nCMakeFiles/StanHeaderExample.dir/source1.cpp.o:source1.cpp:(.text+0x12c0): first defined here\r\nCMakeFiles/StanHeaderExample.dir/source2.cpp.o: In function `stan::math::csr_u_to_z(std::vector<int, std::allocator<int> > const&, int)':\r\nsource2.cpp:(.text+0x13c0): multiple definition of `stan::math::csr_u_to_z(std::vector<int, std::allocator<int> > const&, int)'\r\nCMakeFiles/StanHeaderExample.dir/source1.cpp.o:source1.cpp:(.text+0x12f0): first defined here\r\n... and so on.\r\n```\r\n\r\n#### Expected Output:\r\nA compiled shared library with templates instantiated with Stan types.\r\n\r\n#### Additional Information:\r\nProvide any additional information here.\r\n\r\n#### Current Version:\r\nv2.9.0\r\n"},"comment":{"url":"https://api.github.com/repos/stan-dev/math/issues/comments/231552320","html_url":"https://github.com/stan-dev/math/issues/311#issuecomment-231552320","issue_url":"https://api.github.com/repos/stan-dev/math/issues/311","id":231552320,"user":{"login":"bgoodri","id":3386282,"avatar_url":"https://avatars.githubusercontent.com/u/3386282?v=3","gravatar_id":"","url":"https://api.github.com/users/bgoodri","html_url":"https://github.com/bgoodri","followers_url":"https://api.github.com/users/bgoodri/followers","following_url":"https://api.github.com/users/bgoodri/following{/other_user}","gists_url":"https://api.github.com/users/bgoodri/gists{/gist_id}","starred_url":"https://api.github.com/users/bgoodri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgoodri/subscriptions","organizations_url":"https://api.github.com/users/bgoodri/orgs","repos_url":"https://api.github.com/users/bgoodri/repos","events_url":"https://api.github.com/users/bgoodri/events{/privacy}","received_events_url":"https://api.github.com/users/bgoodri/received_events","type":"User","site_admin":false},"created_at":"2016-07-09T19:45:18Z","updated_at":"2016-07-09T19:45:18Z","body":"I meant LDFLAGS as it is a linker option\r\nhttp://linux.die.net/man/1/ld\r\nI don't think designing the Stan library correctly is in the cards."}}
{"actor":{"display_login":"bgoodri"}}