Когда вы создаете статическую библиотеку, компоновщик не пытается разрешить все, что отсутствует; предполагается, что вы будете позже связывать его с другой библиотекой или что сам исполняемый файл будет вносить некоторую недостающую функцию. Вы, должно быть, забыли включить некоторые важные файлы реализации в проект библиотеки.
Другая возможность состоит в том, что класс реализации pimpl является классом шаблона. Шаблоны не генерируют код сразу, компилятор ждет, пока вы не попытаетесь использовать их с заполненными параметрами шаблона. В вашем файле реализации должен быть экземпляр шаблона с параметрами, которые будут поддерживаться вашей библиотекой.
После просмотра ваших изменений проблема в том, что конструктору Foo :: Foo необходим доступ к конструктору FooImpl :: FooImpl, но компоновщик не знает, где его найти. Когда компоновщик собирает библиотеку, он не пытается разрешить все ссылки в это время, потому что он может зависеть от еще одной библиотеки. Единственный раз, когда все должно быть решено, это когда он собирает исполняемый файл. Поэтому, хотя Bar и не нужно напрямую знать о FooImpl, он все равно зависит от него.
Вы можете решить эту проблему одним из двух способов: либо экспортировать FooImpl из библиотеки вместе с Foo, либо убедиться, что Foo имеет доступ к FooImpl во время компиляции, поместив их обоих в Foo.cpp с FooImpl, предшествующим Foo.